INT_PTR ServiceShutdown(WPARAM wParam, LPARAM lParam) { /* passing 0 as wParam is only to be used internally, undocumented */ if (!wParam) wParam = db_get_b(NULL, "AutoShutdown", "ShutdownType", SETTING_SHUTDOWNTYPE_DEFAULT); if (!IsShutdownTypeEnabled((BYTE)wParam)) return 1; /* does shutdownType range check */ if ((BOOL)lParam && hwndShutdownDlg != NULL) return 2; /* ask others if allowed */ if (NotifyEventHooks(hEventOkToShutdown, wParam, lParam)) { OutputDebugStringA("automatic shutdown denied by event hook\n"); /* all ascii */ return 3; } /* tell others */ NotifyEventHooks(hEventShutdown, wParam, lParam); /* show dialog */ if (lParam && db_get_b(NULL, "AutoShutdown", "ShowConfirmDlg", SETTING_SHOWCONFIRMDLG_DEFAULT)) if (CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_SHUTDOWNNOW), NULL, ShutdownDlgProc, (BYTE)wParam) != NULL) return 0; /* show error */ DWORD dwErrCode = ShutdownNow((BYTE)wParam); if (dwErrCode != ERROR_SUCCESS) { char *pszErr = GetWinErrorDescription(dwErrCode); ShowInfoMessage(NIIF_ERROR, Translate("Automatic Shutdown Error"), Translate("Inititiating the shutdown process failed!\nReason: %s"), (pszErr != NULL) ? pszErr : Translate("Unknown")); if (pszErr != NULL) LocalFree(pszErr); return 4; } return 0; }
/* Debug: Ensure all registry calls do succeed and have valid parameters. * Shows a details message box otherwise. */ static __inline LONG regchk(LONG res, const char *pszFunc, const void *pszInfo, BOOL fInfoUnicode, const char *pszFile, unsigned int nLine) { if (res != ERROR_SUCCESS && res != ERROR_FILE_NOT_FOUND && res != ERROR_NO_MORE_ITEMS) { TCHAR szMsg[1024], *pszInfo2; char *pszErr; pszErr = GetWinErrorDescription(res); pszInfo2 = s2t(pszInfo, fInfoUnicode, FALSE); /* does NULL check */ mir_sntprintf(szMsg, TranslateT("Access failed:\n%.64hs(%.128s)\n%.250hs(%u)\n%.256hs (%u)"), pszFunc, pszInfo2, pszFile, nLine, pszErr, res); MessageBox(NULL, szMsg, TranslateT("Registry warning"), MB_OK | MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TOPMOST | MB_TASKMODAL); if (pszErr != NULL) LocalFree(pszErr); mir_free(pszInfo2); /* does NULL check */ } return res; }
static INT_PTR CALLBACK ShutdownDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { BYTE shutdownType = (BYTE)GetWindowLongPtr(hwndDlg, DWLP_USER); WORD countdown = (WORD)GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_TEXT_HEADER), GWLP_USERDATA); switch (msg) { case WM_INITDIALOG: hwndShutdownDlg = hwndDlg; SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam); TranslateDialogDefault(hwndDlg); if (lParam == SDSDT_SHUTDOWN || lParam == SDSDT_REBOOT || lParam == SDSDT_LOGOFF) ShowWindow(GetDlgItem(hwndDlg, IDC_TEXT_UNSAVEDWARNING), SW_SHOW); SendDlgItemMessage(hwndDlg, IDC_ICON_HEADER, STM_SETIMAGE, IMAGE_ICON, (LPARAM)IcoLib_GetIcon("AutoShutdown_Header")); { HFONT hBoldFont; LOGFONT lf; if (GetObject((HFONT)SendDlgItemMessage(hwndDlg, IDC_TEXT_HEADER, WM_GETFONT, 0, 0), sizeof(lf), &lf)) { lf.lfWeight = FW_BOLD; hBoldFont = CreateFontIndirect(&lf); } else hBoldFont = NULL; SendDlgItemMessage(hwndDlg, IDC_TEXT_HEADER, WM_SETFONT, (WPARAM)hBoldFont, FALSE); SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_TEXT_HEADER), GWLP_USERDATA, (LONG_PTR)hBoldFont); } { countdown = db_get_w(NULL, "AutoShutdown", "ConfirmDlgCountdown", SETTING_CONFIRMDLGCOUNTDOWN_DEFAULT); if (countdown < 3) countdown = SETTING_CONFIRMDLGCOUNTDOWN_DEFAULT; SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_TEXT_HEADER), GWLP_USERDATA, countdown); SendMessage(hwndDlg, M_UPDATE_COUNTDOWN, 0, countdown); } SkinPlaySound("AutoShutdown_Countdown"); if (!SetTimer(hwndDlg, 1, 1000, NULL)) PostMessage(hwndDlg, M_START_SHUTDOWN, 0, 0); Utils_RestoreWindowPositionNoSize(hwndDlg, NULL, "AutoShutdown", "ConfirmDlg_"); /* disallow foreground window changes (WinMe/2000+) */ SetForegroundWindow(hwndDlg); LockSetForegroundWindow(LSFW_LOCK); SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDCANCEL), TRUE); return FALSE; /* focus set on cancel */ case WM_DESTROY: { hwndShutdownDlg = NULL; ShowWindow(hwndDlg, SW_HIDE); /* reallow foreground window changes (WinMe/2000+) */ LockSetForegroundWindow(LSFW_UNLOCK); Utils_SaveWindowPosition(hwndDlg, NULL, "AutoShutdown", "ConfirmDlg_"); HFONT hFont = (HFONT)SendDlgItemMessage(hwndDlg, IDC_TEXT_HEADER, WM_GETFONT, 0, 0); SendDlgItemMessage(hwndDlg, IDC_TEXT_HEADER, WM_SETFONT, 0, FALSE); /* no return value */ if (hFont != NULL) DeleteObject(hFont); } return TRUE; case M_START_SHUTDOWN: if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BUTTON_SHUTDOWNNOW))) { EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_SHUTDOWNNOW), FALSE); ShowWindow(hwndDlg, SW_HIDE); /* get rid of the dialog immediately */ DWORD dwErrCode = ShutdownNow(shutdownType); if (dwErrCode != ERROR_SUCCESS) { char *pszErr = GetWinErrorDescription(dwErrCode); ShowInfoMessage(NIIF_ERROR, Translate("Automatic Shutdown Error"), Translate("The shutdown process failed!\nReason: %s"), (pszErr != NULL) ? pszErr : Translate("Unknown")); if (pszErr != NULL) LocalFree(pszErr); } DestroyWindow(hwndDlg); } return TRUE; case WM_TIMER: if (countdown) { --countdown; SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_TEXT_HEADER), GWLP_USERDATA, countdown); if (countdown == 27 || countdown == 24 || countdown == 21 || countdown == 19 || countdown == 17 || countdown == 15 || countdown == 13 || countdown == 11 || countdown <= 10) SkinPlaySound("AutoShutdown_Countdown"); } else KillTimer(hwndDlg, wParam); /* countdown finished */ PostMessage(hwndDlg, M_UPDATE_COUNTDOWN, 0, countdown); return TRUE; case M_UPDATE_COUNTDOWN: /* lParam=(WORD)countdown */ { TCHAR szText[256]; mir_sntprintf(szText, TranslateTS(desc[shutdownType - 1]), lParam); SetDlgItemText(hwndDlg, IDC_TEXT_HEADER, szText); /* countdown finished */ if (!lParam) PostMessage(hwndDlg, M_START_SHUTDOWN, 0, 0); } return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_BUTTON_SHUTDOWNNOW: KillTimer(hwndDlg, 1); SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_TEXT_HEADER), GWLP_USERDATA, 0); SendMessage(hwndDlg, M_UPDATE_COUNTDOWN, 0, (LONG)0); PostMessage(hwndDlg, M_START_SHUTDOWN, 0, 0); return TRUE; case IDCANCEL: /* WM_CLOSE */ if (countdown) { KillTimer(hwndDlg, 1); DestroyWindow(hwndDlg); } return TRUE; } break; } return FALSE; }