Implement A->W call for GetNamedSecurityInfo.
[wine] / dlls / 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22 #include "wine/port.h"
23
24 #include <string.h>
25 #include <stdarg.h>
26 #include <stdio.h>
27 #include "winerror.h"
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winreg.h"
31 #include "wingdi.h"
32 #include "winuser.h"
33 #include "commdlg.h"
34 #include "wine/debug.h"
35
36 #include "shellapi.h"
37 #include "shlobj.h"
38 #include "shell32_main.h"
39 #include "shresdef.h"
40 #include "undocshell.h"
41
42 typedef struct
43     {
44         HWND hwndOwner ;
45         HICON hIcon ;
46         LPCSTR lpstrDirectory ;
47         LPCSTR lpstrTitle ;
48         LPCSTR lpstrDescription ;
49         UINT uFlags ;
50     } RUNFILEDLGPARAMS ;
51
52 typedef BOOL (*LPFNOFN) (OPENFILENAMEA *) ;
53
54 WINE_DEFAULT_DEBUG_CHANNEL(shell);
55 INT_PTR CALLBACK RunDlgProc (HWND, UINT, WPARAM, LPARAM) ;
56 void FillList (HWND, char *) ;
57
58
59 /*************************************************************************
60  * PickIconDlg                                  [SHELL32.62]
61  *
62  */
63 BOOL WINAPI PickIconDlg(
64         HWND hwndOwner,
65         LPSTR lpstrFile,
66         DWORD nMaxFile,
67         LPDWORD lpdwIconIndex)
68 {
69         FIXME("(%p,%s,%08lx,%p):stub.\n",
70           hwndOwner, lpstrFile, nMaxFile,lpdwIconIndex);
71         return 0xffffffff;
72 }
73
74 /*************************************************************************
75  * RunFileDlg                                   [SHELL32.61]
76  *
77  * NOTES
78  *     Original name: RunFileDlg (exported by ordinal)
79  */
80 void WINAPI RunFileDlg(
81         HWND hwndOwner,
82         HICON hIcon,
83         LPCSTR lpstrDirectory,
84         LPCSTR lpstrTitle,
85         LPCSTR lpstrDescription,
86         UINT uFlags)
87 {
88
89     RUNFILEDLGPARAMS rfdp;
90     HRSRC hRes;
91     LPVOID template;
92     TRACE("\n");
93
94     rfdp.hwndOwner        = hwndOwner;
95     rfdp.hIcon            = hIcon;
96     rfdp.lpstrDirectory   = lpstrDirectory;
97     rfdp.lpstrTitle       = lpstrTitle;
98     rfdp.lpstrDescription = lpstrDescription;
99     rfdp.uFlags           = uFlags;
100
101     if(!(hRes = FindResourceA(shell32_hInstance, "SHELL_RUN_DLG", (LPSTR)RT_DIALOG)))
102         {
103         MessageBoxA (hwndOwner, "Couldn't find dialog.", "Nix", MB_OK) ;
104         return;
105         }
106     if(!(template = (LPVOID)LoadResource(shell32_hInstance, hRes)))
107         {
108         MessageBoxA (hwndOwner, "Couldn't load dialog.", "Nix", MB_OK) ;
109         return;
110         }
111
112     DialogBoxIndirectParamA((HINSTANCE)GetWindowLongA( hwndOwner,
113                                                        GWL_HINSTANCE ),
114                             template, hwndOwner, RunDlgProc, (LPARAM)&rfdp);
115
116 }
117
118 /* Dialog procedure for RunFileDlg */
119 INT_PTR CALLBACK RunDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
120     {
121     int ic ;
122     char *psz, szMsg[256] ;
123     static RUNFILEDLGPARAMS *prfdp = NULL ;
124
125     switch (message)
126         {
127         case WM_INITDIALOG :
128             prfdp = (RUNFILEDLGPARAMS *)lParam ;
129             SetWindowTextA (hwnd, prfdp->lpstrTitle) ;
130             SetClassLongA (hwnd, GCL_HICON, (LPARAM)prfdp->hIcon) ;
131             SendMessageA (GetDlgItem (hwnd, 12297), STM_SETICON,
132                           (WPARAM)LoadIconA (NULL, (LPSTR)IDI_WINLOGO), 0);
133             FillList (GetDlgItem (hwnd, 12298), NULL) ;
134             SetFocus (GetDlgItem (hwnd, 12298)) ;
135             return TRUE ;
136
137         case WM_COMMAND :
138             switch (LOWORD (wParam))
139                 {
140                 case IDOK :
141                     {
142                     HWND htxt = NULL ;
143                     if ((ic = GetWindowTextLengthA (htxt = GetDlgItem (hwnd, 12298))))
144                         {
145                         psz = malloc (ic + 2) ;
146                         GetWindowTextA (htxt, psz, ic + 1) ;
147
148                         if (ShellExecuteA(NULL, "open", psz, NULL, NULL, SW_SHOWNORMAL) < (HINSTANCE)33)
149                             {
150                             char *pszSysMsg = NULL ;
151                             FormatMessageA (
152                                 FORMAT_MESSAGE_ALLOCATE_BUFFER |
153                                 FORMAT_MESSAGE_FROM_SYSTEM |
154                                 FORMAT_MESSAGE_IGNORE_INSERTS,
155                                 NULL, GetLastError (),
156                                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
157                                 (LPSTR)&pszSysMsg, 0, NULL
158                                 ) ;
159                             sprintf (szMsg, "Error: %s", pszSysMsg) ;
160                             LocalFree ((HLOCAL)pszSysMsg) ;
161                             MessageBoxA (hwnd, szMsg, "Nix", MB_OK | MB_ICONEXCLAMATION) ;
162
163                             free (psz) ;
164                             SendMessageA (htxt, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
165                             return TRUE ;
166                             }
167                         FillList (htxt, psz) ;
168                         free (psz) ;
169                         EndDialog (hwnd, 0) ;
170                         }
171                     }
172
173                 case IDCANCEL :
174                     EndDialog (hwnd, 0) ;
175                     return TRUE ;
176
177                 case 12288 :
178                     {
179                     HMODULE hComdlg = NULL ;
180                     LPFNOFN ofnProc = NULL ;
181                     static char szFName[1024] = "", szFileTitle[256] = "", szInitDir[768] = "" ;
182                     static OPENFILENAMEA ofn =
183                         {
184                         sizeof (OPENFILENAMEA),
185                         NULL,
186                         NULL,
187                         "Executable Files\0*.exe\0All Files\0*.*\0\0\0\0",
188                         NULL,
189                         0,
190                         0,
191                         szFName,
192                         1023,
193                         szFileTitle,
194                         255,
195                         (LPCSTR)szInitDir,
196                         "Browse",
197                         OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST,
198                         0,
199                         0,
200                         NULL,
201                         0,
202                         (LPOFNHOOKPROC)NULL,
203                         NULL
204                         } ;
205
206                     ofn.hwndOwner = hwnd ;
207
208                     if (NULL == (hComdlg = LoadLibraryExA ("comdlg32", NULL, 0)))
209                         {
210                         MessageBoxA (hwnd, "Unable to display dialog box (LoadLibraryEx) !", "Nix", MB_OK | MB_ICONEXCLAMATION) ;
211                         return TRUE ;
212                         }
213
214                     if ((LPFNOFN)NULL == (ofnProc = (LPFNOFN)GetProcAddress (hComdlg, "GetOpenFileNameA")))
215                         {
216                         MessageBoxA (hwnd, "Unable to display dialog box (GetProcAddress) !", "Nix", MB_OK | MB_ICONEXCLAMATION) ;
217                         return TRUE ;
218                         }
219
220                     ofnProc (&ofn) ;
221
222                     SetFocus (GetDlgItem (hwnd, IDOK)) ;
223                     SetWindowTextA (GetDlgItem (hwnd, 12298), szFName) ;
224                     SendMessageA (GetDlgItem (hwnd, 12298), CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
225                     SetFocus (GetDlgItem (hwnd, IDOK)) ;
226
227                     FreeLibrary (hComdlg) ;
228
229                     return TRUE ;
230                     }
231                 }
232             return TRUE ;
233         }
234     return FALSE ;
235     }
236
237 /* This grabs the MRU list from the registry and fills the combo for the "Run" dialog above */
238 void FillList (HWND hCb, char *pszLatest)
239     {
240     HKEY hkey ;
241 /*    char szDbgMsg[256] = "" ; */
242     char *pszList = NULL, *pszCmd = NULL, cMatch = 0, cMax = 0x60, szIndex[2] = "-" ;
243     DWORD icList = 0, icCmd = 0 ;
244     UINT Nix ;
245
246     SendMessageA (hCb, CB_RESETCONTENT, 0, 0) ;
247
248     if (ERROR_SUCCESS != RegCreateKeyExA (
249         HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU",
250         0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL))
251         MessageBoxA (hCb, "Unable to open registry key !", "Nix", MB_OK) ;
252
253     RegQueryValueExA (hkey, "MRUList", NULL, NULL, NULL, &icList) ;
254
255     if (icList > 0)
256         {
257         pszList = malloc (icList) ;
258         if (ERROR_SUCCESS != RegQueryValueExA (hkey, "MRUList", NULL, NULL, pszList, &icList))
259             MessageBoxA (hCb, "Unable to grab MRUList !", "Nix", MB_OK) ;
260         }
261     else
262         {
263         pszList = malloc (icList = 1) ;
264         pszList[0] = 0 ;
265         }
266
267     for (Nix = 0 ; Nix < icList - 1 ; Nix++)
268         {
269         if (pszList[Nix] > cMax)
270             cMax = pszList[Nix] ;
271
272         szIndex[0] = pszList[Nix] ;
273
274         if (ERROR_SUCCESS != RegQueryValueExA (hkey, szIndex, NULL, NULL, NULL, &icCmd))
275             MessageBoxA (hCb, "Unable to grab size of index", "Nix", MB_OK) ;
276         pszCmd = realloc (pszCmd, icCmd) ;
277         if (ERROR_SUCCESS != RegQueryValueExA (hkey, szIndex, NULL, NULL, pszCmd, &icCmd))
278             MessageBoxA (hCb, "Unable to grab index", "Nix", MB_OK) ;
279
280         if (NULL != pszLatest)
281             {
282             if (!strcasecmp (pszCmd, pszLatest))
283                 {
284                 /*
285                 sprintf (szDbgMsg, "Found existing (%d).\n", Nix) ;
286                 MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ;
287                 */
288                 SendMessageA (hCb, CB_INSERTSTRING, 0, (LPARAM)pszCmd) ;
289                 SetWindowTextA (hCb, pszCmd) ;
290                 SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
291
292                 cMatch = pszList[Nix] ;
293                 memmove (&pszList[1], pszList, Nix) ;
294                 pszList[0] = cMatch ;
295                 continue ;
296                 }
297             }
298
299         if (26 != icList - 1 || icList - 2 != Nix || cMatch || NULL == pszLatest)
300             {
301             /*
302             sprintf (szDbgMsg, "Happily appending (%d).\n", Nix) ;
303             MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ;
304             */
305             SendMessageA (hCb, CB_ADDSTRING, 0, (LPARAM)pszCmd) ;
306             if (!Nix)
307                 {
308                 SetWindowTextA (hCb, pszCmd) ;
309                 SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
310                 }
311
312             }
313         else
314             {
315             /*
316             sprintf (szDbgMsg, "Doing loop thing.\n") ;
317             MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ;
318             */
319             SendMessageA (hCb, CB_INSERTSTRING, 0, (LPARAM)pszLatest) ;
320             SetWindowTextA (hCb, pszLatest) ;
321             SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
322
323             cMatch = pszList[Nix] ;
324             memmove (&pszList[1], pszList, Nix) ;
325             pszList[0] = cMatch ;
326             szIndex[0] = cMatch ;
327             RegSetValueExA (hkey, szIndex, 0, REG_SZ, pszLatest, strlen (pszLatest) + 1) ;
328             }
329         }
330
331     if (!cMatch && NULL != pszLatest)
332         {
333         /*
334         sprintf (szDbgMsg, "Simply inserting (increasing list).\n") ;
335         MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ;
336         */
337         SendMessageA (hCb, CB_INSERTSTRING, 0, (LPARAM)pszLatest) ;
338         SetWindowTextA (hCb, pszLatest) ;
339         SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
340
341         cMatch = ++cMax ;
342         pszList = realloc (pszList, ++icList) ;
343         memmove (&pszList[1], pszList, icList - 1) ;
344         pszList[0] = cMatch ;
345         szIndex[0] = cMatch ;
346         RegSetValueExA (hkey, szIndex, 0, REG_SZ, pszLatest, strlen (pszLatest) + 1) ;
347         }
348
349     RegSetValueExA (hkey, "MRUList", 0, REG_SZ, pszList, strlen (pszList) + 1) ;
350
351     free (pszCmd) ;
352     free (pszList) ;
353     }
354
355
356 /*************************************************************************
357  * ConfirmDialog                                [internal]
358  *
359  * Put up a confirm box, return TRUE if the user confirmed
360  */
361 static BOOL ConfirmDialog(HWND hWndOwner, UINT PromptId, UINT TitleId)
362 {
363   WCHAR Prompt[256];
364   WCHAR Title[256];
365
366   LoadStringW(shell32_hInstance, PromptId, Prompt, sizeof(Prompt) / sizeof(WCHAR));
367   LoadStringW(shell32_hInstance, TitleId, Title, sizeof(Title) / sizeof(WCHAR));
368   return MessageBoxW(hWndOwner, Prompt, Title, MB_YESNO|MB_ICONQUESTION) == IDYES;
369 }
370
371
372 /*************************************************************************
373  * RestartDialogEx                              [SHELL32.730]
374  */
375
376 int WINAPI RestartDialogEx(HWND hWndOwner, LPCWSTR lpwstrReason, DWORD uFlags, DWORD uReason)
377 {
378     TRACE("(%p)\n", hWndOwner);
379
380     /*FIXME: use uReason */
381
382     if (ConfirmDialog(hWndOwner, IDS_RESTART_PROMPT, IDS_RESTART_TITLE))
383     {
384         HANDLE hToken;
385         TOKEN_PRIVILEGES npr;
386
387         /* enable shutdown privilege for current process */
388         if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
389         {
390             LookupPrivilegeValueA(0, "SeShutdownPrivilege", &npr.Privileges[0].Luid);
391             npr.PrivilegeCount = 1;
392             npr.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
393             AdjustTokenPrivileges(hToken, FALSE, &npr, 0, 0, 0);
394             CloseHandle(hToken);
395         }
396         ExitWindowsEx(EWX_REBOOT, 0);
397     }
398
399     return 0;
400 }
401
402
403 /*************************************************************************
404  * RestartDialog                                [SHELL32.59]
405  */
406
407 int WINAPI RestartDialog(HWND hWndOwner, LPCWSTR lpstrReason, DWORD uFlags)
408 {
409     return RestartDialogEx(hWndOwner, lpstrReason, uFlags, 0);
410 }
411
412
413 /*************************************************************************
414  * ExitWindowsDialog                            [SHELL32.60]
415  *
416  * NOTES
417  *     exported by ordinal
418  */
419 void WINAPI ExitWindowsDialog (HWND hWndOwner)
420 {
421     TRACE("(%p)\n", hWndOwner);
422
423     if (ConfirmDialog(hWndOwner, IDS_SHUTDOWN_PROMPT, IDS_SHUTDOWN_TITLE))
424     {
425         HANDLE hToken;
426         TOKEN_PRIVILEGES npr;
427
428         /* enable shutdown privilege for current process */
429         if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
430         {
431             LookupPrivilegeValueA(0, "SeShutdownPrivilege", &npr.Privileges[0].Luid);
432             npr.PrivilegeCount = 1;
433             npr.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
434             AdjustTokenPrivileges(hToken, FALSE, &npr, 0, 0, 0);
435             CloseHandle(hToken);
436         }
437         ExitWindowsEx(EWX_SHUTDOWN, 0);
438     }
439 }