d3dx9: Print a real pixel format in a FIXME message.
[wine] / dlls / setupapi / dialog.c
1 /*
2  * SetupAPI dialog functions
3  *
4  * Copyright 2009 Ricardo Filipe
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 <stdarg.h>
22
23 #include "wine/debug.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wingdi.h"
27 #include "winuser.h"
28 #include "winreg.h"
29 #include "commdlg.h"
30 #include "setupapi.h"
31 #include "winnls.h"
32 #include "setupapi_private.h"
33
34 #include "wine/unicode.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
37
38 struct promptdisk_params {
39     PCWSTR DialogTitle;
40     PCWSTR DiskName;
41     PCWSTR PathToSource;
42     PCWSTR FileSought;
43     PCWSTR TagFile;
44     DWORD DiskPromptStyle;
45     PWSTR PathBuffer;
46     DWORD PathBufferSize;
47     PDWORD PathRequiredSize;
48 };
49
50 /* initiates the fields of the SetupPromptForDisk dialog according to the parameters
51 */
52 static void promptdisk_init(HWND hwnd, struct promptdisk_params *params)
53 {
54     SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR)params);
55
56     if(params->DialogTitle)
57         SetWindowTextW(hwnd, params->DialogTitle);
58     if(params->PathToSource)
59         SetDlgItemTextW(hwnd, IDC_PATH, params->PathToSource);
60
61     if(!(params->DiskPromptStyle & IDF_OEMDISK))
62     {
63         WCHAR message[256+2*MAX_PATH];
64         WCHAR format[256];
65         WCHAR unknown[256];
66         DWORD_PTR args[2];
67         LoadStringW(SETUPAPI_hInstance, IDS_PROMPTDISK, format,
68             sizeof(format)/sizeof(format[0]));
69
70         args[0] = (DWORD_PTR)params->FileSought;
71         if(params->DiskName)
72             args[1] = (DWORD_PTR)params->DiskName;
73         else
74         {
75             LoadStringW(SETUPAPI_hInstance, IDS_UNKNOWN, unknown,
76                 sizeof(unknown)/sizeof(unknown[0]));
77             args[1] = (DWORD_PTR)unknown;
78         }
79         FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
80                        format, 0, 0, message, sizeof(message)/sizeof(*message),
81                        (__ms_va_list*)args);
82         SetDlgItemTextW(hwnd, IDC_FILENEEDED, message);
83
84         LoadStringW(SETUPAPI_hInstance, IDS_INFO, message,
85             sizeof(message)/sizeof(message[0]));
86         SetDlgItemTextW(hwnd, IDC_INFO, message);
87         LoadStringW(SETUPAPI_hInstance, IDS_COPYFROM, message,
88             sizeof(message)/sizeof(message[0]));
89         SetDlgItemTextW(hwnd, IDC_COPYFROM, message);
90     }
91     if(params->DiskPromptStyle & IDF_NOBROWSE)
92         ShowWindow(GetDlgItem(hwnd, IDC_RUNDLG_BROWSE), SW_HIDE);
93 }
94
95 /* When the user clicks in the Ok button in SetupPromptForDisk dialog
96  * if the parameters are good it copies the path from the dialog to the output buffer
97  * saves the required size for the buffer if PathRequiredSize is given
98  * returns NO_ERROR if there is no PathBuffer to copy too
99  * returns DPROMPT_BUFFERTOOSMALL if the path is too big to fit in PathBuffer
100  */
101 static void promptdisk_ok(HWND hwnd, struct promptdisk_params *params)
102 {
103     int requiredSize;
104     WCHAR aux[MAX_PATH];
105     GetWindowTextW(GetDlgItem(hwnd, IDC_PATH), aux, MAX_PATH);
106     requiredSize = strlenW(aux)+1;
107
108     if(params->PathRequiredSize)
109     {
110         *params->PathRequiredSize = requiredSize;
111         TRACE("returning PathRequiredSize=%d\n",*params->PathRequiredSize);
112     }
113     if(!params->PathBuffer)
114     {
115         EndDialog(hwnd, NO_ERROR);
116         return;
117     }
118     if(requiredSize > params->PathBufferSize)
119     {
120         EndDialog(hwnd, DPROMPT_BUFFERTOOSMALL);
121         return;
122     }
123     strcpyW(params->PathBuffer, aux);
124     TRACE("returning PathBuffer=%s\n", debugstr_w(params->PathBuffer));
125     EndDialog(hwnd, DPROMPT_SUCCESS);
126 }
127
128 /* When the user clicks the browse button in SetupPromptForDisk dialog
129  * it copies the path of the selected file to the dialog path field
130  */
131 static void promptdisk_browse(HWND hwnd, struct promptdisk_params *params)
132 {
133     OPENFILENAMEW ofn;
134     ZeroMemory(&ofn, sizeof(ofn));
135
136     ofn.lStructSize = sizeof(ofn);
137     ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
138     ofn.hwndOwner = hwnd;
139     ofn.nMaxFile = MAX_PATH;
140     ofn.lpstrFile = HeapAlloc(GetProcessHeap(), 0, MAX_PATH*sizeof(WCHAR));
141     strcpyW(ofn.lpstrFile, params->FileSought);
142
143     if(GetOpenFileNameW(&ofn))
144     {
145         WCHAR* last_slash = strrchrW(ofn.lpstrFile, '\\');
146         if (last_slash) *last_slash = 0;
147         SetDlgItemTextW(hwnd, IDC_PATH, ofn.lpstrFile);
148     }
149     HeapFree(GetProcessHeap(), 0, ofn.lpstrFile);
150 }
151
152 /* Handles the messages sent to the SetupPromptForDisk dialog
153 */
154 static INT_PTR CALLBACK promptdisk_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
155 {
156     switch(msg)
157     {
158         case WM_INITDIALOG:
159             promptdisk_init(hwnd, (struct promptdisk_params *)lParam);
160             return TRUE;
161         case WM_COMMAND:
162             switch(wParam)
163             {
164                 case IDOK:
165                 {
166                     struct promptdisk_params *params =
167                         (struct promptdisk_params *)GetWindowLongPtrW(hwnd, DWLP_USER);
168                     promptdisk_ok(hwnd, params);
169                     return TRUE;
170                 }
171                 case IDCANCEL:
172                     EndDialog(hwnd, DPROMPT_CANCEL);
173                     return TRUE;
174                 case IDC_RUNDLG_BROWSE:
175                 {
176                     struct promptdisk_params *params =
177                         (struct promptdisk_params *)GetWindowLongPtrW(hwnd, DWLP_USER);
178                     promptdisk_browse(hwnd, params);
179                     return TRUE;
180                 }
181             }
182     }
183     return FALSE;
184 }
185
186 /***********************************************************************
187  *      SetupPromptForDiskA (SETUPAPI.@)
188  */
189 UINT WINAPI SetupPromptForDiskA(HWND hwndParent, PCSTR DialogTitle, PCSTR DiskName,
190         PCSTR PathToSource, PCSTR FileSought, PCSTR TagFile, DWORD DiskPromptStyle,
191         PSTR PathBuffer, DWORD PathBufferSize, PDWORD PathRequiredSize)
192 {
193     WCHAR *DialogTitleW, *DiskNameW, *PathToSourceW;
194     WCHAR *FileSoughtW, *TagFileW, PathBufferW[MAX_PATH];
195     UINT ret, length;
196
197     TRACE("%p, %s, %s, %s, %s, %s, 0x%08x, %p, %d, %p\n", hwndParent, debugstr_a(DialogTitle),
198           debugstr_a(DiskName), debugstr_a(PathToSource), debugstr_a(FileSought),
199           debugstr_a(TagFile), DiskPromptStyle, PathBuffer, PathBufferSize,
200           PathRequiredSize);
201
202     DialogTitleW = strdupAtoW(DialogTitle);
203     DiskNameW = strdupAtoW(DiskName);
204     PathToSourceW = strdupAtoW(PathToSource);
205     FileSoughtW = strdupAtoW(FileSought);
206     TagFileW = strdupAtoW(TagFile);
207
208     ret = SetupPromptForDiskW(hwndParent, DialogTitleW, DiskNameW, PathToSourceW,
209             FileSoughtW, TagFileW, DiskPromptStyle, PathBufferW, MAX_PATH, PathRequiredSize);
210
211     HeapFree(GetProcessHeap(), 0, DialogTitleW);
212     HeapFree(GetProcessHeap(), 0, DiskNameW);
213     HeapFree(GetProcessHeap(), 0, PathToSourceW);
214     HeapFree(GetProcessHeap(), 0, FileSoughtW);
215     HeapFree(GetProcessHeap(), 0, TagFileW);
216
217     if(ret == DPROMPT_SUCCESS)
218     {
219         length = WideCharToMultiByte(CP_ACP, 0, PathBufferW, -1, NULL, 0, NULL, NULL);
220         if(PathRequiredSize) *PathRequiredSize = length;
221         if(PathBuffer)
222         {
223             if(length > PathBufferSize)
224                 return DPROMPT_BUFFERTOOSMALL;
225             WideCharToMultiByte(CP_ACP, 0, PathBufferW, -1, PathBuffer, length, NULL, NULL);
226         }
227     }
228     return ret;
229 }
230
231 /***********************************************************************
232  *      SetupPromptForDiskW (SETUPAPI.@)
233  */
234 UINT WINAPI SetupPromptForDiskW(HWND hwndParent, PCWSTR DialogTitle, PCWSTR DiskName,
235         PCWSTR PathToSource, PCWSTR FileSought, PCWSTR TagFile, DWORD DiskPromptStyle,
236         PWSTR PathBuffer, DWORD PathBufferSize, PDWORD PathRequiredSize)
237 {
238     struct promptdisk_params params;
239     UINT ret;
240
241     TRACE("%p, %s, %s, %s, %s, %s, 0x%08x, %p, %d, %p\n", hwndParent, debugstr_w(DialogTitle),
242           debugstr_w(DiskName), debugstr_w(PathToSource), debugstr_w(FileSought),
243           debugstr_w(TagFile), DiskPromptStyle, PathBuffer, PathBufferSize,
244           PathRequiredSize);
245
246     if(!FileSought)
247     {
248         SetLastError(ERROR_INVALID_PARAMETER);
249         return DPROMPT_CANCEL;
250     }
251     params.DialogTitle = DialogTitle;
252     params.DiskName = DiskName;
253     params.PathToSource = PathToSource;
254     params.FileSought = FileSought;
255     params.TagFile = TagFile;
256     params.DiskPromptStyle = DiskPromptStyle;
257     params.PathBuffer = PathBuffer;
258     params.PathBufferSize = PathBufferSize;
259     params.PathRequiredSize = PathRequiredSize;
260
261     ret = DialogBoxParamW(SETUPAPI_hInstance, MAKEINTRESOURCEW(IDPROMPTFORDISK),
262         hwndParent, promptdisk_proc, (LPARAM)&params);
263
264     if(ret == DPROMPT_CANCEL)
265         SetLastError(ERROR_CANCELLED);
266     return ret;
267 }