aboutsummaryrefslogtreecommitdiff
path: root/Src/Winamp/Http.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Winamp/Http.cpp')
-rw-r--r--Src/Winamp/Http.cpp795
1 files changed, 795 insertions, 0 deletions
diff --git a/Src/Winamp/Http.cpp b/Src/Winamp/Http.cpp
new file mode 100644
index 00000000..517ad54f
--- /dev/null
+++ b/Src/Winamp/Http.cpp
@@ -0,0 +1,795 @@
+/** (c) Nullsoft, Inc. C O N F I D E N T I A L
+ ** Filename:
+ ** Project:
+ ** Description:
+ ** Author:
+ ** Created:
+ **/
+
+#include "Main.h"
+#include <cstdint>
+#if 1
+#include <sys/types.h>
+#include <winsock.h>
+#include "../nu/threadname.h"
+#include "Wa_dlg.h"
+#include "../nu/AutoWide.h"
+
+static void createDirForFileW(wchar_t *str)
+{
+ wchar_t *p = str;
+ if ((p[0] ==L'\\' || p[0] ==L'/') && (p[1] ==L'\\' || p[1] ==L'/'))
+ {
+ p += 2;
+ while (p && *p && *p !=L'\\' && *p !=L'/') p++;
+ if (!*p) return ;
+ p++;
+ while (p && *p && *p !=L'\\' && *p !=L'/') p++;
+ }
+ else
+ {
+ while (p && *p && *p !=L'\\' && *p !=L'/') p++;
+ }
+
+ while (p && *p)
+ {
+ while (p && *p !=L'\\' && *p !=L'/' && *p) p = CharNextW(p);
+ if (*p)
+ {
+ wchar_t lp = *p;
+ *p = 0;
+ CreateDirectoryW(str, NULL);
+ *p++ = lp;
+ }
+ }
+}
+
+static const wchar_t *rf_file, *rf_dlgtitle;
+static const char *rf_url;
+static int rf_in;
+static HWND rf_dlgWnd, rf_statusWnd;
+static volatile int rf_rv=-1;
+static volatile int rf_abort;
+static int g_rv;
+
+static int _rftabort(int r, char *s)
+{
+ if (s) SetWindowTextA(rf_statusWnd,s);
+ if (rf_dlgWnd) SendMessageW(rf_dlgWnd,WM_USER+1,r,0);
+ else rf_rv=r;
+ return r;
+}
+
+#define rfta(s) return _rftabort(!success,s)
+#define sets(s) SetWindowTextA(rf_statusWnd,s)
+
+typedef int (__stdcall *waP_RECV)(SOCKET s, char FAR* buf, int len, int flags);
+waP_RECV p_recv;
+
+static void encodeMimeStr(char *in, char *out)
+{
+ char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ int shift = 0;
+ int accum = 0;
+
+ while (in && *in)
+ {
+ if (*in)
+ {
+ accum <<= 8;
+ shift += 8;
+ accum |= *in++;
+ }
+ while ( shift >= 6 )
+ {
+ shift -= 6;
+ *out++ = alphabet[(accum >> shift) & 0x3F];
+ }
+ }
+ if (shift == 4)
+ {
+ *out++ = alphabet[(accum & 0xF)<<2];
+ *out++='=';
+ }
+ else if (shift == 2)
+ {
+ *out++ = alphabet[(accum & 0x3)<<4];
+ *out++='=';
+ *out++='=';
+ }
+
+ *out++=0;
+}
+
+static int recv_string(SOCKET s, char *str, int maxlen)
+{
+ int p=0;
+ do
+ {
+ int t=0;
+ while (t!=1)
+ {
+ t=p_recv(s,str+p,1,0);
+ if (t != 1)
+ {
+ if (rf_abort || !t) { str[0]=0; return -1; }
+ Sleep(100);
+ }
+ if (str[p] == '\r') t=0;
+ }
+ } while (str[p] != '\n' && ++p < maxlen-1);
+ str[p--]=0;
+ while (str[p] == '\n' && p > 0)
+ {
+ str[p--]=0;
+ }
+ if (p < 0) p = 0;
+ return p;
+}
+
+static int g_in_resolve;
+
+static DWORD WINAPI rf_ThreadProc(LPVOID p666)
+{
+ char locbuf[1024]={0};
+ int redirect=0;
+ HINSTANCE hws = LoadLibraryA("wsock32.dll");
+ int total_bytes;
+ uint64_t content_length;
+ SOCKET sock;
+ char proxytmp[256]={0};
+ char *proxy;
+ char connect_host[MAX_PATH]={0};
+ unsigned short connect_port;
+ int success=0;
+
+ typedef int (__stdcall *waSELECT)(int nfds,fd_set FAR * readfds,fd_set FAR * writefds,fd_set FAR * exceptfds,const struct timeval FAR * timeout);
+ typedef int (__stdcall *waWSAGETLASTERROR)(void);
+ typedef int (__stdcall *waWSACLEANUP)(void);
+ typedef int (__stdcall *waWSASTARTUP)(WORD wVersionRequested,LPWSADATA lpWSAData);
+ typedef int (__stdcall *waCLOSESOCKET)(SOCKET s);
+ typedef int (__stdcall *waSEND)(SOCKET s,const char FAR *buf,int len,int flags);
+ typedef SOCKET (__stdcall *waSOCKET)(int af, int type,int protocol);
+ typedef int (__stdcall *waCONNECT)( SOCKET s, const struct sockaddr FAR *name, int namelen );
+ typedef unsigned long (__stdcall *waINET_ADDR)(const char FAR *cp );
+ typedef struct hostent FAR * (__stdcall *waGETHOSTBYNAME)(const char FAR *name);
+ typedef int (__stdcall *waIOCTLSOCKET)(SOCKET s,long cmd,u_long FAR *argp);
+ typedef u_short (__stdcall *waHTONS)(u_short hostshort);
+
+ waSELECT select;
+ waWSAGETLASTERROR WSAGetLastError;
+ waWSACLEANUP WSACleanup;
+ waWSASTARTUP WSAStartup;
+ waCLOSESOCKET closesocket;
+ waSEND send;
+ waSOCKET socket;
+ waCONNECT connect;
+ waINET_ADDR inet_addr;
+ waGETHOSTBYNAME gethostbyname;
+ waIOCTLSOCKET ioctlsocket;
+ waHTONS htons;
+
+ char buf[ 4096 ] = { 0 };
+ char errorStr[ 1024 ] = { 0 };
+ char *p;
+ char url_buf[ 1024 ] = { 0 };
+ char *url_lp = NULL;
+ char *url_host = NULL;
+ int url_port = 80;
+ char *url_url = NULL;
+ char authstr[ 1024 ] = { 0 };
+ char proxy_lp[ 1024 ] = { 0 };
+ const char *t;
+
+ SetThreadName((DWORD)-1, "HTTP Retrieve File");
+ if ( hws )
+ {
+ WSAGetLastError = (waWSAGETLASTERROR)GetProcAddress( hws, "WSAGetLastError" );
+ WSACleanup = (waWSACLEANUP)GetProcAddress( hws, "WSACleanup" );
+ WSAStartup = (waWSASTARTUP)GetProcAddress( hws, "WSAStartup" );
+ closesocket = (waCLOSESOCKET)GetProcAddress( hws, "closesocket" );
+ send = (waSEND)GetProcAddress( hws, "send" );
+ p_recv = (waP_RECV)GetProcAddress( hws, "recv" );
+ select = (waSELECT)GetProcAddress( hws, "select" );
+ connect = (waCONNECT)GetProcAddress( hws, "connect" );
+ socket = (waSOCKET)GetProcAddress( hws, "socket" );
+ inet_addr = (waINET_ADDR)GetProcAddress( hws, "inet_addr" );
+ gethostbyname = (waGETHOSTBYNAME)GetProcAddress( hws, "gethostbyname" );
+ ioctlsocket = (waIOCTLSOCKET)GetProcAddress( hws, "ioctlsocket" );
+ htons = (waHTONS)GetProcAddress( hws, "htons" );
+ }
+
+ if (!hws || !p_recv || !WSACleanup ||
+ !WSAStartup || !closesocket || !send ||
+ !connect || !socket || !inet_addr ||
+ !gethostbyname || !ioctlsocket || !htons || !select || !WSAGetLastError)
+ {
+ if (hws)
+ FreeLibrary(hws);
+
+ rfta(getString(IDS_HTTP_LOAD_ERROR,errorStr,1024));
+ }
+
+ sets(getString(IDS_HTTP_INIT_SOCKET,errorStr,1024));
+ {
+ WSADATA wsaData;
+ if (WSAStartup(MAKEWORD(1, 1), &wsaData))
+ {
+ FreeLibrary(hws);
+ rfta(getString(IDS_HTTP_INIT_SOCKET_ERROR,errorStr,1024));
+ }
+ }
+
+_redirect_goto:
+ total_bytes=0;
+ content_length=0;
+
+ // parse out l/p, host, port, and url from loc
+ authstr[0]=0;
+ url_lp=NULL;
+ url_host=NULL;
+ url_port=80;
+ url_url=NULL;
+
+ t= strstr(rf_url,"://");
+ if (t)
+ {
+ StringCchCopyA(url_buf,1024,t+3);
+ }
+ else
+ {
+ StringCchCopyA(url_buf,1024,rf_url);
+ }
+
+ p=url_buf;
+ while (p && *p != '/' && *p) p++;
+ if (p && *p) *p++=0;
+ url_url=p;
+
+ p=url_buf;
+ while (p && *p) p++;
+ while (p>=url_buf && *p != '@') p--;
+ if (p>=url_buf)
+ {
+ *p++=0;
+ url_host=p;
+ url_lp=url_buf;
+ if (lstrlenA(url_lp)>0)
+ {
+ StringCchCopyA(authstr,1024,"Authorization: Basic ");
+ encodeMimeStr(url_lp,authstr+lstrlenA(authstr));
+ StringCchCatA(authstr,1024,"\r\n");
+ }
+ }
+ else url_host=url_buf;
+
+ p=url_host;
+ while (p && *p != ':' && *p) p++;
+ if (p && *p)
+ {
+ *p++=0;
+ if (*p) url_port=atoi(p);
+ }
+
+ // determine if proxy server used
+ {
+ StringCchCopyA(proxytmp,256,config_proxy);
+ proxy=proxytmp;
+ while (proxy && (*proxy == ' ' || *proxy == '\t')) proxy++;
+
+ if (url_port != 80 && GetPrivateProfileIntW(L"Winamp",L"proxyonly80",0,INI_FILE))
+ proxy="";
+ }
+
+ if (*proxy)
+ {
+ p=proxy;
+ while (p && *p && *p != '@') p++;
+ if (p && *p)
+ {
+ *p++=0;
+ StringCchCopyA(proxy_lp,1024,"Proxy-Authorization: Basic ");
+ encodeMimeStr(proxy,proxy_lp+lstrlenA(proxy_lp));
+ StringCchCatA(proxy_lp,1024,"\r\n");
+ proxy=p;
+ }
+
+ lstrcpynA(connect_host,proxy,sizeof(connect_host)/sizeof(*connect_host));
+ p=connect_host;
+ while (p && *p && *p != ':') p++;
+ if (p && *p)
+ {
+ *p++=0;
+ if (*p) connect_port=(unsigned short)atoi(p);
+ else connect_port=80;
+ }
+ }
+ else
+ {
+ lstrcpynA(connect_host,url_host,sizeof(connect_host)/sizeof(*connect_host));
+ connect_port=(unsigned short)url_port;
+ }
+
+ sets(getString(IDS_HTTP_SOCKET_CREATE,errorStr,1024));
+ if (rf_abort || (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))==INVALID_SOCKET)
+ {
+ WSACleanup();
+ FreeLibrary(hws);
+ rfta(getString(IDS_HTTP_SOCKET_ERROR,errorStr,1024));
+ }
+
+ {
+ int t;
+ struct sockaddr_in blah;
+ memset((char *)&blah,0,sizeof(blah));
+ blah.sin_family=AF_INET;
+ blah.sin_addr.s_addr=inet_addr(connect_host);
+ blah.sin_port=htons(connect_port);
+
+ if ( blah.sin_addr.s_addr == INADDR_NONE )
+ {
+ struct hostent *he;
+ g_in_resolve = 1;
+ sets( *proxy ? getString( IDS_HTTP_RESOLVE_PROXY, errorStr, 1024 ) : getString( IDS_HTTP_RESOLVE_HOST, errorStr, 1024 ) );
+ if ( ( he = gethostbyname( connect_host ) ) != NULL )
+ memcpy( (char *)&blah.sin_addr, he->h_addr, he->h_length );
+ else if ( ( blah.sin_addr.s_addr = inet_addr( connect_host ) ) == INADDR_NONE )
+ {
+ g_in_resolve = 0;
+ closesocket( sock );
+ WSACleanup();
+ FreeLibrary( hws );
+ rfta( *proxy ? getString( IDS_HTTP_RESOLVE_PROXY_ERROR, errorStr, 1024 ) : getString( IDS_HTTP_RESOLVE_HOST_ERROR, errorStr, 1024 ) );
+ }
+
+ g_in_resolve = 0;
+ }
+
+ sets(*proxy?getString(IDS_HTTP_CONNECT_PROXY,errorStr,1024):getString(IDS_HTTP_CONNECT_HOST,errorStr,1024));
+ {
+ unsigned long arg=1;
+ ioctlsocket(sock,FIONBIO,&arg);
+ }
+
+ t=connect(sock,(struct sockaddr *)&blah,16);
+ if (t == -1 && WSAGetLastError()==WSAEWOULDBLOCK)
+ {
+ int a=0;
+ while (!rf_abort && t==-1)
+ {
+ TIMEVAL to={0,250*1000};
+ fd_set f;
+ FD_ZERO(&f);
+ FD_SET(sock,&f);
+ switch (select(0,NULL,&f,NULL,&to))
+ {
+ case 1: t=0; break;
+ case 0: if (a++ > 40) rf_abort =1; break;
+ case -1: rf_abort =1; break;
+ }
+ }
+ }
+ if (rf_abort || t==-1)
+ {
+ closesocket(sock);
+ WSACleanup();
+ FreeLibrary(hws);
+ rfta(*proxy?getString(IDS_HTTP_CONNECT_PROXY_ERROR,errorStr,1024):getString(IDS_HTTP_CONNECT_HOST_ERROR,errorStr,1024));
+ }
+ }
+
+ sets(getString(IDS_HTTP_SEND_REQUEST,errorStr,1024));
+ {
+ if ( *proxy )
+ StringCchPrintfA( buf, 4096, "GET http://%s:%d/%s", url_host, url_port, url_url );
+ else
+ StringCchPrintfA( buf, 4096, "GET /%s", url_url );
+
+ if (url_port != 80)
+ StringCchPrintfA( buf + lstrlenA( buf ), 4096 - lstrlenA( buf ), " HTTP/1.0\r\nHost: %s:%d\r\n", url_host, url_port );
+ else
+ StringCchPrintfA( buf + lstrlenA( buf ), 4096 - lstrlenA( buf ), " HTTP/1.0\r\nHost: %s\r\n", url_host );
+
+ StringCchPrintfA( buf + lstrlenA( buf ), 4096 - lstrlenA( buf ),
+ "User-Agent: Winamp/%s%s\r\n"
+ "%s%s"
+ "Accept: */*\r\n\r\n",
+ app_version,
+ ( redirect == 2 ? " (Mozilla)" : "" ),
+ proxy_lp, authstr );
+
+ //MessageBox(NULL,buf,"SENDING:",0);
+ {
+ unsigned long arg = 0;
+ ioctlsocket( sock, FIONBIO, &arg );
+ }
+
+ send(sock,buf,lstrlenA(buf),0);
+
+ {
+ unsigned long arg = 1;
+ ioctlsocket( sock, FIONBIO, &arg );
+ }
+ }
+
+ sets( getString( IDS_HTTP_READ_REQUEST, errorStr, 1024 ) );
+
+ { // get the standard HTTP 1.0 200 OK
+ char buf[1024] = {0};
+ int x = recv_string(sock,buf,sizeof(buf));
+ //MessageBox(0, buf, "RECEIVING:", 0);
+ if (x < 0 || rf_abort)
+ {
+ closesocket(sock);
+ WSACleanup();
+ FreeLibrary(hws);
+ rfta(getString(IDS_HTTP_CONNECTION_LOST,errorStr,1024));
+ }
+
+ if (strstr(buf," 302") || strstr(buf,"301"))
+ {
+ redirect=1;
+ }
+ else
+ {
+ // this is a very specific handling to allow for /listen.m3u with v1.x DNAS to work correctly
+ // as we need alter the user-agent so it will provide us with the needed response (a DNAS bug)
+ if ((redirect != 2) && strstr(buf,"ICY 404 Resource Not Found") && strstr(url_url,"listen.m3u")) {
+ redirect=2;
+ closesocket(sock);
+ goto _redirect_goto;
+ }
+ else
+ {
+ redirect=0;
+ }
+ }
+
+ if (!strstr(buf,"OK") && !redirect)
+ {
+ StringCchCatA(buf,1024,getString(IDS_HTTP_CONNECTION_CLOSED,errorStr,1024));
+ closesocket(sock);
+ WSACleanup();
+ FreeLibrary(hws);
+ rfta(buf);
+ }
+
+ sets(buf);
+ }
+
+ while (1)
+ {
+ char buf[1024] = {0}, *p;
+ int x = recv_string(sock,buf,sizeof(buf));
+ if (x < 0 || rf_abort)
+ {
+ closesocket(sock);
+ WSACleanup();
+ FreeLibrary(hws);
+ rfta(getString(IDS_HTTP_CONNECTION_LOST,errorStr,1024));
+ }
+
+ if (buf[0] == '\r' || !buf[0])
+ break;
+
+ {
+ p=buf;
+ while (p && *p && *p != ':') p++;
+ if (p && *p == ':')
+ {
+ *p++=0;
+ while (p && (*p == ' ' || *p == '\t'))
+ p++;
+ }
+ else
+ p=NULL;
+ }
+
+ if (!lstrcmpiA(buf,"Content-Length") && (*p >= '0' && *p <= '9'))
+ {
+ content_length=0;
+ while (p && *p >= '0' && *p <= '9')
+ {
+ content_length *= 10;
+ content_length += *p++-'0';
+ }
+ }
+
+ if (!lstrcmpiA(buf,"Location") && redirect)
+ {
+ StringCchCopyA(locbuf,1024,p);
+ rf_url=locbuf;
+ closesocket(sock);
+
+ //blah
+ goto _redirect_goto;
+ }
+ }
+
+ {
+ createDirForFileW((wchar_t *)rf_file);
+ HANDLE h = CreateFileW(rf_file,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,0,NULL);
+ if (h == INVALID_HANDLE_VALUE)
+ {
+ closesocket(sock);
+ WSACleanup();
+ FreeLibrary(hws);
+ rfta(getString(IDS_HTTP_ERROR_OPEN_FILE,errorStr,1024));
+ }
+
+ {
+ unsigned int start_time=GetTickCount();
+ char buf[4096] = {0};
+ while (1)
+ {
+ int x=p_recv(sock,buf,sizeof(buf),0);
+ if (x == 0 || rf_abort)
+ break;
+ else if (x < 0)
+ {
+ if (WSAGetLastError()!=WSAEWOULDBLOCK) break;
+ Sleep(50);
+ }
+ else // x > 0
+ {
+ DWORD t = 0;
+ int lb=total_bytes;
+ WriteFile(h,buf,x,&t,NULL);
+
+ total_bytes += x;
+ if ( lb / 16384 != total_bytes / 16384 )
+ {
+ int bps;
+ int t = ( GetTickCount() - start_time );
+ if ( t < 1000 ) t = 1000;
+ bps = total_bytes / ( ( t + 999 ) / 1000 );
+
+ if ( content_length )
+ 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 );
+ else
+ StringCchPrintfA( buf, 4096, getString( IDS_HTTP_RETRIEVE_FILE, errorStr, 1024 ), total_bytes, bps / 1000, ( bps / 10 ) % 100 );
+
+ sets( buf );
+ }
+ }
+ }
+ }
+ CloseHandle(h);
+ }
+
+ if (!content_length || total_bytes == content_length)
+ success=1;
+ else
+ sets(getString(IDS_HTTP_FILE_INCOMPLETE,errorStr,1024));
+
+ closesocket(sock);
+ WSACleanup();
+ FreeLibrary(hws);
+ rfta(success?getString(IDS_HTTP_SUCCESS,errorStr,1024):NULL);
+}
+
+#undef rfta
+#undef sets
+
+static BOOL CALLBACK rf_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ static HANDLE hThread;
+ static int r;
+
+ if (WADlg_initted())
+ {
+ INT_PTR a = WADlg_handleDialogMsgs(hwndDlg, uMsg, wParam, lParam);
+ if (a)
+ return a;
+ }
+
+ switch (uMsg)
+ {
+ case WM_USER+1:
+ if (hThread != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(hThread);
+ hThread=INVALID_HANDLE_VALUE;
+ }
+
+ if (!wParam)
+ {
+ g_rv=0;
+ PostMessageW(hwndDlg,WM_USER,0,0); // make it go quick
+ }
+ else
+ {
+ SetDlgItemTextA(hwndDlg,IDCANCEL,getString(IDS_HTTP_CLOSE,NULL,0));
+ r=5;
+ SetTimer(hwndDlg,123,1000,NULL);
+ }
+
+ return 0;
+ case WM_TIMER:
+ if (wParam == 123)
+ {
+ if ( r == 0 )
+ {
+ KillTimer( hwndDlg, wParam );
+ g_rv = 1;
+ }
+ else
+ {
+ char s[ 32 ] = { 0 };
+ StringCchPrintfA( s, 32, getString( IDS_CLOSE_COUNTDOWN, NULL, 0 ), r-- );
+ SetDlgItemTextA( hwndDlg, IDCANCEL, s );
+ }
+ }
+ return 0;
+ case WM_ERASEBKGND:
+ if (WADlg_initted())
+ return 1; //handled by WADlg_DrawChildWindowBorders in WM_PAINT
+ break;
+ case WM_PAINT:
+ {
+ if (WADlg_initted())
+ {
+ int tab[] = { IDC_STATUS | DCW_SUNKENBORDER};
+ WADlg_DrawChildWindowBorders(hwndDlg, tab, sizeof(tab) / sizeof(tab[0]));
+ return 0;
+ }
+ }
+ break;
+ case WM_INITDIALOG:
+ {
+ DWORD id;
+ char errorStr[ 1024 ] = { 0 };
+
+ if ( WADlg_initted() )
+ SetWindowLong( GetDlgItem( hwndDlg, IDCANCEL ), GWL_STYLE, GetWindowLongW( GetDlgItem( hwndDlg, IDCANCEL ), GWL_STYLE ) | BS_OWNERDRAW );
+
+ rf_dlgWnd = hwndDlg;
+ rf_statusWnd = GetDlgItem( hwndDlg, IDC_STATUS );
+ SetWindowTextW( hwndDlg, rf_dlgtitle );
+
+ if ( strstr( rf_url, "client.winamp.com/update" ) )
+ SetDlgItemTextA( hwndDlg, IDC_URL, getString( IDS_HTTP_WINAMP_UPDATE_SITE, errorStr, 1024 ) );
+ else
+ SetDlgItemTextA( hwndDlg, IDC_URL, rf_url );
+
+ SetDlgItemTextA( hwndDlg, IDC_STATUS, getString( IDS_HTTP_INIT, errorStr, 1024 ) );
+ rf_abort = 0;
+ hThread = CreateThread( NULL, 0, rf_ThreadProc, 0, 0, &id );
+ }
+ return FALSE;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDCANCEL:
+ if (hThread!=INVALID_HANDLE_VALUE)
+ {
+ char errorStr[1024] = {0};
+ rf_abort=1;
+#if 0
+ if (g_in_resolve) g_in_resolve++;
+ if (0 && g_in_resolve==3) // lame terminatethread shouldnt be used
+ {
+ TerminateThread(hThread,0);
+ CloseHandle(hThread);
+ hThread=INVALID_HANDLE_VALUE;
+ g_rv=1;
+ }
+ else
+#endif
+ SetDlgItemTextA(hwndDlg,IDCANCEL,getString(IDS_HTTP_ABORT,errorStr,1024));
+ }
+ else
+ {
+ g_rv=1;
+ }
+
+ return 0;
+ }
+
+ return 0;
+ }
+
+ return 0;
+}
+
+int httpRetrieveFileW(HWND hwnd, const char *url, const wchar_t *file, const wchar_t *dlgtitle)
+{
+ int i;
+ int activated=0;
+ RECT r;
+ HWND dlgWnd;
+ if (rf_in) return 1;
+ rf_in=1;
+ g_rv=-1;
+ rf_url=url;
+ rf_file=file;
+ rf_dlgtitle=dlgtitle;
+ g_in_resolve=0;
+ if (!hwnd) hwnd=hMainWindow;
+
+ if (hwnd == hMainWindow && g_dialog_box_parent)
+ hwnd=g_dialog_box_parent;
+
+ {
+ if (_strnicmp(url,"http://",7))
+ {
+// MessageBox(hwnd,getString(IDS_ONLYHTTP,NULL,0),"Winamp",MB_OK|MB_ICONSTOP);
+ rf_in=0;
+ return 1;
+ }
+ }
+
+ GetWindowRect(hwnd,&r);
+ dlgWnd=LPCreateDialogW(IDD_HTTPGET, hwnd, (WNDPROC)rf_DlgProc);
+ 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)
+ {
+ activated=1;
+ 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 (g_rv != -1) break;
+ GetMessage(&msg,NULL,0,0);
+ DispatchMessage(&msg);
+ }
+
+ if ( activated && GetForegroundWindow() == dlgWnd )
+ {
+ }
+ else
+ activated = 0;
+
+ if ( hwnd == hMainWindow )
+ {
+ if ( hMainWindow )
+ EnableWindow( hMainWindow, 1 );
+
+ if ( hPLWindow )
+ EnableWindow( hPLWindow, 1 );
+
+ if ( hEQWindow )
+ EnableWindow( hEQWindow, 1 );
+ //if (hMBWindow) EnableWindow(hMBWindow,1);
+ }
+ else
+ EnableWindow( hwnd, 1 );
+
+ DestroyWindow(dlgWnd);
+ if (activated)
+ SetForegroundWindow(hwnd);
+
+ i = g_rv;
+ rf_in=0;
+
+ return i;
+}
+
+int httpRetrieveFile(HWND hwnd, const char *url, char *file, char *dlgtitle)
+{
+ return httpRetrieveFileW(hwnd, url, AutoWide(file), AutoWide(dlgtitle));
+}
+
+#endif \ No newline at end of file