mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-12-28 22:46:06 +00:00
305 lines
6.5 KiB
C++
305 lines
6.5 KiB
C++
/** (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
|