- Fixed potential crash caused by WinSock being shutdown while the connection is still open.

- Cleaned up dialog creation a little (some details, such as font, were being changed after the dialog was already visible).
- Restores focus to its previous state when exiting.
- Fixed another one of those "holding down Cancel at the wrong moment can cause the installer to suddenly exit" problems.


git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@3443 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
eccles 2004-02-01 15:50:00 +00:00
parent 438365532e
commit 38d9a9aa37
3 changed files with 72 additions and 70 deletions

View file

@ -27,14 +27,14 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// //
IDD_DIALOG1 DIALOGEX 0, 0, 265, 104 IDD_DIALOG1 DIALOGEX 0, 0, 265, 104
STYLE DS_CONTROL | WS_CHILD STYLE WS_CHILD
EXSTYLE WS_EX_NOPARENTNOTIFY EXSTYLE WS_EX_NOPARENTNOTIFY
FONT 8, "MS Sans Serif" FONT 8, "MS Sans Serif"
BEGIN BEGIN
CONTROL "Progress1",IDC_PROGRESS1,"msctls_progress32",NOT CONTROL "Progress1",IDC_PROGRESS1,"msctls_progress32",NOT
WS_VISIBLE | WS_BORDER,0,36,265,11 WS_VISIBLE | WS_BORDER,0,36,265,11
CTEXT "",IDC_STATIC2,0,25,263,8 CTEXT "",IDC_STATIC2,0,25,263,8
CONTROL "Progress1",IDC_PROGRESS2,"msctls_progress32",PBS_SMOOTH | CONTROL "Progress1",IDC_PROGRESS2,"msctls_progress32",PBS_SMOOTH |
NOT WS_VISIBLE | WS_BORDER,0,37,265,11 NOT WS_VISIBLE | WS_BORDER,0,37,265,11
END END
@ -45,18 +45,18 @@ END
// TEXTINCLUDE // TEXTINCLUDE
// //
1 TEXTINCLUDE DISCARDABLE 1 TEXTINCLUDE DISCARDABLE
BEGIN BEGIN
"resource.h\0" "resource.h\0"
END END
2 TEXTINCLUDE DISCARDABLE 2 TEXTINCLUDE DISCARDABLE
BEGIN BEGIN
"#include ""afxres.h""\r\n" "#include ""afxres.h""\r\n"
"\0" "\0"
END END
3 TEXTINCLUDE DISCARDABLE 3 TEXTINCLUDE DISCARDABLE
BEGIN BEGIN
"\r\n" "\r\n"
"\0" "\0"

View file

