Http.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795
  1. /** (c) Nullsoft, Inc. C O N F I D E N T I A L
  2. ** Filename:
  3. ** Project:
  4. ** Description:
  5. ** Author:
  6. ** Created:
  7. **/
  8. #include "Main.h"
  9. #include <cstdint>
  10. #if 1
  11. #include <sys/types.h>
  12. #include <winsock.h>
  13. #include "../nu/threadname.h"
  14. #include "Wa_dlg.h"
  15. #include "../nu/AutoWide.h"
  16. static void createDirForFileW(wchar_t *str)
  17. {
  18. wchar_t *p = str;
  19. if ((p[0] ==L'\\' || p[0] ==L'/') && (p[1] ==L'\\' || p[1] ==L'/'))
  20. {
  21. p += 2;
  22. while (p && *p && *p !=L'\\' && *p !=L'/') p++;
  23. if (!*p) return ;
  24. p++;
  25. while (p && *p && *p !=L'\\' && *p !=L'/') p++;
  26. }
  27. else
  28. {
  29. while (p && *p && *p !=L'\\' && *p !=L'/') p++;
  30. }
  31. while (p && *p)
  32. {
  33. while (p && *p !=L'\\' && *p !=L'/' && *p) p = CharNextW(p);
  34. if (*p)
  35. {
  36. wchar_t lp = *p;
  37. *p = 0;
  38. CreateDirectoryW(str, NULL);
  39. *p++ = lp;
  40. }
  41. }
  42. }
  43. static const wchar_t *rf_file, *rf_dlgtitle;
  44. static const char *rf_url;
  45. static int rf_in;
  46. static HWND rf_dlgWnd, rf_statusWnd;
  47. static volatile int rf_rv=-1;
  48. static volatile int rf_abort;
  49. static int g_rv;
  50. static int _rftabort(int r, char *s)
  51. {
  52. if (s) SetWindowTextA(rf_statusWnd,s);
  53. if (rf_dlgWnd) SendMessageW(rf_dlgWnd,WM_USER+1,r,0);
  54. else rf_rv=r;
  55. return r;
  56. }
  57. #define rfta(s) return _rftabort(!success,s)
  58. #define sets(s) SetWindowTextA(rf_statusWnd,s)
  59. typedef int (__stdcall *waP_RECV)(SOCKET s, char FAR* buf, int len, int flags);
  60. waP_RECV p_recv;
  61. static void encodeMimeStr(char *in, char *out)
  62. {
  63. char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  64. int shift = 0;
  65. int accum = 0;
  66. while (in && *in)
  67. {
  68. if (*in)
  69. {
  70. accum <<= 8;
  71. shift += 8;
  72. accum |= *in++;
  73. }
  74. while ( shift >= 6 )
  75. {
  76. shift -= 6;
  77. *out++ = alphabet[(accum >> shift) & 0x3F];
  78. }
  79. }
  80. if (shift == 4)
  81. {
  82. *out++ = alphabet[(accum & 0xF)<<2];
  83. *out++='=';
  84. }
  85. else if (shift == 2)
  86. {
  87. *out++ = alphabet[(accum & 0x3)<<4];
  88. *out++='=';
  89. *out++='=';
  90. }
  91. *out++=0;
  92. }
  93. static int recv_string(SOCKET s, char *str, int maxlen)
  94. {
  95. int p=0;
  96. do
  97. {
  98. int t=0;
  99. while (t!=1)
  100. {
  101. t=p_recv(s,str+p,1,0);
  102. if (t != 1)
  103. {
  104. if (rf_abort || !t) { str[0]=0; return -1; }
  105. Sleep(100);
  106. }
  107. if (str[p] == '\r') t=0;
  108. }
  109. } while (str[p] != '\n' && ++p < maxlen-1);
  110. str[p--]=0;
  111. while (str[p] == '\n' && p > 0)
  112. {
  113. str[p--]=0;
  114. }
  115. if (p < 0) p = 0;
  116. return p;
  117. }
  118. static int g_in_resolve;
  119. static DWORD WINAPI rf_ThreadProc(LPVOID p666)
  120. {
  121. char locbuf[1024]={0};
  122. int redirect=0;
  123. HINSTANCE hws = LoadLibraryA("wsock32.dll");
  124. int total_bytes;
  125. uint64_t content_length;
  126. SOCKET sock;
  127. char proxytmp[256]={0};
  128. char *proxy;
  129. char connect_host[MAX_PATH]={0};
  130. unsigned short connect_port;
  131. int success=0;
  132. typedef int (__stdcall *waSELECT)(int nfds,fd_set FAR * readfds,fd_set FAR * writefds,fd_set FAR * exceptfds,const struct timeval FAR * timeout);
  133. typedef int (__stdcall *waWSAGETLASTERROR)(void);
  134. typedef int (__stdcall *waWSACLEANUP)(void);
  135. typedef int (__stdcall *waWSASTARTUP)(WORD wVersionRequested,LPWSADATA lpWSAData);
  136. typedef int (__stdcall *waCLOSESOCKET)(SOCKET s);
  137. typedef int (__stdcall *waSEND)(SOCKET s,const char FAR *buf,int len,int flags);
  138. typedef SOCKET (__stdcall *waSOCKET)(int af, int type,int protocol);
  139. typedef int (__stdcall *waCONNECT)( SOCKET s, const struct sockaddr FAR *name, int namelen );
  140. typedef unsigned long (__stdcall *waINET_ADDR)(const char FAR *cp );
  141. typedef struct hostent FAR * (__stdcall *waGETHOSTBYNAME)(const char FAR *name);
  142. typedef int (__stdcall *waIOCTLSOCKET)(SOCKET s,long cmd,u_long FAR *argp);
  143. typedef u_short (__stdcall *waHTONS)(u_short hostshort);
  144. waSELECT select;
  145. waWSAGETLASTERROR WSAGetLastError;
  146. waWSACLEANUP WSACleanup;
  147. waWSASTARTUP WSAStartup;
  148. waCLOSESOCKET closesocket;
  149. waSEND send;
  150. waSOCKET socket;
  151. waCONNECT connect;
  152. waINET_ADDR inet_addr;
  153. waGETHOSTBYNAME gethostbyname;
  154. waIOCTLSOCKET ioctlsocket;
  155. waHTONS htons;
  156. char buf[ 4096 ] = { 0 };
  157. char errorStr[ 1024 ] = { 0 };
  158. char *p;
  159. char url_buf[ 1024 ] = { 0 };
  160. char *url_lp = NULL;
  161. char *url_host = NULL;
  162. int url_port = 80;
  163. char *url_url = NULL;
  164. char authstr[ 1024 ] = { 0 };
  165. char proxy_lp[ 1024 ] = { 0 };
  166. const char *t;
  167. SetThreadName((DWORD)-1, "HTTP Retrieve File");
  168. if ( hws )
  169. {
  170. WSAGetLastError = (waWSAGETLASTERROR)GetProcAddress( hws, "WSAGetLastError" );
  171. WSACleanup = (waWSACLEANUP)GetProcAddress( hws, "WSACleanup" );
  172. WSAStartup = (waWSASTARTUP)GetProcAddress( hws, "WSAStartup" );
  173. closesocket = (waCLOSESOCKET)GetProcAddress( hws, "closesocket" );
  174. send = (waSEND)GetProcAddress( hws, "send" );
  175. p_recv = (waP_RECV)GetProcAddress( hws, "recv" );
  176. select = (waSELECT)GetProcAddress( hws, "select" );
  177. connect = (waCONNECT)GetProcAddress( hws, "connect" );
  178. socket = (waSOCKET)GetProcAddress( hws, "socket" );
  179. inet_addr = (waINET_ADDR)GetProcAddress( hws, "inet_addr" );
  180. gethostbyname = (waGETHOSTBYNAME)GetProcAddress( hws, "gethostbyname" );
  181. ioctlsocket = (waIOCTLSOCKET)GetProcAddress( hws, "ioctlsocket" );
  182. htons = (waHTONS)GetProcAddress( hws, "htons" );
  183. }
  184. if (!hws || !p_recv || !WSACleanup ||
  185. !WSAStartup || !closesocket || !send ||
  186. !connect || !socket || !inet_addr ||
  187. !gethostbyname || !ioctlsocket || !htons || !select || !WSAGetLastError)
  188. {
  189. if (hws)
  190. FreeLibrary(hws);
  191. rfta(getString(IDS_HTTP_LOAD_ERROR,errorStr,1024));
  192. }
  193. sets(getString(IDS_HTTP_INIT_SOCKET,errorStr,1024));
  194. {
  195. WSADATA wsaData;
  196. if (WSAStartup(MAKEWORD(1, 1), &wsaData))
  197. {
  198. FreeLibrary(hws);
  199. rfta(getString(IDS_HTTP_INIT_SOCKET_ERROR,errorStr,1024));
  200. }
  201. }
  202. _redirect_goto:
  203. total_bytes=0;
  204. content_length=0;
  205. // parse out l/p, host, port, and url from loc
  206. authstr[0]=0;
  207. url_lp=NULL;
  208. url_host=NULL;
  209. url_port=80;
  210. url_url=NULL;
  211. t= strstr(rf_url,"://");
  212. if (t)
  213. {
  214. StringCchCopyA(url_buf,1024,t+3);
  215. }
  216. else
  217. {
  218. StringCchCopyA(url_buf,1024,rf_url);
  219. }
  220. p=url_buf;
  221. while (p && *p != '/' && *p) p++;
  222. if (p && *p) *p++=0;
  223. url_url=p;
  224. p=url_buf;
  225. while (p && *p) p++;
  226. while (p>=url_buf && *p != '@') p--;
  227. if (p>=url_buf)
  228. {
  229. *p++=0;
  230. url_host=p;
  231. url_lp=url_buf;
  232. if (lstrlenA(url_lp)>0)
  233. {
  234. StringCchCopyA(authstr,1024,"Authorization: Basic ");
  235. encodeMimeStr(url_lp,authstr+lstrlenA(authstr));
  236. StringCchCatA(authstr,1024,"\r\n");
  237. }
  238. }
  239. else url_host=url_buf;
  240. p=url_host;
  241. while (p && *p != ':' && *p) p++;
  242. if (p && *p)
  243. {
  244. *p++=0;
  245. if (*p) url_port=atoi(p);
  246. }
  247. // determine if proxy server used
  248. {
  249. StringCchCopyA(proxytmp,256,config_proxy);
  250. proxy=proxytmp;
  251. while (proxy && (*proxy == ' ' || *proxy == '\t')) proxy++;
  252. if (url_port != 80 && GetPrivateProfileIntW(L"Winamp",L"proxyonly80",0,INI_FILE))
  253. proxy="";
  254. }
  255. if (*proxy)
  256. {
  257. p=proxy;
  258. while (p && *p && *p != '@') p++;
  259. if (p && *p)
  260. {
  261. *p++=0;
  262. StringCchCopyA(proxy_lp,1024,"Proxy-Authorization: Basic ");
  263. encodeMimeStr(proxy,proxy_lp+lstrlenA(proxy_lp));
  264. StringCchCatA(proxy_lp,1024,"\r\n");
  265. proxy=p;
  266. }
  267. lstrcpynA(connect_host,proxy,sizeof(connect_host)/sizeof(*connect_host));
  268. p=connect_host;
  269. while (p && *p && *p != ':') p++;
  270. if (p && *p)
  271. {
  272. *p++=0;
  273. if (*p) connect_port=(unsigned short)atoi(p);
  274. else connect_port=80;
  275. }
  276. }
  277. else
  278. {
  279. lstrcpynA(connect_host,url_host,sizeof(connect_host)/sizeof(*connect_host));
  280. connect_port=(unsigned short)url_port;
  281. }
  282. sets(getString(IDS_HTTP_SOCKET_CREATE,errorStr,1024));
  283. if (rf_abort || (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))==INVALID_SOCKET)
  284. {
  285. WSACleanup();
  286. FreeLibrary(hws);
  287. rfta(getString(IDS_HTTP_SOCKET_ERROR,errorStr,1024));
  288. }
  289. {
  290. int t;
  291. struct sockaddr_in blah;
  292. memset((char *)&blah,0,sizeof(blah));
  293. blah.sin_family=AF_INET;
  294. blah.sin_addr.s_addr=inet_addr(connect_host);
  295. blah.sin_port=htons(connect_port);
  296. if ( blah.sin_addr.s_addr == INADDR_NONE )
  297. {
  298. struct hostent *he;
  299. g_in_resolve = 1;
  300. sets( *proxy ? getString( IDS_HTTP_RESOLVE_PROXY, errorStr, 1024 ) : getString( IDS_HTTP_RESOLVE_HOST, errorStr, 1024 ) );
  301. if ( ( he = gethostbyname( connect_host ) ) != NULL )
  302. memcpy( (char *)&blah.sin_addr, he->h_addr, he->h_length );
  303. else if ( ( blah.sin_addr.s_addr = inet_addr( connect_host ) ) == INADDR_NONE )
  304. {
  305. g_in_resolve = 0;
  306. closesocket( sock );
  307. WSACleanup();
  308. FreeLibrary( hws );
  309. rfta( *proxy ? getString( IDS_HTTP_RESOLVE_PROXY_ERROR, errorStr, 1024 ) : getString( IDS_HTTP_RESOLVE_HOST_ERROR, errorStr, 1024 ) );
  310. }
  311. g_in_resolve = 0;
  312. }
  313. sets(*proxy?getString(IDS_HTTP_CONNECT_PROXY,errorStr,1024):getString(IDS_HTTP_CONNECT_HOST,errorStr,1024));
  314. {
  315. unsigned long arg=1;
  316. ioctlsocket(sock,FIONBIO,&arg);
  317. }
  318. t=connect(sock,(struct sockaddr *)&blah,16);
  319. if (t == -1 && WSAGetLastError()==WSAEWOULDBLOCK)
  320. {
  321. int a=0;
  322. while (!rf_abort && t==-1)
  323. {
  324. TIMEVAL to={0,250*1000};
  325. fd_set f;
  326. FD_ZERO(&f);
  327. FD_SET(sock,&f);
  328. switch (select(0,NULL,&f,NULL,&to))
  329. {
  330. case 1: t=0; break;
  331. case 0: if (a++ > 40) rf_abort =1; break;
  332. case -1: rf_abort =1; break;
  333. }
  334. }
  335. }
  336. if (rf_abort || t==-1)
  337. {
  338. closesocket(sock);
  339. WSACleanup();
  340. FreeLibrary(hws);
  341. rfta(*proxy?getString(IDS_HTTP_CONNECT_PROXY_ERROR,errorStr,1024):getString(IDS_HTTP_CONNECT_HOST_ERROR,errorStr,1024));
  342. }
  343. }
  344. sets(getString(IDS_HTTP_SEND_REQUEST,errorStr,1024));
  345. {
  346. if ( *proxy )
  347. StringCchPrintfA( buf, 4096, "GET http://%s:%d/%s", url_host, url_port, url_url );
  348. else
  349. StringCchPrintfA( buf, 4096, "GET /%s", url_url );
  350. if (url_port != 80)
  351. StringCchPrintfA( buf + lstrlenA( buf ), 4096 - lstrlenA( buf ), " HTTP/1.0\r\nHost: %s:%d\r\n", url_host, url_port );
  352. else
  353. StringCchPrintfA( buf + lstrlenA( buf ), 4096 - lstrlenA( buf ), " HTTP/1.0\r\nHost: %s\r\n", url_host );
  354. StringCchPrintfA( buf + lstrlenA( buf ), 4096 - lstrlenA( buf ),
  355. "User-Agent: Winamp/%s%s\r\n"
  356. "%s%s"
  357. "Accept: */*\r\n\r\n",
  358. app_version,
  359. ( redirect == 2 ? " (Mozilla)" : "" ),
  360. proxy_lp, authstr );
  361. //MessageBox(NULL,buf,"SENDING:",0);
  362. {
  363. unsigned long arg = 0;
  364. ioctlsocket( sock, FIONBIO, &arg );
  365. }
  366. send(sock,buf,lstrlenA(buf),0);
  367. {
  368. unsigned long arg = 1;
  369. ioctlsocket( sock, FIONBIO, &arg );
  370. }
  371. }
  372. sets( getString( IDS_HTTP_READ_REQUEST, errorStr, 1024 ) );
  373. { // get the standard HTTP 1.0 200 OK
  374. char buf[1024] = {0};
  375. int x = recv_string(sock,buf,sizeof(buf));
  376. //MessageBox(0, buf, "RECEIVING:", 0);
  377. if (x < 0 || rf_abort)
  378. {
  379. closesocket(sock);
  380. WSACleanup();
  381. FreeLibrary(hws);
  382. rfta(getString(IDS_HTTP_CONNECTION_LOST,errorStr,1024));
  383. }
  384. if (strstr(buf," 302") || strstr(buf,"301"))
  385. {
  386. redirect=1;
  387. }
  388. else
  389. {
  390. // this is a very specific handling to allow for /listen.m3u with v1.x DNAS to work correctly
  391. // as we need alter the user-agent so it will provide us with the needed response (a DNAS bug)
  392. if ((redirect != 2) && strstr(buf,"ICY 404 Resource Not Found") && strstr(url_url,"listen.m3u")) {
  393. redirect=2;
  394. closesocket(sock);
  395. goto _redirect_goto;
  396. }
  397. else
  398. {
  399. redirect=0;
  400. }
  401. }
  402. if (!strstr(buf,"OK") && !redirect)
  403. {
  404. StringCchCatA(buf,1024,getString(IDS_HTTP_CONNECTION_CLOSED,errorStr,1024));
  405. closesocket(sock);
  406. WSACleanup();
  407. FreeLibrary(hws);
  408. rfta(buf);
  409. }
  410. sets(buf);
  411. }
  412. while (1)
  413. {
  414. char buf[1024] = {0}, *p;
  415. int x = recv_string(sock,buf,sizeof(buf));
  416. if (x < 0 || rf_abort)
  417. {
  418. closesocket(sock);
  419. WSACleanup();
  420. FreeLibrary(hws);
  421. rfta(getString(IDS_HTTP_CONNECTION_LOST,errorStr,1024));
  422. }
  423. if (buf[0] == '\r' || !buf[0])
  424. break;
  425. {
  426. p=buf;
  427. while (p && *p && *p != ':') p++;
  428. if (p && *p == ':')
  429. {
  430. *p++=0;
  431. while (p && (*p == ' ' || *p == '\t'))
  432. p++;
  433. }
  434. else
  435. p=NULL;
  436. }
  437. if (!lstrcmpiA(buf,"Content-Length") && (*p >= '0' && *p <= '9'))
  438. {
  439. content_length=0;
  440. while (p && *p >= '0' && *p <= '9')
  441. {
  442. content_length *= 10;
  443. content_length += *p++-'0';
  444. }
  445. }
  446. if (!lstrcmpiA(buf,"Location") && redirect)
  447. {
  448. StringCchCopyA(locbuf,1024,p);
  449. rf_url=locbuf;
  450. closesocket(sock);
  451. //blah
  452. goto _redirect_goto;
  453. }
  454. }
  455. {
  456. createDirForFileW((wchar_t *)rf_file);
  457. HANDLE h = CreateFileW(rf_file,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,0,NULL);
  458. if (h == INVALID_HANDLE_VALUE)
  459. {
  460. closesocket(sock);
  461. WSACleanup();
  462. FreeLibrary(hws);
  463. rfta(getString(IDS_HTTP_ERROR_OPEN_FILE,errorStr,1024));
  464. }
  465. {
  466. unsigned int start_time=GetTickCount();
  467. char buf[4096] = {0};
  468. while (1)
  469. {
  470. int x=p_recv(sock,buf,sizeof(buf),0);
  471. if (x == 0 || rf_abort)
  472. break;
  473. else if (x < 0)
  474. {
  475. if (WSAGetLastError()!=WSAEWOULDBLOCK) break;
  476. Sleep(50);
  477. }
  478. else // x > 0
  479. {
  480. DWORD t = 0;
  481. int lb=total_bytes;
  482. WriteFile(h,buf,x,&t,NULL);
  483. total_bytes += x;
  484. if ( lb / 16384 != total_bytes / 16384 )
  485. {
  486. int bps;
  487. int t = ( GetTickCount() - start_time );
  488. if ( t < 1000 ) t = 1000;
  489. bps = total_bytes / ( ( t + 999 ) / 1000 );
  490. if ( content_length )
  491. StringCchPrintfA( buf, 4096, getString( IDS_HTTP_RETRIEVE_FILE_LENGTH, errorStr, 1024 ), ( total_bytes * 100 ) / content_length, total_bytes, content_length, bps / 1000, ( bps / 10 ) % 100 );
  492. else
  493. StringCchPrintfA( buf, 4096, getString( IDS_HTTP_RETRIEVE_FILE, errorStr, 1024 ), total_bytes, bps / 1000, ( bps / 10 ) % 100 );
  494. sets( buf );
  495. }
  496. }
  497. }
  498. }
  499. CloseHandle(h);
  500. }
  501. if (!content_length || total_bytes == content_length)
  502. success=1;
  503. else
  504. sets(getString(IDS_HTTP_FILE_INCOMPLETE,errorStr,1024));
  505. closesocket(sock);
  506. WSACleanup();
  507. FreeLibrary(hws);
  508. rfta(success?getString(IDS_HTTP_SUCCESS,errorStr,1024):NULL);
  509. }
  510. #undef rfta
  511. #undef sets
  512. static BOOL CALLBACK rf_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
  513. {
  514. static HANDLE hThread;
  515. static int r;
  516. if (WADlg_initted())
  517. {
  518. INT_PTR a = WADlg_handleDialogMsgs(hwndDlg, uMsg, wParam, lParam);
  519. if (a)
  520. return a;
  521. }
  522. switch (uMsg)
  523. {
  524. case WM_USER+1:
  525. if (hThread != INVALID_HANDLE_VALUE)
  526. {
  527. CloseHandle(hThread);
  528. hThread=INVALID_HANDLE_VALUE;
  529. }
  530. if (!wParam)
  531. {
  532. g_rv=0;
  533. PostMessageW(hwndDlg,WM_USER,0,0); // make it go quick
  534. }
  535. else
  536. {
  537. SetDlgItemTextA(hwndDlg,IDCANCEL,getString(IDS_HTTP_CLOSE,NULL,0));
  538. r=5;
  539. SetTimer(hwndDlg,123,1000,NULL);
  540. }
  541. return 0;
  542. case WM_TIMER:
  543. if (wParam == 123)
  544. {
  545. if ( r == 0 )
  546. {
  547. KillTimer( hwndDlg, wParam );
  548. g_rv = 1;
  549. }
  550. else
  551. {
  552. char s[ 32 ] = { 0 };
  553. StringCchPrintfA( s, 32, getString( IDS_CLOSE_COUNTDOWN, NULL, 0 ), r-- );
  554. SetDlgItemTextA( hwndDlg, IDCANCEL, s );
  555. }
  556. }
  557. return 0;
  558. case WM_ERASEBKGND:
  559. if (WADlg_initted())
  560. return 1; //handled by WADlg_DrawChildWindowBorders in WM_PAINT
  561. break;
  562. case WM_PAINT:
  563. {
  564. if (WADlg_initted())
  565. {
  566. int tab[] = { IDC_STATUS | DCW_SUNKENBORDER};
  567. WADlg_DrawChildWindowBorders(hwndDlg, tab, sizeof(tab) / sizeof(tab[0]));
  568. return 0;
  569. }
  570. }
  571. break;
  572. case WM_INITDIALOG:
  573. {
  574. DWORD id;
  575. char errorStr[ 1024 ] = { 0 };
  576. if ( WADlg_initted() )
  577. SetWindowLong( GetDlgItem( hwndDlg, IDCANCEL ), GWL_STYLE, GetWindowLongW( GetDlgItem( hwndDlg, IDCANCEL ), GWL_STYLE ) | BS_OWNERDRAW );
  578. rf_dlgWnd = hwndDlg;
  579. rf_statusWnd = GetDlgItem( hwndDlg, IDC_STATUS );
  580. SetWindowTextW( hwndDlg, rf_dlgtitle );
  581. if ( strstr( rf_url, "client.winamp.com/update" ) )
  582. SetDlgItemTextA( hwndDlg, IDC_URL, getString( IDS_HTTP_WINAMP_UPDATE_SITE, errorStr, 1024 ) );
  583. else
  584. SetDlgItemTextA( hwndDlg, IDC_URL, rf_url );
  585. SetDlgItemTextA( hwndDlg, IDC_STATUS, getString( IDS_HTTP_INIT, errorStr, 1024 ) );
  586. rf_abort = 0;
  587. hThread = CreateThread( NULL, 0, rf_ThreadProc, 0, 0, &id );
  588. }
  589. return FALSE;
  590. case WM_COMMAND:
  591. switch (LOWORD(wParam))
  592. {
  593. case IDCANCEL:
  594. if (hThread!=INVALID_HANDLE_VALUE)
  595. {
  596. char errorStr[1024] = {0};
  597. rf_abort=1;
  598. #if 0
  599. if (g_in_resolve) g_in_resolve++;
  600. if (0 && g_in_resolve==3) // lame terminatethread shouldnt be used
  601. {
  602. TerminateThread(hThread,0);
  603. CloseHandle(hThread);
  604. hThread=INVALID_HANDLE_VALUE;
  605. g_rv=1;
  606. }
  607. else
  608. #endif
  609. SetDlgItemTextA(hwndDlg,IDCANCEL,getString(IDS_HTTP_ABORT,errorStr,1024));
  610. }
  611. else
  612. {
  613. g_rv=1;
  614. }
  615. return 0;
  616. }
  617. return 0;
  618. }
  619. return 0;
  620. }
  621. int httpRetrieveFileW(HWND hwnd, const char *url, const wchar_t *file, const wchar_t *dlgtitle)
  622. {
  623. int i;
  624. int activated=0;
  625. RECT r;
  626. HWND dlgWnd;
  627. if (rf_in) return 1;
  628. rf_in=1;
  629. g_rv=-1;
  630. rf_url=url;
  631. rf_file=file;
  632. rf_dlgtitle=dlgtitle;
  633. g_in_resolve=0;
  634. if (!hwnd) hwnd=hMainWindow;
  635. if (hwnd == hMainWindow && g_dialog_box_parent)
  636. hwnd=g_dialog_box_parent;
  637. {
  638. if (_strnicmp(url,"http://",7))
  639. {
  640. // MessageBox(hwnd,getString(IDS_ONLYHTTP,NULL,0),"Winamp",MB_OK|MB_ICONSTOP);
  641. rf_in=0;
  642. return 1;
  643. }
  644. }
  645. GetWindowRect(hwnd,&r);
  646. dlgWnd=LPCreateDialogW(IDD_HTTPGET, hwnd, (WNDPROC)rf_DlgProc);
  647. if (r.bottom > GetSystemMetrics(SM_CXSCREEN)/2 && r.bottom-r.top < 100)
  648. {
  649. RECT r2;
  650. GetWindowRect(dlgWnd,&r2);
  651. r.top=r.bottom-(r2.bottom-r2.top);
  652. }
  653. SetWindowPos(dlgWnd,NULL,r.left,r.top,0,0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
  654. if (GetForegroundWindow()==hwnd)
  655. {
  656. activated=1;
  657. ShowWindow(dlgWnd,SW_SHOW);
  658. }
  659. else
  660. ShowWindow(dlgWnd,SW_SHOWNA);
  661. if (hwnd == hMainWindow)
  662. {
  663. if (hMainWindow) EnableWindow(hMainWindow,0);
  664. if (hPLWindow) EnableWindow(hPLWindow,0);
  665. if (hEQWindow) EnableWindow(hEQWindow,0);
  666. //if (hMBWindow) EnableWindow(hMBWindow,0);
  667. }
  668. else
  669. EnableWindow(hwnd,0);
  670. while (1)
  671. {
  672. MSG msg;
  673. if (g_rv != -1) break;
  674. GetMessage(&msg,NULL,0,0);
  675. DispatchMessage(&msg);
  676. }
  677. if ( activated && GetForegroundWindow() == dlgWnd )
  678. {
  679. }
  680. else
  681. activated = 0;
  682. if ( hwnd == hMainWindow )
  683. {
  684. if ( hMainWindow )
  685. EnableWindow( hMainWindow, 1 );
  686. if ( hPLWindow )
  687. EnableWindow( hPLWindow, 1 );
  688. if ( hEQWindow )
  689. EnableWindow( hEQWindow, 1 );
  690. //if (hMBWindow) EnableWindow(hMBWindow,1);
  691. }
  692. else
  693. EnableWindow( hwnd, 1 );
  694. DestroyWindow(dlgWnd);
  695. if (activated)
  696. SetForegroundWindow(hwnd);
  697. i = g_rv;
  698. rf_in=0;
  699. return i;
  700. }
  701. int httpRetrieveFile(HWND hwnd, const char *url, char *file, char *dlgtitle)
  702. {
  703. return httpRetrieveFileW(hwnd, url, AutoWide(file), AutoWide(dlgtitle));
  704. }
  705. #endif