795 lines
18 KiB
C++
795 lines
18 KiB
C++
|
/** (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
|