Index: base/applications/rapps/loaddlg.c =================================================================== --- base/applications/rapps/loaddlg.c (revision 43946) +++ base/applications/rapps/loaddlg.c (working copy) @@ -35,6 +35,7 @@ #include #include #include +#include static PAPPLICATION_INFO AppInfo; static HICON hIcon = NULL; @@ -47,6 +48,25 @@ BOOL *pbCancelled; } IBindStatusCallbackImpl; +#if DBG +#define TRACEW(_va_) DbgPrintW _va_ +#else +#define TRACEW(_va_) +#endif + +ULONG __cdecl DbgPrintW( IN LPWSTR Format, IN ... ) +{ + WCHAR Buf[ MAX_PATH*2 ]; + ULONG Len; + va_list va; + + va_start( va, Format ); + Len = wvsprintfW( Buf, Format, va ); + va_end( va ); + OutputDebugStringW( Buf ); + return Len; +} + static HRESULT WINAPI dlQueryInterface(IBindStatusCallback* This, REFIID riid, void** ppvObject) @@ -208,6 +228,11 @@ return (IBindStatusCallback*) This; } +#define MB_QUERY MB_YESNO |MB_ICONQUESTION +LPWSTR szWaitMoreCap = L"Installer Timeout"; +LPWSTR szWaitMore = L"The installation program appears to have stalled.\n" + "Would You like to wait a bit longer to see if it runs to completion ?"; + static DWORD WINAPI ThreadFunc(LPVOID Context) @@ -218,21 +243,24 @@ STARTUPINFOW si; PROCESS_INFORMATION pi; HWND Dlg = (HWND) Context; - DWORD r; + DWORD r, wr; BOOL bCancelled = FALSE; BOOL bTempfile = FALSE; BOOL bCab = FALSE; + BOOL makeNoise = FALSE; + UINT Len, waitTime; /* built the path for the download */ p = wcsrchr(AppInfo->szUrlDownload, L'/'); if (!p) goto end; - if (wcslen(AppInfo->szUrlDownload) > 4) + Len = wcslen(AppInfo->szUrlDownload); + if (Len > 4) { - if (AppInfo->szUrlDownload[wcslen(AppInfo->szUrlDownload) - 4] == '.' && - AppInfo->szUrlDownload[wcslen(AppInfo->szUrlDownload) - 3] == 'c' && - AppInfo->szUrlDownload[wcslen(AppInfo->szUrlDownload) - 2] == 'a' && - AppInfo->szUrlDownload[wcslen(AppInfo->szUrlDownload) - 1] == 'b') + if (AppInfo->szUrlDownload[Len - 4] == '.' && + AppInfo->szUrlDownload[Len - 3] == 'c' && + AppInfo->szUrlDownload[Len - 2] == 'a' && + AppInfo->szUrlDownload[Len - 1] == 'b') { bCab = TRUE; if (!GetCurrentDirectoryW(MAX_PATH, path)) @@ -256,7 +284,9 @@ /* download it */ bTempfile = TRUE; - dl = CreateDl(Context, &bCancelled); + dl = CreateDl( Context, &bCancelled ); + if (!dl) DbgPrint( "err:(%s:%d) CreateDl returned NULL!\n", __FILE__, __LINE__ ); + r = URLDownloadToFileW(NULL, AppInfo->szUrlDownload, path, 0, dl); if (dl) IBindStatusCallback_Release(dl); if (S_OK != r) goto end; @@ -270,19 +300,39 @@ r = CreateProcessW(path, NULL, NULL, NULL, 0, 0, NULL, NULL, &si, &pi); if (0 == r) goto end; - CloseHandle(pi.hThread); - WaitForSingleObject(pi.hProcess, INFINITE); - CloseHandle(pi.hProcess); + CloseHandle( pi.hThread ); + waitTime = 0; + while( TRUE ) + { + wr = WaitForSingleObject( pi.hProcess, 60000 ); // Wait one minute + if (wr == WAIT_OBJECT_0) break; + if (++waitTime == 5) // Every 5 minutes + { + waitTime = 0; + if (makeNoise) MessageBeep( 0 ); + if (IDNO == MessageBoxW( + GetParent( Dlg ), szWaitMore, szWaitMoreCap, MB_QUERY + )) break; + } + } + if (wr != WAIT_OBJECT_0) + { + DbgPrint( "(%s:%d) Terminating stalled installer.\n", __FILE__, __LINE__ ); + if (!TerminateProcess( pi.hProcess, EXIT_FAILURE )) + DbgPrint( "err:(%s:%d) TerminateProcess failed. Error code = %d.\n", + __FILE__, __LINE__, GetLastError() + ); + } + CloseHandle( pi.hProcess ); end: if (bTempfile) { if (bCancelled || (SettingsInfo.bDelInstaller && !bCab)) - DeleteFileW(path); + DeleteFileW( path ); } - EndDialog(Dlg, 0); - + EndDialog( Dlg, 0 ); return 0; }