|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define _WIN32_WINNT 0x0500 |
|
|
|
#include <windows.h> |
|
|
|
#include <wininet.h> |
|
#include <commctrl.h> |
|
#include "pluginapi.h" |
|
#include "resource.h" |
|
|
|
#include <string.h> |
|
|
|
#ifndef PBM_SETMARQUEE |
|
#define PBM_SETMARQUEE (WM_USER + 10) |
|
#define PBS_MARQUEE 0x08 |
|
#endif |
|
#ifndef HTTP_QUERY_PROXY_AUTHORIZATION |
|
#define HTTP_QUERY_PROXY_AUTHORIZATION 61 |
|
#endif |
|
#ifndef SECURITY_FLAG_IGNORE_REVOCATION |
|
#define SECURITY_FLAG_IGNORE_REVOCATION 0x00000080 |
|
#endif |
|
#ifndef SECURITY_FLAG_IGNORE_UNKNOWN_CA |
|
#define SECURITY_FLAG_IGNORE_UNKNOWN_CA 0x00000100 |
|
#endif |
|
|
|
|
|
typedef BOOL (__stdcall *FTP_CMD)(HINTERNET,BOOL,DWORD,LPCTSTR,DWORD,HINTERNET *); |
|
FTP_CMD myFtpCommand; |
|
|
|
#define PLUGIN_NAME TEXT("Inetc plug-in") |
|
#define INETC_USERAGENT TEXT("NSIS_Inetc (Mozilla)") |
|
#define PB_RANGE 400 |
|
#define PAUSE1_SEC 2 |
|
#define PAUSE2_SEC 3 |
|
#define PAUSE3_SEC 1 |
|
#define NOT_AVAILABLE 0xffffffff |
|
#define POST_HEADER TEXT("Content-Type: application/x-www-form-urlencoded") |
|
#define PUT_HEADER TEXT("Content-Type: octet-stream\nContent-Length: %d") |
|
#define INTERNAL_OK 0xFFEE |
|
#define PROGRESS_MS 1000 |
|
#define DEF_QUESTION TEXT("Are you sure that you want to stop download?") |
|
#define HOST_AUTH_HDR TEXT("Authorization: basic %s") |
|
#define PROXY_AUTH_HDR TEXT("Proxy-authorization: basic %s") |
|
|
|
|
|
#define MY_WEAKSECURITY_CERT_FLAGS SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_FLAG_IGNORE_REVOCATION |
|
#define MY_REDIR_FLAGS INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP | INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS |
|
#define MY_HTTPS_FLAGS (MY_REDIR_FLAGS | INTERNET_FLAG_SECURE) |
|
|
|
enum STATUS_CODES { |
|
ST_OK = 0, |
|
ST_CONNECTING, |
|
ST_DOWNLOAD, |
|
ST_CANCELLED, |
|
ST_URLOPEN, |
|
|
|
ST_PAUSE, |
|
ERR_TERMINATED, |
|
ERR_DIALOG, |
|
ERR_INETOPEN, |
|
ERR_URLOPEN, |
|
ERR_TRANSFER, |
|
ERR_FILEOPEN, |
|
ERR_FILEWRITE, |
|
ERR_FILEREAD, |
|
ERR_REGET, |
|
ERR_CONNECT, |
|
ERR_OPENREQUEST, |
|
ERR_SENDREQUEST, |
|
ERR_CRACKURL, |
|
ERR_NOTFOUND, |
|
ERR_THREAD, |
|
ERR_PROXY, |
|
ERR_FORBIDDEN, |
|
ERR_NOTALLOWED, |
|
ERR_REQUEST, |
|
ERR_SERVER, |
|
ERR_AUTH, |
|
ERR_CREATEDIR, |
|
ERR_PATH, |
|
ERR_NOTMODIFIED, |
|
ERR_REDIRECTION |
|
}; |
|
|
|
|
|
static TCHAR szStatus[][32] = { |
|
TEXT("OK"),TEXT("Connecting"),TEXT("Downloading"),TEXT("Cancelled"),TEXT("Connecting"), |
|
TEXT("Reconnect Pause"),TEXT("Terminated"),TEXT("Dialog Error"),TEXT("Open Internet Error"), |
|
TEXT("Open URL Error"),TEXT("Transfer Error"),TEXT("File Open Error"),TEXT("File Write Error"),TEXT("File Read Error"), |
|
TEXT("Reget Error"),TEXT("Connection Error"),TEXT("OpenRequest Error"),TEXT("SendRequest Error"), |
|
TEXT("URL Parts Error"),TEXT("File Not Found (404)"),TEXT("CreateThread Error"),TEXT("Proxy Error (407)"), |
|
TEXT("Access Forbidden (403)"),TEXT("Not Allowed (405)"),TEXT("Request Error"),TEXT("Server Error"), |
|
TEXT("Unauthorized (401)"),TEXT("FtpCreateDir failed (550)"),TEXT("Error FTP path (550)"),TEXT("Not Modified"), |
|
TEXT("Redirection") |
|
}; |
|
|
|
HINSTANCE g_hInstance; |
|
TCHAR fn[MAX_PATH]=TEXT(""), |
|
*url = NULL, |
|
*szAlias = NULL, |
|
*szProxy = NULL, |
|
*szHeader = NULL, |
|
*szBanner = NULL, |
|
*szQuestion = NULL, |
|
szCancel[64]=TEXT(""), |
|
szCaption[128]=TEXT(""), |
|
szUserAgent[256]=TEXT(""), |
|
szResume[256] = TEXT("Your internet connection seems to be not permitted or dropped out!\nPlease reconnect and click Retry to resume installation."); |
|
CHAR *szPost = NULL, |
|
post_fname[MAX_PATH] = ""; |
|
DWORD fSize = 0; |
|
TCHAR *szToStack = NULL; |
|
|
|
int status; |
|
DWORD cnt = 0, |
|
cntToStack = 0, |
|
fs = 0, |
|
timeout = 0, |
|
receivetimeout = 0; |
|
DWORD startTime, transfStart, openType; |
|
bool silent, popup, resume, nocancel, noproxy, nocookies, convToStack, g_ignorecertissues; |
|
|
|
HWND childwnd; |
|
HWND hDlg; |
|
bool fput = false, fhead = false; |
|
|
|
|
|
#define Option_IgnoreCertIssues() ( g_ignorecertissues ) |
|
|
|
static FARPROC GetWininetProcAddress(LPCSTR Name) |
|
{ |
|
return GetProcAddress(LoadLibraryA("WININET"), Name); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static TCHAR szUrl[64] = TEXT(""); |
|
static TCHAR szDownloading[64] = TEXT("Downloading %s"); |
|
static TCHAR szConnecting[64] = TEXT("Connecting ..."); |
|
static TCHAR szSecond[64] = TEXT("second"); |
|
static TCHAR szMinute[32] = TEXT("minute"); |
|
static TCHAR szHour[32] = TEXT("hour"); |
|
static TCHAR szPlural[32] = TEXT("s"); |
|
static TCHAR szProgress[128] = TEXT("%dkB (%d%%) of %dkB @ %d.%01dkB/s"); |
|
static TCHAR szRemaining[64] = TEXT(" (%d %s%s remaining)"); |
|
static TCHAR szBasic[128] = TEXT(""); |
|
static TCHAR szAuth[128] = TEXT(""); |
|
|
|
|
|
|
|
|
|
static TCHAR encode(unsigned char u) { |
|
|
|
if(u < 26) return TEXT('A')+u; |
|
if(u < 52) return TEXT('a')+(u-26); |
|
if(u < 62) return TEXT('0')+(u-52); |
|
if(u == 62) return TEXT('+'); |
|
return TEXT('/'); |
|
} |
|
|
|
TCHAR *encode_base64(int size, TCHAR *src, TCHAR *dst) { |
|
|
|
int i; |
|
TCHAR *p; |
|
|
|
if(!src) |
|
return NULL; |
|
|
|
if(!size) |
|
size= lstrlen(src); |
|
|
|
p = dst; |
|
|
|
for(i=0; i<size; i+=3) { |
|
|
|
unsigned char b1=0, b2=0, b3=0, b4=0, b5=0, b6=0, b7=0; |
|
|
|
b1 = (unsigned char)src[i]; |
|
|
|
if(i+1<size) |
|
b2 = (unsigned char)src[i+1]; |
|
|
|
if(i+2<size) |
|
b3 = (unsigned char)src[i+2]; |
|
|
|
b4= b1>>2; |
|
b5= ((b1&0x3)<<4)|(b2>>4); |
|
b6= ((b2&0xf)<<2)|(b3>>6); |
|
b7= b3&0x3f; |
|
|
|
*p++= encode(b4); |
|
*p++= encode(b5); |
|
|
|
if(i+1<size) { |
|
*p++= encode(b6); |
|
} else { |
|
*p++= TEXT('='); |
|
} |
|
|
|
if(i+2<size) { |
|
*p++= encode(b7); |
|
} else { |
|
*p++= TEXT('='); |
|
} |
|
|
|
} |
|
|
|
return dst; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void fileTransfer(HANDLE localFile, |
|
HINTERNET hFile) |
|
{ |
|
static BYTE data_buf[1024*8]; |
|
BYTE *dw; |
|
DWORD rslt = 0; |
|
DWORD bytesDone; |
|
|
|
status = ST_DOWNLOAD; |
|
while(status == ST_DOWNLOAD) |
|
{ |
|
if(fput) |
|
{ |
|
if(!ReadFile(localFile, data_buf, rslt = sizeof(data_buf), &bytesDone, NULL)) |
|
{ |
|
status = ERR_FILEREAD; |
|
break; |
|
} |
|
if(bytesDone == 0) |
|
{ |
|
status = ST_OK; |
|
break; |
|
} |
|
while(bytesDone > 0) |
|
{ |
|
dw = data_buf; |
|
if(!InternetWriteFile(hFile, dw, bytesDone, &rslt) || rslt == 0) |
|
{ |
|
status = ERR_TRANSFER; |
|
break; |
|
} |
|
dw += rslt; |
|
cnt += rslt; |
|
bytesDone -= rslt; |
|
} |
|
} |
|
else |
|
{ |
|
if(!InternetReadFile(hFile, data_buf, sizeof(data_buf), &rslt)) |
|
{ |
|
status = ERR_TRANSFER; |
|
break; |
|
} |
|
if(rslt == 0) |
|
{ |
|
|
|
|
|
status = (fs != NOT_AVAILABLE && cnt < fs) ? ERR_TRANSFER : ST_OK; |
|
break; |
|
} |
|
if(szToStack) |
|
{ |
|
for (DWORD i = 0; cntToStack < g_stringsize && i < rslt; i++, cntToStack++) |
|
if (convToStack) |
|
*((BYTE*)szToStack + cntToStack) = data_buf[i]; |
|
else |
|
*(szToStack + cntToStack) = data_buf[i]; |
|
} |
|
else if(!WriteFile(localFile, data_buf, rslt, &bytesDone, NULL) || |
|
rslt != bytesDone) |
|
{ |
|
status = ERR_FILEWRITE; |
|
break; |
|
} |
|
cnt += rslt; |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int mySendRequest(HINTERNET hFile) |
|
{ |
|
INTERNET_BUFFERS BufferIn = {0}; |
|
if(fput) |
|
{ |
|
BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS ); |
|
BufferIn.dwBufferTotal = fs; |
|
return HttpSendRequestEx( hFile, &BufferIn, NULL, HSR_INITIATE, 0); |
|
} |
|
return HttpSendRequest(hFile, NULL, 0, szPost, fSize); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool queryStatus(HINTERNET hFile) |
|
{ |
|
TCHAR buf[256] = TEXT(""); |
|
DWORD rslt; |
|
if(HttpQueryInfo(hFile, HTTP_QUERY_STATUS_CODE, |
|
buf, &(rslt = sizeof(buf)), NULL)) |
|
{ |
|
buf[3] = 0; |
|
if(lstrcmp(buf, TEXT("0")) == 0 || *buf == 0) |
|
status = ERR_SENDREQUEST; |
|
else if(lstrcmp(buf, TEXT("401")) == 0) |
|
status = ERR_AUTH; |
|
else if(lstrcmp(buf, TEXT("403")) == 0) |
|
status = ERR_FORBIDDEN; |
|
else if(lstrcmp(buf, TEXT("404")) == 0) |
|
status = ERR_NOTFOUND; |
|
else if(lstrcmp(buf, TEXT("407")) == 0) |
|
status = ERR_PROXY; |
|
else if(lstrcmp(buf, TEXT("405")) == 0) |
|
status = ERR_NOTALLOWED; |
|
else if(lstrcmp(buf, TEXT("304")) == 0) |
|
status = ERR_NOTMODIFIED; |
|
else if(*buf == TEXT('3')) |
|
{ |
|
status = ERR_REDIRECTION; |
|
wsprintf(szStatus[status] + lstrlen(szStatus[status]), TEXT(" (%s)"), buf); |
|
} |
|
else if(*buf == TEXT('4')) |
|
{ |
|
status = ERR_REQUEST; |
|
wsprintf(szStatus[status] + lstrlen(szStatus[status]), TEXT(" (%s)"), buf); |
|
} |
|
else if(*buf == TEXT('5')) |
|
{ |
|
status = ERR_SERVER; |
|
wsprintf(szStatus[status] + lstrlen(szStatus[status]), TEXT(" (%s)"), buf); |
|
} |
|
return true; |
|
} |
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HINTERNET openFtpFile(HINTERNET hConn, |
|
TCHAR *path) |
|
{ |
|
TCHAR buf[256] = TEXT(""), *movp; |
|
HINTERNET hFile; |
|
DWORD rslt, err, gle; |
|
bool https_req_ok = false; |
|
|
|
|
|
InternetGetLastResponseInfo(&err, buf, &(rslt = sizeof(buf))); |
|
if(cnt == 0) |
|
{ |
|
if(!fput) |
|
{ |
|
if (myFtpCommand) |
|
{ |
|
|
|
|
|
myFtpCommand(hConn, false, FTP_TRANSFER_TYPE_ASCII, TEXT("TYPE I"), 0, &hFile); |
|
} |
|
|
|
|
|
|
|
wsprintf(buf, TEXT("SIZE %s"), path + 1); |
|
if(myFtpCommand != NULL && |
|
myFtpCommand(hConn, false, FTP_TRANSFER_TYPE_ASCII, buf, 0, &hFile) != 9999 && |
|
memset(buf, 0, sizeof(buf)) != NULL && |
|
InternetGetLastResponseInfo(&err, buf, &(rslt = sizeof(buf)))) |
|
{ |
|
if(_tcsstr(buf, TEXT("213 "))) |
|
{ |
|
fs = myatou(_tcschr(buf, TEXT(' ')) + 1); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
if(fs == 0) |
|
{ |
|
fs = NOT_AVAILABLE; |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
wsprintf(buf, TEXT("REST %d"), cnt); |
|
if(myFtpCommand == NULL || |
|
!myFtpCommand(hConn, false, FTP_TRANSFER_TYPE_BINARY, buf, 0, &hFile) || |
|
memset(buf, 0, sizeof(buf)) == NULL || |
|
!InternetGetLastResponseInfo(&err, buf, &(rslt = sizeof(buf))) || |
|
(_tcsstr(buf, TEXT("350")) == NULL && _tcsstr(buf, TEXT("110")) == NULL)) |
|
{ |
|
status = ERR_REGET; |
|
return NULL; |
|
} |
|
} |
|
if((hFile = FtpOpenFile(hConn, path + 1, fput ? GENERIC_WRITE : GENERIC_READ, |
|
FTP_TRANSFER_TYPE_BINARY|INTERNET_FLAG_RELOAD,0)) == NULL) |
|
{ |
|
gle = GetLastError(); |
|
*buf = 0; |
|
InternetGetLastResponseInfo(&err, buf, &(rslt = sizeof(buf))); |
|
|
|
|
|
if(fput && (_tcsstr(buf, TEXT("550")) != NULL || _tcsstr(buf, TEXT("553")) != NULL)) |
|
{ |
|
movp = path + 1; |
|
if(*movp == TEXT('/')) movp++; |
|
for (UINT8 escapehatch = 0; ++escapehatch;) |
|
{ |
|
TCHAR *pbs = _tcschr(movp, TEXT('/')); |
|
if (!pbs) break; |
|
*pbs = TEXT('\0'); |
|
FtpCreateDirectory(hConn, path + 1); |
|
InternetGetLastResponseInfo(&err, buf, &(rslt = sizeof(buf))); |
|
*(movp + lstrlen(movp)) = TEXT('/'); |
|
movp = _tcschr(movp, TEXT('/')) + 1; |
|
} |
|
if(status != ERR_CREATEDIR && |
|
(hFile = FtpOpenFile(hConn, path + 1, GENERIC_WRITE, |
|
FTP_TRANSFER_TYPE_BINARY|INTERNET_FLAG_RELOAD,0)) == NULL) |
|
{ |
|
status = ERR_PATH; |
|
if(InternetGetLastResponseInfo(&err, buf, &(rslt = sizeof(buf)))) |
|
lstrcpyn(szStatus[status], _tcsstr(buf, TEXT("550")), sizeof(szStatus[0]) / sizeof(TCHAR)); |
|
} |
|
} |
|
|
|
else if(gle == 12003) |
|
{ |
|
if(_tcsstr(buf, TEXT("550"))) |
|
{ |
|
status = ERR_NOTFOUND; |
|
lstrcpyn(szStatus[status], _tcsstr(buf, TEXT("550")), sizeof(szStatus[0]) / sizeof(TCHAR)); |
|
} |
|
else |
|
{ |
|
lstrcpyn(szStatus[status], buf, sizeof(szStatus[0]) / sizeof(TCHAR)); |
|
} |
|
} |
|
|
|
else if(gle == 12002) |
|
{ |
|
if(!silent) |
|
resume = true; |
|
status = ERR_URLOPEN; |
|
} |
|
} |
|
else |
|
InternetGetLastResponseInfo(&err, buf, &(rslt = sizeof(buf))); |
|
if (hFile && NOT_AVAILABLE == fs) |
|
{ |
|
FARPROC ftpgfs = GetWininetProcAddress("FtpGetFileSize"); |
|
if (ftpgfs) |
|
{ |
|
DWORD shi, slo = ((DWORD(WINAPI*)(HINTERNET,DWORD*))ftpgfs)(hFile, &shi); |
|
if (slo != -1 && !shi) fs = slo; |
|
} |
|
} |
|
return hFile; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HINTERNET openHttpFile(HINTERNET hConn, INTERNET_SCHEME nScheme, TCHAR *path) |
|
{ |
|
TCHAR buf[256] = TEXT(""); |
|
HINTERNET hFile; |
|
DWORD rslt, err; |
|
bool first_attempt = true;; |
|
|
|
|
|
|
|
|
|
if(fput) |
|
{ |
|
|
|
if((hFile = HttpOpenRequest(hConn, TEXT("HEAD"), path, NULL, NULL, NULL, |
|
|
|
INTERNET_FLAG_RELOAD | INTERNET_FLAG_KEEP_CONNECTION | |
|
(nocookies ? (INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_COOKIES) : 0), 0)) != NULL) |
|
{ |
|
if(*szAuth) |
|
{ |
|
wsprintf(buf, PROXY_AUTH_HDR, szAuth); |
|
HttpAddRequestHeaders(hFile, buf, -1, |
|
HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE); |
|
} |
|
resend_proxy1: |
|
if(*szBasic) |
|
{ |
|
wsprintf(buf, HOST_AUTH_HDR, szBasic); |
|
HttpAddRequestHeaders(hFile, buf, -1, |
|
HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE); |
|
} |
|
resend_auth1: |
|
if(HttpSendRequest(hFile, NULL, 0, NULL, 0)) |
|
{ |
|
queryStatus(hFile); |
|
|
|
while(InternetReadFile(hFile, buf, sizeof(buf), &rslt) && rslt > 0) {} |
|
if(!silent && (status == ERR_PROXY || status == ERR_AUTH)) |
|
{ |
|
rslt = InternetErrorDlg(hDlg, hFile, |
|
ERROR_INTERNET_INCORRECT_PASSWORD, |
|
FLAGS_ERROR_UI_FILTER_FOR_ERRORS | |
|
FLAGS_ERROR_UI_FLAGS_GENERATE_DATA | |
|
FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS, |
|
NULL); |
|
if (rslt == ERROR_INTERNET_FORCE_RETRY) |
|
{ |
|
status = ST_URLOPEN; |
|
if(status == ERR_PROXY) goto resend_proxy1; |
|
else goto resend_auth1; |
|
} |
|
else |
|
{ |
|
status = ST_CANCELLED; |
|
} |
|
|
|
} |
|
|
|
if(status == ERR_NOTFOUND || status == ERR_FORBIDDEN || status == ERR_NOTALLOWED) |
|
{ |
|
|
|
status = ST_URLOPEN; |
|
} |
|
|
|
if(status == ST_URLOPEN) |
|
{ |
|
*buf = 0; |
|
if(HttpQueryInfo(hFile, HTTP_QUERY_AUTHORIZATION, buf, &(rslt = sizeof(buf)), NULL) && *buf) |
|
lstrcpyn(szBasic, buf, rslt); |
|
*buf = 0; |
|
if(HttpQueryInfo(hFile, HTTP_QUERY_PROXY_AUTHORIZATION, buf, &(rslt = sizeof(buf)), NULL) && *buf) |
|
lstrcpyn(szAuth, buf, rslt); |
|
} |
|
} |
|
else status = ERR_SENDREQUEST; |
|
InternetCloseHandle(hFile); |
|
} |
|
else status = ERR_OPENREQUEST; |
|
} |
|
|
|
if(status == ST_URLOPEN) |
|
{ |
|
DWORD secflags = nScheme == INTERNET_SCHEME_HTTPS ? MY_HTTPS_FLAGS : 0; |
|
if (Option_IgnoreCertIssues()) secflags |= MY_WEAKSECURITY_CERT_FLAGS; |
|
DWORD cokflags = nocookies ? (INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_COOKIES) : 0; |
|
if((hFile = HttpOpenRequest(hConn, fput ? TEXT("PUT") : (fhead ? TEXT("HEAD") : (szPost ? TEXT("POST") : NULL)), |
|
path, NULL, NULL, NULL, |
|
|
|
|
|
|
|
|
|
(cnt ? 0 : INTERNET_FLAG_RELOAD) | INTERNET_FLAG_KEEP_CONNECTION | cokflags | secflags, 0)) != NULL) |
|
{ |
|
if(*szAuth) |
|
{ |
|
wsprintf(buf, PROXY_AUTH_HDR, szAuth); |
|
HttpAddRequestHeaders(hFile, buf, -1, |
|
HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE); |
|
} |
|
resend_proxy2: |
|
if(szPost != NULL) |
|
HttpAddRequestHeaders(hFile, POST_HEADER, |
|
-1, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE); |
|
if(*post_fname) |
|
HttpAddRequestHeadersA(hFile, post_fname, |
|
-1, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE); |
|
if(szHeader != NULL) |
|
HttpAddRequestHeaders(hFile, szHeader, -1, |
|
HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE); |
|
if(*szBasic) |
|
{ |
|
wsprintf(buf, HOST_AUTH_HDR, szBasic); |
|
HttpAddRequestHeaders(hFile, buf, -1, |
|
HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE); |
|
} |
|
if(fput) |
|
{ |
|
wsprintf(buf, PUT_HEADER, fs); |
|
HttpAddRequestHeaders(hFile, buf, -1, |
|
HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE); |
|
} |
|
resend_auth2: |
|
first_attempt = true; |
|
if(nScheme == INTERNET_SCHEME_HTTPS) |
|
{ |
|
if(!mySendRequest(hFile)) |
|
{ |
|
InternetQueryOption (hFile, INTERNET_OPTION_SECURITY_FLAGS, |
|
(LPVOID)&rslt, &(err = sizeof(rslt))); |
|
rslt |= Option_IgnoreCertIssues() ? MY_WEAKSECURITY_CERT_FLAGS : 0; |
|
InternetSetOption (hFile, INTERNET_OPTION_SECURITY_FLAGS, |
|
&rslt, sizeof(rslt) ); |
|
} |
|
else first_attempt = false; |
|
} |
|
|
|
if(!first_attempt || mySendRequest(hFile)) |
|
{ |
|
|
|
if(!fput) |
|
{ |
|
queryStatus(hFile); |
|
if(!silent && (status == ERR_PROXY || status == ERR_AUTH)) |
|
{ |
|
rslt = InternetErrorDlg(hDlg, hFile, |
|
ERROR_INTERNET_INCORRECT_PASSWORD, |
|
FLAGS_ERROR_UI_FILTER_FOR_ERRORS | |
|
FLAGS_ERROR_UI_FLAGS_GENERATE_DATA | |
|
FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS, |
|
NULL); |
|
if (rslt == ERROR_INTERNET_FORCE_RETRY) |
|
{ |
|
status = ST_URLOPEN; |
|
if(status == ERR_PROXY) goto resend_proxy2; |
|
else goto resend_auth2; |
|
} |
|
else |
|
status = ST_CANCELLED; |
|
|
|
} |
|
|
|
if(status == ST_URLOPEN) |
|
{ |
|
if(cnt == 0) |
|
{ |
|
if(HttpQueryInfo(hFile, HTTP_QUERY_CONTENT_LENGTH, buf, |
|
&(rslt = sizeof(buf)), NULL)) |
|
fs = myatou(buf); |
|
else |
|
fs = NOT_AVAILABLE; |
|
} |
|
else |
|
{ |
|
if((int)InternetSetFilePointer(hFile, cnt, NULL, FILE_BEGIN, 0) == -1) |
|
status = ERR_REGET; |
|
} |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
if(!queryStatus(hFile)) |
|
status = ERR_SENDREQUEST; |
|
} |
|
} |
|
else status = ERR_OPENREQUEST; |
|
} |
|
return hFile; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DWORD __stdcall inetTransfer(void *hw) |
|
{ |
|
HINTERNET hSes, hConn, hFile; |
|
HANDLE localFile = NULL; |
|
HWND hDlg = (HWND)hw; |
|
DWORD lastCnt, rslt, err; |
|
static TCHAR hdr[2048]; |
|
TCHAR *host = (TCHAR*)LocalAlloc(LPTR, g_stringsize * sizeof(TCHAR)), |
|
*path = (TCHAR*)LocalAlloc(LPTR, g_stringsize * sizeof(TCHAR)), |
|
*params = (TCHAR*)LocalAlloc(LPTR, g_stringsize * sizeof(TCHAR)), |
|
*user = (TCHAR*)LocalAlloc(LPTR, g_stringsize * sizeof(TCHAR)), |
|
*passwd = (TCHAR*)LocalAlloc(LPTR, g_stringsize * sizeof(TCHAR)); |
|
|
|
URL_COMPONENTS uc = {sizeof(URL_COMPONENTS), NULL, 0, |
|
(INTERNET_SCHEME)0, host, g_stringsize, 0 , user, g_stringsize, |
|
passwd, g_stringsize, path, g_stringsize, params, g_stringsize}; |
|
|
|
if((hSes = InternetOpen(szUserAgent, openType, szProxy, NULL, 0)) != NULL) |
|
{ |
|
if(InternetQueryOption(hSes, INTERNET_OPTION_CONNECTED_STATE, &(rslt=0), |
|
&(lastCnt=sizeof(DWORD))) && |
|
(rslt & INTERNET_STATE_DISCONNECTED_BY_USER)) |
|
{ |
|
INTERNET_CONNECTED_INFO ci = {INTERNET_STATE_CONNECTED, 0}; |
|
InternetSetOption(hSes, |
|
INTERNET_OPTION_CONNECTED_STATE, &ci, sizeof(ci)); |
|
} |
|
if(timeout > 0) |
|
lastCnt = InternetSetOption(hSes, INTERNET_OPTION_CONNECT_TIMEOUT, &timeout, sizeof(timeout)); |
|
if(receivetimeout > 0) |
|
InternetSetOption(hSes, INTERNET_OPTION_RECEIVE_TIMEOUT, &receivetimeout, sizeof(receivetimeout)); |
|
|
|
myFtpCommand = (FTP_CMD) GetWininetProcAddress( |
|
#ifdef UNICODE |
|
"FtpCommandW" |
|
#else |
|
"FtpCommandA" |
|
#endif |
|
); |
|
while(!popstring(url) && lstrcmpi(url, TEXT("/end")) != 0) |
|
{ |
|
|
|
|
|
if(popstring(fn) != 0 || lstrcmpi(url, TEXT("/end")) == 0) break; |
|
status = ST_CONNECTING; |
|
cnt = fs = *host = *user = *passwd = *path = *params = 0; |
|
PostMessage(hDlg, WM_TIMER, 1, 0); |
|
if(szToStack || (localFile = CreateFile(fn, fput ? GENERIC_READ : GENERIC_WRITE, FILE_SHARE_READ, |
|
NULL, fput ? OPEN_EXISTING : CREATE_ALWAYS, 0, NULL)) != INVALID_HANDLE_VALUE) |
|
{ |
|
uc.dwHostNameLength = uc.dwUserNameLength = uc.dwPasswordLength = |
|
uc.dwUrlPathLength = uc.dwExtraInfoLength = g_stringsize; |
|
if(fput) |
|
{ |
|
fs = GetFileSize(localFile, NULL); |
|
} |
|
if(InternetCrackUrl(url, 0, 0 , &uc)) |
|
{ |
|
|
|
if(*user && *passwd) |
|
{ |
|
wsprintf(hdr, TEXT("%s:%s"), user, passwd); |
|
|
|
|
|
encode_base64(lstrlen(hdr), hdr, szBasic); |
|
*hdr = 0; |
|
} |
|
lstrcat(path, params); |
|
transfStart = GetTickCount(); |
|
do |
|
{ |
|
|
|
|
|
if((fput && uc.nScheme != INTERNET_SCHEME_FTP) || szPost) |
|
{ |
|
cnt = 0; |
|
SetFilePointer(localFile, 0, NULL, FILE_BEGIN); |
|
} |
|
status = ST_CONNECTING; |
|
lastCnt = cnt; |
|
if((hConn = InternetConnect(hSes, host, uc.nPort, |
|
lstrlen(user) > 0 ? user : NULL, |
|
lstrlen(passwd) > 0 ? passwd : NULL, |
|
uc.nScheme == INTERNET_SCHEME_FTP ? INTERNET_SERVICE_FTP : INTERNET_SERVICE_HTTP, |
|
uc.nScheme == INTERNET_SCHEME_FTP ? INTERNET_FLAG_PASSIVE : 0, 0)) != NULL) |
|
{ |
|
status = ST_URLOPEN; |
|
hFile = uc.nScheme == INTERNET_SCHEME_FTP ? |
|
openFtpFile(hConn, path) : openHttpFile(hConn, uc.nScheme, path); |
|
if(status != ST_URLOPEN && hFile != NULL) |
|
{ |
|
InternetCloseHandle(hFile); |
|
hFile = NULL; |
|
} |
|
if(hFile != NULL) |
|
{ |
|
if(fhead) |
|
{ |
|
if(HttpQueryInfo(hFile, HTTP_QUERY_RAW_HEADERS_CRLF, hdr, &(rslt=2048), NULL)) |
|
{ |
|
if(szToStack) |
|
{ |
|
for (DWORD i = 0; cntToStack < g_stringsize && i < rslt; i++, cntToStack++) |
|
*(szToStack + cntToStack) = hdr[i]; |
|
} |
|
else |
|
{ |
|
WriteFile(localFile, hdr, rslt, &lastCnt, NULL); |
|
} |
|
} |
|
status = ST_OK; |
|
} |
|
else |
|
{ |
|
HWND hBar = GetDlgItem(hDlg, IDC_PROGRESS1); |
|
SendDlgItemMessage(hDlg, IDC_PROGRESS1, PBM_SETPOS, 0, 0); |
|
SetWindowText(GetDlgItem(hDlg, IDC_STATIC5), fs == NOT_AVAILABLE ? TEXT("Not Available") : TEXT("")); |
|
SetWindowText(GetDlgItem(hDlg, IDC_STATIC4), fs == NOT_AVAILABLE ? TEXT("Unknown") : TEXT("")); |
|
SetWindowLong(hBar, GWL_STYLE, fs == NOT_AVAILABLE ? |
|
(GetWindowLong(hBar, GWL_STYLE) | PBS_MARQUEE) : (GetWindowLong(hBar, GWL_STYLE) & ~PBS_MARQUEE)); |
|
SendDlgItemMessage(hDlg, IDC_PROGRESS1, PBM_SETMARQUEE, (WPARAM)(fs == NOT_AVAILABLE ? 1 : 0), (LPARAM)50 ); |
|
fileTransfer(localFile, hFile); |
|
if(fput && uc.nScheme != INTERNET_SCHEME_FTP) |
|
{ |
|
rslt = HttpEndRequest(hFile, NULL, 0, 0); |
|
queryStatus(hFile); |
|
} |
|
} |
|
InternetCloseHandle(hFile); |
|
} |
|
InternetCloseHandle(hConn); |
|
} |
|
else |
|
{ |
|
status = ERR_CONNECT; |
|
if(uc.nScheme == INTERNET_SCHEME_FTP && |
|
InternetGetLastResponseInfo(&err, hdr, &(rslt = sizeof(hdr))) && |
|
_tcsstr(hdr, TEXT("530"))) |
|
{ |
|
lstrcpyn(szStatus[status], _tcsstr(hdr, TEXT("530")), sizeof(szStatus[0]) / sizeof(TCHAR)); |
|
} |
|
else |
|
{ |
|
rslt = GetLastError(); |
|
if((rslt == 12003 || rslt == 12002) && !silent) |
|
resume = true; |
|
} |
|
} |
|
} while(((!fput || uc.nScheme == INTERNET_SCHEME_FTP) && |
|
cnt > lastCnt && |
|
status == ERR_TRANSFER && |
|
SleepEx(PAUSE1_SEC * 1000, false) == 0 && |
|
(status = ST_PAUSE) != ST_OK && |
|
SleepEx(PAUSE2_SEC * 1000, false) == 0) |
|
|| (resume && |
|
status != ST_OK && |
|
status != ST_CANCELLED && |
|
status != ERR_NOTFOUND && |
|
ShowWindow(hDlg, SW_HIDE) != -1 && |
|
MessageBox(GetParent(hDlg), szResume, *szCaption ? szCaption : PLUGIN_NAME, MB_RETRYCANCEL|MB_ICONWARNING) == IDRETRY && |
|
(status = ST_PAUSE) != ST_OK && |
|
ShowWindow(hDlg, silent ? SW_HIDE : SW_SHOW) == false && |
|
SleepEx(PAUSE3_SEC * 1000, false) == 0)); |
|
} |
|
else status = ERR_CRACKURL; |
|
CloseHandle(localFile); |
|
if(!fput && status != ST_OK && !szToStack) |
|
{ |
|
rslt = DeleteFile(fn); |
|
break; |
|
} |
|
} |
|
else status = ERR_FILEOPEN; |
|
} |
|
InternetCloseHandle(hSes); |
|
if (lstrcmpi(url, TEXT("/end"))==0) |
|
pushstring(url); |
|
} |
|
else status = ERR_INETOPEN; |
|
LocalFree(host); |
|
LocalFree(path); |
|
LocalFree(user); |
|
LocalFree(passwd); |
|
LocalFree(params); |
|
if(IsWindow(hDlg)) |
|
PostMessage(hDlg, WM_COMMAND, MAKELONG(IDOK, INTERNAL_OK), 0); |
|
return status; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void fsFormat(DWORD bfs, TCHAR *b) |
|
{ |
|
if(bfs == NOT_AVAILABLE) |
|
lstrcpy(b, TEXT("???")); |
|
else if(bfs == 0) |
|
lstrcpy(b, TEXT("0")); |
|
else if(bfs < 10 * 1024) |
|
wsprintf(b, TEXT("%u bytes"), bfs); |
|
else if(bfs < 10 * 1024 * 1024) |
|
wsprintf(b, TEXT("%u kB"), bfs / 1024); |
|
else wsprintf(b, TEXT("%u MB"), (bfs / 1024 / 1024)); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void progress_callback(void) |
|
{ |
|
static TCHAR buf[1024] = TEXT(""), b[1024] = TEXT(""); |
|
int time_sofar = max(1, (GetTickCount() - transfStart) / 1000); |
|
int bps = cnt / time_sofar; |
|
int remain = (cnt > 0 && fs != NOT_AVAILABLE) ? (MulDiv(time_sofar, fs, cnt) - time_sofar) : 0; |
|
TCHAR *rtext=szSecond; |
|
if(remain < 0) remain = 0; |
|
if (remain >= 60) |
|
{ |
|
remain/=60; |
|
rtext=szMinute; |
|
if (remain >= 60) |
|
{ |
|
remain/=60; |
|
rtext=szHour; |
|
} |
|
} |
|
wsprintf(buf, |
|
szProgress, |
|
cnt/1024, |
|
fs > 0 && fs != NOT_AVAILABLE ? MulDiv(100, cnt, fs) : 0, |
|
fs != NOT_AVAILABLE ? fs/1024 : 0, |
|
bps/1024,((bps*10)/1024)%10 |
|
); |
|
if (remain) wsprintf(buf + lstrlen(buf), |
|
szRemaining, |
|
remain, |
|
rtext, |
|
remain==1?TEXT(""):szPlural |
|
); |
|
SetDlgItemText(hDlg, IDC_STATIC1, (cnt == 0 || status == ST_CONNECTING) ? szConnecting : buf); |
|
if(fs > 0 && fs != NOT_AVAILABLE) |
|
SendMessage(GetDlgItem(hDlg, IDC_PROGRESS1), PBM_SETPOS, MulDiv(cnt, PB_RANGE, fs), 0); |
|
if (*szCaption == 0) |
|
wsprintf(buf, szDownloading, _tcsrchr(fn, TEXT('\\')) ? _tcsrchr(fn, TEXT('\\')) + 1 : fn); |
|
else |
|
wsprintf(buf, TEXT("%s"),szCaption); |
|
HWND hwndS = GetDlgItem(childwnd, 1006); |
|
if(!silent && hwndS != NULL && IsWindow(hwndS)) |
|
{ |
|
GetWindowText(hwndS, b, sizeof(b)); |
|
if(lstrcmp(b, buf) != 0) |
|
SetWindowText(hwndS, buf); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void onTimer(HWND hDlg) |
|
{ |
|
TCHAR b[128]; |
|
DWORD ct = (GetTickCount() - transfStart) / 1000, |
|
tt = (GetTickCount() - startTime) / 1000; |
|
|
|
wsprintf(b, TEXT("%s - %s"), *szCaption ? szCaption : PLUGIN_NAME, szStatus[status]); |
|
if(fs > 0 && fs != NOT_AVAILABLE && status == ST_DOWNLOAD) |
|
{ |
|
wsprintf(b + lstrlen(b), TEXT(" %d%%"), MulDiv(100, cnt, fs)); |
|
} |
|
if(szBanner == NULL) SetWindowText(hDlg, b); |
|
|
|
SetDlgItemText(hDlg, IDC_STATIC1, (szAlias && *szAlias) ? szAlias : url); |
|
SetDlgItemText(hDlg, IDC_STATIC2, fn); |
|
|
|
if(cnt > 0) |
|
{ |
|
fsFormat(cnt, b); |
|
if(ct > 1 && status == ST_DOWNLOAD) |
|
{ |
|
lstrcat(b, TEXT(" ( ")); |
|
fsFormat(cnt / ct, b + lstrlen(b)); |
|
lstrcat(b, TEXT("/sec )")); |
|
} |
|
} |
|
else *b = 0; |
|
SetDlgItemText(hDlg, IDC_STATIC3, b); |
|
|
|
wsprintf(b, TEXT("%d:%02d:%02d"), tt / 3600, (tt / 60) % 60, tt % 60); |
|
SetDlgItemText(hDlg, IDC_STATIC6, b); |
|
|
|
if(fs > 0 && fs != NOT_AVAILABLE) |
|
{ |
|
fsFormat(fs, b); |
|
SetDlgItemText(hDlg, IDC_STATIC5, b); |
|
SendDlgItemMessage(hDlg, IDC_PROGRESS1, PBM_SETPOS, MulDiv(cnt, PB_RANGE, fs), 0); |
|
if(cnt > 5000) |
|
{ |
|
ct = MulDiv(fs - cnt, ct, cnt); |
|
wsprintf(b, TEXT("%d:%02d:%02d"), ct / 3600, (ct / 60) % 60, ct % 60); |
|
} |
|
else *b = 0; |
|
SetWindowText(GetDlgItem(hDlg, IDC_STATIC4), b); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void centerDlg(HWND hDlg) |
|
{ |
|
HWND hwndParent = GetParent(hDlg); |
|
RECT nsisRect, dlgRect, waRect; |
|
int dlgX, dlgY, dlgWidth, dlgHeight; |
|
|
|
if(hwndParent == NULL || silent) |
|
return; |
|
if(popup) |
|
GetWindowRect(hwndParent, &nsisRect); |
|
else GetClientRect(hwndParent, &nsisRect); |
|
GetWindowRect(hDlg, &dlgRect); |
|
|
|
dlgWidth = dlgRect.right - dlgRect.left; |
|
dlgHeight = dlgRect.bottom - dlgRect.top; |
|
dlgX = (nsisRect.left + nsisRect.right - dlgWidth) / 2; |
|
dlgY = (nsisRect.top + nsisRect.bottom - dlgHeight) / 2; |
|
|
|
if(popup) |
|
{ |
|
SystemParametersInfo(SPI_GETWORKAREA, 0, &waRect, 0); |
|
if(dlgX > waRect.right - dlgWidth) |
|
dlgX = waRect.right - dlgWidth; |
|
if(dlgX < waRect.left) dlgX = waRect.left; |
|
if(dlgY > waRect.bottom - dlgHeight) |
|
dlgY = waRect.bottom - dlgHeight; |
|
if(dlgY < waRect.top) dlgY = waRect.top; |
|
} |
|
else dlgY += 20; |
|
|
|
SetWindowPos(hDlg, HWND_TOP, dlgX, dlgY, 0, 0, SWP_NOSIZE); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void onInitDlg(HWND hDlg) |
|
{ |
|
HFONT hFont; |
|
HWND hPrbNew; |
|
HWND hPrbOld; |
|
HWND hCan = GetDlgItem(hDlg, IDCANCEL); |
|
|
|
if(childwnd) |
|
{ |
|
hPrbNew = GetDlgItem(hDlg, IDC_PROGRESS1); |
|
hPrbOld = GetDlgItem(childwnd, 0x3ec); |
|
|
|
|
|
|
|
LONG prbStyle = WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; |
|
if(hPrbOld != NULL) |
|
{ |
|
prbStyle |= GetWindowLong(hPrbOld, GWL_STYLE); |
|
} |
|
SetWindowLong(hPrbNew, GWL_STYLE, prbStyle); |
|
|
|
if(!popup) |
|
{ |
|
if((hFont = (HFONT)SendMessage(childwnd, WM_GETFONT, 0, 0)) != NULL) |
|
{ |
|
SendDlgItemMessage(hDlg, IDC_STATIC1, WM_SETFONT, (WPARAM)hFont, 0); |
|
SendDlgItemMessage(hDlg, IDCANCEL, WM_SETFONT, (WPARAM)hFont, 0); |
|
} |
|
if(*szCancel == 0) |
|
GetWindowText(GetDlgItem(GetParent(childwnd), IDCANCEL), szCancel, sizeof(szCancel)); |
|
SetWindowText(hCan, szCancel); |
|
SetWindowPos(hPrbNew, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); |
|
} |
|
} |
|
|
|
if(nocancel) |
|
{ |
|
if(hCan != NULL) |
|
ShowWindow(hCan, SW_HIDE); |
|
if(popup) |
|
SetWindowLong(hDlg, GWL_STYLE, GetWindowLong(hDlg, GWL_STYLE) ^ WS_SYSMENU); |
|
} |
|
SendDlgItemMessage(hDlg, IDC_PROGRESS1, PBM_SETRANGE, |
|
0, MAKELPARAM(0, PB_RANGE)); |
|
if(szBanner != NULL) |
|
{ |
|
SendDlgItemMessage(hDlg, IDC_STATIC13, STM_SETICON, |
|
(WPARAM)LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(103)), 0); |
|
SetDlgItemText(hDlg, IDC_STATIC12, szBanner); |
|
SetWindowText(hDlg, *szCaption ? szCaption : PLUGIN_NAME); |
|
} |
|
SetTimer(hDlg, 1, 1000, NULL); |
|
if(*szUrl != 0) |
|
{ |
|
SetDlgItemText(hDlg, IDC_STATIC20, szUrl); |
|
SetDlgItemText(hDlg, IDC_STATIC21, szDownloading); |
|
SetDlgItemText(hDlg, IDC_STATIC22, szConnecting); |
|
SetDlgItemText(hDlg, IDC_STATIC23, szProgress); |
|
SetDlgItemText(hDlg, IDC_STATIC24, szSecond); |
|
SetDlgItemText(hDlg, IDC_STATIC25, szRemaining); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
INT_PTR CALLBACK dlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ) |
|
{ |
|
switch(message) |
|
{ |
|
case WM_INITDIALOG: |
|
onInitDlg(hDlg); |
|
centerDlg(hDlg); |
|
return false; |
|
case WM_PAINT: |
|
|
|
{ |
|
HWND hS1 = GetDlgItem(hDlg, IDC_STATIC1), hC = GetDlgItem(hDlg, IDCANCEL), hP1 = GetDlgItem(hDlg, IDC_PROGRESS1); |
|
RedrawWindow(hS1, NULL, NULL, RDW_INVALIDATE); |
|
RedrawWindow(hC, NULL, NULL, RDW_INVALIDATE); |
|
RedrawWindow(hP1, NULL, NULL, RDW_INVALIDATE); |
|
UpdateWindow(hS1); |
|
UpdateWindow(hC); |
|
UpdateWindow(hP1); |
|
} |
|
return false; |
|
case WM_TIMER: |
|
if(!silent && IsWindow(hDlg)) |
|
{ |
|
|
|
if(status != ST_DOWNLOAD && GetTickCount() - transfStart > PROGRESS_MS) |
|
transfStart += PROGRESS_MS; |
|
if(popup) onTimer(hDlg); else progress_callback(); |
|
RedrawWindow(GetDlgItem(hDlg, IDC_STATIC1), NULL, NULL, RDW_INVALIDATE); |
|
RedrawWindow(GetDlgItem(hDlg, IDCANCEL), NULL, NULL, RDW_INVALIDATE); |
|
RedrawWindow(GetDlgItem(hDlg, IDC_PROGRESS1), NULL, NULL, RDW_INVALIDATE); |
|
} |
|
break; |
|
case WM_COMMAND: |
|
switch(LOWORD(wParam)) |
|
{ |
|
case IDCANCEL: |
|
if(nocancel) break; |
|
if(szQuestion && |
|
MessageBox(hDlg, szQuestion, *szCaption ? szCaption : PLUGIN_NAME, MB_ICONWARNING|MB_YESNO) == IDNO) |
|
break; |
|
status = ST_CANCELLED; |
|
|
|
case IDOK: |
|
if(status != ST_CANCELLED && HIWORD(wParam) != INTERNAL_OK) break; |
|
|
|
|
|
KillTimer(hDlg, 1); |
|
DestroyWindow(hDlg); |
|
break; |
|
} |
|
return false; |
|
default: |
|
return false; |
|
} |
|
return true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" |
|
void __declspec(dllexport) __cdecl get(HWND hwndParent, |
|
int string_size, |
|
TCHAR *variables, |
|
stack_t **stacktop, |
|
extra_parameters *extra |
|
) |
|
{ |
|
HANDLE hThread; |
|
DWORD dwThreadId; |
|
MSG msg; |
|
TCHAR szUsername[64]=TEXT(""), |
|
szPassword[64]=TEXT(""); |
|
|
|
|
|
EXDLL_INIT(); |
|
|
|
|
|
silent = popup = resume = nocancel = noproxy = nocookies = false; |
|
g_ignorecertissues = false; |
|
myFtpCommand = NULL; |
|
openType = INTERNET_OPEN_TYPE_PRECONFIG; |
|
status = ST_CONNECTING; |
|
*szCaption = *szCancel = *szUserAgent = *szBasic = *szAuth = 0; |
|
|
|
url = (TCHAR*)LocalAlloc(LPTR, string_size * sizeof(TCHAR)); |
|
if(szPost) |
|
{ |
|
popstring(url); |
|
#ifdef UNICODE |
|
WideCharToMultiByte(CP_ACP, 0, url, -1, szPost, string_size, NULL, NULL); |
|
#else |
|
lstrcpy(szPost, url); |
|
#endif |
|
fSize = (DWORD)lstrlenA(szPost); |
|
} |
|
|
|
if(extra->exec_flags->silent != 0) |
|
silent = true; |
|
|
|
while(!popstring(url) && *url == TEXT('/')) |
|
{ |
|
if(lstrcmpi(url, TEXT("/silent")) == 0) |
|
silent = true; |
|
else if(lstrcmpi(url, TEXT("/weaksecurity")) == 0) |
|
g_ignorecertissues = true; |
|
else if(lstrcmpi(url, TEXT("/caption")) == 0) |
|
popstring(szCaption); |
|
else if(lstrcmpi(url, TEXT("/username")) == 0) |
|
popstring(szUsername); |
|
else if(lstrcmpi(url, TEXT("/password")) == 0) |
|
popstring(szPassword); |
|
else if(lstrcmpi(url, TEXT("/nocancel")) == 0) |
|
nocancel = true; |
|
else if(lstrcmpi(url, TEXT("/nocookies")) == 0) |
|
nocookies = true; |
|
else if(lstrcmpi(url, TEXT("/noproxy")) == 0) |
|
openType = INTERNET_OPEN_TYPE_DIRECT; |
|
else if(lstrcmpi(url, TEXT("/popup")) == 0) |
|
{ |
|
popup = true; |
|
szAlias = (TCHAR*)LocalAlloc(LPTR, string_size * sizeof(TCHAR)); |
|
popstring(szAlias); |
|
} |
|
else if(lstrcmpi(url, TEXT("/resume")) == 0) |
|
{ |
|
popstring(url); |
|
if(url[0]) lstrcpy(szResume, url); |
|
resume = true; |
|
} |
|
else if(lstrcmpi(url, TEXT("/translate")) == 0) |
|
{ |
|
if(popup) |
|
{ |
|
popstring(szUrl); |
|
popstring(szStatus[ST_DOWNLOAD]); |
|
popstring(szStatus[ST_CONNECTING]); |
|
lstrcpy(szStatus[ST_URLOPEN], szStatus[ST_CONNECTING]); |
|
popstring(szDownloading); |
|
popstring(szConnecting); |
|
popstring(szProgress); |
|
popstring(szSecond); |
|
popstring(szRemaining); |
|
} |
|
else |
|
{ |
|
popstring(szDownloading); |
|
popstring(szConnecting); |
|
popstring(szSecond); |
|
popstring(szMinute); |
|
popstring(szHour); |
|
popstring(szPlural); |
|
popstring(szProgress); |
|
popstring(szRemaining); |
|
} |
|
} |
|
else if(lstrcmpi(url, TEXT("/banner")) == 0) |
|
{ |
|
popup = true; |
|
szBanner = (TCHAR*)LocalAlloc(LPTR, string_size * sizeof(TCHAR)); |
|
popstring(szBanner); |
|
} |
|
else if(lstrcmpi(url, TEXT("/canceltext")) == 0) |
|
{ |
|
popstring(szCancel); |
|
} |
|
else if(lstrcmpi(url, TEXT("/question")) == 0) |
|
{ |
|
szQuestion = (TCHAR*)LocalAlloc(LPTR, string_size * sizeof(TCHAR)); |
|
popstring(szQuestion); |
|
if(*szQuestion == 0) lstrcpy(szQuestion, DEF_QUESTION); |
|
} |
|
else if(lstrcmpi(url, TEXT("/useragent")) == 0) |
|
{ |
|
popstring(szUserAgent); |
|
} |
|
else if(lstrcmpi(url, TEXT("/proxy")) == 0) |
|
{ |
|
szProxy = (TCHAR*)LocalAlloc(LPTR, string_size * sizeof(TCHAR)); |
|
popstring(szProxy); |
|
openType = INTERNET_OPEN_TYPE_PROXY; |
|
} |
|
else if(lstrcmpi(url, TEXT("/connecttimeout")) == 0) |
|
{ |
|
popstring(url); |
|
timeout = myatou(url) * 1000; |
|
} |
|
else if(lstrcmpi(url, TEXT("/receivetimeout")) == 0) |
|
{ |
|
popstring(url); |
|
receivetimeout = myatou(url) * 1000; |
|
} |
|
else if(lstrcmpi(url, TEXT("/header")) == 0) |
|
{ |
|
szHeader = (TCHAR*)LocalAlloc(LPTR, string_size * sizeof(TCHAR)); |
|
popstring(szHeader); |
|
} |
|
else if(!fput && ((convToStack = lstrcmpi(url, TEXT("/tostackconv")) == 0) || lstrcmpi(url, TEXT("/tostack")) == 0)) |
|
{ |
|
szToStack = (TCHAR*)LocalAlloc(LPTR, string_size * sizeof(TCHAR)); |
|
cntToStack = 0; |
|
lstrcpy(fn, TEXT("file")); |
|
} |
|
else if(lstrcmpi(url, TEXT("/file")) == 0) |
|
{ |
|
HANDLE hFile = CreateFileA(szPost, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); |
|
DWORD rslt; |
|
if(hFile == INVALID_HANDLE_VALUE) |
|
{ |
|
status = ERR_FILEOPEN; |
|
goto cleanup; |
|
} |
|
if((fSize = GetFileSize(hFile, NULL)) == 0) |
|
{ |
|
CloseHandle(hFile); |
|
status = ERR_FILEREAD; |
|
goto cleanup; |
|
} |
|
wsprintfA(post_fname, "Filename: %s", |
|
strchr(szPost, '\\') ? strrchr(szPost, '\\') + 1 : szPost); |
|
LocalFree(szPost); |
|
szPost = (char*)LocalAlloc(LPTR, fSize); |
|
if(ReadFile(hFile, szPost, fSize, &rslt, NULL) == 0 || rslt != fSize) |
|
{ |
|
CloseHandle(hFile); |
|
status = ERR_FILEREAD; |
|
goto cleanup; |
|
} |
|
CloseHandle(hFile); |
|
} |
|
} |
|
pushstring(url); |
|
|
|
if(*szUserAgent == 0) lstrcpy(szUserAgent, INETC_USERAGENT); |
|
if(*szPassword && *szUsername) |
|
{ |
|
wsprintf(url, TEXT("%s:%s"), szUsername, szPassword); |
|
encode_base64(lstrlen(url), url, szAuth); |
|
} |
|
|
|
if(hwndParent != NULL && |
|
(childwnd = FindWindowEx(hwndParent, NULL, TEXT("#32770"), NULL)) != NULL && |
|
!silent) |
|
SetDlgItemText(childwnd, 1006, *szCaption ? szCaption : PLUGIN_NAME); |
|
else InitCommonControls(); |
|
|
|
if(childwnd == NULL && !popup) silent = true; |
|
|
|
if(silent) { resume = false; popup = true; } |
|
|
|
if(!popup) |
|
{ |
|
unsigned int wstyle = GetWindowLong(childwnd, GWL_STYLE); |
|
wstyle |= WS_CLIPSIBLINGS; |
|
SetWindowLong(childwnd, GWL_STYLE, wstyle); |
|
} |
|
startTime = GetTickCount(); |
|
if((hDlg = CreateDialog(g_hInstance, |
|
MAKEINTRESOURCE(szBanner ? IDD_DIALOG2 : (popup ? IDD_DIALOG1 : IDD_DIALOG3)), |
|
(popup ? hwndParent : childwnd), dlgProc)) != NULL) |
|
{ |
|
|
|
if((hThread = CreateThread(NULL, 0, inetTransfer, (LPVOID)hDlg, 0, |
|
&dwThreadId)) != NULL) |
|
{ |
|
HWND hButton = GetDlgItem(childwnd, 0x403); |
|
HWND hList = GetDlgItem(childwnd, 0x3f8); |
|
DWORD dwStyleButton = 0; |
|
BOOL fVisibleList = false; |
|
if(!silent) |
|
{ |
|
ShowWindow(hDlg, SW_NORMAL); |
|
if(childwnd && !popup) |
|
{ |
|
if(hButton) |
|
{ |
|
dwStyleButton = GetWindowLong(hButton, GWL_STYLE); |
|
EnableWindow(hButton, false); |
|
} |
|
if(hList) |
|
{ |
|
fVisibleList = IsWindowVisible(hList); |
|
ShowWindow(hList, SW_HIDE); |
|
} |
|
} |
|
} |
|
|
|
while(IsWindow(hDlg) && |
|
GetMessage(&msg, NULL, 0, 0) > 0) |
|
{ |
|
if(!IsDialogMessage(hDlg, &msg) && |
|
!IsDialogMessage(hwndParent, &msg) && |
|
!TranslateMessage(&msg)) |
|
DispatchMessage(&msg); |
|
} |
|
|
|
if(WaitForSingleObject(hThread, 3000) == WAIT_TIMEOUT) |
|
{ |
|
TerminateThread(hThread, 1); |
|
status = ERR_TERMINATED; |
|
} |
|
CloseHandle(hThread); |
|
if(!silent && childwnd) |
|
{ |
|
SetDlgItemText(childwnd, 1006, TEXT("")); |
|
if(!popup) |
|
{ |
|
if(hButton) |
|
SetWindowLong(hButton, GWL_STYLE, dwStyleButton); |
|
if(hList && fVisibleList) |
|
ShowWindow(hList, SW_SHOW); |
|
} |
|
|
|
} |
|
} |
|
else |
|
{ |
|
status = ERR_THREAD; |
|
DestroyWindow(hDlg); |
|
} |
|
} |
|
else { |
|
status = ERR_DIALOG; |
|
wsprintf(szStatus[status] + lstrlen(szStatus[status]), TEXT(" (Err=%d)"), GetLastError()); |
|
} |
|
cleanup: |
|
|
|
|
|
while(!popstring(url) && lstrcmpi(url, TEXT("/end")) != 0) |
|
{ |
|
|
|
} |
|
LocalFree(url); |
|
if(szAlias) LocalFree(szAlias); |
|
if(szBanner) LocalFree(szAlias); |
|
if(szQuestion) LocalFree(szQuestion); |
|
if(szProxy) LocalFree(szProxy); |
|
if(szPost) LocalFree(szPost); |
|
if(szHeader) LocalFree(szHeader); |
|
|
|
url = szProxy = szHeader = szAlias = szQuestion = NULL; |
|
szPost = NULL; |
|
fput = fhead = false; |
|
|
|
if(szToStack && status == ST_OK) |
|
{ |
|
if(cntToStack > 0 && convToStack) |
|
{ |
|
#ifdef UNICODE |
|
int cp = CP_ACP; |
|
if (0xef == ((BYTE*)szToStack)[0] && 0xbb == ((BYTE*)szToStack)[1] && 0xbf == ((BYTE*)szToStack)[2]) cp = 65001; |
|
if (0xff == ((BYTE*)szToStack)[0] && 0xfe == ((BYTE*)szToStack)[1]) |
|
{ |
|
cp = 1200; |
|
pushstring((LPWSTR)szToStack); |
|
} |
|
int required = (cp == 1200) ? 0 : MultiByteToWideChar(cp, 0, (CHAR*)szToStack, string_size * sizeof(TCHAR), NULL, 0); |
|
if(required > 0) |
|
{ |
|
WCHAR* pszToStackNew = (WCHAR*)LocalAlloc(LPTR, sizeof(WCHAR) * (required + 1)); |
|
if(pszToStackNew) |
|
{ |
|
if(MultiByteToWideChar(cp, 0, (CHAR*)szToStack, string_size * sizeof(TCHAR), pszToStackNew, required) > 0) |
|
pushstring(pszToStackNew); |
|
LocalFree(pszToStackNew); |
|
} |
|
} |
|
#else |
|
int required = WideCharToMultiByte(CP_ACP, 0, (WCHAR*)szToStack, -1, NULL, 0, NULL, NULL); |
|
if(required > 0) |
|
{ |
|
CHAR* pszToStackNew = (CHAR*)LocalAlloc(LPTR, required + 1); |
|
if(pszToStackNew) |
|
{ |
|
if(WideCharToMultiByte(CP_ACP, 0, (WCHAR*)szToStack, -1, pszToStackNew, required, NULL, NULL) > 0) |
|
pushstring(pszToStackNew); |
|
LocalFree(pszToStackNew); |
|
} |
|
} |
|
#endif |
|
} |
|
else |
|
{ |
|
pushstring(szToStack); |
|
} |
|
LocalFree(szToStack); |
|
szToStack = NULL; |
|
} |
|
|
|
pushstring(szStatus[status]); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" |
|
void __declspec(dllexport) __cdecl put(HWND hwndParent, |
|
int string_size, |
|
TCHAR *variables, |
|
stack_t **stacktop, |
|
extra_parameters *extra |
|
) |
|
{ |
|
fput = true; |
|
lstrcpy(szDownloading, TEXT("Uploading %s")); |
|
lstrcpy(szStatus[2], TEXT("Uploading")); |
|
get(hwndParent, string_size, variables, stacktop, extra); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" |
|
void __declspec(dllexport) __cdecl post(HWND hwndParent, |
|
int string_size, |
|
TCHAR *variables, |
|
stack_t **stacktop, |
|
extra_parameters *extra |
|
) |
|
{ |
|
szPost = (CHAR*)LocalAlloc(LPTR, string_size); |
|
get(hwndParent, string_size, variables, stacktop, extra); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" |
|
void __declspec(dllexport) __cdecl head(HWND hwndParent, |
|
int string_size, |
|
TCHAR *variables, |
|
stack_t **stacktop, |
|
extra_parameters *extra |
|
) |
|
{ |
|
fhead = true; |
|
get(hwndParent, string_size, variables, stacktop, extra); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _VC_NODEFAULTLIB |
|
#define DllMain _DllMainCRTStartup |
|
#endif |
|
EXTERN_C BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) |
|
{ |
|
g_hInstance = hinstDLL; |
|
return TRUE; |
|
} |
|
|