@ -51,8 +51,8 @@ ULONG idThreadOwner;
ULONG ulRefCount; ULONG ulRefCount;
static void *lpWndProcOld; static void *lpWndProcOld;
BOOL CALLBACK DownloadDialogProc(HWND hwndDlg, BOOL CALLBACK DownloadDialogProc(HWND hwndDlg,
UINT uMsg, UINT uMsg,
WPARAM wParam, WPARAM wParam,
LPARAM lParam) LPARAM lParam)
{ {
@ -83,7 +83,7 @@ BOOL TryEnterCS()
bRet = FALSE; bRet = FALSE;
} }
::InterlockedExchange(plBusy, 0); ::InterlockedExchange(plBusy, 0);
return bRet; return bRet;
} }
@ -111,18 +111,15 @@ static LRESULT CALLBACK ParentWndProc(HWND hwnd, UINT message, WPARAM wParam, LP
LRESULT Res = 0; LRESULT Res = 0;
while ( !TryEnterCS() ) Sleep(0); while ( !TryEnterCS() ) Sleep(0);
if (message == WM_COMMAND && LOWORD(wParam) == IDCANCEL) if (message == WM_COMMAND && LOWORD(wParam) == IDCANCEL)
{
SendMessage(GetDlgItem(hwnd, IDCANCEL), BM_SETSTATE, FALSE, 0);
g_cancelled = 1; g_cancelled = 1;
}
else else
Res = CallWindowProc((long (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long))lpWndProcOld,hwnd,message,wParam,lParam); Res = CallWindowProc((long (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long))lpWndProcOld,hwnd,message,wParam,lParam);
LeaveCS(); LeaveCS();
return Res; return Res;
} }
BOOL APIENTRY DllMain( HANDLE _hModule, BOOL APIENTRY DllMain( HANDLE _hModule,
DWORD ul_reason_for_call, DWORD ul_reason_for_call,
LPVOID lpReserved LPVOID lpReserved
) )
{ {
@ -153,18 +150,17 @@ void progress_callback(HWND dlg, char *msg, int read_bytes)
extern char *_strstr(char *i, char *s); extern char *_strstr(char *i, char *s);
#define strstr _strstr #define strstr _strstr
extern "C" extern "C"
{ {
__declspec(dllexport) void download (HWND parent, __declspec(dllexport) void download (HWND parent,
int string_size, int string_size,
char *variables, char *variables,
stack_t **stacktop) stack_t **stacktop)
{ {
char buf[1024]; char buf[1024];
char url[1024]; char url[1024];
char filename[1024]; char filename[1024];
int wasen=0;
HWND hwndAux; HWND hwndAux;
HWND hwndL=0; HWND hwndL=0;
HWND hwndB=0; HWND hwndB=0;
@ -174,8 +170,6 @@ __declspec(dllexport) void download (HWND parent,
RECT r, cr, orig_childRc; RECT r, cr, orig_childRc;
int timeout_ms=30000; int timeout_ms=30000;
JNL_HTTPGet *get = 0;
char *error=NULL; char *error=NULL;
static char szDownloading[1024];//= "Downloading %s"; static char szDownloading[1024];//= "Downloading %s";
@ -220,10 +214,16 @@ __declspec(dllexport) void download (HWND parent,
HANDLE hFile = CreateFile(filename,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,0,NULL); HANDLE hFile = CreateFile(filename,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,0,NULL);
if (hFile == INVALID_HANDLE_VALUE) { if (hFile == INVALID_HANDLE_VALUE)
wsprintf (buf, "Unable to open %s", filename); {
error=buf; wsprintf(buf, "Unable to open %s", filename);
} else { error = buf;
}
else
{
HWND hwndPrevFocus;
BOOL fCancelDisabled;
if (parent) if (parent)
{ {
childwnd=FindWindowEx(parent,NULL,"#32770",NULL); childwnd=FindWindowEx(parent,NULL,"#32770",NULL);
@ -236,7 +236,7 @@ __declspec(dllexport) void download (HWND parent,
lpWndProcOld = (void *)SetWindowLong(parent,GWL_WNDPROC,(long)ParentWndProc); lpWndProcOld = (void *)SetWindowLong(parent,GWL_WNDPROC,(long)ParentWndProc);
dlg = CreateDialog((HINSTANCE)hModule, dlg = CreateDialog((HINSTANCE)hModule,
MAKEINTRESOURCE(IDD_DIALOG1), MAKEINTRESOURCE(IDD_DIALOG1),
parent, parent,
DownloadDialogProc); DownloadDialogProc);
@ -251,10 +251,10 @@ __declspec(dllexport) void download (HWND parent,
HWND pb = g_hwndProgressBar = GetDlgItem(dlg, pbid); HWND pb = g_hwndProgressBar = GetDlgItem(dlg, pbid);
long c;
if (hwPb) if (hwPb)
{ {
long c;
c = SendMessage(hwPb, PBM_SETBARCOLOR, 0, 0); c = SendMessage(hwPb, PBM_SETBARCOLOR, 0, 0);
SendMessage(hwPb, PBM_SETBARCOLOR, 0, c); SendMessage(hwPb, PBM_SETBARCOLOR, 0, c);
SendMessage(pb, PBM_SETBARCOLOR, 0, c); SendMessage(pb, PBM_SETBARCOLOR, 0, c);
@ -264,23 +264,23 @@ __declspec(dllexport) void download (HWND parent,
SendMessage(pb, PBM_SETBKCOLOR, 0, c); SendMessage(pb, PBM_SETBKCOLOR, 0, c);
} }
ShowWindow(pb, SW_SHOW); ShowWindow(pb, SW_SHOWNA);
GetWindowRect(childwnd,&orig_childRc); GetWindowRect(childwnd,&orig_childRc);
GetWindowRect(dlg,&cr); GetWindowRect(dlg,&cr);
ScreenToClient(dlg,(LPPOINT)&cr); ScreenToClient(dlg,(LPPOINT)&cr);
ScreenToClient(dlg,((LPPOINT)&cr)+1); ScreenToClient(dlg,((LPPOINT)&cr)+1);
hwndAux = GetDlgItem(childwnd,1016); hwndAux = GetDlgItem(childwnd,1016);
GetWindowRect(hwndAux,&r); GetWindowRect(hwndAux,&r);
ScreenToClient(childwnd,(LPPOINT)&r); ScreenToClient(childwnd,(LPPOINT)&r);
ScreenToClient(childwnd,((LPPOINT)&r)+1); ScreenToClient(childwnd,((LPPOINT)&r)+1);
SetWindowPos(childwnd,0,0,0,r.right-r.left,r.top,SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE); SetWindowPos(childwnd,0,0,0,r.right-r.left,r.top,SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE);
GetWindowRect(hwndAux,&r); GetWindowRect(hwndAux,&r);
ScreenToClient(parent,(LPPOINT)&r); ScreenToClient(parent,(LPPOINT)&r);
ScreenToClient(parent,((LPPOINT)&r)+1); ScreenToClient(parent,((LPPOINT)&r)+1);
SetWindowPos(dlg,0,r.left,r.top,r.right-r.left,cr.bottom-cr.top,SWP_NOACTIVATE|SWP_NOZORDER|SWP_SHOWWINDOW); SetWindowPos(dlg,0,r.left,r.top,r.right-r.left,cr.bottom-cr.top,SWP_NOACTIVATE|SWP_NOZORDER);
hwndAux = GetDlgItem(dlg,IDC_STATIC2); hwndAux = GetDlgItem(dlg,IDC_STATIC2);
GetWindowRect(hwndAux,&cr); GetWindowRect(hwndAux,&cr);
@ -305,20 +305,25 @@ __declspec(dllexport) void download (HWND parent,
long hFont = SendMessage(parent, WM_GETFONT, 0, 0); long hFont = SendMessage(parent, WM_GETFONT, 0, 0);
SendDlgItemMessage(dlg, pbid, WM_SETFONT, hFont, 0); SendDlgItemMessage(dlg, pbid, WM_SETFONT, hFont, 0);
SendDlgItemMessage(dlg, IDC_STATIC2, WM_SETFONT, hFont, 0); SendDlgItemMessage(dlg, IDC_STATIC2, WM_SETFONT, hFont, 0);
ShowWindow(dlg, SW_SHOWNA);
} }
// enable the cancel button // enable the cancel button
wasen=EnableWindow(GetDlgItem(parent,IDCANCEL),TRUE); hwndPrevFocus = GetFocus();
SendMessage(parent, WM_NEXTDLGCTL, (WPARAM) GetDlgItem(parent, IDCANCEL), TRUE); fCancelDisabled = EnableWindow(GetDlgItem(parent, IDCANCEL), TRUE);
SendMessage(parent, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(parent, IDCANCEL), TRUE);
} }
{ {
WSADATA wsaData; WSADATA wsaData;
WSAStartup(MAKEWORD(1, 1), &wsaData); WSAStartup(MAKEWORD(1, 1), &wsaData);
JNL_HTTPGet *get = 0;
static char main_buf[8192]; static char main_buf[8192];
char *buf=main_buf; char *buf=main_buf;
char *p=NULL; char *p=NULL;
HKEY hKey; HKEY hKey;
if (RegOpenKeyEx(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",0,KEY_READ,&hKey) == ERROR_SUCCESS) if (RegOpenKeyEx(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",0,KEY_READ,&hKey) == ERROR_SUCCESS)
{ {
@ -373,16 +378,22 @@ __declspec(dllexport) void download (HWND parent,
} }
} }
while (!TryEnterCS()); // Process messages while (!TryEnterCS()); // Process messages
if ((g_cancelled || error) && dlg) if (g_cancelled || error)
DestroyWindow(dlg); {
if (dlg)
DestroyWindow(dlg);
dlg = NULL;
if (!error)
error = "cancel";
}
LeaveCS(); LeaveCS();
if ( g_cancelled || error ) if (error)
{ {
if (parent) if (parent)
{ {
SetWindowLong(parent,GWL_WNDPROC,(long)lpWndProcOld); SetWindowLong(parent,GWL_WNDPROC,(long)lpWndProcOld);
if (hwndB) ShowWindow(hwndB,SW_SHOWNA); if (hwndB) ShowWindow(hwndB,SW_SHOWNA);
if (hwndL) ShowWindow(hwndL,SW_SHOWNA); if (hwndL) ShowWindow(hwndL,SW_SHOWNA);
@ -393,21 +404,24 @@ __declspec(dllexport) void download (HWND parent,
SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE
); );
if (wasen) // Prevent wierd stuff happening if the cancel button happens to be
// pressed at the moment we are finishing
SendMessage(GetDlgItem(parent, IDCANCEL), BM_SETSTATE, FALSE, 0);
// Restore the previous focus and cancel button states
SendMessage(parent, WM_NEXTDLGCTL, (WPARAM)hwndPrevFocus, TRUE);
if (fCancelDisabled)
EnableWindow(GetDlgItem(parent, IDCANCEL), FALSE); EnableWindow(GetDlgItem(parent, IDCANCEL), FALSE);
} }
if ( !error )
error = "cancel";
break; break;
} }
Sleep(25); Sleep(25);
st = get->run (); st = get->run ();
if (st == -1) { if (st == -1) {
error=get->geterrorstr(); lstrcpyn(url, get->geterrorstr(), sizeof(url));
//break; error = url;
} else if (st == 1) { } else if (st == 1) {
if (sofar < cl) if (sofar < cl)
error="download incomplete"; error="download incomplete";
@ -416,25 +430,18 @@ __declspec(dllexport) void download (HWND parent,
bSuccess=TRUE; bSuccess=TRUE;
error = "success"; error = "success";
} }
//break;
} else { } else {
if (get->get_status () == 0) { if (get->get_status () == 0) {
// progressFunc ("Connecting ...", 0); // progressFunc ("Connecting ...", 0);
if (last_recv_time+timeout_ms < GetTickCount()) if (last_recv_time+timeout_ms < GetTickCount())
{
error = "Timed out on connecting."; error = "Timed out on connecting.";
//break;
}
} else if (get->get_status () == 1) { } else if (get->get_status () == 1) {
progress_callback(dlg, "Reading headers", 0); progress_callback(dlg, "Reading headers", 0);
if (last_recv_time+timeout_ms < GetTickCount()) if (last_recv_time+timeout_ms < GetTickCount())
{
error = "Timed out on getting headers."; error = "Timed out on getting headers.";
//break;
}
} else if (get->get_status () == 2) { } else if (get->get_status () == 2) {
@ -443,12 +450,11 @@ __declspec(dllexport) void download (HWND parent,
last_recv_time=GetTickCount(); last_recv_time=GetTickCount();
cl = get->content_length (); cl = get->content_length ();
if (cl == 0) { if (cl == 0)
error = "Server did not specify content length."; error = "Server did not specify content length.";
//break; else if (dlg) {
} else if (dlg) { SendMessage(g_hwndProgressBar, PBM_SETRANGE, 0, MAKELPARAM(0,30000));
SendMessage(g_hwndProgressBar, PBM_SETRANGE, 0, MAKELPARAM(0,30000)); g_file_size=cl;
g_file_size=cl;
} }
} }
@ -465,7 +471,7 @@ __declspec(dllexport) void download (HWND parent,
int bps=sofar/(time_sofar?time_sofar:1); int bps=sofar/(time_sofar?time_sofar:1);
int remain=MulDiv(time_sofar,cl,sofar) - time_sofar; int remain=MulDiv(time_sofar,cl,sofar) - time_sofar;
char *rtext=szSecond; char *rtext=szSecond;
if (remain >= 60) if (remain >= 60)
{ {
remain/=60; remain/=60;
rtext=szMinute; rtext=szMinute;
@ -475,7 +481,7 @@ __declspec(dllexport) void download (HWND parent,
rtext=szHour; rtext=szHour;
} }
} }
wsprintf (buf, wsprintf (buf,
szProgress, szProgress,
sofar/1024, sofar/1024,
MulDiv(100,sofar,cl), MulDiv(100,sofar,cl),
@ -491,45 +497,41 @@ __declspec(dllexport) void download (HWND parent,
} else { } else {
if (sofar < cl) if (sofar < cl)
error = "Server aborted."; error = "Server aborted.";
//break;
} }
} }
if (GetTickCount() > last_recv_time+timeout_ms) if (GetTickCount() > last_recv_time+timeout_ms)
{
error = "Downloading timed out."; error = "Downloading timed out.";
//break;
}
} else { } else {
error = "Bad response status."; error = "Bad response status.";
} }
} }
} }
// Clean up the connection then release winsock
if (get) delete get;
WSACleanup(); WSACleanup();
} }
CloseHandle(hFile); CloseHandle(hFile);
} }
if (g_cancelled || !bSuccess) { if (g_cancelled || !bSuccess) {
DeleteFile(filename); DeleteFile(filename);
} }
pushstring(error); pushstring(error);
if (get) delete get;
} }
__declspec(dllexport) void download_quiet(HWND parent, __declspec(dllexport) void download_quiet(HWND parent,
int stringsize, int stringsize,
char *variables, char *variables,
stack_t **stacktop) stack_t **stacktop)
{ {
g_hwndProgressBar=0; g_hwndProgressBar=0;
download(NULL,stringsize,variables,stacktop); download(NULL,stringsize,variables,stacktop);
} }
} //extern "C" } //extern "C"

Binary file not shown.