diff options
Diffstat (limited to 'Src/Winamp/HTTPRetrieveFile.cpp')
-rw-r--r-- | Src/Winamp/HTTPRetrieveFile.cpp | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/Src/Winamp/HTTPRetrieveFile.cpp b/Src/Winamp/HTTPRetrieveFile.cpp new file mode 100644 index 00000000..7c655a80 --- /dev/null +++ b/Src/Winamp/HTTPRetrieveFile.cpp @@ -0,0 +1,305 @@ +/** (c) Nullsoft, Inc. C O N F I D E N T I A L + ** Filename: + ** Project: + ** Description: + ** Author: Ben Allison benski@nullsoft.com + ** Created: + **/ + +#include "Main.h" +#include "api.h" +#include "..\Components\wac_network\wac_network_http_receiver_api.h" + +#include "api/service/waServiceFactory.h" + + +void GetMIMEType(const char *url, char *mimeType, int mimeTypeCch) +{ + api_httpreceiver *http = 0; + waServiceFactory *sf = 0; + if (WASABI_API_SVC) + { + sf = WASABI_API_SVC->service_getServiceByGuid(httpreceiverGUID); + if (sf) + http = (api_httpreceiver *)sf->getInterface(); + } + + if (!http) + return ; + + int ret; + http->open(API_DNS_AUTODNS, 2048, config_proxy); + http->connect(url, 0, "HEAD"); + + do + { + Sleep(10); + ret = http->run(); + if (ret == -1) // connection failed + break; + + // ---- check our reply code ---- + int replycode = http->getreplycode(); + switch (replycode) + { + case 0: + case 100: + break; + case 200: + { + const char *contentType = http->getheader("Content-Type"); + if (contentType) + lstrcpynA(mimeType, contentType, mimeTypeCch); + else + mimeType[0] = 0; + + sf->releaseInterface(http); + return ; + } + break; + default: + sf->releaseInterface(http); + return ; + } + } + while (ret == HTTPRECEIVER_RUN_OK); + + sf->releaseInterface(http); +} + +#if 0 +#define WM_HRF_READINGHTTP WM_USER +#define WM_HRF_DOWNLOADING (WM_USER+1) +struct RFData +{ +public: + char *url, *file; + HWND hwnd; +}; + +bool killswitch; +static DWORD WINAPI rf_ThreadProc(void *p) +{ + RFData *rfData = (RFData *)p; + char *url = rfData->url, *file = rfData->file; + waServiceFactory *sf = 0; + api_httpreceiver *http = 0; + if (WASABI_API_SVC) + { + sf = WASABI_API_SVC->service_getServiceByGuid(httpreceiverGUID); + if (sf) + http = (api_httpreceiver *)sf->getInterface(); + } + + if (!http) + return 1; + + HANDLE hFile = CreateFile(file, GENERIC_WRITE, 0, + NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + sf->releaseInterface(http); + return 1; + } + + http->Open(API_DNS_AUTODNS, 16384); + http->AddHeader("User-Agent: Winamp/" APP_VERSION); + http->Connect(url); + int ret; + do + { + Sleep(50); + http->Run(); + ret = http->GetStatus(); + if (ret == HTTPRECEIVER_STATUS_ERROR) + killswitch = true; + + if (killswitch) + break; + } + while (ret == HTTPRECEIVER_STATUS_CONNECTING); + + if (ret == HTTPRECEIVER_STATUS_READING_HEADERS || ret == HTTPRECEIVER_STATUS_READING_CONTENT) + { + PostMessageW(rfData->hwnd, WM_HRF_READINGHTTP, 0, 0); + int replycode = http->GetReplyCode(); + switch (replycode) + { + case 0: case 100: // shouldn't really get here + break; + case 200: + break; + default: + killswitch = true; + break; + } + } + bool error = false; + char block[16384] = {0}; + size_t downloadSize; + size_t currentSize = 0, totalSize = 0; + + do + { + if (killswitch) + { + error = true; + break; + } + // ---- Pause a bit and then run the http downloader ---- + Sleep(50); + ret = http->Run(); + + if (ret == -1) // connection failed + { + error = true; + break; + } + + // ---- download ---- + downloadSize = http->GetBytesAvailable(); + if (downloadSize) + { + totalSize = http->GetContentLength(); + + downloadSize = http->GetBytes(block, downloadSize); + currentSize += downloadSize; + PostMessageW(rfData->hwnd, WM_HRF_DOWNLOADING, currentSize, totalSize); + + // ---- write to disk ---- + if (downloadSize) // WriteFile doesn't like 0 byte writes + { + DWORD numWritten = 0; + WriteFile(hFile, block, downloadSize, &numWritten, FALSE); + if (numWritten != downloadSize) // make sure that the block was actually written + { + error = true; + break; // failed writing + } + } + } + } + while (ret != 1 || downloadSize); // http may be closed, but make sure we get all the data. + + CloseHandle(hFile); + if (error) + DeleteFile(file); + sf->releaseInterface(http); + return 0; + +} + +static LRESULT CALLBACK rf_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_INITDIALOG: + SetDlgItemText(hwndDlg, IDC_STATUS, getString(IDS_HTTP_INIT,NULL,0)); + return FALSE; + case WM_HRF_READINGHTTP: + SetDlgItemText(hwndDlg, IDC_STATUS, getString(IDS_HTTP_READ_REQUEST,NULL,0)); + return TRUE; + case WM_HRF_DOWNLOADING: + { + char temp[128] = {0}; + if (!lParam) + StringCchPrintf(temp, 128, getString(IDS_HTTP_RET_FILE,NULL,0), wParam); + else + StringCchPrintf(temp, 128, getString(IDS_HTTP_RET_FILE_PERCENT,NULL,0), (100*wParam) / lParam, wParam, lParam); + SetDlgItemText(hwndDlg, IDC_STATUS, temp); + } + return TRUE; + case WM_DESTROY: + if (GetParent(hwndDlg) == hMainWindow) + { + if (hMainWindow) EnableWindow(hMainWindow, 1); + if (hPLWindow) EnableWindow(hPLWindow, 1); + if (hEQWindow) EnableWindow(hEQWindow, 1); + //if (hMBWindow) EnableWindow(hMBWindow,1); + } + else + EnableWindow(GetParent(hwndDlg), 1); + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDCANCEL: + DestroyWindow(hwndDlg); + return 0; + } + return 0; + } + return 0; +} + +int httpRetrieveFile(HWND hwnd, char *url, char *file, char *dlgtitle) +{ + killswitch = false; + RECT r; + HANDLE hThread = 0; + if (!hwnd) hwnd = hMainWindow; + + if (hwnd == hMainWindow && g_dialog_box_parent) hwnd = g_dialog_box_parent; + + GetWindowRect(hwnd, &r); + HWND dlgWnd = LPCreateDialog(IDD_HTTPGET, hwnd, rf_DlgProc); + SetWindowText(dlgWnd, dlgtitle); + SetDlgItemText(dlgWnd, IDC_URL, url); + + RFData data = {url, file, dlgWnd}; + DWORD id; + hThread = CreateThread(NULL, 0, rf_ThreadProc, (void *) & data, CREATE_SUSPENDED, &id); + if (NULL) + return 1; + + ResumeThread(hThread); + if (r.bottom > GetSystemMetrics(SM_CXSCREEN) / 2 && r.bottom - r.top < 100) + { + RECT r2; + GetWindowRect(dlgWnd, &r2); + r.top = r.bottom - (r2.bottom - r2.top); + } + SetWindowPos(dlgWnd, NULL, r.left, r.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); + + if (GetForegroundWindow() == hwnd) + ShowWindow(dlgWnd, SW_SHOW); + else + ShowWindow(dlgWnd, SW_SHOWNA); + + if (hwnd == hMainWindow) + { + if (hMainWindow) EnableWindow(hMainWindow, 0); + if (hPLWindow) EnableWindow(hPLWindow, 0); + if (hEQWindow) EnableWindow(hEQWindow, 0); + //if (hMBWindow) EnableWindow(hMBWindow,0); + } + else + EnableWindow(hwnd, 0); + + while (1) + { + MSG msg; + if (!IsWindow(dlgWnd)) + { + killswitch = true; + break; + } + if (WaitForSingleObject(hThread, 0) == WAIT_OBJECT_0) + { + DestroyWindow(dlgWnd); + break; + } + GetMessage(&msg, NULL, 0, 0); + DispatchMessage(&msg); + } + + WaitForSingleObject(hThread, 5000); + DWORD exitCode; + if (GetExitCodeThread(hThread, &exitCode)) + return exitCode; + else + { + // CUT: TerminateThread(hThread, 0); + return 1; + } +} +#endif
\ No newline at end of file |