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