Sync to trunk (r46918)
[reactos.git] / dll / win32 / shell32 / dialogs.c
1 /*
2 * common shell dialogs
3 *
4 * Copyright 2000 Juergen Schmied
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #include <precomp.h>
22
23
24 typedef struct
25 {
26 HWND hwndOwner ;
27 HICON hIcon ;
28 LPCSTR lpstrDirectory ;
29 LPCSTR lpstrTitle ;
30 LPCSTR lpstrDescription ;
31 UINT uFlags ;
32 } RUNFILEDLGPARAMS ;
33
34 typedef BOOL (*LPFNOFN) (OPENFILENAMEA *) ;
35
36 WINE_DEFAULT_DEBUG_CHANNEL(shell);
37 static INT_PTR CALLBACK RunDlgProc (HWND, UINT, WPARAM, LPARAM) ;
38 static void FillList (HWND, char *) ;
39
40
41 /*************************************************************************
42 * PickIconDlg [SHELL32.62]
43 *
44 */
45
46 typedef struct
47 {
48 HMODULE hLibrary;
49 HWND hDlgCtrl;
50 WCHAR szName[MAX_PATH];
51 INT Index;
52 }PICK_ICON_CONTEXT, *PPICK_ICON_CONTEXT;
53
54 BOOL CALLBACK EnumPickIconResourceProc(HMODULE hModule,
55 LPCWSTR lpszType,
56 LPWSTR lpszName,
57 LONG_PTR lParam
58 )
59 {
60 WCHAR szName[100];
61 int index;
62 HICON hIcon;
63 PPICK_ICON_CONTEXT pIconContext = (PPICK_ICON_CONTEXT)lParam;
64
65 if (IS_INTRESOURCE(lpszName))
66 swprintf(szName, L"%u\n", lpszName);
67 else
68 wcscpy(szName, (WCHAR*)lpszName);
69
70
71 hIcon = LoadIconW(pIconContext->hLibrary, (LPCWSTR)lpszName);
72 if (hIcon == NULL)
73 return TRUE;
74
75 index = SendMessageW(pIconContext->hDlgCtrl, LB_ADDSTRING, 0, (LPARAM)szName);
76 if (index != LB_ERR)
77 SendMessageW(pIconContext->hDlgCtrl, LB_SETITEMDATA, index, (LPARAM)hIcon);
78
79 return TRUE;
80 }
81
82 void
83 DestroyIconList(HWND hDlgCtrl)
84 {
85 int count;
86 int index;
87
88 count = SendMessage(hDlgCtrl, LB_GETCOUNT, 0, 0);
89 if (count == LB_ERR)
90 return;
91
92 for(index = 0; index < count; index++)
93 {
94 HICON hIcon = (HICON)SendMessageW(hDlgCtrl, LB_GETITEMDATA, index, 0);
95 DestroyIcon(hIcon);
96 }
97 }
98
99 INT_PTR CALLBACK PickIconProc(HWND hwndDlg,
100 UINT uMsg,
101 WPARAM wParam,
102 LPARAM lParam
103 )
104 {
105 LPMEASUREITEMSTRUCT lpmis;
106 LPDRAWITEMSTRUCT lpdis;
107 HICON hIcon;
108 INT index;
109 WCHAR szText[MAX_PATH], szTitle[100], szFilter[100];
110 OPENFILENAMEW ofn = {0};
111
112 PPICK_ICON_CONTEXT pIconContext = (PPICK_ICON_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER);
113
114 switch(uMsg)
115 {
116 case WM_INITDIALOG:
117 pIconContext = (PPICK_ICON_CONTEXT)lParam;
118 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG)pIconContext);
119 pIconContext->hDlgCtrl = GetDlgItem(hwndDlg, IDC_PICKICON_LIST);
120 EnumResourceNamesW(pIconContext->hLibrary, RT_ICON, EnumPickIconResourceProc, (LPARAM)pIconContext);
121 if (PathUnExpandEnvStringsW(pIconContext->szName, szText, MAX_PATH))
122 SendDlgItemMessageW(hwndDlg, IDC_EDIT_PATH, WM_SETTEXT, 0, (LPARAM)szText);
123 else
124 SendDlgItemMessageW(hwndDlg, IDC_EDIT_PATH, WM_SETTEXT, 0, (LPARAM)pIconContext->szName);
125
126 swprintf(szText, L"%u", pIconContext->Index);
127 index = SendMessageW(pIconContext->hDlgCtrl, LB_FINDSTRING, -1, (LPARAM)szText);
128 if (index != LB_ERR)
129 SendMessageW(pIconContext->hDlgCtrl, LB_SETCURSEL, index, 0);
130 return TRUE;
131 case WM_COMMAND:
132 switch(LOWORD(wParam))
133 {
134 case IDOK:
135 index = SendMessageW(pIconContext->hDlgCtrl, LB_GETCURSEL, 0, 0);
136 SendMessageW(pIconContext->hDlgCtrl, LB_GETTEXT, index, (LPARAM)szText);
137 pIconContext->Index = _wtoi(szText);
138 SendDlgItemMessageW(hwndDlg, IDC_EDIT_PATH, WM_GETTEXT, MAX_PATH, (LPARAM)pIconContext->szName);
139 DestroyIconList(pIconContext->hDlgCtrl);
140 EndDialog(hwndDlg, 1);
141 break;
142 case IDCANCEL:
143 DestroyIconList(pIconContext->hDlgCtrl);
144 EndDialog(hwndDlg, 0);
145 break;
146 case IDC_PICKICON_LIST:
147 if (HIWORD(wParam) == LBN_SELCHANGE)
148 InvalidateRect((HWND)lParam, NULL, TRUE); // FIXME USE UPDATE RECT
149 break;
150 case IDC_BUTTON_PATH:
151 szText[0] = 0;
152 szTitle[0] = 0;
153 szFilter[0] = 0;
154 ofn.lStructSize = sizeof(ofn);
155 ofn.hwndOwner = hwndDlg;
156 ofn.lpstrFile = szText;
157 ofn.nMaxFile = MAX_PATH;
158 LoadStringW(shell32_hInstance, IDS_PICK_ICON_TITLE, szTitle, sizeof(szTitle) / sizeof(WCHAR));
159 ofn.lpstrTitle = szTitle;
160 LoadStringW(shell32_hInstance, IDS_PICK_ICON_FILTER, szFilter, sizeof(szFilter) / sizeof(WCHAR));
161 ofn.lpstrFilter = szFilter;
162 if (GetOpenFileNameW(&ofn))
163 {
164 HMODULE hLibrary;
165
166 if (!wcsicmp(pIconContext->szName, szText))
167 break;
168
169 DestroyIconList(pIconContext->hDlgCtrl);
170
171 hLibrary = LoadLibraryExW(szText, NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
172 if (hLibrary == NULL)
173 break;
174 FreeLibrary(pIconContext->hLibrary);
175 pIconContext->hLibrary = hLibrary;
176 wcscpy(pIconContext->szName, szText);
177 EnumResourceNamesW(pIconContext->hLibrary, RT_ICON, EnumPickIconResourceProc, (LPARAM)pIconContext);
178 if (PathUnExpandEnvStringsW(pIconContext->szName, szText, MAX_PATH))
179 SendDlgItemMessageW(hwndDlg, IDC_EDIT_PATH, WM_SETTEXT, 0, (LPARAM)szText);
180 else
181 SendDlgItemMessageW(hwndDlg, IDC_EDIT_PATH, WM_SETTEXT, 0, (LPARAM)pIconContext->szName);
182
183 SendMessageW(pIconContext->hDlgCtrl, LB_SETCURSEL, 0, 0);
184 }
185 break;
186 }
187 break;
188 case WM_MEASUREITEM:
189 lpmis = (LPMEASUREITEMSTRUCT) lParam;
190 lpmis->itemHeight = 32;
191 lpmis->itemWidth = 64;
192 return TRUE;
193 case WM_DRAWITEM:
194 lpdis = (LPDRAWITEMSTRUCT) lParam;
195 if (lpdis->itemID == -1)
196 {
197 break;
198 }
199 switch (lpdis->itemAction)
200 {
201 case ODA_SELECT:
202 case ODA_DRAWENTIRE:
203 index = SendMessageW(pIconContext->hDlgCtrl, LB_GETCURSEL, 0, 0);
204 hIcon =(HICON)SendMessage(lpdis->hwndItem, LB_GETITEMDATA, lpdis->itemID, (LPARAM) 0);
205
206 if (lpdis->itemID == index)
207 {
208 HBRUSH hBrush;
209 hBrush = CreateSolidBrush(RGB(0, 0, 255));
210 FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
211 DeleteObject(hBrush);
212 }
213 else
214 {
215 HBRUSH hBrush;
216 hBrush = CreateSolidBrush(RGB(255, 255, 255));
217 FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
218 DeleteObject(hBrush);
219 }
220 DrawIconEx(lpdis->hDC, lpdis->rcItem.left,lpdis->rcItem.top, hIcon,
221 0,
222 0,
223 0,
224 NULL,
225 DI_NORMAL);
226 break;
227 }
228 break;
229 }
230
231 return FALSE;
232 }
233
234 BOOL WINAPI PickIconDlg(
235 HWND hwndOwner,
236 LPWSTR lpstrFile,
237 UINT nMaxFile,
238 INT* lpdwIconIndex)
239 {
240 HMODULE hLibrary;
241 int res;
242 PICK_ICON_CONTEXT IconContext;
243
244 hLibrary = LoadLibraryExW(lpstrFile, NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
245 IconContext.hLibrary = hLibrary;
246 IconContext.Index = *lpdwIconIndex;
247 wcscpy(IconContext.szName, lpstrFile);
248
249 res = DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(IDD_PICK_ICON_DIALOG), hwndOwner, PickIconProc, (LPARAM)&IconContext);
250 if (res)
251 {
252 wcscpy(lpstrFile, IconContext.szName);
253 *lpdwIconIndex = IconContext.Index;
254 }
255
256 FreeLibrary(hLibrary);
257 return res;
258 }
259
260 /*************************************************************************
261 * RunFileDlg [SHELL32.61]
262 *
263 * NOTES
264 * Original name: RunFileDlg (exported by ordinal)
265 */
266 void WINAPI RunFileDlg(
267 HWND hwndOwner,
268 HICON hIcon,
269 LPCSTR lpstrDirectory,
270 LPCSTR lpstrTitle,
271 LPCSTR lpstrDescription,
272 UINT uFlags)
273 {
274
275 RUNFILEDLGPARAMS rfdp;
276 HRSRC hRes;
277 LPVOID template;
278 TRACE("\n");
279
280 rfdp.hwndOwner = hwndOwner;
281 rfdp.hIcon = hIcon;
282 rfdp.lpstrDirectory = lpstrDirectory;
283 rfdp.lpstrTitle = lpstrTitle;
284 rfdp.lpstrDescription = lpstrDescription;
285 rfdp.uFlags = uFlags;
286
287 if(!(hRes = FindResourceA(shell32_hInstance, "SHELL_RUN_DLG", (LPSTR)RT_DIALOG)))
288 {
289 MessageBoxA (hwndOwner, "Couldn't find dialog.", "Nix", MB_OK) ;
290 return;
291 }
292 if(!(template = (LPVOID)LoadResource(shell32_hInstance, hRes)))
293 {
294 MessageBoxA (hwndOwner, "Couldn't load dialog.", "Nix", MB_OK) ;
295 return;
296 }
297
298 DialogBoxIndirectParamA((HINSTANCE)GetWindowLongPtrW( hwndOwner,
299 GWLP_HINSTANCE ),
300 template, hwndOwner, RunDlgProc, (LPARAM)&rfdp);
301
302 }
303
304 /* Dialog procedure for RunFileDlg */
305 static INT_PTR CALLBACK RunDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
306 {
307 int ic ;
308 char *psz, *pdir, szMsg[256];
309 static RUNFILEDLGPARAMS *prfdp = NULL ;
310
311 switch (message)
312 {
313 case WM_INITDIALOG :
314 prfdp = (RUNFILEDLGPARAMS *)lParam ;
315
316 if (prfdp->lpstrTitle)
317 SetWindowTextA (hwnd, prfdp->lpstrTitle) ;
318
319 SetClassLongPtrW (hwnd, GCLP_HICON, (LPARAM)prfdp->hIcon) ;
320 SendMessageW (GetDlgItem (hwnd, 12297), STM_SETICON,
321 (WPARAM)LoadIconW (NULL, (LPCWSTR)IDI_WINLOGO), 0);
322 FillList (GetDlgItem (hwnd, 12298), NULL) ;
323 SetFocus (GetDlgItem (hwnd, 12298)) ;
324 return TRUE ;
325
326 case WM_COMMAND :
327 switch (LOWORD (wParam))
328 {
329 case IDOK :
330 {
331 HWND htxt = NULL ;
332 if ((ic = GetWindowTextLengthA (htxt = GetDlgItem (hwnd, 12298))))
333 {
334 psz = HeapAlloc( GetProcessHeap(), 0, (ic + 2) );
335 GetWindowTextA (htxt, psz, ic + 1) ;
336 pdir = HeapAlloc( GetProcessHeap(), 0, (ic + 2) );
337 if (pdir)
338 {
339 char * ptr;
340 strcpy(pdir, psz);
341 ptr = strrchr(pdir + 4, '\\');
342 if(ptr)
343 ptr[0] = '\0';
344 else
345 pdir[3] = '\0';
346 }
347 if (ShellExecuteA(NULL, NULL, psz, NULL, pdir, SW_SHOWNORMAL) < (HINSTANCE)33)
348 {
349 char *pszSysMsg = NULL ;
350 FormatMessageA (
351 FORMAT_MESSAGE_ALLOCATE_BUFFER |
352 FORMAT_MESSAGE_FROM_SYSTEM |
353 FORMAT_MESSAGE_IGNORE_INSERTS,
354 NULL, GetLastError (),
355 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
356 (LPSTR)&pszSysMsg, 0, NULL
357 ) ;
358 sprintf (szMsg, "Error: %s", pszSysMsg) ;
359 LocalFree ((HLOCAL)pszSysMsg) ;
360 MessageBoxA (hwnd, szMsg, NULL, MB_OK | MB_ICONEXCLAMATION) ;
361
362 HeapFree(GetProcessHeap(), 0, psz);
363 HeapFree(GetProcessHeap(), 0, pdir);
364 SendMessageA (htxt, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
365 return TRUE ;
366 }
367 FillList (htxt, psz) ;
368 HeapFree(GetProcessHeap(), 0, psz);
369 HeapFree(GetProcessHeap(), 0, pdir);
370 EndDialog (hwnd, 0) ;
371 }
372 }
373
374 case IDCANCEL :
375 EndDialog (hwnd, 0) ;
376 return TRUE ;
377
378 case 12288 :
379 {
380 HMODULE hComdlg = NULL ;
381 LPFNOFN ofnProc = NULL ;
382 static char szFName[1024] = "", szFileTitle[256] = "", szInitDir[768] = "" ;
383 static OPENFILENAMEA ofn =
384 {
385 sizeof (OPENFILENAMEA),
386 NULL,
387 NULL,
388 "Executable Files\0*.exe\0All Files\0*.*\0\0\0\0",
389 NULL,
390 0,
391 0,
392 szFName,
393 1023,
394 szFileTitle,
395 255,
396 (LPCSTR)szInitDir,
397 "Browse",
398 OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST,
399 0,
400 0,
401 NULL,
402 0,
403 (LPOFNHOOKPROC)NULL,
404 NULL
405 } ;
406
407 ofn.hwndOwner = hwnd ;
408
409 if (NULL == (hComdlg = LoadLibraryExA ("comdlg32", NULL, 0)))
410 {
411 MessageBoxA (hwnd, "Unable to display dialog box (LoadLibraryEx) !", "Nix", MB_OK | MB_ICONEXCLAMATION) ;
412 return TRUE ;
413 }
414
415 if ((LPFNOFN)NULL == (ofnProc = (LPFNOFN)GetProcAddress (hComdlg, "GetOpenFileNameA")))
416 {
417 MessageBoxA (hwnd, "Unable to display dialog box (GetProcAddress) !", "Nix", MB_OK | MB_ICONEXCLAMATION) ;
418 return TRUE ;
419 }
420
421 ofnProc (&ofn) ;
422
423 SetFocus (GetDlgItem (hwnd, IDOK)) ;
424 SetWindowTextA (GetDlgItem (hwnd, 12298), szFName) ;
425 SendMessageA (GetDlgItem (hwnd, 12298), CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
426 SetFocus (GetDlgItem (hwnd, IDOK)) ;
427
428 FreeLibrary (hComdlg) ;
429
430 return TRUE ;
431 }
432 }
433 return TRUE ;
434 }
435 return FALSE ;
436 }
437
438 /* This grabs the MRU list from the registry and fills the combo for the "Run" dialog above */
439 static void FillList (HWND hCb, char *pszLatest)
440 {
441 HKEY hkey ;
442 /* char szDbgMsg[256] = "" ; */
443 char *pszList = NULL, *pszCmd = NULL, cMatch = 0, cMax = 0x60, szIndex[2] = "-" ;
444 DWORD icList = 0, icCmd = 0 ;
445 UINT Nix ;
446
447 SendMessageA (hCb, CB_RESETCONTENT, 0, 0) ;
448
449 if (ERROR_SUCCESS != RegCreateKeyExA (
450 HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU",
451 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL))
452 MessageBoxA (hCb, "Unable to open registry key !", "Nix", MB_OK) ;
453
454 RegQueryValueExA (hkey, "MRUList", NULL, NULL, NULL, &icList) ;
455
456 if (icList > 0)
457 {
458 pszList = HeapAlloc( GetProcessHeap(), 0, icList) ;
459 if (ERROR_SUCCESS != RegQueryValueExA (hkey, "MRUList", NULL, NULL, (LPBYTE)pszList, &icList))
460 MessageBoxA (hCb, "Unable to grab MRUList !", "Nix", MB_OK) ;
461 }
462 else
463 {
464 icList = 1 ;
465 pszList = HeapAlloc( GetProcessHeap(), 0, icList) ;
466 pszList[0] = 0 ;
467 }
468
469 for (Nix = 0 ; Nix < icList - 1 ; Nix++)
470 {
471 if (pszList[Nix] > cMax)
472 cMax = pszList[Nix] ;
473
474 szIndex[0] = pszList[Nix] ;
475
476 if (ERROR_SUCCESS != RegQueryValueExA (hkey, szIndex, NULL, NULL, NULL, &icCmd))
477 MessageBoxA (hCb, "Unable to grab size of index", "Nix", MB_OK) ;
478 if( pszCmd )
479 pszCmd = HeapReAlloc(GetProcessHeap(), 0, pszCmd, icCmd) ;
480 else
481 pszCmd = HeapAlloc(GetProcessHeap(), 0, icCmd) ;
482 if (ERROR_SUCCESS != RegQueryValueExA (hkey, szIndex, NULL, NULL, (LPBYTE)pszCmd, &icCmd))
483 MessageBoxA (hCb, "Unable to grab index", "Nix", MB_OK) ;
484
485 if (NULL != pszLatest)
486 {
487 if (!lstrcmpiA(pszCmd, pszLatest))
488 {
489 /*
490 sprintf (szDbgMsg, "Found existing (%d).\n", Nix) ;
491 MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ;
492 */
493 SendMessageA (hCb, CB_INSERTSTRING, 0, (LPARAM)pszCmd) ;
494 SetWindowTextA (hCb, pszCmd) ;
495 SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
496
497 cMatch = pszList[Nix] ;
498 memmove (&pszList[1], pszList, Nix) ;
499 pszList[0] = cMatch ;
500 continue ;
501 }
502 }
503
504 if (26 != icList - 1 || icList - 2 != Nix || cMatch || NULL == pszLatest)
505 {
506 /*
507 sprintf (szDbgMsg, "Happily appending (%d).\n", Nix) ;
508 MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ;
509 */
510 SendMessageA (hCb, CB_ADDSTRING, 0, (LPARAM)pszCmd) ;
511 if (!Nix)
512 {
513 SetWindowTextA (hCb, pszCmd) ;
514 SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
515 }
516
517 }
518 else
519 {
520 /*
521 sprintf (szDbgMsg, "Doing loop thing.\n") ;
522 MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ;
523 */
524 SendMessageA (hCb, CB_INSERTSTRING, 0, (LPARAM)pszLatest) ;
525 SetWindowTextA (hCb, pszLatest) ;
526 SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
527
528 cMatch = pszList[Nix] ;
529 memmove (&pszList[1], pszList, Nix) ;
530 pszList[0] = cMatch ;
531 szIndex[0] = cMatch ;
532 RegSetValueExA (hkey, szIndex, 0, REG_SZ, (LPBYTE)pszLatest, strlen (pszLatest) + 1) ;
533 }
534 }
535
536 if (!cMatch && NULL != pszLatest)
537 {
538 /*
539 sprintf (szDbgMsg, "Simply inserting (increasing list).\n") ;
540 MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ;
541 */
542 SendMessageA (hCb, CB_INSERTSTRING, 0, (LPARAM)pszLatest) ;
543 SetWindowTextA (hCb, pszLatest) ;
544 SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
545
546 cMatch = ++cMax ;
547 if( pszList )
548 pszList = HeapReAlloc(GetProcessHeap(), 0, pszList, ++icList) ;
549 else
550 pszList = HeapAlloc(GetProcessHeap(), 0, ++icList) ;
551 memmove (&pszList[1], pszList, icList - 1) ;
552 pszList[0] = cMatch ;
553 szIndex[0] = cMatch ;
554 RegSetValueExA (hkey, szIndex, 0, REG_SZ, (LPBYTE)pszLatest, strlen (pszLatest) + 1) ;
555 }
556
557 RegSetValueExA (hkey, "MRUList", 0, REG_SZ, (LPBYTE)pszList, strlen (pszList) + 1) ;
558
559 HeapFree( GetProcessHeap(), 0, pszCmd) ;
560 HeapFree( GetProcessHeap(), 0, pszList) ;
561 }
562
563
564 /*************************************************************************
565 * ConfirmDialog [internal]
566 *
567 * Put up a confirm box, return TRUE if the user confirmed
568 */
569 static BOOL ConfirmDialog(HWND hWndOwner, UINT PromptId, UINT TitleId)
570 {
571 WCHAR Prompt[256];
572 WCHAR Title[256];
573
574 LoadStringW(shell32_hInstance, PromptId, Prompt, sizeof(Prompt) / sizeof(WCHAR));
575 LoadStringW(shell32_hInstance, TitleId, Title, sizeof(Title) / sizeof(WCHAR));
576 return MessageBoxW(hWndOwner, Prompt, Title, MB_YESNO|MB_ICONQUESTION) == IDYES;
577 }
578
579
580 /*************************************************************************
581 * RestartDialogEx [SHELL32.730]
582 */
583
584 int WINAPI RestartDialogEx(HWND hWndOwner, LPCWSTR lpwstrReason, DWORD uFlags, DWORD uReason)
585 {
586 TRACE("(%p)\n", hWndOwner);
587
588 /* FIXME: use lpwstrReason */
589 if (ConfirmDialog(hWndOwner, IDS_RESTART_PROMPT, IDS_RESTART_TITLE))
590 {
591 HANDLE hToken;
592 TOKEN_PRIVILEGES npr;
593
594 /* enable the shutdown privilege for the current process */
595 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
596 {
597 LookupPrivilegeValueA(0, "SeShutdownPrivilege", &npr.Privileges[0].Luid);
598 npr.PrivilegeCount = 1;
599 npr.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
600 AdjustTokenPrivileges(hToken, FALSE, &npr, 0, 0, 0);
601 CloseHandle(hToken);
602 }
603 ExitWindowsEx(EWX_REBOOT, uReason);
604 }
605
606 return 0;
607 }
608
609 /*************************************************************************
610 * LogoffWindowsDialog [SHELL32.54]
611 */
612
613 int WINAPI LogoffWindowsDialog(HWND hWndOwner)
614 {
615 if (ConfirmDialog(hWndOwner, IDS_LOGOFF_PROMPT, IDS_LOGOFF_TITLE))
616 {
617 ExitWindowsEx(EWX_LOGOFF, 0);
618 }
619 return 0;
620 }
621
622 /*************************************************************************
623 * RestartDialog [SHELL32.59]
624 */
625
626 int WINAPI RestartDialog(HWND hWndOwner, LPCWSTR lpstrReason, DWORD uFlags)
627 {
628 return RestartDialogEx(hWndOwner, lpstrReason, uFlags, 0);
629 }
630
631
632 /*************************************************************************
633 * ExitWindowsDialog [SHELL32.60]
634 *
635 * NOTES
636 * exported by ordinal
637 */
638 void WINAPI ExitWindowsDialog (HWND hWndOwner)
639 {
640 TRACE("(%p)\n", hWndOwner);
641
642 if (ConfirmDialog(hWndOwner, IDS_SHUTDOWN_PROMPT, IDS_SHUTDOWN_TITLE))
643 {
644 HANDLE hToken;
645 TOKEN_PRIVILEGES npr;
646
647 /* enable shutdown privilege for current process */
648 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
649 {
650 LookupPrivilegeValueA(0, "SeShutdownPrivilege", &npr.Privileges[0].Luid);
651 npr.PrivilegeCount = 1;
652 npr.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
653 AdjustTokenPrivileges(hToken, FALSE, &npr, 0, 0, 0);
654 CloseHandle(hToken);
655 }
656 ExitWindowsEx(EWX_SHUTDOWN, 0);
657 }
658 }