From 53d954e00bde114c31b9b417bc93acffaec77866 Mon Sep 17 00:00:00 2001 From: kichik Date: Wed, 4 Dec 2002 20:05:35 +0000 Subject: [PATCH] Smaller git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@1879 212acab6-be3b-0410-9dea-997c60f758d6 --- Contrib/NSISdl/asyncdns.cpp | 2 - Contrib/NSISdl/connection.cpp | 2 - Contrib/NSISdl/netinc.h | 60 ++----- Contrib/NSISdl/nsisdl.cpp | 319 ++++++++++++++++------------------ Contrib/NSISdl/util.cpp | 25 --- Contrib/NSISdl/util.h | 11 +- Plugins/nsisdl.dll | Bin 13312 -> 12800 bytes 7 files changed, 160 insertions(+), 259 deletions(-) diff --git a/Contrib/NSISdl/asyncdns.cpp b/Contrib/NSISdl/asyncdns.cpp index cf8b7c27..d7516f22 100644 --- a/Contrib/NSISdl/asyncdns.cpp +++ b/Contrib/NSISdl/asyncdns.cpp @@ -33,7 +33,6 @@ JNL_AsyncDNS::~JNL_AsyncDNS() unsigned long WINAPI JNL_AsyncDNS::_threadfunc(LPVOID _d) { JNL_AsyncDNS *_this=(JNL_AsyncDNS*)_d; - int nowinsock=JNL::open_socketlib(); struct hostent *hostentry; hostentry=::gethostbyname(_this->m_hostname); if (hostentry) @@ -42,7 +41,6 @@ unsigned long WINAPI JNL_AsyncDNS::_threadfunc(LPVOID _d) } else _this->m_addr=INADDR_NONE; - if (!nowinsock) JNL::close_socketlib(); _this->m_thread_kill=1; return 0; } diff --git a/Contrib/NSISdl/connection.cpp b/Contrib/NSISdl/connection.cpp index 9bee6223..b5426544 100644 --- a/Contrib/NSISdl/connection.cpp +++ b/Contrib/NSISdl/connection.cpp @@ -29,8 +29,6 @@ JNL_Connection::JNL_Connection(JNL_AsyncDNS *dns, int sendbufsize, int recvbufsi m_recv_buffer=(char*)malloc(m_recv_buffer_len); m_send_buffer=(char*)malloc(m_send_buffer_len); m_socket=-1; - memset(m_recv_buffer,0,recvbufsize); - memset(m_send_buffer,0,sendbufsize); m_remote_port=0; m_state=STATE_NOCONNECTION; m_recv_len=m_recv_pos=0; diff --git a/Contrib/NSISdl/netinc.h b/Contrib/NSISdl/netinc.h index b4d96fda..0bac8a0c 100644 --- a/Contrib/NSISdl/netinc.h +++ b/Contrib/NSISdl/netinc.h @@ -9,53 +9,24 @@ #ifndef _NETINC_H_ #define _NETINC_H_ -#ifdef _WIN32 - #include -#include -#include +#include "util.h" + #define strcasecmp(x,y) stricmp(x,y) #define ERRNO (WSAGetLastError()) #define SET_SOCK_BLOCK(s,block) { unsigned long __i=block?0:1; ioctlsocket(s,FIONBIO,&__i); } #define EWOULDBLOCK WSAEWOULDBLOCK #define EINPROGRESS WSAEWOULDBLOCK +#define memset mini_memset +#define memcpy mini_memcpy +#define strcpy lstrcpy +#define strncpy lstrcpyn +#define strcat lstrcat +#define strlen lstrlen +#define malloc(x) (new char[x]) +#define free(x) {delete x;} typedef int socklen_t; -#else - -#ifndef THREAD_SAFE -#define THREAD_SAFE -#endif -#ifndef _REENTRANT -#define _REENTRANT -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ERRNO errno -#define closesocket(s) close(s) -#define SET_SOCK_BLOCK(s,block) { int __flags; if ((__flags = fcntl(s, F_GETFL, 0)) != -1) { if (!block) __flags |= O_NONBLOCK; else __flags &= ~O_NONBLOCK; fcntl(s, F_SETFL, __flags); } } - -#define stricmp(x,y) strcasecmp(x,y) -#define strnicmp(x,y,z) strncasecmp(x,y,z) -#define wsprintf sprintf - -#endif // !_WIN32 - #ifndef INADDR_NONE #define INADDR_NONE 0xffffffff #endif @@ -68,15 +39,4 @@ typedef int socklen_t; #define SHUT_RDWR 2 #endif -extern void mini_memset(void *,char,int); -extern void mini_memcpy(void *,void*,int); -#define memset mini_memset -#define memcpy mini_memcpy -#define strcpy lstrcpy -#define strncpy lstrcpyn -#define strcat lstrcat -#define strlen lstrlen -#define malloc(x) GlobalAlloc(GPTR,(x)) -#define free(x) { if (x) GlobalFree(x); } - #endif //_NETINC_H_ diff --git a/Contrib/NSISdl/nsisdl.cpp b/Contrib/NSISdl/nsisdl.cpp index c2c692b8..0071ec5f 100644 --- a/Contrib/NSISdl/nsisdl.cpp +++ b/Contrib/NSISdl/nsisdl.cpp @@ -48,14 +48,15 @@ HANDLE hModule; HWND g_parent; HWND g_dialog; HWND g_childwnd; +HWND g_hwndProgressBar; static int g_cancelled; BOOL CALLBACK DownloadDialogProc(HWND hwndDlg, - UINT uMsg, - WPARAM wParam, - LPARAM lParam) + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { - return 0; + return 0; } @@ -63,37 +64,21 @@ static void *lpWndProcOld; static LRESULT CALLBACK ParentWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - if (message == WM_COMMAND && LOWORD(wParam) == IDCANCEL) + if (message == WM_COMMAND && LOWORD(wParam) == IDCANCEL) { - g_cancelled = 1; + g_cancelled = 1; return 0; } return CallWindowProc((long (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long))lpWndProcOld,hwnd,message,wParam,lParam); } - BOOL APIENTRY DllMain( HANDLE _hModule, DWORD ul_reason_for_call, LPVOID lpReserved - ) + ) { - - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - hModule = _hModule; - JNL::open_socketlib (); - break; - - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - JNL::close_socketlib (); - break; - - } - - return TRUE; + hModule = _hModule; + return TRUE; } @@ -103,75 +88,66 @@ static void progress_callback(char *msg, int read_bytes) { if (g_dialog) { - HWND hwndProgressBar = GetDlgItem (g_dialog, IDC_PROGRESS1); - - SetDlgItemText (g_dialog, IDC_STATIC2, msg); - if (g_file_size) SendMessage(hwndProgressBar, PBM_SETPOS, (WPARAM)MulDiv(read_bytes,30000,g_file_size), 0); + SetDlgItemText (g_dialog, IDC_STATIC2, msg); + if (g_file_size) SendMessage(g_hwndProgressBar, PBM_SETPOS, (WPARAM)MulDiv(read_bytes,30000,g_file_size), 0); } } -static int getProxyInfo(char *out) -{ - DWORD v=0; - HKEY hKey; - if (RegOpenKeyEx(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",0,KEY_READ,&hKey) == ERROR_SUCCESS) - { - DWORD l = 4; - DWORD t; - if (RegQueryValueEx(hKey,"ProxyEnable",NULL,&t,(unsigned char *)&v,&l) == ERROR_SUCCESS && t == REG_DWORD) - { - l=8192; - if (RegQueryValueEx(hKey,"ProxyServer",NULL,&t,(unsigned char *)out,&l ) != ERROR_SUCCESS || t != REG_SZ) - { - v=0; - *out=0; - } - } - else v=0; - out[8192-1]=0; - RegCloseKey(hKey); - } - return v; -} - - extern char *_strstr(char *i, char *s); #define strstr _strstr static void downloadFile(char *url, - HANDLE hFile, - char **error) + HANDLE hFile, + char **error) { - static char buf[8192]; + WSADATA wsaData; + WSAStartup(MAKEWORD(1, 1), &wsaData); + + static char buf[8192]=""; char *p=NULL; - if (getProxyInfo(buf)) + + HKEY hKey; + if (RegOpenKeyEx(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",0,KEY_READ,&hKey) == ERROR_SUCCESS) { - p=strstr(buf,"http="); - if (!p) p=buf; - else { - p+=5; + DWORD l = 4; + DWORD t; + DWORD v; + if (RegQueryValueEx(hKey,"ProxyEnable",NULL,&t,(unsigned char *)&v,&l) == ERROR_SUCCESS && t == REG_DWORD && v) + { + l=8192; + if (RegQueryValueEx(hKey,"ProxyServer",NULL,&t,(unsigned char *)buf,&l ) == ERROR_SUCCESS && t == REG_SZ) + { + p=strstr(buf,"http="); + if (!p) p=buf; + else { + p+=5; + } + char *tp=strstr(p,";"); + if (tp) *tp=0; + char *p2=strstr(p,"="); + if (p2) p=0; // we found the wrong proxy + } } - char *tp=strstr(p,";"); - if (tp) *tp=0; - char *p2=strstr(p,"="); - if (p2) p=0; // we found the wrong proxy + buf[8192-1]=0; + RegCloseKey(hKey); } + DWORD start_time=GetTickCount(); JNL_HTTPGet *get=new JNL_HTTPGet(JNL_CONNECTION_AUTODNS,16384,(p&&p[0])?p:NULL); - int st; - int has_printed_headers = 0; - int cl; - int len; - int sofar = 0; + int st; + int has_printed_headers = 0; + int cl; + int len; + int sofar = 0; DWORD last_recv_time=start_time; - get->addheader ("User-Agent: NSISDL/1.2 (Mozilla)"); - get->addheader ("Accept: */*"); + get->addheader ("User-Agent: NSISDL/1.2 (Mozilla)"); + get->addheader ("Accept: */*"); - get->connect (url); + get->connect (url); - while (1) { + while (1) { if (g_dialog) { MSG msg; @@ -181,65 +157,64 @@ void downloadFile(char *url, DispatchMessage(&msg); } } - + Sleep(25); - if (g_cancelled) break; + if (g_cancelled) break; - st = get->run (); + st = get->run (); - if (st == -1) { + if (st == -1) { *error=get->geterrorstr(); - break; - } else if (st == 1) { - if (sofar < cl) + break; + } else if (st == 1) { + if (sofar < cl) *error="download incomplete"; - break; - } else { + break; + } else { - if (get->get_status () == 0) { - // progressFunc ("Connecting ...", 0); + if (get->get_status () == 0) { + // progressFunc ("Connecting ...", 0); if (last_recv_time+g_timeout_ms < GetTickCount()) { - *error = "Timed out on connecting."; - break; + *error = "Timed out on connecting."; + break; } - } else if (get->get_status () == 1) { + } else if (get->get_status () == 1) { - progress_callback("Reading headers", 0); + progress_callback("Reading headers", 0); if (last_recv_time+g_timeout_ms < GetTickCount()) { - *error = "Timed out on getting headers."; - break; + *error = "Timed out on getting headers."; + break; } - } else if (get->get_status () == 2) { + } else if (get->get_status () == 2) { - if (! has_printed_headers) { - has_printed_headers = 1; + if (! has_printed_headers) { + has_printed_headers = 1; last_recv_time=GetTickCount(); - cl = get->content_length (); - if (cl == 0) { - *error = "Server did not specify content length."; - break; - } else if (g_dialog) { - HWND hwndProgressBar = GetDlgItem (g_dialog, IDC_PROGRESS1); - SendMessage(hwndProgressBar, PBM_SETRANGE, 0, MAKELPARAM(0,30000)); + cl = get->content_length (); + if (cl == 0) { + *error = "Server did not specify content length."; + break; + } else if (g_dialog) { + SendMessage(g_hwndProgressBar, PBM_SETRANGE, 0, MAKELPARAM(0,30000)); g_file_size=cl; - } - } + } + } - while ((len = get->bytes_available ()) > 0) { - if (len > 8192) - len = 8192; - len = get->get_bytes (buf, len); - if (len > 0) { + while ((len = get->bytes_available ()) > 0) { + if (len > 8192) + len = 8192; + len = get->get_bytes (buf, len); + if (len > 0) { last_recv_time=GetTickCount(); DWORD dw; WriteFile(hFile,buf,len,&dw,NULL); - sofar += len; + sofar += len; int time_sofar=(GetTickCount()-start_time)/1000; int bps=sofar/(time_sofar?time_sofar:1); int remain=MulDiv(time_sofar,cl,sofar) - time_sofar; @@ -254,47 +229,49 @@ void downloadFile(char *url, rtext="hour"; } } - wsprintf (buf, - "%dkB (%d%%) of %dkB @ %d.%01dkB/s", + wsprintf (buf, + "%dkB (%d%%) of %dkB @ %d.%01dkB/s", sofar/1024, - MulDiv(100,sofar,cl), - cl/1024, - bps/1024,((bps*10)/1024)%10 + MulDiv(100,sofar,cl), + cl/1024, + bps/1024,((bps*10)/1024)%10 ); if (remain) wsprintf(buf+lstrlen(buf)," (%d %s%s remaining)", remain, rtext, remain==1?"":"s" ); - progress_callback(buf, sofar); - } else { - if (sofar < cl) - *error = "Server aborted."; + progress_callback(buf, sofar); + } else { + if (sofar < cl) + *error = "Server aborted."; - break; - } - } + break; + } + } if (GetTickCount() > last_recv_time+g_timeout_ms) { - *error = "Downloading timed out."; - break; + *error = "Downloading timed out."; + break; } - } else { - *error = "Bad response status."; - break; - } - } - - } + } else { + *error = "Bad response status."; + break; + } + } + + } if (*error) { char *t=*error; - *error = (char *)GlobalAlloc(GPTR,strlen(t)+1); + *error = new char[lstrlen(t)+1]; lstrcpy(*error,t); } delete get; + + WSACleanup(); } RECT r, cr; @@ -310,34 +287,34 @@ extern "C" { __declspec(dllexport) void download (HWND parent, - int string_size, - char *variables, - stack_t **stacktop) + int string_size, + char *variables, + stack_t **stacktop) { - static char buf[1024]; - static char url[1024]; - static char filename[1024]; + static char buf[1024]; + static char url[1024]; + static char filename[1024]; int wasen=0; HWND hwndL=0; HWND hwndB=0; - g_parent = parent; + g_parent = parent; EXDLL_INIT(); - popstring(url); + popstring(url); lstrcpyn(buf, url, 10); if (!lstrcmp(buf, "/TIMEOUT=")) { g_timeout_ms=my_atoi(url+9); popstring(url); } - popstring(filename); + popstring(filename); HANDLE hFile = CreateFile(filename,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,0,NULL); - if (hFile == INVALID_HANDLE_VALUE) { - wsprintf (buf, "Unable to open %s", filename); - setuservariable(INST_0, buf); - } else { + if (hFile == INVALID_HANDLE_VALUE) { + wsprintf (buf, "Unable to open %s", filename); + setuservariable(INST_0, buf); + } else { if (g_parent) { g_childwnd=FindWindowEx(g_parent,NULL,"#32770",NULL); @@ -349,13 +326,13 @@ __declspec(dllexport) void download (HWND parent, else hwndB=NULL; wasen=EnableWindow(GetDlgItem(g_parent,IDCANCEL),1); - lpWndProcOld = (void *) GetWindowLong(g_parent,GWL_WNDPROC); - SetWindowLong(g_parent,GWL_WNDPROC,(long)ParentWndProc); + lpWndProcOld = (void *) GetWindowLong(g_parent,GWL_WNDPROC); + SetWindowLong(g_parent,GWL_WNDPROC,(long)ParentWndProc); - g_dialog = CreateDialog((HINSTANCE)hModule, - MAKEINTRESOURCE(IDD_DIALOG1), - g_childwnd, - DownloadDialogProc); + g_dialog = CreateDialog((HINSTANCE)hModule, + MAKEINTRESOURCE(IDD_DIALOG1), + g_childwnd, + DownloadDialogProc); if (g_dialog) { GetWindowRect(g_dialog,&cr); @@ -371,18 +348,19 @@ __declspec(dllexport) void download (HWND parent, char *p=filename; while (*p) p++; while (*p != '\\' && p != filename) p=CharPrev(filename,p); - wsprintf(buf,"Downloading %s", p+1); + wsprintf(buf,"Downloading %s", p+1); SetDlgItemText(g_childwnd,1006,buf); - wsprintf(buf,"Connecting ..."); - SetDlgItemText (g_dialog, IDC_STATIC2, buf); + wsprintf(buf,"Connecting ..."); + SetDlgItemText (g_dialog, IDC_STATIC2, buf); } } + g_hwndProgressBar = GetDlgItem (g_dialog, IDC_PROGRESS1); - char *error=NULL; - - downloadFile(url, hFile, &error); + char *error=NULL; + + downloadFile(url, hFile, &error); CloseHandle(hFile); if (g_parent) @@ -398,29 +376,28 @@ __declspec(dllexport) void download (HWND parent, if (wasen) EnableWindow(GetDlgItem(g_parent,IDCANCEL),0); } - - if (g_cancelled) { - setuservariable(INST_0, "cancel"); - DeleteFile(filename); - } else if (error == NULL) { - setuservariable(INST_0, "success"); - } else { - DeleteFile(filename); - setuservariable(INST_0, error); - } + setuservariable(INST_0, "cancel"); + DeleteFile(filename); + } else if (error == NULL) { + setuservariable(INST_0, "success"); + } else { + DeleteFile(filename); + setuservariable(INST_0, error); + } if (error) GlobalFree(error); } } __declspec(dllexport) void download_quiet(HWND parent, - int stringsize, - char *variables, - stack_t **stacktop) + int stringsize, + char *variables, + stack_t **stacktop) { + g_hwndProgressBar=0; download(NULL,stringsize,variables,stacktop); } -} +} //extern "C" diff --git a/Contrib/NSISdl/util.cpp b/Contrib/NSISdl/util.cpp index dd80613f..8edaaedd 100644 --- a/Contrib/NSISdl/util.cpp +++ b/Contrib/NSISdl/util.cpp @@ -10,31 +10,6 @@ #include "util.h" -int JNL::open_socketlib() -{ -#ifdef _WIN32 - WSADATA wsaData; - if (WSAStartup(MAKEWORD(1, 1), &wsaData)) return 1; -#endif - return 0; -} -void JNL::close_socketlib() -{ -#ifdef _WIN32 - WSACleanup(); -#endif -} -unsigned long JNL::ipstr_to_addr(const char *cp) -{ - return ::inet_addr(cp); -} - -void JNL::addr_to_ipstr(unsigned long addr, char *host, int maxhostlen) -{ - struct in_addr a; a.s_addr=addr; - char *p=::inet_ntoa(a); strncpy(host,p?p:"",maxhostlen); -} - int my_atoi(char *s) { int sign=0; diff --git a/Contrib/NSISdl/util.h b/Contrib/NSISdl/util.h index d271fd6c..58116842 100644 --- a/Contrib/NSISdl/util.h +++ b/Contrib/NSISdl/util.h @@ -27,15 +27,8 @@ #ifndef _UTIL_H_ #define _UTIL_H_ -class JNL -{ - public: - static int open_socketlib(); - static void close_socketlib(); - static unsigned long ipstr_to_addr(const char *cp); - static void addr_to_ipstr(unsigned long addr, char *host, int maxhostlen); -}; - int my_atoi(char *p); +void mini_memset(void *,char,int); +void mini_memcpy(void *,void*,int); #endif //_UTIL_H_ diff --git a/Plugins/nsisdl.dll b/Plugins/nsisdl.dll index 544e1fe63066b60f9204172eb9fec54d3dfaa8f9..ca141e169d58c158e0f1984fe99a7960a311ec79 100644 GIT binary patch delta 5599 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 BAeI0C delta 5896 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