HRESULT CALLBACK FinalTaskDialogCallbackProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam, _In_ LONG_PTR dwRefData ) { PPH_UPDATER_CONTEXT context = (PPH_UPDATER_CONTEXT)dwRefData; switch (uMsg) { case TDN_NAVIGATED: { if (!UpdaterCheckApplicationDirectory()) { SendMessage(hwndDlg, TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE, IDYES, TRUE); } } break; case TDN_BUTTON_CLICKED: { INT buttonId = (INT)wParam; if (buttonId == IDRETRY) { ShowCheckForUpdatesDialog(context); return S_FALSE; } else if (buttonId == IDYES) { SHELLEXECUTEINFO info = { sizeof(SHELLEXECUTEINFO) }; PPH_STRING parameters; if (PhIsNullOrEmptyString(context->SetupFilePath)) break; parameters = PH_AUTO(PhGetApplicationDirectory()); parameters = PH_AUTO(PhBufferToHexString((PUCHAR)parameters->Buffer, (ULONG)parameters->Length)); parameters = PH_AUTO(PhConcatStrings(3, L"-update \"", PhGetStringOrEmpty(parameters), L"\"")); info.lpFile = PhGetStringOrEmpty(context->SetupFilePath); info.lpParameters = PhGetString(parameters); info.lpVerb = UpdaterCheckApplicationDirectory() ? NULL : L"runas"; info.nShow = SW_SHOW; info.hwnd = hwndDlg; info.fMask = SEE_MASK_NOASYNC | SEE_MASK_FLAG_NO_UI | SEE_MASK_NOZONECHECKS; ProcessHacker_PrepareForEarlyShutdown(PhMainWndHandle); if (ShellExecuteEx(&info)) { ProcessHacker_Destroy(PhMainWndHandle); } else { ULONG errorCode = GetLastError(); // Install failed, cancel the shutdown. ProcessHacker_CancelEarlyShutdown(PhMainWndHandle); // Show error dialog. if (errorCode != ERROR_CANCELLED) // Ignore UAC decline. { PhShowStatus(hwndDlg, L"Unable to execute the setup.", 0, errorCode); if (context->StartupCheck) ShowAvailableDialog(context); else ShowCheckForUpdatesDialog(context); } return S_FALSE; } } } break; case TDN_HYPERLINK_CLICKED: { TaskDialogLinkClicked(context); return S_FALSE; } break; } return S_OK; }
INT_PTR CALLBACK UpdaterWndProc( __in HWND hwndDlg, __in UINT uMsg, __in WPARAM wParam, __in LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { LOGFONT lHeaderFont = { 0 }; // load the PH main icon using the 'magic' resource id. HANDLE hPhIcon = LoadImage( GetModuleHandle(NULL), MAKEINTRESOURCE(PHAPP_IDI_PROCESSHACKER), IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), LR_SHARED ); // Set our initial state as download PhUpdaterState = Download; // Set the window icon. SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hPhIcon); lHeaderFont.lfHeight = -15; lHeaderFont.lfWeight = FW_MEDIUM; lHeaderFont.lfQuality = CLEARTYPE_QUALITY | ANTIALIASED_QUALITY; // We don't check if Segoe exists, CreateFontIndirect does this for us. wcscpy_s( lHeaderFont.lfFaceName, _countof(lHeaderFont.lfFaceName), L"Segoe UI" ); // Create the font handle. FontHandle = CreateFontIndirectW(&lHeaderFont); // Set the header font. SendMessage(GetDlgItem(hwndDlg, IDC_MESSAGE), WM_SETFONT, (WPARAM)FontHandle, FALSE); // Center the update window on PH if visible and not mimimized else center on desktop. PhCenterWindow(hwndDlg, (IsWindowVisible(GetParent(hwndDlg)) && !IsIconic(GetParent(hwndDlg))) ? GetParent(hwndDlg) : NULL); // Create our update check thread. UpdateCheckThreadHandle = PhCreateThread(0, (PUSER_THREAD_START_ROUTINE)CheckUpdateThreadStart, hwndDlg); } break; case WM_SHOWDIALOG: { if (IsIconic(hwndDlg)) ShowWindow(hwndDlg, SW_RESTORE); else ShowWindow(hwndDlg, SW_SHOW); SetForegroundWindow(hwndDlg); } break; case WM_CTLCOLORBTN: case WM_CTLCOLORDLG: case WM_CTLCOLORSTATIC: { HDC hDC = (HDC)wParam; HWND hwndChild = (HWND)lParam; // Check for our static label and change the color. if (GetDlgCtrlID(hwndChild) == IDC_MESSAGE) { SetTextColor(hDC, RGB(19, 112, 171)); } // Set a transparent background for the control backcolor. SetBkMode(hDC, TRANSPARENT); // set window background color. return (INT_PTR)GetSysColorBrush(COLOR_WINDOW); } case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: { PostQuitMessage(0); } break; case IDC_DOWNLOAD: { switch (PhUpdaterState) { case Download: { if (PhInstalledUsingSetup()) { // Start our Downloader thread DownloadThreadHandle = PhCreateThread(0, (PUSER_THREAD_START_ROUTINE)DownloadUpdateThreadStart, hwndDlg); } else { // Let the user handle non-setup installation, show the homepage and close this dialog. PhShellExecute(hwndDlg, L"http://processhacker.sourceforge.net/downloads.php", NULL); PostQuitMessage(0); } } break; case Install: { SHELLEXECUTEINFO info = { sizeof(SHELLEXECUTEINFO) }; info.lpFile = SetupFilePath->Buffer; info.lpVerb = L"runas"; info.nShow = SW_SHOW; info.hwnd = hwndDlg; ProcessHacker_PrepareForEarlyShutdown(PhMainWndHandle); if (!ShellExecuteEx(&info)) { // Install failed, cancel the shutdown. ProcessHacker_CancelEarlyShutdown(PhMainWndHandle); // Set button text for next action Button_SetText(GetDlgItem(hwndDlg, IDC_DOWNLOAD), L"Retry"); } else { ProcessHacker_Destroy(PhMainWndHandle); } } break; } } break; } break; } break; case WM_UPDATE: { if (IsUpdating) { DWORD time_taken; DWORD download_speed; //DWORD time_remain = (MulDiv(time_taken, contentLength, bytesDownloaded) - time_taken); int percent; PPH_STRING dlRemaningBytes; PPH_STRING dlLength; PPH_STRING dlSpeed; PPH_STRING statusText; PhAcquireQueuedLockExclusive(&Lock); time_taken = (GetTickCount() - timeTransferred); download_speed = (bytesDownloaded / max(time_taken, 1)); percent = MulDiv(100, bytesDownloaded, contentLength); dlRemaningBytes = PhFormatSize(bytesDownloaded, -1); dlLength = PhFormatSize(contentLength, -1); dlSpeed = PhFormatSize(download_speed * 1024, -1); LastUpdateTime = GetTickCount(); PhReleaseQueuedLockExclusive(&Lock); statusText = PhFormatString( L"%s (%d%%) of %s @ %s/s", dlRemaningBytes->Buffer, percent, dlLength->Buffer, dlSpeed->Buffer ); SetDlgItemText(hwndDlg, IDC_STATUS, statusText->Buffer); SendDlgItemMessage(hwndDlg, IDC_PROGRESS, PBM_SETPOS, percent, 0); PhDereferenceObject(statusText); PhDereferenceObject(dlSpeed); PhDereferenceObject(dlLength); PhDereferenceObject(dlRemaningBytes); IsUpdating = FALSE; } } break; } return FALSE; }
HRESULT CALLBACK FinalTaskDialogCallbackProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam, _In_ LONG_PTR dwRefData ) { PPH_UPDATER_CONTEXT context = (PPH_UPDATER_CONTEXT)dwRefData; switch (uMsg) { case TDN_NAVIGATED: { if (!PhGetOwnTokenAttributes().Elevated) { SendMessage(hwndDlg, TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE, IDYES, TRUE); } } break; case TDN_BUTTON_CLICKED: { if ((INT)wParam == IDRETRY) { ShowCheckingForUpdatesDialog(context); return S_FALSE; } if ((INT)wParam == IDYES) { SHELLEXECUTEINFO info = { sizeof(SHELLEXECUTEINFO) }; if (PhIsNullOrEmptyString(context->SetupFilePath)) break; info.lpFile = context->SetupFilePath->Buffer; info.lpVerb = PhGetOwnTokenAttributes().Elevated ? NULL : L"runas"; info.nShow = SW_SHOW; info.hwnd = hwndDlg; ProcessHacker_PrepareForEarlyShutdown(PhMainWndHandle); if (!ShellExecuteEx(&info)) { // Install failed, cancel the shutdown. ProcessHacker_CancelEarlyShutdown(PhMainWndHandle); // Set button text for next action //Button_SetText(GetDlgItem(hwndDlg, IDOK), L"Retry"); return S_FALSE; } else { ProcessHacker_Destroy(PhMainWndHandle); } } } break; case TDN_HYPERLINK_CLICKED: { TaskDialogLinkClicked(context); } break; } return S_OK; }