Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

470 lines
12 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: shutdown.c
  3. *
  4. * Copyright (c) 1992, Microsoft Corporation
  5. *
  6. * Handles shutdown dialog.
  7. *
  8. * History:
  9. * 2-25-92 JohanneC Created - extracted from old pmdlgs.c with security
  10. * added.
  11. \***************************************************************************/
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include "progman.h"
  16. #define LOGOFF_SETTING L"Logoff Setting"
  17. INT_PTR WINAPI
  18. ShutdownDlgProc(
  19. HWND hDlg,
  20. UINT message,
  21. WPARAM wParam,
  22. LPARAM lParam
  23. );
  24. VOID
  25. CentreWindow(
  26. HWND hwnd
  27. );
  28. /***************************************************************************\
  29. * ShutdownDialog
  30. *
  31. * Creates the shutdown dialog
  32. *
  33. *
  34. * History:
  35. * 2-28-92 Johannec Created
  36. *
  37. \***************************************************************************/
  38. BOOL
  39. ShutdownDialog(
  40. HANDLE hInst,
  41. HWND hwnd
  42. )
  43. {
  44. INT_PTR nResult;
  45. BOOLEAN WasEnabled;
  46. NTSTATUS Status;
  47. TCHAR szMessage[MAXMESSAGELEN];
  48. TCHAR szTitle[MAXMESSAGELEN];
  49. Status = RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,
  50. (BOOLEAN)TRUE,
  51. (BOOLEAN)FALSE,
  52. &WasEnabled);
  53. if (!NT_SUCCESS(Status)) {
  54. //
  55. // We don't have permission to shutdown
  56. //
  57. LoadString(hInst, IDS_NO_PERMISSION_SHUTDOWN, szMessage, CharSizeOf(szMessage));
  58. LoadString(hInst, IDS_SHUTDOWN_MESSAGE, szTitle, CharSizeOf(szTitle));
  59. nResult = MessageBox(hwnd, szMessage, szTitle, MB_OK | MB_ICONSTOP);
  60. return(FALSE);
  61. }
  62. //
  63. // Put up the shutdown dialog
  64. //
  65. nResult = DialogBox(hInst, (LPTSTR) MAKEINTRESOURCE(IDD_SHUTDOWN_QUERY), hwnd, ShutdownDlgProc);
  66. //
  67. // Restore the shutdown privilege state
  68. //
  69. if (!WasEnabled) {
  70. Status = RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,
  71. (BOOLEAN)WasEnabled,
  72. (BOOLEAN)FALSE,
  73. &WasEnabled);
  74. }
  75. return(FALSE);
  76. }
  77. /***************************************************************************\
  78. * FUNCTION: ShutdownDlgProc
  79. *
  80. * PURPOSE: Processes messages for shutdown confirmation dialog
  81. *
  82. * RETURNS: if user decided not to shutdown or reboot.
  83. *
  84. * HISTORY:
  85. *
  86. * 05-17-92 Davidc Created.
  87. *
  88. \***************************************************************************/
  89. INT_PTR WINAPI
  90. ShutdownDlgProc(
  91. HWND hDlg,
  92. UINT message,
  93. WPARAM wParam,
  94. LPARAM lParam
  95. )
  96. {
  97. UINT uiOptions;
  98. static DWORD dwShutdown = 1;
  99. static HKEY hkeyShutdown = NULL;
  100. switch (message) {
  101. case WM_INITDIALOG:
  102. {
  103. DWORD dwType;
  104. DWORD cbData;
  105. DWORD dwDisposition;
  106. BOOL bPowerdown;
  107. bPowerdown = GetProfileInt(TEXT("Winlogon"), TEXT("PowerdownAfterShutdown"), 0);
  108. if (!bPowerdown) {
  109. ShowWindow(GetDlgItem(hDlg, IDD_POWEROFF), SW_HIDE);
  110. ShowWindow(GetDlgItem(hDlg, IDOK2), SW_HIDE);
  111. ShowWindow(GetDlgItem(hDlg, IDCANCEL2), SW_HIDE);
  112. SendMessage(hDlg, DM_SETDEFID, IDOK, 0);
  113. }
  114. else {
  115. ShowWindow(GetDlgItem(hDlg, IDOK), SW_HIDE);
  116. ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_HIDE);
  117. }
  118. //
  119. // Check the button that was the user's last shutdown selection.
  120. //
  121. if (RegCreateKeyEx(HKEY_CURRENT_USER, SHUTDOWN_SETTING_KEY, 0, 0, 0,
  122. KEY_READ | KEY_WRITE | DELETE,
  123. NULL, &hkeyShutdown, &dwDisposition) == ERROR_SUCCESS) {
  124. cbData = sizeof(dwShutdown);
  125. RegQueryValueEx(hkeyShutdown, SHUTDOWN_SETTING, 0, &dwType, (LPBYTE)&dwShutdown, &cbData);
  126. }
  127. switch(dwShutdown) {
  128. case DLGSEL_SHUTDOWN_AND_RESTART:
  129. CheckDlgButton(hDlg, IDD_RESTART, 1);
  130. break;
  131. case DLGSEL_SHUTDOWN_AND_POWEROFF:
  132. if (bPowerdown) {
  133. CheckDlgButton(hDlg, IDD_POWEROFF, 1);
  134. break;
  135. }
  136. //
  137. // Fall thru.
  138. // Default to shutdown.
  139. //
  140. default:
  141. CheckDlgButton(hDlg, IDD_SHUTDOWN, 1);
  142. break;
  143. }
  144. //
  145. // Position ourselves
  146. //
  147. CentreWindow(hDlg);
  148. return(TRUE);
  149. }
  150. case WM_COMMAND:
  151. switch (LOWORD(wParam)) {
  152. case IDOK:
  153. case IDOK2:
  154. if (IsDlgButtonChecked(hDlg, IDD_SHUTDOWN)) {
  155. uiOptions = EWX_SHUTDOWN;
  156. dwShutdown = DLGSEL_SHUTDOWN;
  157. }
  158. else if (IsDlgButtonChecked(hDlg, IDD_RESTART)) {
  159. uiOptions = EWX_SHUTDOWN | EWX_REBOOT;
  160. dwShutdown = DLGSEL_SHUTDOWN_AND_RESTART;
  161. }
  162. else {
  163. uiOptions = EWX_SHUTDOWN | EWX_POWEROFF;
  164. dwShutdown = DLGSEL_SHUTDOWN_AND_POWEROFF;
  165. }
  166. if (hkeyShutdown) {
  167. RegSetValueEx(hkeyShutdown, SHUTDOWN_SETTING, 0, REG_DWORD, (LPBYTE)&dwShutdown, sizeof(dwShutdown));
  168. RegCloseKey(hkeyShutdown);
  169. hkeyShutdown = NULL;
  170. }
  171. ExitWindowsEx(uiOptions, (DWORD)-1);
  172. case IDCANCEL2:
  173. case IDCANCEL:
  174. if (hkeyShutdown) {
  175. RegCloseKey(hkeyShutdown);
  176. hkeyShutdown = NULL;
  177. }
  178. EndDialog(hDlg, 0);
  179. return(TRUE);
  180. }
  181. break;
  182. }
  183. // We didn't process the message
  184. return(FALSE);
  185. }
  186. /***************************************************************************\
  187. * FUNCTION: NewLogoffDlgProc
  188. *
  189. * PURPOSE: Processes messages for logoff/shutdown confirmation dialog
  190. *
  191. * RETURNS: if user decided not to logoff, shutdown or reboot.
  192. *
  193. * HISTORY:
  194. *
  195. * 10-05-93 Johannec Created.
  196. *
  197. \***************************************************************************/
  198. INT_PTR APIENTRY
  199. NewLogoffDlgProc(
  200. HWND hDlg,
  201. UINT message,
  202. WPARAM wParam,
  203. LPARAM lParam
  204. )
  205. {
  206. UINT uiOptions;
  207. BOOLEAN WasEnabled = FALSE;
  208. NTSTATUS Status;
  209. static DWORD dwShutdown = 0;
  210. static HKEY hkeyShutdown = NULL;
  211. switch (message) {
  212. case WM_INITDIALOG:
  213. {
  214. DWORD dwType;
  215. BOOL bPowerdown;
  216. DWORD cbData;
  217. DWORD dwDisposition;
  218. bPowerdown = GetProfileInt(TEXT("Winlogon"), TEXT("PowerdownAfterShutdown"), 0);
  219. if (!bPowerdown) {
  220. ShowWindow(GetDlgItem(hDlg, IDD_POWEROFF), SW_HIDE);
  221. ShowWindow(GetDlgItem(hDlg, IDOK2), SW_HIDE);
  222. ShowWindow(GetDlgItem(hDlg, IDCANCEL2), SW_HIDE);
  223. SendMessage(hDlg, DM_SETDEFID, IDOK, 0);
  224. }
  225. else {
  226. ShowWindow(GetDlgItem(hDlg, IDOK), SW_HIDE);
  227. ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_HIDE);
  228. }
  229. //
  230. // Initial setting is User's last selection
  231. //
  232. if (RegCreateKeyEx(HKEY_CURRENT_USER, SHUTDOWN_SETTING_KEY, 0, 0, 0,
  233. KEY_READ | KEY_WRITE | DELETE,
  234. NULL, &hkeyShutdown, &dwDisposition) == ERROR_SUCCESS) {
  235. cbData = sizeof(dwShutdown);
  236. RegQueryValueEx(hkeyShutdown, LOGOFF_SETTING, 0, &dwType, (LPBYTE)&dwShutdown, &cbData);
  237. }
  238. switch(dwShutdown) {
  239. case DLGSEL_SHUTDOWN:
  240. CheckDlgButton(hDlg, IDD_SHUTDOWN, 1);
  241. break;
  242. case DLGSEL_SHUTDOWN_AND_RESTART:
  243. CheckDlgButton(hDlg, IDD_RESTART, 1);
  244. break;
  245. case DLGSEL_SHUTDOWN_AND_POWEROFF:
  246. if (bPowerdown) {
  247. CheckDlgButton(hDlg, IDD_POWEROFF, 1);
  248. }
  249. else {
  250. CheckDlgButton(hDlg, IDD_SHUTDOWN, 1);
  251. }
  252. break;
  253. default:
  254. CheckDlgButton(hDlg, IDD_LOGOFF, 1);
  255. break;
  256. }
  257. //
  258. // Make sure the user has the privileges to shutdown the computer.
  259. //
  260. Status = RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,
  261. (BOOLEAN)TRUE,
  262. (BOOLEAN)FALSE,
  263. &WasEnabled);
  264. if (!NT_SUCCESS(Status)) {
  265. //
  266. // We don't have permission to shutdown
  267. //
  268. EnableWindow(GetDlgItem(hDlg, IDD_SHUTDOWN), 0);
  269. EnableWindow(GetDlgItem(hDlg, IDD_RESTART), 0);
  270. EnableWindow(GetDlgItem(hDlg, IDD_POWEROFF), 0);
  271. }
  272. //
  273. // Position ourselves
  274. //
  275. CentreWindow(hDlg);
  276. return(TRUE);
  277. }
  278. case WM_COMMAND:
  279. switch (LOWORD(wParam)) {
  280. case IDOK:
  281. case IDOK2:
  282. if (IsDlgButtonChecked(hDlg, IDD_LOGOFF)) {
  283. uiOptions = EWX_LOGOFF;
  284. dwShutdown = DLGSEL_LOGOFF;
  285. }
  286. else if (IsDlgButtonChecked(hDlg, IDD_SHUTDOWN)) {
  287. uiOptions = EWX_SHUTDOWN;
  288. dwShutdown = DLGSEL_SHUTDOWN;
  289. }
  290. else if (IsDlgButtonChecked(hDlg, IDD_RESTART)) {
  291. uiOptions = EWX_SHUTDOWN | EWX_REBOOT;
  292. dwShutdown = DLGSEL_SHUTDOWN_AND_RESTART;
  293. }
  294. else {
  295. uiOptions = EWX_SHUTDOWN | EWX_POWEROFF;
  296. dwShutdown = DLGSEL_SHUTDOWN_AND_POWEROFF;
  297. }
  298. //
  299. // Save user's shutdown selection.
  300. //
  301. if (hkeyShutdown) {
  302. RegSetValueEx(hkeyShutdown, LOGOFF_SETTING, 0, REG_DWORD, (LPBYTE)&dwShutdown, sizeof(dwShutdown));
  303. RegCloseKey(hkeyShutdown);
  304. hkeyShutdown = NULL;
  305. }
  306. //
  307. // Make sure the user has the privileges to shutdown the computer.
  308. //
  309. ExitWindowsEx(uiOptions, (DWORD)-1);
  310. //
  311. // Restore the shutdown privilege state
  312. //
  313. if (!WasEnabled) {
  314. Status = RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,
  315. (BOOLEAN)WasEnabled,
  316. (BOOLEAN)FALSE,
  317. &WasEnabled);
  318. }
  319. case IDCANCEL:
  320. case IDCANCEL2:
  321. if (hkeyShutdown) {
  322. RegCloseKey(hkeyShutdown);
  323. hkeyShutdown = NULL;
  324. }
  325. EndDialog(hDlg, 0);
  326. return(TRUE);
  327. }
  328. break;
  329. }
  330. // We didn't process the message
  331. return(FALSE);
  332. }
  333. /***************************************************************************\
  334. * CentreWindow
  335. *
  336. * Purpose : Positions a window so that it is centred in its parent
  337. *
  338. * !!! WARNING this code is duplicated in winlogon\winutil.c
  339. *
  340. * History:
  341. * 12-09-91 Davidc Created.
  342. \***************************************************************************/
  343. VOID
  344. CentreWindow(
  345. HWND hwnd
  346. )
  347. {
  348. RECT rect;
  349. RECT rectParent;
  350. HWND hwndParent;
  351. LONG dx, dy;
  352. LONG dxParent, dyParent;
  353. LONG Style;
  354. // Get window rect
  355. GetWindowRect(hwnd, &rect);
  356. dx = rect.right - rect.left;
  357. dy = rect.bottom - rect.top;
  358. // Get parent rect
  359. Style = GetWindowLong(hwnd, GWL_STYLE);
  360. if ((Style & WS_CHILD) == 0) {
  361. // Return the desktop windows size (size of main screen)
  362. dxParent = GetSystemMetrics(SM_CXSCREEN);
  363. dyParent = GetSystemMetrics(SM_CYSCREEN);
  364. } else {
  365. hwndParent = GetParent(hwnd);
  366. if (hwndParent == NULL) {
  367. hwndParent = GetDesktopWindow();
  368. }
  369. GetWindowRect(hwndParent, &rectParent);
  370. dxParent = rectParent.right - rectParent.left;
  371. dyParent = rectParent.bottom - rectParent.top;
  372. }
  373. // Centre the child in the parent
  374. rect.left = (dxParent - dx) / 2;
  375. rect.top = (dyParent - dy) / 3;
  376. // Move the child into position
  377. SetWindowPos(hwnd, NULL, rect.left, rect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
  378. SetForegroundWindow(hwnd);
  379. }
  380. INT_PTR APIENTRY ExitDlgProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
  381. {
  382. switch (uiMsg) {
  383. case WM_INITDIALOG:
  384. CentreWindow(hwnd);
  385. break;
  386. case WM_COMMAND:
  387. switch (LOWORD(wParam)) {
  388. case IDOK:
  389. // fall through...
  390. case IDCANCEL:
  391. EndDialog(hwnd, LOWORD(wParam) == IDOK);
  392. break;
  393. default:
  394. return(FALSE);
  395. }
  396. break;
  397. default:
  398. return(FALSE);
  399. }
  400. UNREFERENCED_PARAMETER(lParam);
  401. return(TRUE);
  402. }