HTTPRetrieveFile.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /** (c) Nullsoft, Inc. C O N F I D E N T I A L
  2. ** Filename:
  3. ** Project:
  4. ** Description:
  5. ** Author: Ben Allison [email protected]
  6. ** Created:
  7. **/
  8. #include "Main.h"
  9. #include "api.h"
  10. #include "..\Components\wac_network\wac_network_http_receiver_api.h"
  11. #include "api/service/waServiceFactory.h"
  12. void GetMIMEType(const char *url, char *mimeType, int mimeTypeCch)
  13. {
  14. api_httpreceiver *http = 0;
  15. waServiceFactory *sf = 0;
  16. if (WASABI_API_SVC)
  17. {
  18. sf = WASABI_API_SVC->service_getServiceByGuid(httpreceiverGUID);
  19. if (sf)
  20. http = (api_httpreceiver *)sf->getInterface();
  21. }
  22. if (!http)
  23. return ;
  24. int ret;
  25. http->open(API_DNS_AUTODNS, 2048, config_proxy);
  26. http->connect(url, 0, "HEAD");
  27. do
  28. {
  29. Sleep(10);
  30. ret = http->run();
  31. if (ret == -1) // connection failed
  32. break;
  33. // ---- check our reply code ----
  34. int replycode = http->getreplycode();
  35. switch (replycode)
  36. {
  37. case 0:
  38. case 100:
  39. break;
  40. case 200:
  41. {
  42. const char *contentType = http->getheader("Content-Type");
  43. if (contentType)
  44. lstrcpynA(mimeType, contentType, mimeTypeCch);
  45. else
  46. mimeType[0] = 0;
  47. sf->releaseInterface(http);
  48. return ;
  49. }
  50. break;
  51. default:
  52. sf->releaseInterface(http);
  53. return ;
  54. }
  55. }
  56. while (ret == HTTPRECEIVER_RUN_OK);
  57. sf->releaseInterface(http);
  58. }
  59. #if 0
  60. #define WM_HRF_READINGHTTP WM_USER
  61. #define WM_HRF_DOWNLOADING (WM_USER+1)
  62. struct RFData
  63. {
  64. public:
  65. char *url, *file;
  66. HWND hwnd;
  67. };
  68. bool killswitch;
  69. static DWORD WINAPI rf_ThreadProc(void *p)
  70. {
  71. RFData *rfData = (RFData *)p;
  72. char *url = rfData->url, *file = rfData->file;
  73. waServiceFactory *sf = 0;
  74. api_httpreceiver *http = 0;
  75. if (WASABI_API_SVC)
  76. {
  77. sf = WASABI_API_SVC->service_getServiceByGuid(httpreceiverGUID);
  78. if (sf)
  79. http = (api_httpreceiver *)sf->getInterface();
  80. }
  81. if (!http)
  82. return 1;
  83. HANDLE hFile = CreateFile(file, GENERIC_WRITE, 0,
  84. NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  85. if (hFile == INVALID_HANDLE_VALUE)
  86. {
  87. sf->releaseInterface(http);
  88. return 1;
  89. }
  90. http->Open(API_DNS_AUTODNS, 16384);
  91. http->AddHeader("User-Agent: Winamp/" APP_VERSION);
  92. http->Connect(url);
  93. int ret;
  94. do
  95. {
  96. Sleep(50);
  97. http->Run();
  98. ret = http->GetStatus();
  99. if (ret == HTTPRECEIVER_STATUS_ERROR)
  100. killswitch = true;
  101. if (killswitch)
  102. break;
  103. }
  104. while (ret == HTTPRECEIVER_STATUS_CONNECTING);
  105. if (ret == HTTPRECEIVER_STATUS_READING_HEADERS || ret == HTTPRECEIVER_STATUS_READING_CONTENT)
  106. {
  107. PostMessageW(rfData->hwnd, WM_HRF_READINGHTTP, 0, 0);
  108. int replycode = http->GetReplyCode();
  109. switch (replycode)
  110. {
  111. case 0: case 100: // shouldn't really get here
  112. break;
  113. case 200:
  114. break;
  115. default:
  116. killswitch = true;
  117. break;
  118. }
  119. }
  120. bool error = false;
  121. char block[16384] = {0};
  122. size_t downloadSize;
  123. size_t currentSize = 0, totalSize = 0;
  124. do
  125. {
  126. if (killswitch)
  127. {
  128. error = true;
  129. break;
  130. }
  131. // ---- Pause a bit and then run the http downloader ----
  132. Sleep(50);
  133. ret = http->Run();
  134. if (ret == -1) // connection failed
  135. {
  136. error = true;
  137. break;
  138. }
  139. // ---- download ----
  140. downloadSize = http->GetBytesAvailable();
  141. if (downloadSize)
  142. {
  143. totalSize = http->GetContentLength();
  144. downloadSize = http->GetBytes(block, downloadSize);
  145. currentSize += downloadSize;
  146. PostMessageW(rfData->hwnd, WM_HRF_DOWNLOADING, currentSize, totalSize);
  147. // ---- write to disk ----
  148. if (downloadSize) // WriteFile doesn't like 0 byte writes
  149. {
  150. DWORD numWritten = 0;
  151. WriteFile(hFile, block, downloadSize, &numWritten, FALSE);
  152. if (numWritten != downloadSize) // make sure that the block was actually written
  153. {
  154. error = true;
  155. break; // failed writing
  156. }
  157. }
  158. }
  159. }
  160. while (ret != 1 || downloadSize); // http may be closed, but make sure we get all the data.
  161. CloseHandle(hFile);
  162. if (error)
  163. DeleteFile(file);
  164. sf->releaseInterface(http);
  165. return 0;
  166. }
  167. static LRESULT CALLBACK rf_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  168. {
  169. switch (uMsg)
  170. {
  171. case WM_INITDIALOG:
  172. SetDlgItemText(hwndDlg, IDC_STATUS, getString(IDS_HTTP_INIT,NULL,0));
  173. return FALSE;
  174. case WM_HRF_READINGHTTP:
  175. SetDlgItemText(hwndDlg, IDC_STATUS, getString(IDS_HTTP_READ_REQUEST,NULL,0));
  176. return TRUE;
  177. case WM_HRF_DOWNLOADING:
  178. {
  179. char temp[128] = {0};
  180. if (!lParam)
  181. StringCchPrintf(temp, 128, getString(IDS_HTTP_RET_FILE,NULL,0), wParam);
  182. else
  183. StringCchPrintf(temp, 128, getString(IDS_HTTP_RET_FILE_PERCENT,NULL,0), (100*wParam) / lParam, wParam, lParam);
  184. SetDlgItemText(hwndDlg, IDC_STATUS, temp);
  185. }
  186. return TRUE;
  187. case WM_DESTROY:
  188. if (GetParent(hwndDlg) == hMainWindow)
  189. {
  190. if (hMainWindow) EnableWindow(hMainWindow, 1);
  191. if (hPLWindow) EnableWindow(hPLWindow, 1);
  192. if (hEQWindow) EnableWindow(hEQWindow, 1);
  193. //if (hMBWindow) EnableWindow(hMBWindow,1);
  194. }
  195. else
  196. EnableWindow(GetParent(hwndDlg), 1);
  197. case WM_COMMAND:
  198. switch (LOWORD(wParam))
  199. {
  200. case IDCANCEL:
  201. DestroyWindow(hwndDlg);
  202. return 0;
  203. }
  204. return 0;
  205. }
  206. return 0;
  207. }
  208. int httpRetrieveFile(HWND hwnd, char *url, char *file, char *dlgtitle)
  209. {
  210. killswitch = false;
  211. RECT r;
  212. HANDLE hThread = 0;
  213. if (!hwnd) hwnd = hMainWindow;
  214. if (hwnd == hMainWindow && g_dialog_box_parent) hwnd = g_dialog_box_parent;
  215. GetWindowRect(hwnd, &r);
  216. HWND dlgWnd = LPCreateDialog(IDD_HTTPGET, hwnd, rf_DlgProc);
  217. SetWindowText(dlgWnd, dlgtitle);
  218. SetDlgItemText(dlgWnd, IDC_URL, url);
  219. RFData data = {url, file, dlgWnd};
  220. DWORD id;
  221. hThread = CreateThread(NULL, 0, rf_ThreadProc, (void *) & data, CREATE_SUSPENDED, &id);
  222. if (NULL)
  223. return 1;
  224. ResumeThread(hThread);
  225. if (r.bottom > GetSystemMetrics(SM_CXSCREEN) / 2 && r.bottom - r.top < 100)
  226. {
  227. RECT r2;
  228. GetWindowRect(dlgWnd, &r2);
  229. r.top = r.bottom - (r2.bottom - r2.top);
  230. }
  231. SetWindowPos(dlgWnd, NULL, r.left, r.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
  232. if (GetForegroundWindow() == hwnd)
  233. ShowWindow(dlgWnd, SW_SHOW);
  234. else
  235. ShowWindow(dlgWnd, SW_SHOWNA);
  236. if (hwnd == hMainWindow)
  237. {
  238. if (hMainWindow) EnableWindow(hMainWindow, 0);
  239. if (hPLWindow) EnableWindow(hPLWindow, 0);
  240. if (hEQWindow) EnableWindow(hEQWindow, 0);
  241. //if (hMBWindow) EnableWindow(hMBWindow,0);
  242. }
  243. else
  244. EnableWindow(hwnd, 0);
  245. while (1)
  246. {
  247. MSG msg;
  248. if (!IsWindow(dlgWnd))
  249. {
  250. killswitch = true;
  251. break;
  252. }
  253. if (WaitForSingleObject(hThread, 0) == WAIT_OBJECT_0)
  254. {
  255. DestroyWindow(dlgWnd);
  256. break;
  257. }
  258. GetMessage(&msg, NULL, 0, 0);
  259. DispatchMessage(&msg);
  260. }
  261. WaitForSingleObject(hThread, 5000);
  262. DWORD exitCode;
  263. if (GetExitCodeThread(hThread, &exitCode))
  264. return exitCode;
  265. else
  266. {
  267. // CUT: TerminateThread(hThread, 0);
  268. return 1;
  269. }
  270. }
  271. #endif