* Addendum to r65483.
[reactos.git] / dll / win32 / msgina / shutdown.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS msgina.dll
4 * FILE: lib/msgina/shutdown.c
5 * PURPOSE: Shutdown Dialog Box
6 * PROGRAMMER: Lee Schroeder (spaceseel at gmail dot com)
7 */
8
9 #include "msgina.h"
10 #include <powrprof.h>
11 #include <strsafe.h>
12 #include <wingdi.h>
13 #include <stdlib.h>
14
15 int g_shutdownCode = 0;
16 BOOL g_logoffHideState = FALSE;
17
18 VOID UpdateShutdownShellDesc(HWND hwnd)
19 {
20 WCHAR tmpBuffer[256];
21 UINT shutdownDescId = 0;
22 HWND shutdownHwnd = GetDlgItem(hwnd, IDC_SHUTDOWN_DESCRIPTION);
23 int shutdownCode = 0;
24
25 shutdownCode = SendDlgItemMessageW(hwnd, IDC_SHUTDOWN_LIST, CB_GETCURSEL, 0, 0);
26
27 if(!g_logoffHideState)
28 {
29 switch (shutdownCode)
30 {
31 case 0: /* Log off */
32 shutdownDescId = IDS_SHUTDOWN_LOGOFF_DESC;
33 break;
34 case 1: /* Shut down */
35 shutdownDescId = IDS_SHUTDOWN_SHUTDOWN_DESC;
36 break;
37 case 2: /* Restart */
38 shutdownDescId = IDS_SHUTDOWN_RESTART_DESC;
39 break;
40 default:
41 break;
42 }
43
44 if (IsPwrSuspendAllowed())
45 {
46 if (shutdownCode == 3) /* Sleep */
47 {
48 shutdownDescId = IDS_SHUTDOWN_SLEEP_DESC;
49 }
50 else if (shutdownCode == 4) /* Hibernate */
51 {
52 shutdownDescId = IDS_SHUTDOWN_HIBERNATE_DESC;
53 }
54 }
55 else
56 {
57 if (shutdownCode == 3) /* Hibernate */
58 {
59 shutdownDescId = IDS_SHUTDOWN_SLEEP_DESC;
60 }
61 }
62 }
63 else
64 {
65 switch (shutdownCode)
66 {
67 case 0: /* Shut down */
68 shutdownDescId = IDS_SHUTDOWN_SHUTDOWN_DESC;
69 break;
70 case 1: /* Restart */
71 shutdownDescId = IDS_SHUTDOWN_RESTART_DESC;
72 break;
73 default:
74 break;
75 }
76
77 if (IsPwrSuspendAllowed())
78 {
79 if (shutdownCode == 2) /* Sleep */
80 {
81 shutdownDescId = IDS_SHUTDOWN_SLEEP_DESC;
82 }
83 else if (shutdownCode == 3) /* Hibernate */
84 {
85 shutdownDescId = IDS_SHUTDOWN_HIBERNATE_DESC;
86 }
87 }
88 else
89 {
90 if (shutdownCode == 2) /* Hibernate */
91 {
92 shutdownDescId = IDS_SHUTDOWN_SLEEP_DESC;
93 }
94 }
95 }
96
97 LoadStringW(hDllInstance, shutdownDescId, tmpBuffer, sizeof(tmpBuffer));
98 SetWindowTextW(shutdownHwnd, tmpBuffer);
99 }
100
101 BOOL CALLBACK ExitWindowsDialogShellProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
102 {
103 PGINA_CONTEXT pgContext;
104
105 pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwnd, GWL_USERDATA);
106
107 switch (Message)
108 {
109 case WM_INITDIALOG:
110 {
111 int defSelect = 0;
112 WCHAR userBuffer[256];
113 DWORD userBufferSize = _countof(userBuffer);
114 WCHAR tmpBuffer[256];
115 WCHAR tmpBuffer2[512];
116
117 pgContext = (PGINA_CONTEXT)lParam;
118 if (!pgContext)
119 {
120 WARN("pgContext is NULL, branding bitmaps will not be displayed.\n");
121 }
122
123 SetWindowLongPtr(hwnd, GWL_USERDATA, (DWORD_PTR)pgContext);
124
125 /* Clears the content before it's used */
126 SendDlgItemMessageW(hwnd, IDC_SHUTDOWN_LIST, CB_RESETCONTENT, 0, 0);
127
128 if(!g_logoffHideState)
129 {
130 /* Log off */
131 LoadStringW(hDllInstance, IDS_SHUTDOWN_LOGOFF, tmpBuffer, sizeof(tmpBuffer)/sizeof(WCHAR));
132 GetUserNameW(userBuffer, &userBufferSize);
133 StringCchPrintfW(tmpBuffer2, 512, tmpBuffer, userBuffer);
134 SendDlgItemMessageW(hwnd, IDC_SHUTDOWN_LIST, CB_ADDSTRING, 0, (LPARAM)tmpBuffer2);
135 }
136
137 /* Shut down - DEFAULT */
138 LoadStringW(hDllInstance, IDS_SHUTDOWN_SHUTDOWN, tmpBuffer, sizeof(tmpBuffer)/sizeof(WCHAR));
139 defSelect = SendDlgItemMessageW(hwnd, IDC_SHUTDOWN_LIST, CB_ADDSTRING, 0, (LPARAM)tmpBuffer);
140
141 /* Restart */
142 LoadStringW(hDllInstance, IDS_SHUTDOWN_RESTART, tmpBuffer, sizeof(tmpBuffer)/sizeof(WCHAR));
143 SendDlgItemMessageW(hwnd, IDC_SHUTDOWN_LIST, CB_ADDSTRING, 0, (LPARAM)tmpBuffer);
144
145 /* Sleep */
146 if (IsPwrSuspendAllowed())
147 {
148 LoadStringW(hDllInstance, IDS_SHUTDOWN_SLEEP, tmpBuffer, sizeof(tmpBuffer)/sizeof(WCHAR));
149 SendDlgItemMessageW(hwnd, IDC_SHUTDOWN_LIST, CB_ADDSTRING, 0, (LPARAM)tmpBuffer);
150 }
151
152 /* Hibernate */
153 if (IsPwrHibernateAllowed())
154 {
155 LoadStringW(hDllInstance, IDS_SHUTDOWN_HIBERNATE, tmpBuffer, sizeof(tmpBuffer)/sizeof(WCHAR));
156 SendDlgItemMessageW(hwnd, IDC_SHUTDOWN_LIST, CB_ADDSTRING, 0, (LPARAM)tmpBuffer);
157 }
158
159 /* Sets the default shut down selection */
160 SendDlgItemMessageW(hwnd, IDC_SHUTDOWN_LIST, CB_SETCURSEL, defSelect, 0);
161
162 /* Updates the choice description based on the current selection */
163 UpdateShutdownShellDesc(hwnd);
164
165 /* Draw the logo graphic */
166 if (pgContext)
167 pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
168
169 return TRUE;
170 }
171 case WM_PAINT:
172 {
173 PAINTSTRUCT ps;
174 HDC hdc;
175 if (pgContext && pgContext->hBitmap)
176 {
177 hdc = BeginPaint(hwnd, &ps);
178 DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP);
179 EndPaint(hwnd, &ps);
180 return TRUE;
181 }
182 return FALSE;
183 }
184 case WM_DESTROY:
185 {
186 if (pgContext)
187 DeleteObject(pgContext->hBitmap);
188 return TRUE;
189 }
190 case WM_COMMAND:
191 switch(LOWORD(wParam))
192 {
193 case IDOK:
194 g_shutdownCode = SendDlgItemMessageW(hwnd, IDC_SHUTDOWN_LIST, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
195 EndDialog(hwnd, IDOK);
196 break;
197 case IDCANCEL:
198 EndDialog(hwnd, IDCANCEL);
199 break;
200 case IDHELP:
201 EndDialog(hwnd, IDHELP);
202 break;
203 case IDC_SHUTDOWN_LIST:
204 UpdateShutdownShellDesc(hwnd);
205 break;
206 }
207 break;
208 default:
209 return FALSE;
210 }
211 return TRUE;
212 }
213
214 /*
215 * NOTES:
216 * - Based upon observations on the ShellShutdownDialog() function, the function doesn't actually
217 * do anything except show a dialog box and returning a value based upon the value chosen. That
218 * means that any code that calls the function has to execute the chosen action (shut down,
219 * restart, etc.).
220 * - When this function is called in Windows XP, it shows the classic dialog box regardless if
221 * SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\LogonType is enabled or not.
222 * - When the Help button is pushed, it sends the same return value as IDCANCEL (0x00), but
223 * at the same time, it calls the help file directly from the dialog box.
224 * - When the dialog is created, it doesn't disable all other input from the other windows.
225 * This is done elsewhere. When running the function ShellShutdownDialog() from XP/2K3, if the user clicks
226 * out of the window, it automatically closes itself.
227 * - The parameter, lpUsername never seems to be used when calling the function from Windows XP. Either
228 * it was a parameter that was never used in the final version before release, or it has a use that
229 * is currently not known.
230 */
231 DWORD WINAPI
232 ShellShutdownDialog(
233 HWND hParent,
234 LPWSTR lpUsername,
235 BOOL bHideLogoff)
236 {
237 GINA_CONTEXT pgContext = { 0 };
238 int dlgValue = 0;
239
240 g_logoffHideState = bHideLogoff;
241
242 UNREFERENCED_PARAMETER(lpUsername);
243
244 // Loads the shut down dialog box
245 dlgValue = DialogBoxParam(hDllInstance,
246 MAKEINTRESOURCE(IDD_SHUTDOWN_SHELL),
247 hParent,
248 ExitWindowsDialogShellProc,
249 (LPARAM)&pgContext);
250
251 // Determines what to do based on user selection
252 if (dlgValue == IDOK)
253 {
254 switch (g_shutdownCode)
255 {
256 case 0: /* Log off */
257 return 0x01;
258 case 1: /* Shut down */
259 return 0x02;
260 case 2: /* Reboot */
261 return 0x04;
262 case 3: /* Sleep */
263 return 0x10;
264 case 4: /* Hibernate */
265 return 0x40;
266 }
267 }
268 /* Help file is called directly here */
269 else if (dlgValue == IDHELP)
270 {
271 FIXME("Help is not implemented yet.");
272 MessageBoxW(hParent, L"Help is not implemented yet.", L"Message", MB_OK | MB_ICONEXCLAMATION);
273 }
274 else if (dlgValue == -1)
275 {
276 ERR("Failed to create dialog\n");
277 }
278
279 return 0x00;
280 }