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