1c2c66affSColin Finck /*
2c2c66affSColin Finck * New device installer (newdev.dll)
3c2c66affSColin Finck *
43b496432SJose Carlos Jesus * Copyright 2006 Hervé Poussineau (hpoussin@reactos.org)
5c2c66affSColin Finck *
6c2c66affSColin Finck * This library is free software; you can redistribute it and/or
7c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
8c2c66affSColin Finck * License as published by the Free Software Foundation; either
9c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
10c2c66affSColin Finck *
11c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
12c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
13c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14c2c66affSColin Finck * Lesser General Public License for more details.
15c2c66affSColin Finck *
16c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
17c2c66affSColin Finck * License along with this library; if not, write to the Free Software
18c2c66affSColin Finck * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19c2c66affSColin Finck */
20c2c66affSColin Finck
21c2c66affSColin Finck #include "newdev_private.h"
22c2c66affSColin Finck
23c2c66affSColin Finck #include <wincon.h>
24c2c66affSColin Finck #include <cfgmgr32.h>
25c2c66affSColin Finck #include <shlobj.h>
2662b13979SKatayama Hirofumi MZ #include <shlwapi.h>
27c2c66affSColin Finck
28c2c66affSColin Finck HANDLE hThread;
29c2c66affSColin Finck
30c2c66affSColin Finck static VOID
CenterWindow(IN HWND hWnd)31c2c66affSColin Finck CenterWindow(
32c2c66affSColin Finck IN HWND hWnd)
33c2c66affSColin Finck {
34c2c66affSColin Finck HWND hWndParent;
35c2c66affSColin Finck RECT rcParent;
36c2c66affSColin Finck RECT rcWindow;
37c2c66affSColin Finck
38c2c66affSColin Finck hWndParent = GetParent(hWnd);
39c2c66affSColin Finck if (hWndParent == NULL)
40c2c66affSColin Finck hWndParent = GetDesktopWindow();
41c2c66affSColin Finck
42c2c66affSColin Finck GetWindowRect(hWndParent, &rcParent);
43c2c66affSColin Finck GetWindowRect(hWnd, &rcWindow);
44c2c66affSColin Finck
453b496432SJose Carlos Jesus /* Check if the child window fits inside the parent window */
463b496432SJose Carlos Jesus if (rcWindow.left < rcParent.left || rcWindow.top < rcParent.top ||
473b496432SJose Carlos Jesus rcWindow.right > rcParent.right || rcWindow.bottom > rcParent.bottom)
483b496432SJose Carlos Jesus {
493b496432SJose Carlos Jesus return;
503b496432SJose Carlos Jesus }
513b496432SJose Carlos Jesus
52c2c66affSColin Finck SetWindowPos(
53c2c66affSColin Finck hWnd,
54c2c66affSColin Finck HWND_TOP,
55c2c66affSColin Finck ((rcParent.right - rcParent.left) - (rcWindow.right - rcWindow.left)) / 2,
56c2c66affSColin Finck ((rcParent.bottom - rcParent.top) - (rcWindow.bottom - rcWindow.top)) / 2,
57c2c66affSColin Finck 0,
58c2c66affSColin Finck 0,
59c2c66affSColin Finck SWP_NOSIZE);
60c2c66affSColin Finck }
61c2c66affSColin Finck
62c2c66affSColin Finck static BOOL
SetFailedInstall(IN HDEVINFO DeviceInfoSet,IN PSP_DEVINFO_DATA DevInfoData OPTIONAL,IN BOOLEAN Set)63c2c66affSColin Finck SetFailedInstall(
64c2c66affSColin Finck IN HDEVINFO DeviceInfoSet,
65c2c66affSColin Finck IN PSP_DEVINFO_DATA DevInfoData OPTIONAL,
66c2c66affSColin Finck IN BOOLEAN Set)
67c2c66affSColin Finck {
68c2c66affSColin Finck DWORD dwType, dwSize, dwFlags = 0;
69c2c66affSColin Finck
70c2c66affSColin Finck dwSize = sizeof(dwFlags);
71c2c66affSColin Finck if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
72c2c66affSColin Finck DevInfoData,
73c2c66affSColin Finck SPDRP_CONFIGFLAGS,
74c2c66affSColin Finck &dwType,
75c2c66affSColin Finck (PBYTE)&dwFlags,
76c2c66affSColin Finck dwSize,
77c2c66affSColin Finck &dwSize))
78c2c66affSColin Finck {
79c2c66affSColin Finck return FALSE;
80c2c66affSColin Finck }
81c2c66affSColin Finck
82c2c66affSColin Finck if (Set)
83c2c66affSColin Finck dwFlags |= CONFIGFLAG_FAILEDINSTALL;
84c2c66affSColin Finck else
85c2c66affSColin Finck dwFlags &= ~CONFIGFLAG_FAILEDINSTALL;
86c2c66affSColin Finck
87c2c66affSColin Finck if (!SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
88c2c66affSColin Finck DevInfoData,
89c2c66affSColin Finck SPDRP_CONFIGFLAGS,
90c2c66affSColin Finck (PBYTE)&dwFlags,
91c2c66affSColin Finck dwSize))
92c2c66affSColin Finck {
93c2c66affSColin Finck
94c2c66affSColin Finck return FALSE;
95c2c66affSColin Finck }
96c2c66affSColin Finck
973fa57b8fSEric Kohl if (Set)
983fa57b8fSEric Kohl {
993fa57b8fSEric Kohl /* Set the 'Unknown' device class */
1003fa57b8fSEric Kohl PWSTR pszUnknown = L"Unknown";
1013fa57b8fSEric Kohl SetupDiSetDeviceRegistryPropertyW(DeviceInfoSet,
1023fa57b8fSEric Kohl DevInfoData,
1033fa57b8fSEric Kohl SPDRP_CLASS,
1043fa57b8fSEric Kohl (PBYTE)pszUnknown,
1053fa57b8fSEric Kohl (wcslen(pszUnknown) + 1) * sizeof(WCHAR));
1063fa57b8fSEric Kohl
1073fa57b8fSEric Kohl PWSTR pszUnknownGuid = L"{4D36E97E-E325-11CE-BFC1-08002BE10318}";
1083fa57b8fSEric Kohl SetupDiSetDeviceRegistryPropertyW(DeviceInfoSet,
1093fa57b8fSEric Kohl DevInfoData,
1103fa57b8fSEric Kohl SPDRP_CLASSGUID,
1113fa57b8fSEric Kohl (PBYTE)pszUnknownGuid,
1123fa57b8fSEric Kohl (wcslen(pszUnknownGuid) + 1) * sizeof(WCHAR));
1133fa57b8fSEric Kohl
11432428a39SEric Kohl /* Set device problem code CM_PROB_FAILED_INSTALL */
11532428a39SEric Kohl CM_Set_DevNode_Problem(DevInfoData->DevInst,
11632428a39SEric Kohl CM_PROB_FAILED_INSTALL,
11732428a39SEric Kohl CM_SET_DEVNODE_PROBLEM_OVERRIDE);
1183fa57b8fSEric Kohl }
1193fa57b8fSEric Kohl
120c2c66affSColin Finck return TRUE;
121c2c66affSColin Finck }
122c2c66affSColin Finck
123c2c66affSColin Finck static BOOL
CanDisableDevice(IN DEVINST DevInst,IN HMACHINE hMachine,OUT BOOL * CanDisable)124c2c66affSColin Finck CanDisableDevice(
125c2c66affSColin Finck IN DEVINST DevInst,
126c2c66affSColin Finck IN HMACHINE hMachine,
127c2c66affSColin Finck OUT BOOL *CanDisable)
128c2c66affSColin Finck {
129c2c66affSColin Finck CONFIGRET cr;
130c2c66affSColin Finck ULONG Status, ProblemNumber;
131c2c66affSColin Finck BOOL Ret = FALSE;
132c2c66affSColin Finck
133c2c66affSColin Finck cr = CM_Get_DevNode_Status_Ex(&Status,
134c2c66affSColin Finck &ProblemNumber,
135c2c66affSColin Finck DevInst,
136c2c66affSColin Finck 0,
137c2c66affSColin Finck hMachine);
138c2c66affSColin Finck if (cr == CR_SUCCESS)
139c2c66affSColin Finck {
140c2c66affSColin Finck *CanDisable = ((Status & DN_DISABLEABLE) != 0);
141c2c66affSColin Finck Ret = TRUE;
142c2c66affSColin Finck }
143c2c66affSColin Finck
144c2c66affSColin Finck return Ret;
145c2c66affSColin Finck }
146c2c66affSColin Finck
147c2c66affSColin Finck static BOOL
IsDeviceStarted(IN DEVINST DevInst,IN HMACHINE hMachine,OUT BOOL * IsEnabled)148c2c66affSColin Finck IsDeviceStarted(
149c2c66affSColin Finck IN DEVINST DevInst,
150c2c66affSColin Finck IN HMACHINE hMachine,
151c2c66affSColin Finck OUT BOOL *IsEnabled)
152c2c66affSColin Finck {
153c2c66affSColin Finck CONFIGRET cr;
154c2c66affSColin Finck ULONG Status, ProblemNumber;
155c2c66affSColin Finck BOOL Ret = FALSE;
156c2c66affSColin Finck
157c2c66affSColin Finck cr = CM_Get_DevNode_Status_Ex(
158c2c66affSColin Finck &Status,
159c2c66affSColin Finck &ProblemNumber,
160c2c66affSColin Finck DevInst,
161c2c66affSColin Finck 0,
162c2c66affSColin Finck hMachine);
163c2c66affSColin Finck if (cr == CR_SUCCESS)
164c2c66affSColin Finck {
165c2c66affSColin Finck *IsEnabled = ((Status & DN_STARTED) != 0);
166c2c66affSColin Finck Ret = TRUE;
167c2c66affSColin Finck }
168c2c66affSColin Finck
169c2c66affSColin Finck return Ret;
170c2c66affSColin Finck }
171c2c66affSColin Finck
172c2c66affSColin Finck static BOOL
StartDevice(IN HDEVINFO DeviceInfoSet,IN PSP_DEVINFO_DATA DevInfoData OPTIONAL,IN BOOL bEnable,IN DWORD HardwareProfile OPTIONAL,OUT BOOL * bNeedReboot OPTIONAL)173c2c66affSColin Finck StartDevice(
174c2c66affSColin Finck IN HDEVINFO DeviceInfoSet,
175c2c66affSColin Finck IN PSP_DEVINFO_DATA DevInfoData OPTIONAL,
176c2c66affSColin Finck IN BOOL bEnable,
177c2c66affSColin Finck IN DWORD HardwareProfile OPTIONAL,
178c2c66affSColin Finck OUT BOOL *bNeedReboot OPTIONAL)
179c2c66affSColin Finck {
180c2c66affSColin Finck SP_PROPCHANGE_PARAMS pcp;
181c2c66affSColin Finck SP_DEVINSTALL_PARAMS dp;
182c2c66affSColin Finck DWORD LastErr;
183c2c66affSColin Finck BOOL Ret = FALSE;
184c2c66affSColin Finck
185c2c66affSColin Finck pcp.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
186c2c66affSColin Finck pcp.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
187c2c66affSColin Finck pcp.HwProfile = HardwareProfile;
188c2c66affSColin Finck
189c2c66affSColin Finck if (bEnable)
190c2c66affSColin Finck {
191c2c66affSColin Finck /* try to enable the device on the global profile */
192c2c66affSColin Finck pcp.StateChange = DICS_ENABLE;
193c2c66affSColin Finck pcp.Scope = DICS_FLAG_GLOBAL;
194c2c66affSColin Finck
195c2c66affSColin Finck /* ignore errors */
196c2c66affSColin Finck LastErr = GetLastError();
197c2c66affSColin Finck if (SetupDiSetClassInstallParams(
198c2c66affSColin Finck DeviceInfoSet,
199c2c66affSColin Finck DevInfoData,
200c2c66affSColin Finck &pcp.ClassInstallHeader,
201c2c66affSColin Finck sizeof(SP_PROPCHANGE_PARAMS)))
202c2c66affSColin Finck {
203c2c66affSColin Finck SetupDiCallClassInstaller(
204c2c66affSColin Finck DIF_PROPERTYCHANGE,
205c2c66affSColin Finck DeviceInfoSet,
206c2c66affSColin Finck DevInfoData);
207c2c66affSColin Finck }
208c2c66affSColin Finck SetLastError(LastErr);
209c2c66affSColin Finck }
210c2c66affSColin Finck
211c2c66affSColin Finck /* try config-specific */
212c2c66affSColin Finck pcp.StateChange = (bEnable ? DICS_ENABLE : DICS_DISABLE);
213c2c66affSColin Finck pcp.Scope = DICS_FLAG_CONFIGSPECIFIC;
214c2c66affSColin Finck
215c2c66affSColin Finck if (SetupDiSetClassInstallParams(
216c2c66affSColin Finck DeviceInfoSet,
217c2c66affSColin Finck DevInfoData,
218c2c66affSColin Finck &pcp.ClassInstallHeader,
219c2c66affSColin Finck sizeof(SP_PROPCHANGE_PARAMS)) &&
220c2c66affSColin Finck SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
221c2c66affSColin Finck DeviceInfoSet,
222c2c66affSColin Finck DevInfoData))
223c2c66affSColin Finck {
224c2c66affSColin Finck dp.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
225c2c66affSColin Finck if (SetupDiGetDeviceInstallParams(
226c2c66affSColin Finck DeviceInfoSet,
227c2c66affSColin Finck DevInfoData,
228c2c66affSColin Finck &dp))
229c2c66affSColin Finck {
230c2c66affSColin Finck if (bNeedReboot != NULL)
231c2c66affSColin Finck {
232c2c66affSColin Finck *bNeedReboot = ((dp.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT)) != 0);
233c2c66affSColin Finck }
234c2c66affSColin Finck
235c2c66affSColin Finck Ret = TRUE;
236c2c66affSColin Finck }
237c2c66affSColin Finck }
238c2c66affSColin Finck return Ret;
239c2c66affSColin Finck }
240c2c66affSColin Finck
241c2c66affSColin Finck static DWORD WINAPI
FindDriverProc(IN LPVOID lpParam)242c2c66affSColin Finck FindDriverProc(
243c2c66affSColin Finck IN LPVOID lpParam)
244c2c66affSColin Finck {
245c2c66affSColin Finck PDEVINSTDATA DevInstData;
246c2c66affSColin Finck BOOL result = FALSE;
247c2c66affSColin Finck
248c2c66affSColin Finck DevInstData = (PDEVINSTDATA)lpParam;
249c2c66affSColin Finck
250c2c66affSColin Finck result = ScanFoldersForDriver(DevInstData);
251c2c66affSColin Finck
252c2c66affSColin Finck if (result)
253c2c66affSColin Finck {
254c2c66affSColin Finck PostMessage(DevInstData->hDialog, WM_SEARCH_FINISHED, 1, 0);
255c2c66affSColin Finck }
256c2c66affSColin Finck else
257c2c66affSColin Finck {
25825019525SOlaf Schmerse if (!DevInstData->bUpdate)
25925019525SOlaf Schmerse {
260c2c66affSColin Finck /* Update device configuration */
2613fa57b8fSEric Kohl SetFailedInstall(DevInstData->hDevInfo,
262c2c66affSColin Finck &DevInstData->devInfoData,
2633fa57b8fSEric Kohl TRUE);
26425019525SOlaf Schmerse }
265c2c66affSColin Finck PostMessage(DevInstData->hDialog, WM_SEARCH_FINISHED, 0, 0);
266c2c66affSColin Finck }
267c2c66affSColin Finck return 0;
268c2c66affSColin Finck }
269c2c66affSColin Finck
270c2c66affSColin Finck static DWORD WINAPI
InstallDriverProc(IN LPVOID lpParam)271c2c66affSColin Finck InstallDriverProc(
272c2c66affSColin Finck IN LPVOID lpParam)
273c2c66affSColin Finck {
274c2c66affSColin Finck PDEVINSTDATA DevInstData;
275c2c66affSColin Finck BOOL res;
276c2c66affSColin Finck
277c2c66affSColin Finck DevInstData = (PDEVINSTDATA)lpParam;
278c2c66affSColin Finck res = InstallCurrentDriver(DevInstData);
279c2c66affSColin Finck PostMessage(DevInstData->hDialog, WM_INSTALL_FINISHED, res ? 0 : 1, 0);
280c2c66affSColin Finck return 0;
281c2c66affSColin Finck }
282c2c66affSColin Finck
283c2c66affSColin Finck static VOID
PopulateCustomPathCombo(IN HWND hwndCombo)284c2c66affSColin Finck PopulateCustomPathCombo(
285c2c66affSColin Finck IN HWND hwndCombo)
286c2c66affSColin Finck {
287c2c66affSColin Finck HKEY hKey = NULL;
288c2c66affSColin Finck DWORD dwRegType;
289c2c66affSColin Finck DWORD dwPathLength = 0;
290c2c66affSColin Finck LPWSTR Buffer = NULL;
291c2c66affSColin Finck LPCWSTR Path;
292c2c66affSColin Finck LONG rc;
293c2c66affSColin Finck
294c2c66affSColin Finck (void)ComboBox_ResetContent(hwndCombo);
295c2c66affSColin Finck
296c2c66affSColin Finck /* RegGetValue would have been better... */
297c2c66affSColin Finck rc = RegOpenKeyEx(
298c2c66affSColin Finck HKEY_LOCAL_MACHINE,
299c2c66affSColin Finck REGSTR_PATH_SETUP REGSTR_KEY_SETUP,
300c2c66affSColin Finck 0,
301c2c66affSColin Finck KEY_QUERY_VALUE,
302c2c66affSColin Finck &hKey);
303c2c66affSColin Finck if (rc != ERROR_SUCCESS)
304c2c66affSColin Finck {
305c2c66affSColin Finck TRACE("RegOpenKeyEx() failed with error 0x%lx\n", rc);
306c2c66affSColin Finck goto cleanup;
307c2c66affSColin Finck }
308c2c66affSColin Finck rc = RegQueryValueExW(
309c2c66affSColin Finck hKey,
310c2c66affSColin Finck L"Installation Sources",
311c2c66affSColin Finck NULL,
312c2c66affSColin Finck &dwRegType,
313c2c66affSColin Finck NULL,
314c2c66affSColin Finck &dwPathLength);
315c2c66affSColin Finck if (rc != ERROR_SUCCESS || dwRegType != REG_MULTI_SZ)
316c2c66affSColin Finck {
317c2c66affSColin Finck TRACE("RegQueryValueEx() failed with error 0x%lx\n", rc);
318c2c66affSColin Finck goto cleanup;
319c2c66affSColin Finck }
320c2c66affSColin Finck
321c2c66affSColin Finck /* Allocate enough space to add 2 NULL chars at the end of the string */
322c2c66affSColin Finck Buffer = HeapAlloc(GetProcessHeap(), 0, dwPathLength + 2 * sizeof(WCHAR));
323c2c66affSColin Finck if (!Buffer)
324c2c66affSColin Finck {
325c2c66affSColin Finck TRACE("HeapAlloc() failed\n");
326c2c66affSColin Finck goto cleanup;
327c2c66affSColin Finck }
328c2c66affSColin Finck rc = RegQueryValueExW(
329c2c66affSColin Finck hKey,
330c2c66affSColin Finck L"Installation Sources",
331c2c66affSColin Finck NULL,
332c2c66affSColin Finck NULL,
333c2c66affSColin Finck (LPBYTE)Buffer,
334c2c66affSColin Finck &dwPathLength);
335c2c66affSColin Finck if (rc != ERROR_SUCCESS)
336c2c66affSColin Finck {
337c2c66affSColin Finck TRACE("RegQueryValueEx() failed with error 0x%lx\n", rc);
338c2c66affSColin Finck goto cleanup;
339c2c66affSColin Finck }
340c2c66affSColin Finck
341c2c66affSColin Finck Buffer[dwPathLength / sizeof(WCHAR)] = UNICODE_NULL;
342c2c66affSColin Finck Buffer[dwPathLength / sizeof(WCHAR) + 1] = UNICODE_NULL;
343c2c66affSColin Finck
344c2c66affSColin Finck /* Populate combo box */
345c2c66affSColin Finck for (Path = Buffer; *Path; Path += wcslen(Path) + 1)
346c2c66affSColin Finck {
347c2c66affSColin Finck (void)ComboBox_AddString(hwndCombo, Path);
348c2c66affSColin Finck if (Path == Buffer)
349c2c66affSColin Finck (void)ComboBox_SetCurSel(hwndCombo, 0);
350c2c66affSColin Finck }
351c2c66affSColin Finck
352c2c66affSColin Finck cleanup:
353c2c66affSColin Finck if (hKey != NULL)
354c2c66affSColin Finck RegCloseKey(hKey);
355c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, Buffer);
356c2c66affSColin Finck }
357c2c66affSColin Finck
358c2c66affSColin Finck static VOID
SaveCustomPath(IN HWND hwndCombo)359c2c66affSColin Finck SaveCustomPath(
360c2c66affSColin Finck IN HWND hwndCombo)
361c2c66affSColin Finck {
362c2c66affSColin Finck LPWSTR CustomPath = NULL;
363c2c66affSColin Finck DWORD CustomPathLength;
364c2c66affSColin Finck LPWSTR Buffer = NULL;
365c2c66affSColin Finck LPWSTR pBuffer; /* Pointer into Buffer */
366c2c66affSColin Finck int ItemsCount, Length;
367c2c66affSColin Finck int i;
368c2c66affSColin Finck DWORD TotalLength = 0;
369c2c66affSColin Finck BOOL UseCustomPath = TRUE;
370c2c66affSColin Finck HKEY hKey = NULL;
371c2c66affSColin Finck LONG rc;
372c2c66affSColin Finck
373c2c66affSColin Finck /* Get custom path */
374c2c66affSColin Finck Length = ComboBox_GetTextLength(hwndCombo) + 1;
375c2c66affSColin Finck CustomPath = HeapAlloc(GetProcessHeap(), 0, Length * sizeof(WCHAR));
376c2c66affSColin Finck if (!CustomPath)
377c2c66affSColin Finck {
378c2c66affSColin Finck TRACE("HeapAlloc() failed\n");
379c2c66affSColin Finck goto cleanup;
380c2c66affSColin Finck }
381c2c66affSColin Finck CustomPathLength = GetWindowTextW(hwndCombo, CustomPath, Length) + 1;
382c2c66affSColin Finck
383c2c66affSColin Finck /* Calculate length of the buffer */
384c2c66affSColin Finck ItemsCount = ComboBox_GetCount(hwndCombo);
385c2c66affSColin Finck if (ItemsCount == CB_ERR)
386c2c66affSColin Finck {
387c2c66affSColin Finck TRACE("ComboBox_GetCount() failed\n");
388c2c66affSColin Finck goto cleanup;
389c2c66affSColin Finck }
390c2c66affSColin Finck for (i = 0; i < ItemsCount; i++)
391c2c66affSColin Finck {
392c2c66affSColin Finck Length = ComboBox_GetLBTextLen(hwndCombo, i);
393c2c66affSColin Finck if (Length == CB_ERR)
394c2c66affSColin Finck {
395c2c66affSColin Finck TRACE("ComboBox_GetLBTextLen() failed\n");
396c2c66affSColin Finck goto cleanup;
397c2c66affSColin Finck }
398c2c66affSColin Finck TotalLength += Length + 1;
399c2c66affSColin Finck }
400c2c66affSColin Finck TotalLength++; /* Final NULL char */
401c2c66affSColin Finck
402c2c66affSColin Finck /* Allocate buffer */
403c2c66affSColin Finck Buffer = HeapAlloc(GetProcessHeap(), 0, (CustomPathLength + TotalLength + 1) * sizeof(WCHAR));
404c2c66affSColin Finck if (!Buffer)
405c2c66affSColin Finck {
406c2c66affSColin Finck TRACE("HeapAlloc() failed\n");
407c2c66affSColin Finck goto cleanup;
408c2c66affSColin Finck }
409c2c66affSColin Finck
410c2c66affSColin Finck /* Fill the buffer */
411c2c66affSColin Finck pBuffer = &Buffer[CustomPathLength];
412c2c66affSColin Finck for (i = 0; i < ItemsCount; i++)
413c2c66affSColin Finck {
414c2c66affSColin Finck Length = ComboBox_GetLBText(hwndCombo, i, pBuffer);
415c2c66affSColin Finck if (Length == CB_ERR)
416c2c66affSColin Finck {
417c2c66affSColin Finck TRACE("ComboBox_GetLBText() failed\n");
418c2c66affSColin Finck goto cleanup;
419c2c66affSColin Finck }
420c2c66affSColin Finck else if (UseCustomPath && _wcsicmp(CustomPath, pBuffer) == 0)
421c2c66affSColin Finck UseCustomPath = FALSE;
422c2c66affSColin Finck pBuffer += 1 + Length;
423c2c66affSColin Finck }
424c2c66affSColin Finck *pBuffer = '\0'; /* Add final NULL char */
425c2c66affSColin Finck
426c2c66affSColin Finck if (!UseCustomPath)
427c2c66affSColin Finck {
428c2c66affSColin Finck /* Nothing to save to registry */
429c2c66affSColin Finck goto cleanup;
430c2c66affSColin Finck }
431c2c66affSColin Finck
432c2c66affSColin Finck TotalLength += CustomPathLength;
433c2c66affSColin Finck wcscpy(Buffer, CustomPath);
434c2c66affSColin Finck
435c2c66affSColin Finck /* Save the buffer */
436c2c66affSColin Finck /* RegSetKeyValue would have been better... */
437c2c66affSColin Finck rc = RegOpenKeyEx(
438c2c66affSColin Finck HKEY_LOCAL_MACHINE,
439c2c66affSColin Finck REGSTR_PATH_SETUP REGSTR_KEY_SETUP,
440c2c66affSColin Finck 0,
441c2c66affSColin Finck KEY_SET_VALUE,
442c2c66affSColin Finck &hKey);
443c2c66affSColin Finck if (rc != ERROR_SUCCESS)
444c2c66affSColin Finck {
445c2c66affSColin Finck TRACE("RegOpenKeyEx() failed with error 0x%lx\n", rc);
446c2c66affSColin Finck goto cleanup;
447c2c66affSColin Finck }
448c2c66affSColin Finck rc = RegSetValueExW(
449c2c66affSColin Finck hKey,
450c2c66affSColin Finck L"Installation Sources",
451c2c66affSColin Finck 0,
452c2c66affSColin Finck REG_MULTI_SZ,
453c2c66affSColin Finck (const BYTE*)Buffer,
454c2c66affSColin Finck TotalLength * sizeof(WCHAR));
455c2c66affSColin Finck if (rc != ERROR_SUCCESS)
456c2c66affSColin Finck {
457c2c66affSColin Finck TRACE("RegSetValueEx() failed with error 0x%lx\n", rc);
458c2c66affSColin Finck goto cleanup;
459c2c66affSColin Finck }
460c2c66affSColin Finck
461c2c66affSColin Finck cleanup:
462c2c66affSColin Finck if (hKey != NULL)
463c2c66affSColin Finck RegCloseKey(hKey);
464c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, CustomPath);
465c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, Buffer);
466c2c66affSColin Finck }
467c2c66affSColin Finck
468c2c66affSColin Finck static INT_PTR CALLBACK
WelcomeDlgProc(IN HWND hwndDlg,IN UINT uMsg,IN WPARAM wParam,IN LPARAM lParam)469c2c66affSColin Finck WelcomeDlgProc(
470c2c66affSColin Finck IN HWND hwndDlg,
471c2c66affSColin Finck IN UINT uMsg,
472c2c66affSColin Finck IN WPARAM wParam,
473c2c66affSColin Finck IN LPARAM lParam)
474c2c66affSColin Finck {
475c2c66affSColin Finck PDEVINSTDATA DevInstData;
476c2c66affSColin Finck UNREFERENCED_PARAMETER(wParam);
477c2c66affSColin Finck
478c2c66affSColin Finck /* Retrieve pointer to the global setup data */
479d281d14fSTimo Kreuzer DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
480c2c66affSColin Finck
481c2c66affSColin Finck switch (uMsg)
482c2c66affSColin Finck {
483c2c66affSColin Finck case WM_INITDIALOG:
484c2c66affSColin Finck {
485c2c66affSColin Finck HWND hwndControl;
486c2c66affSColin Finck DWORD dwStyle;
487c2c66affSColin Finck
488c2c66affSColin Finck /* Get pointer to the global setup data */
489c2c66affSColin Finck DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam;
490d281d14fSTimo Kreuzer SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData);
491c2c66affSColin Finck
492c2c66affSColin Finck hwndControl = GetParent(hwndDlg);
493c2c66affSColin Finck
494c2c66affSColin Finck /* Center the wizard window */
495c2c66affSColin Finck CenterWindow(hwndControl);
496c2c66affSColin Finck
497c2c66affSColin Finck /* Hide the system menu */
498c2c66affSColin Finck dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE);
499c2c66affSColin Finck SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
500c2c66affSColin Finck
501c2c66affSColin Finck /* Set title font */
502c2c66affSColin Finck SendDlgItemMessage(
503c2c66affSColin Finck hwndDlg,
504c2c66affSColin Finck IDC_WELCOMETITLE,
505c2c66affSColin Finck WM_SETFONT,
506c2c66affSColin Finck (WPARAM)DevInstData->hTitleFont,
507c2c66affSColin Finck (LPARAM)TRUE);
508c2c66affSColin Finck
509c2c66affSColin Finck SendDlgItemMessage(
510c2c66affSColin Finck hwndDlg,
511c2c66affSColin Finck IDC_DEVICE,
512c2c66affSColin Finck WM_SETTEXT,
513c2c66affSColin Finck 0,
514c2c66affSColin Finck (LPARAM)DevInstData->buffer);
515c2c66affSColin Finck
516c2c66affSColin Finck SendDlgItemMessage(
517c2c66affSColin Finck hwndDlg,
518c2c66affSColin Finck IDC_RADIO_AUTO,
519c2c66affSColin Finck BM_SETCHECK,
520c2c66affSColin Finck (WPARAM)TRUE,
521c2c66affSColin Finck (LPARAM)0);
522c2c66affSColin Finck
52325019525SOlaf Schmerse if (!DevInstData->bUpdate)
52425019525SOlaf Schmerse {
525c2c66affSColin Finck SetFailedInstall(DevInstData->hDevInfo,
526c2c66affSColin Finck &DevInstData->devInfoData,
527c2c66affSColin Finck TRUE);
52825019525SOlaf Schmerse }
529c2c66affSColin Finck break;
530c2c66affSColin Finck }
531c2c66affSColin Finck
532c2c66affSColin Finck case WM_NOTIFY:
533c2c66affSColin Finck {
534c2c66affSColin Finck LPNMHDR lpnm = (LPNMHDR)lParam;
535c2c66affSColin Finck
536c2c66affSColin Finck switch (lpnm->code)
537c2c66affSColin Finck {
538c2c66affSColin Finck case PSN_SETACTIVE:
539c2c66affSColin Finck /* Enable the Next button */
540c2c66affSColin Finck PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
541c2c66affSColin Finck break;
542c2c66affSColin Finck
543c2c66affSColin Finck case PSN_WIZNEXT:
544c2c66affSColin Finck /* Handle a Next button click, if necessary */
545c2c66affSColin Finck if (SendDlgItemMessage(hwndDlg, IDC_RADIO_AUTO, BM_GETCHECK, (WPARAM)0, (LPARAM)0) == BST_CHECKED)
546c2c66affSColin Finck {
547c2c66affSColin Finck if (PrepareFoldersToScan(DevInstData, TRUE, FALSE, NULL))
548c2c66affSColin Finck PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_SEARCHDRV);
549c2c66affSColin Finck else
550c2c66affSColin Finck PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLFAILED);
551c2c66affSColin Finck }
552c2c66affSColin Finck return TRUE;
553c2c66affSColin Finck
554c2c66affSColin Finck default:
555c2c66affSColin Finck break;
556c2c66affSColin Finck }
557c2c66affSColin Finck break;
558c2c66affSColin Finck }
559c2c66affSColin Finck
560c2c66affSColin Finck default:
561c2c66affSColin Finck break;
562c2c66affSColin Finck }
563c2c66affSColin Finck
564c2c66affSColin Finck return FALSE;
565c2c66affSColin Finck }
566c2c66affSColin Finck
567c2c66affSColin Finck static void
IncludePath(HWND Dlg,BOOL Enabled)568c2c66affSColin Finck IncludePath(HWND Dlg, BOOL Enabled)
569c2c66affSColin Finck {
570c2c66affSColin Finck EnableWindow(GetDlgItem(Dlg, IDC_COMBO_PATH), Enabled);
571c2c66affSColin Finck EnableWindow(GetDlgItem(Dlg, IDC_BROWSE), Enabled);
572c2c66affSColin Finck }
573c2c66affSColin Finck
574c2c66affSColin Finck static void
AutoDriver(HWND Dlg,BOOL Enabled)575c2c66affSColin Finck AutoDriver(HWND Dlg, BOOL Enabled)
576c2c66affSColin Finck {
577c2c66affSColin Finck EnableWindow(GetDlgItem(Dlg, IDC_CHECK_MEDIA), Enabled);
578c2c66affSColin Finck EnableWindow(GetDlgItem(Dlg, IDC_CHECK_PATH), Enabled);
579c2c66affSColin Finck IncludePath(Dlg, Enabled & IsDlgButtonChecked(Dlg, IDC_CHECK_PATH));
580c2c66affSColin Finck }
581c2c66affSColin Finck
582*45c8e4dcSJose Carlos Jesus static INT CALLBACK
BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM lpData)583*45c8e4dcSJose Carlos Jesus BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
584*45c8e4dcSJose Carlos Jesus {
585*45c8e4dcSJose Carlos Jesus BOOL bValid = FALSE;
586*45c8e4dcSJose Carlos Jesus
587*45c8e4dcSJose Carlos Jesus switch (uMsg)
588*45c8e4dcSJose Carlos Jesus {
589*45c8e4dcSJose Carlos Jesus case BFFM_INITIALIZED:
590*45c8e4dcSJose Carlos Jesus {
591*45c8e4dcSJose Carlos Jesus PCWSTR pszPath = ((PDEVINSTDATA)lpData)->CustomSearchPath;
592*45c8e4dcSJose Carlos Jesus
593*45c8e4dcSJose Carlos Jesus bValid = CheckBestDriver((PDEVINSTDATA)lpData, pszPath);
594*45c8e4dcSJose Carlos Jesus SendMessageW(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)pszPath);
595*45c8e4dcSJose Carlos Jesus SendMessageW(hwnd, BFFM_ENABLEOK, 0, bValid);
596*45c8e4dcSJose Carlos Jesus break;
597*45c8e4dcSJose Carlos Jesus }
598*45c8e4dcSJose Carlos Jesus
599*45c8e4dcSJose Carlos Jesus case BFFM_SELCHANGED:
600*45c8e4dcSJose Carlos Jesus {
601*45c8e4dcSJose Carlos Jesus WCHAR szDir[MAX_PATH];
602*45c8e4dcSJose Carlos Jesus
603*45c8e4dcSJose Carlos Jesus if (SHGetPathFromIDListW((LPITEMIDLIST)lParam, szDir))
604*45c8e4dcSJose Carlos Jesus {
605*45c8e4dcSJose Carlos Jesus bValid = CheckBestDriver((PDEVINSTDATA)lpData, szDir);
606*45c8e4dcSJose Carlos Jesus }
607*45c8e4dcSJose Carlos Jesus PostMessageW(hwnd, BFFM_ENABLEOK, 0, bValid);
608*45c8e4dcSJose Carlos Jesus break;
609*45c8e4dcSJose Carlos Jesus }
610*45c8e4dcSJose Carlos Jesus }
611*45c8e4dcSJose Carlos Jesus return 0;
612*45c8e4dcSJose Carlos Jesus }
613*45c8e4dcSJose Carlos Jesus
614c2c66affSColin Finck static INT_PTR CALLBACK
CHSourceDlgProc(IN HWND hwndDlg,IN UINT uMsg,IN WPARAM wParam,IN LPARAM lParam)615c2c66affSColin Finck CHSourceDlgProc(
616c2c66affSColin Finck IN HWND hwndDlg,
617c2c66affSColin Finck IN UINT uMsg,
618c2c66affSColin Finck IN WPARAM wParam,
619c2c66affSColin Finck IN LPARAM lParam)
620c2c66affSColin Finck {
621c2c66affSColin Finck PDEVINSTDATA DevInstData;
622c2c66affSColin Finck
623c2c66affSColin Finck /* Retrieve pointer to the global setup data */
624d281d14fSTimo Kreuzer DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
625c2c66affSColin Finck
626c2c66affSColin Finck switch (uMsg)
627c2c66affSColin Finck {
628c2c66affSColin Finck case WM_INITDIALOG:
629c2c66affSColin Finck {
63062b13979SKatayama Hirofumi MZ HWND hwndControl, hwndCombo;
631c2c66affSColin Finck DWORD dwStyle;
63262b13979SKatayama Hirofumi MZ COMBOBOXINFO info = { sizeof(info) };
633c2c66affSColin Finck
634c2c66affSColin Finck /* Get pointer to the global setup data */
635c2c66affSColin Finck DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam;
636d281d14fSTimo Kreuzer SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData);
637c2c66affSColin Finck
638c2c66affSColin Finck hwndControl = GetParent(hwndDlg);
639c2c66affSColin Finck
640c2c66affSColin Finck /* Center the wizard window */
641c2c66affSColin Finck CenterWindow(hwndControl);
642c2c66affSColin Finck
643c2c66affSColin Finck /* Hide the system menu */
644c2c66affSColin Finck dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE);
645c2c66affSColin Finck SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
646c2c66affSColin Finck
64762b13979SKatayama Hirofumi MZ hwndCombo = GetDlgItem(hwndDlg, IDC_COMBO_PATH);
64862b13979SKatayama Hirofumi MZ PopulateCustomPathCombo(hwndCombo);
64962b13979SKatayama Hirofumi MZ
65062b13979SKatayama Hirofumi MZ GetComboBoxInfo(hwndCombo, &info);
65162b13979SKatayama Hirofumi MZ SHAutoComplete(info.hwndItem, SHACF_FILESYS_DIRS);
652c2c66affSColin Finck
653c2c66affSColin Finck SendDlgItemMessage(
654c2c66affSColin Finck hwndDlg,
655c2c66affSColin Finck IDC_RADIO_SEARCHHERE,
656c2c66affSColin Finck BM_SETCHECK,
657c2c66affSColin Finck (WPARAM)TRUE,
658c2c66affSColin Finck (LPARAM)0);
659c2c66affSColin Finck AutoDriver(hwndDlg, TRUE);
660c2c66affSColin Finck IncludePath(hwndDlg, FALSE);
661c2c66affSColin Finck
662c2c66affSColin Finck /* Disable manual driver choice for now */
663c2c66affSColin Finck EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_CHOOSE), FALSE);
664c2c66affSColin Finck
665c2c66affSColin Finck break;
666c2c66affSColin Finck }
667c2c66affSColin Finck
668c2c66affSColin Finck case WM_COMMAND:
669c2c66affSColin Finck {
670c2c66affSColin Finck switch (LOWORD(wParam))
671c2c66affSColin Finck {
672c2c66affSColin Finck case IDC_RADIO_SEARCHHERE:
673c2c66affSColin Finck AutoDriver(hwndDlg, TRUE);
674c2c66affSColin Finck return TRUE;
675c2c66affSColin Finck
676c2c66affSColin Finck case IDC_RADIO_CHOOSE:
677c2c66affSColin Finck AutoDriver(hwndDlg, FALSE);
678c2c66affSColin Finck return TRUE;
679c2c66affSColin Finck
680c2c66affSColin Finck case IDC_CHECK_PATH:
681c2c66affSColin Finck IncludePath(hwndDlg, IsDlgButtonChecked(hwndDlg, IDC_CHECK_PATH));
682c2c66affSColin Finck return TRUE;
683c2c66affSColin Finck
684c2c66affSColin Finck case IDC_BROWSE:
685c2c66affSColin Finck {
686*45c8e4dcSJose Carlos Jesus BROWSEINFOW bi = { 0 };
687c2c66affSColin Finck LPITEMIDLIST pidl;
6885165179aSJose Carlos Jesus WCHAR Title[MAX_PATH];
689*45c8e4dcSJose Carlos Jesus WCHAR CustomSearchPath[MAX_PATH] = { 0 };
690*45c8e4dcSJose Carlos Jesus INT len, idx = (INT)SendDlgItemMessageW(hwndDlg, IDC_COMBO_PATH, CB_GETCURSEL, 0, 0);
6915165179aSJose Carlos Jesus LoadStringW(hDllInstance, IDS_BROWSE_FOR_FOLDER_TITLE, Title, _countof(Title));
692c2c66affSColin Finck
693*45c8e4dcSJose Carlos Jesus if (idx == CB_ERR)
694*45c8e4dcSJose Carlos Jesus len = GetWindowTextLengthW(GetDlgItem(hwndDlg, IDC_COMBO_PATH));
695*45c8e4dcSJose Carlos Jesus else
696*45c8e4dcSJose Carlos Jesus len = (INT)SendDlgItemMessageW(hwndDlg, IDC_COMBO_PATH, CB_GETLBTEXTLEN, idx, 0);
697*45c8e4dcSJose Carlos Jesus
698*45c8e4dcSJose Carlos Jesus if (len < _countof(CustomSearchPath))
699*45c8e4dcSJose Carlos Jesus {
700*45c8e4dcSJose Carlos Jesus if (idx == CB_ERR)
701*45c8e4dcSJose Carlos Jesus GetWindowTextW(GetDlgItem(hwndDlg, IDC_COMBO_PATH), CustomSearchPath, _countof(CustomSearchPath));
702*45c8e4dcSJose Carlos Jesus else
703*45c8e4dcSJose Carlos Jesus SendDlgItemMessageW(hwndDlg, IDC_COMBO_PATH, CB_GETLBTEXT, idx, (LPARAM)CustomSearchPath);
704*45c8e4dcSJose Carlos Jesus }
705*45c8e4dcSJose Carlos Jesus DevInstData->CustomSearchPath = CustomSearchPath;
706*45c8e4dcSJose Carlos Jesus
707c2c66affSColin Finck bi.hwndOwner = hwndDlg;
7085165179aSJose Carlos Jesus bi.ulFlags = BIF_USENEWUI | BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NONEWFOLDERBUTTON;
7095165179aSJose Carlos Jesus bi.lpszTitle = Title;
710*45c8e4dcSJose Carlos Jesus bi.lpfn = BrowseCallbackProc;
711*45c8e4dcSJose Carlos Jesus bi.lParam = (LPARAM)DevInstData;
712*45c8e4dcSJose Carlos Jesus pidl = SHBrowseForFolderW(&bi);
713c2c66affSColin Finck if (pidl)
714c2c66affSColin Finck {
715c2c66affSColin Finck WCHAR Directory[MAX_PATH];
716c2c66affSColin Finck IMalloc* malloc;
717c2c66affSColin Finck
718c2c66affSColin Finck if (SHGetPathFromIDListW(pidl, Directory))
719c2c66affSColin Finck {
720c2c66affSColin Finck /* Set the IDC_COMBO_PATH text */
721c2c66affSColin Finck SetWindowTextW(GetDlgItem(hwndDlg, IDC_COMBO_PATH), Directory);
722c2c66affSColin Finck }
723c2c66affSColin Finck
724c2c66affSColin Finck /* Free memory, if possible */
725c2c66affSColin Finck if (SUCCEEDED(SHGetMalloc(&malloc)))
726c2c66affSColin Finck {
727c2c66affSColin Finck IMalloc_Free(malloc, pidl);
728c2c66affSColin Finck IMalloc_Release(malloc);
729c2c66affSColin Finck }
730c2c66affSColin Finck return TRUE;
731c2c66affSColin Finck }
732c2c66affSColin Finck break;
733c2c66affSColin Finck }
734c2c66affSColin Finck }
735c2c66affSColin Finck break;
736c2c66affSColin Finck }
737c2c66affSColin Finck
738c2c66affSColin Finck case WM_NOTIFY:
739c2c66affSColin Finck {
740c2c66affSColin Finck LPNMHDR lpnm = (LPNMHDR)lParam;
741c2c66affSColin Finck
742c2c66affSColin Finck switch (lpnm->code)
743c2c66affSColin Finck {
744c2c66affSColin Finck case PSN_SETACTIVE:
745c2c66affSColin Finck /* Enable the Next and Back buttons */
746c2c66affSColin Finck PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK);
747c2c66affSColin Finck break;
748c2c66affSColin Finck
749c2c66affSColin Finck case PSN_WIZNEXT:
750c2c66affSColin Finck /* Handle a Next button click, if necessary */
751c2c66affSColin Finck if (IsDlgButtonChecked(hwndDlg, IDC_RADIO_SEARCHHERE))
752c2c66affSColin Finck {
753c2c66affSColin Finck SaveCustomPath(GetDlgItem(hwndDlg, IDC_COMBO_PATH));
754c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, DevInstData->CustomSearchPath);
755c2c66affSColin Finck DevInstData->CustomSearchPath = NULL;
756c2c66affSColin Finck if (PrepareFoldersToScan(
757c2c66affSColin Finck DevInstData,
758c2c66affSColin Finck IsDlgButtonChecked(hwndDlg, IDC_CHECK_MEDIA),
759c2c66affSColin Finck IsDlgButtonChecked(hwndDlg, IDC_CHECK_PATH),
760c2c66affSColin Finck GetDlgItem(hwndDlg, IDC_COMBO_PATH)))
761c2c66affSColin Finck {
762c2c66affSColin Finck PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_SEARCHDRV);
763c2c66affSColin Finck }
764c2c66affSColin Finck else
765c2c66affSColin Finck {
766c2c66affSColin Finck PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLFAILED);
767c2c66affSColin Finck }
768c2c66affSColin Finck }
769c2c66affSColin Finck else
770c2c66affSColin Finck {
771c2c66affSColin Finck /* FIXME */;
772c2c66affSColin Finck }
773c2c66affSColin Finck return TRUE;
774c2c66affSColin Finck
775c2c66affSColin Finck default:
776c2c66affSColin Finck break;
777c2c66affSColin Finck }
778c2c66affSColin Finck break;
779c2c66affSColin Finck }
780c2c66affSColin Finck
781c2c66affSColin Finck default:
782c2c66affSColin Finck break;
783c2c66affSColin Finck }
784c2c66affSColin Finck
785c2c66affSColin Finck return FALSE;
786c2c66affSColin Finck }
787c2c66affSColin Finck
788c2c66affSColin Finck static INT_PTR CALLBACK
SearchDrvDlgProc(IN HWND hwndDlg,IN UINT uMsg,IN WPARAM wParam,IN LPARAM lParam)789c2c66affSColin Finck SearchDrvDlgProc(
790c2c66affSColin Finck IN HWND hwndDlg,
791c2c66affSColin Finck IN UINT uMsg,
792c2c66affSColin Finck IN WPARAM wParam,
793c2c66affSColin Finck IN LPARAM lParam)
794c2c66affSColin Finck {
795c2c66affSColin Finck PDEVINSTDATA DevInstData;
796c2c66affSColin Finck DWORD dwThreadId;
797c2c66affSColin Finck
798c2c66affSColin Finck /* Retrieve pointer to the global setup data */
799d281d14fSTimo Kreuzer DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
800c2c66affSColin Finck
801c2c66affSColin Finck switch (uMsg)
802c2c66affSColin Finck {
803c2c66affSColin Finck case WM_INITDIALOG:
804c2c66affSColin Finck {
805c2c66affSColin Finck HWND hwndControl;
806c2c66affSColin Finck DWORD dwStyle;
807c2c66affSColin Finck
808c2c66affSColin Finck /* Get pointer to the global setup data */
809c2c66affSColin Finck DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam;
810d281d14fSTimo Kreuzer SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData);
811c2c66affSColin Finck
812c2c66affSColin Finck DevInstData->hDialog = hwndDlg;
813c2c66affSColin Finck hwndControl = GetParent(hwndDlg);
814c2c66affSColin Finck
815c2c66affSColin Finck /* Center the wizard window */
816c2c66affSColin Finck CenterWindow(hwndControl);
817c2c66affSColin Finck
818c2c66affSColin Finck SendDlgItemMessage(
819c2c66affSColin Finck hwndDlg,
820c2c66affSColin Finck IDC_DEVICE,
821c2c66affSColin Finck WM_SETTEXT,
822c2c66affSColin Finck 0,
823c2c66affSColin Finck (LPARAM)DevInstData->buffer);
824c2c66affSColin Finck
825c2c66affSColin Finck /* Hide the system menu */
826c2c66affSColin Finck dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE);
827c2c66affSColin Finck SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
828c2c66affSColin Finck break;
829c2c66affSColin Finck }
830c2c66affSColin Finck
831c2c66affSColin Finck case WM_SEARCH_FINISHED:
832c2c66affSColin Finck {
833c2c66affSColin Finck CloseHandle(hThread);
834c2c66affSColin Finck hThread = 0;
835c2c66affSColin Finck if (wParam == 0)
836c2c66affSColin Finck PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_NODRIVER);
837c2c66affSColin Finck else
838c2c66affSColin Finck PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLDRV);
839c2c66affSColin Finck break;
840c2c66affSColin Finck }
841c2c66affSColin Finck
842c2c66affSColin Finck case WM_NOTIFY:
843c2c66affSColin Finck {
844c2c66affSColin Finck LPNMHDR lpnm = (LPNMHDR)lParam;
845c2c66affSColin Finck
846c2c66affSColin Finck switch (lpnm->code)
847c2c66affSColin Finck {
848c2c66affSColin Finck case PSN_SETACTIVE:
849c2c66affSColin Finck PropSheet_SetWizButtons(GetParent(hwndDlg), !PSWIZB_NEXT | !PSWIZB_BACK);
850c2c66affSColin Finck /* Yes, we can safely ignore the problem (if any) */
851c2c66affSColin Finck SetupDiDestroyDriverInfoList(
852c2c66affSColin Finck DevInstData->hDevInfo,
853c2c66affSColin Finck &DevInstData->devInfoData,
854c2c66affSColin Finck SPDIT_COMPATDRIVER);
855c2c66affSColin Finck hThread = CreateThread(NULL, 0, FindDriverProc, DevInstData, 0, &dwThreadId);
856c2c66affSColin Finck break;
857c2c66affSColin Finck
858c2c66affSColin Finck case PSN_KILLACTIVE:
859c2c66affSColin Finck if (hThread != 0)
860c2c66affSColin Finck {
8610182dcd7STimo Kreuzer SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
862c2c66affSColin Finck return TRUE;
863c2c66affSColin Finck }
864c2c66affSColin Finck break;
865c2c66affSColin Finck
866c2c66affSColin Finck case PSN_WIZNEXT:
867c2c66affSColin Finck /* Handle a Next button click, if necessary */
868c2c66affSColin Finck break;
869c2c66affSColin Finck
870c2c66affSColin Finck default:
871c2c66affSColin Finck break;
872c2c66affSColin Finck }
873c2c66affSColin Finck break;
874c2c66affSColin Finck }
875c2c66affSColin Finck
876c2c66affSColin Finck default:
877c2c66affSColin Finck break;
878c2c66affSColin Finck }
879c2c66affSColin Finck
880c2c66affSColin Finck return FALSE;
881c2c66affSColin Finck }
882c2c66affSColin Finck
883c2c66affSColin Finck static INT_PTR CALLBACK
InstallDrvDlgProc(IN HWND hwndDlg,IN UINT uMsg,IN WPARAM wParam,IN LPARAM lParam)884c2c66affSColin Finck InstallDrvDlgProc(
885c2c66affSColin Finck IN HWND hwndDlg,
886c2c66affSColin Finck IN UINT uMsg,
887c2c66affSColin Finck IN WPARAM wParam,
888c2c66affSColin Finck IN LPARAM lParam)
889c2c66affSColin Finck {
890c2c66affSColin Finck PDEVINSTDATA DevInstData;
891c2c66affSColin Finck DWORD dwThreadId;
892c2c66affSColin Finck
893c2c66affSColin Finck /* Retrieve pointer to the global setup data */
894d281d14fSTimo Kreuzer DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
895c2c66affSColin Finck
896c2c66affSColin Finck switch (uMsg)
897c2c66affSColin Finck {
898c2c66affSColin Finck case WM_INITDIALOG:
899c2c66affSColin Finck {
900c2c66affSColin Finck HWND hwndControl;
901c2c66affSColin Finck DWORD dwStyle;
902c2c66affSColin Finck
903c2c66affSColin Finck /* Get pointer to the global setup data */
904c2c66affSColin Finck DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam;
905d281d14fSTimo Kreuzer SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData);
906c2c66affSColin Finck
907c2c66affSColin Finck DevInstData->hDialog = hwndDlg;
908c2c66affSColin Finck hwndControl = GetParent(hwndDlg);
909c2c66affSColin Finck
910c2c66affSColin Finck /* Center the wizard window */
911c2c66affSColin Finck CenterWindow(hwndControl);
912c2c66affSColin Finck
913c2c66affSColin Finck SendDlgItemMessage(
914c2c66affSColin Finck hwndDlg,
915c2c66affSColin Finck IDC_DEVICE,
916c2c66affSColin Finck WM_SETTEXT,
917c2c66affSColin Finck 0,
918c2c66affSColin Finck (LPARAM)DevInstData->drvInfoData.Description);
919c2c66affSColin Finck
920c2c66affSColin Finck /* Hide the system menu */
921c2c66affSColin Finck dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE);
922c2c66affSColin Finck SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
923c2c66affSColin Finck break;
924c2c66affSColin Finck }
925c2c66affSColin Finck
926c2c66affSColin Finck case WM_INSTALL_FINISHED:
927c2c66affSColin Finck {
928c2c66affSColin Finck CloseHandle(hThread);
929c2c66affSColin Finck hThread = 0;
930c2c66affSColin Finck if (wParam == 0)
931c2c66affSColin Finck {
932c2c66affSColin Finck SP_DEVINSTALL_PARAMS installParams;
933c2c66affSColin Finck
934c2c66affSColin Finck SetFailedInstall(DevInstData->hDevInfo,
935c2c66affSColin Finck &DevInstData->devInfoData,
936c2c66affSColin Finck FALSE);
937c2c66affSColin Finck
938c2c66affSColin Finck /* Should we reboot? */
939c2c66affSColin Finck installParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
940c2c66affSColin Finck if (SetupDiGetDeviceInstallParams(
941c2c66affSColin Finck DevInstData->hDevInfo,
942c2c66affSColin Finck &DevInstData->devInfoData,
943c2c66affSColin Finck &installParams))
944c2c66affSColin Finck {
945c2c66affSColin Finck if (installParams.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT))
946c2c66affSColin Finck {
947c2c66affSColin Finck PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_NEEDREBOOT);
948c2c66affSColin Finck }
949c2c66affSColin Finck else
950c2c66affSColin Finck PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_FINISHPAGE);
951c2c66affSColin Finck break;
952c2c66affSColin Finck }
953c2c66affSColin Finck }
954c2c66affSColin Finck PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLFAILED);
955c2c66affSColin Finck break;
956c2c66affSColin Finck }
957c2c66affSColin Finck
958c2c66affSColin Finck case WM_NOTIFY:
959c2c66affSColin Finck {
960c2c66affSColin Finck LPNMHDR lpnm = (LPNMHDR)lParam;
961c2c66affSColin Finck
962c2c66affSColin Finck switch (lpnm->code)
963c2c66affSColin Finck {
964c2c66affSColin Finck case PSN_SETACTIVE:
965c2c66affSColin Finck PropSheet_SetWizButtons(GetParent(hwndDlg), !PSWIZB_NEXT | !PSWIZB_BACK);
966c2c66affSColin Finck hThread = CreateThread(NULL, 0, InstallDriverProc, DevInstData, 0, &dwThreadId);
967c2c66affSColin Finck break;
968c2c66affSColin Finck
969c2c66affSColin Finck case PSN_KILLACTIVE:
970c2c66affSColin Finck if (hThread != 0)
971c2c66affSColin Finck {
9720182dcd7STimo Kreuzer SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
973c2c66affSColin Finck return TRUE;
974c2c66affSColin Finck }
975c2c66affSColin Finck break;
976c2c66affSColin Finck
977c2c66affSColin Finck case PSN_WIZNEXT:
978c2c66affSColin Finck /* Handle a Next button click, if necessary */
979c2c66affSColin Finck break;
980c2c66affSColin Finck
981c2c66affSColin Finck default:
982c2c66affSColin Finck break;
983c2c66affSColin Finck }
984c2c66affSColin Finck break;
985c2c66affSColin Finck }
986c2c66affSColin Finck
987c2c66affSColin Finck default:
988c2c66affSColin Finck break;
989c2c66affSColin Finck }
990c2c66affSColin Finck
991c2c66affSColin Finck return FALSE;
992c2c66affSColin Finck }
993c2c66affSColin Finck
994c2c66affSColin Finck static INT_PTR CALLBACK
NoDriverDlgProc(IN HWND hwndDlg,IN UINT uMsg,IN WPARAM wParam,IN LPARAM lParam)995c2c66affSColin Finck NoDriverDlgProc(
996c2c66affSColin Finck IN HWND hwndDlg,
997c2c66affSColin Finck IN UINT uMsg,
998c2c66affSColin Finck IN WPARAM wParam,
999c2c66affSColin Finck IN LPARAM lParam)
1000c2c66affSColin Finck {
1001c2c66affSColin Finck PDEVINSTDATA DevInstData;
1002c2c66affSColin Finck HWND hwndControl;
1003c2c66affSColin Finck
1004c2c66affSColin Finck UNREFERENCED_PARAMETER(wParam);
1005c2c66affSColin Finck
1006c2c66affSColin Finck /* Get pointer to the global setup data */
1007d281d14fSTimo Kreuzer DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
1008c2c66affSColin Finck
1009c2c66affSColin Finck switch (uMsg)
1010c2c66affSColin Finck {
1011c2c66affSColin Finck case WM_INITDIALOG:
1012c2c66affSColin Finck {
1013c2c66affSColin Finck BOOL DisableableDevice = FALSE;
1014c2c66affSColin Finck
1015c2c66affSColin Finck /* Get pointer to the global setup data */
1016c2c66affSColin Finck DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam;
1017d281d14fSTimo Kreuzer SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData);
1018c2c66affSColin Finck
1019c2c66affSColin Finck /* Center the wizard window */
1020c2c66affSColin Finck CenterWindow(GetParent(hwndDlg));
1021c2c66affSColin Finck
1022c2c66affSColin Finck hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL);
1023c2c66affSColin Finck ShowWindow(hwndControl, SW_HIDE);
1024c2c66affSColin Finck EnableWindow(hwndControl, FALSE);
1025c2c66affSColin Finck
1026c2c66affSColin Finck /* Set title font */
1027c2c66affSColin Finck SendDlgItemMessage(
1028c2c66affSColin Finck hwndDlg,
1029c2c66affSColin Finck IDC_FINISHTITLE,
1030c2c66affSColin Finck WM_SETFONT,
1031c2c66affSColin Finck (WPARAM)DevInstData->hTitleFont,
1032c2c66affSColin Finck (LPARAM)TRUE);
1033c2c66affSColin Finck
1034c2c66affSColin Finck /* disable the "do not show this dialog anymore" checkbox
1035c2c66affSColin Finck if the device cannot be disabled */
1036c2c66affSColin Finck CanDisableDevice(
1037c2c66affSColin Finck DevInstData->devInfoData.DevInst,
1038c2c66affSColin Finck NULL,
1039c2c66affSColin Finck &DisableableDevice);
1040c2c66affSColin Finck EnableWindow(
1041c2c66affSColin Finck GetDlgItem(hwndDlg, IDC_DONOTSHOWDLG),
1042c2c66affSColin Finck DisableableDevice);
1043c2c66affSColin Finck break;
1044c2c66affSColin Finck }
1045c2c66affSColin Finck
1046c2c66affSColin Finck case WM_NOTIFY:
1047c2c66affSColin Finck {
1048c2c66affSColin Finck LPNMHDR lpnm = (LPNMHDR)lParam;
1049c2c66affSColin Finck
1050c2c66affSColin Finck switch (lpnm->code)
1051c2c66affSColin Finck {
1052c2c66affSColin Finck case PSN_SETACTIVE:
1053c2c66affSColin Finck /* Enable the correct buttons on for the active page */
1054c2c66affSColin Finck PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_FINISH);
1055c2c66affSColin Finck break;
1056c2c66affSColin Finck
1057c2c66affSColin Finck case PSN_WIZBACK:
1058c2c66affSColin Finck /* Handle a Back button click, if necessary */
1059c2c66affSColin Finck hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL);
1060c2c66affSColin Finck ShowWindow(hwndControl, SW_SHOW);
1061c2c66affSColin Finck EnableWindow(hwndControl, TRUE);
1062c2c66affSColin Finck PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_CHSOURCE);
1063c2c66affSColin Finck return TRUE;
1064c2c66affSColin Finck
1065c2c66affSColin Finck case PSN_WIZFINISH:
1066c2c66affSColin Finck {
1067c2c66affSColin Finck BOOL DisableableDevice = FALSE;
1068c2c66affSColin Finck BOOL IsStarted = FALSE;
1069c2c66affSColin Finck
1070c2c66affSColin Finck if (CanDisableDevice(DevInstData->devInfoData.DevInst,
1071c2c66affSColin Finck NULL,
1072c2c66affSColin Finck &DisableableDevice) &&
1073c2c66affSColin Finck DisableableDevice &&
1074c2c66affSColin Finck IsDeviceStarted(
1075c2c66affSColin Finck DevInstData->devInfoData.DevInst,
1076c2c66affSColin Finck NULL,
1077c2c66affSColin Finck &IsStarted) &&
1078c2c66affSColin Finck !IsStarted &&
1079c2c66affSColin Finck SendDlgItemMessage(
1080c2c66affSColin Finck hwndDlg,
1081c2c66affSColin Finck IDC_DONOTSHOWDLG,
1082c2c66affSColin Finck BM_GETCHECK,
1083c2c66affSColin Finck (WPARAM)0, (LPARAM)0) == BST_CHECKED)
1084c2c66affSColin Finck {
1085c2c66affSColin Finck /* disable the device */
1086c2c66affSColin Finck StartDevice(
1087c2c66affSColin Finck DevInstData->hDevInfo,
1088c2c66affSColin Finck &DevInstData->devInfoData,
1089c2c66affSColin Finck FALSE,
1090c2c66affSColin Finck 0,
1091c2c66affSColin Finck NULL);
1092c2c66affSColin Finck }
1093c2c66affSColin Finck else
1094c2c66affSColin Finck {
1095c2c66affSColin Finck SetFailedInstall(DevInstData->hDevInfo,
1096c2c66affSColin Finck &DevInstData->devInfoData,
1097c2c66affSColin Finck FALSE);
1098c2c66affSColin Finck }
1099c2c66affSColin Finck break;
1100c2c66affSColin Finck }
1101c2c66affSColin Finck
1102c2c66affSColin Finck default:
1103c2c66affSColin Finck break;
1104c2c66affSColin Finck }
1105c2c66affSColin Finck break;
1106c2c66affSColin Finck }
1107c2c66affSColin Finck
1108c2c66affSColin Finck default:
1109c2c66affSColin Finck break;
1110c2c66affSColin Finck }
1111c2c66affSColin Finck
1112c2c66affSColin Finck return FALSE;
1113c2c66affSColin Finck }
1114c2c66affSColin Finck
1115c2c66affSColin Finck static INT_PTR CALLBACK
InstallFailedDlgProc(IN HWND hwndDlg,IN UINT uMsg,IN WPARAM wParam,IN LPARAM lParam)1116c2c66affSColin Finck InstallFailedDlgProc(
1117c2c66affSColin Finck IN HWND hwndDlg,
1118c2c66affSColin Finck IN UINT uMsg,
1119c2c66affSColin Finck IN WPARAM wParam,
1120c2c66affSColin Finck IN LPARAM lParam)
1121c2c66affSColin Finck {
1122c2c66affSColin Finck PDEVINSTDATA DevInstData;
1123c2c66affSColin Finck UNREFERENCED_PARAMETER(wParam);
1124c2c66affSColin Finck
1125c2c66affSColin Finck /* Retrieve pointer to the global setup data */
1126d281d14fSTimo Kreuzer DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
1127c2c66affSColin Finck
1128c2c66affSColin Finck switch (uMsg)
1129c2c66affSColin Finck {
1130c2c66affSColin Finck case WM_INITDIALOG:
1131c2c66affSColin Finck {
1132c2c66affSColin Finck HWND hwndControl;
1133c2c66affSColin Finck
1134c2c66affSColin Finck /* Get pointer to the global setup data */
1135c2c66affSColin Finck DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam;
1136d281d14fSTimo Kreuzer SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData);
1137c2c66affSColin Finck
1138c2c66affSColin Finck /* Center the wizard window */
1139c2c66affSColin Finck CenterWindow(GetParent(hwndDlg));
1140c2c66affSColin Finck
1141c2c66affSColin Finck hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL);
1142c2c66affSColin Finck ShowWindow(hwndControl, SW_HIDE);
1143c2c66affSColin Finck EnableWindow(hwndControl, FALSE);
1144c2c66affSColin Finck
1145c2c66affSColin Finck SendDlgItemMessage(
1146c2c66affSColin Finck hwndDlg,
1147c2c66affSColin Finck IDC_DEVICE,
1148c2c66affSColin Finck WM_SETTEXT,
1149c2c66affSColin Finck 0,
1150c2c66affSColin Finck (LPARAM)DevInstData->drvInfoData.Description);
1151c2c66affSColin Finck
1152c2c66affSColin Finck /* Set title font */
1153c2c66affSColin Finck SendDlgItemMessage(
1154c2c66affSColin Finck hwndDlg,
1155c2c66affSColin Finck IDC_FINISHTITLE,
1156c2c66affSColin Finck WM_SETFONT,
1157c2c66affSColin Finck (WPARAM)DevInstData->hTitleFont,
1158c2c66affSColin Finck (LPARAM)TRUE);
1159c2c66affSColin Finck break;
1160c2c66affSColin Finck }
1161c2c66affSColin Finck
1162c2c66affSColin Finck case WM_NOTIFY:
1163c2c66affSColin Finck {
1164c2c66affSColin Finck LPNMHDR lpnm = (LPNMHDR)lParam;
1165c2c66affSColin Finck
1166c2c66affSColin Finck switch (lpnm->code)
1167c2c66affSColin Finck {
1168c2c66affSColin Finck case PSN_SETACTIVE:
1169c2c66affSColin Finck /* Enable the correct buttons on for the active page */
1170c2c66affSColin Finck PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH);
1171c2c66affSColin Finck break;
1172c2c66affSColin Finck
1173c2c66affSColin Finck case PSN_WIZBACK:
1174c2c66affSColin Finck /* Handle a Back button click, if necessary */
1175c2c66affSColin Finck break;
1176c2c66affSColin Finck
1177c2c66affSColin Finck case PSN_WIZFINISH:
1178c2c66affSColin Finck /* Handle a Finish button click, if necessary */
1179c2c66affSColin Finck break;
1180c2c66affSColin Finck
1181c2c66affSColin Finck default:
1182c2c66affSColin Finck break;
1183c2c66affSColin Finck }
1184c2c66affSColin Finck break;
1185c2c66affSColin Finck }
1186c2c66affSColin Finck
1187c2c66affSColin Finck default:
1188c2c66affSColin Finck break;
1189c2c66affSColin Finck }
1190c2c66affSColin Finck
1191c2c66affSColin Finck return FALSE;
1192c2c66affSColin Finck }
1193c2c66affSColin Finck
1194c2c66affSColin Finck static INT_PTR CALLBACK
NeedRebootDlgProc(IN HWND hwndDlg,IN UINT uMsg,IN WPARAM wParam,IN LPARAM lParam)1195c2c66affSColin Finck NeedRebootDlgProc(
1196c2c66affSColin Finck IN HWND hwndDlg,
1197c2c66affSColin Finck IN UINT uMsg,
1198c2c66affSColin Finck IN WPARAM wParam,
1199c2c66affSColin Finck IN LPARAM lParam)
1200c2c66affSColin Finck {
1201c2c66affSColin Finck PDEVINSTDATA DevInstData;
1202c2c66affSColin Finck UNREFERENCED_PARAMETER(wParam);
1203c2c66affSColin Finck
1204c2c66affSColin Finck /* Retrieve pointer to the global setup data */
1205d281d14fSTimo Kreuzer DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
1206c2c66affSColin Finck
1207c2c66affSColin Finck switch (uMsg)
1208c2c66affSColin Finck {
1209c2c66affSColin Finck case WM_INITDIALOG:
1210c2c66affSColin Finck {
1211c2c66affSColin Finck HWND hwndControl;
1212c2c66affSColin Finck
1213c2c66affSColin Finck /* Get pointer to the global setup data */
1214c2c66affSColin Finck DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam;
1215d281d14fSTimo Kreuzer SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData);
1216c2c66affSColin Finck
1217c2c66affSColin Finck /* Center the wizard window */
1218c2c66affSColin Finck CenterWindow(GetParent(hwndDlg));
1219c2c66affSColin Finck
1220c2c66affSColin Finck hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL);
1221c2c66affSColin Finck ShowWindow(hwndControl, SW_HIDE);
1222c2c66affSColin Finck EnableWindow(hwndControl, FALSE);
1223c2c66affSColin Finck
1224c2c66affSColin Finck SendDlgItemMessage(
1225c2c66affSColin Finck hwndDlg,
1226c2c66affSColin Finck IDC_DEVICE,
1227c2c66affSColin Finck WM_SETTEXT,
1228c2c66affSColin Finck 0,
1229c2c66affSColin Finck (LPARAM)DevInstData->drvInfoData.Description);
1230c2c66affSColin Finck
1231c2c66affSColin Finck /* Set title font */
1232c2c66affSColin Finck SendDlgItemMessage(
1233c2c66affSColin Finck hwndDlg,
1234c2c66affSColin Finck IDC_FINISHTITLE,
1235c2c66affSColin Finck WM_SETFONT,
1236c2c66affSColin Finck (WPARAM)DevInstData->hTitleFont,
1237c2c66affSColin Finck (LPARAM)TRUE);
1238c2c66affSColin Finck break;
1239c2c66affSColin Finck }
1240c2c66affSColin Finck
1241c2c66affSColin Finck case WM_NOTIFY:
1242c2c66affSColin Finck {
1243c2c66affSColin Finck LPNMHDR lpnm = (LPNMHDR)lParam;
1244c2c66affSColin Finck
1245c2c66affSColin Finck switch (lpnm->code)
1246c2c66affSColin Finck {
1247c2c66affSColin Finck case PSN_SETACTIVE:
1248c2c66affSColin Finck /* Enable the correct buttons on for the active page */
1249c2c66affSColin Finck PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH);
1250c2c66affSColin Finck break;
1251c2c66affSColin Finck
1252c2c66affSColin Finck case PSN_WIZBACK:
1253c2c66affSColin Finck /* Handle a Back button click, if necessary */
1254c2c66affSColin Finck break;
1255c2c66affSColin Finck
1256c2c66affSColin Finck case PSN_WIZFINISH:
1257c2c66affSColin Finck /* Handle a Finish button click, if necessary */
1258c2c66affSColin Finck break;
1259c2c66affSColin Finck
1260c2c66affSColin Finck default:
1261c2c66affSColin Finck break;
1262c2c66affSColin Finck }
1263c2c66affSColin Finck break;
1264c2c66affSColin Finck }
1265c2c66affSColin Finck
1266c2c66affSColin Finck default:
1267c2c66affSColin Finck break;
1268c2c66affSColin Finck }
1269c2c66affSColin Finck
1270c2c66affSColin Finck return FALSE;
1271c2c66affSColin Finck }
1272c2c66affSColin Finck
1273c2c66affSColin Finck static INT_PTR CALLBACK
FinishDlgProc(IN HWND hwndDlg,IN UINT uMsg,IN WPARAM wParam,IN LPARAM lParam)1274c2c66affSColin Finck FinishDlgProc(
1275c2c66affSColin Finck IN HWND hwndDlg,
1276c2c66affSColin Finck IN UINT uMsg,
1277c2c66affSColin Finck IN WPARAM wParam,
1278c2c66affSColin Finck IN LPARAM lParam)
1279c2c66affSColin Finck {
1280c2c66affSColin Finck PDEVINSTDATA DevInstData;
1281c2c66affSColin Finck UNREFERENCED_PARAMETER(wParam);
1282c2c66affSColin Finck
1283c2c66affSColin Finck /* Retrieve pointer to the global setup data */
1284d281d14fSTimo Kreuzer DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
1285c2c66affSColin Finck
1286c2c66affSColin Finck switch (uMsg)
1287c2c66affSColin Finck {
1288c2c66affSColin Finck case WM_INITDIALOG:
1289c2c66affSColin Finck {
1290c2c66affSColin Finck HWND hwndControl;
1291c2c66affSColin Finck
1292c2c66affSColin Finck /* Get pointer to the global setup data */
1293c2c66affSColin Finck DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam;
1294d281d14fSTimo Kreuzer SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData);
1295c2c66affSColin Finck
1296c2c66affSColin Finck /* Center the wizard window */
1297c2c66affSColin Finck CenterWindow(GetParent(hwndDlg));
1298c2c66affSColin Finck
1299c2c66affSColin Finck hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL);
1300c2c66affSColin Finck ShowWindow(hwndControl, SW_HIDE);
1301c2c66affSColin Finck EnableWindow(hwndControl, FALSE);
1302c2c66affSColin Finck
1303c2c66affSColin Finck SendDlgItemMessage(
1304c2c66affSColin Finck hwndDlg,
1305c2c66affSColin Finck IDC_DEVICE,
1306c2c66affSColin Finck WM_SETTEXT,
1307c2c66affSColin Finck 0,
1308c2c66affSColin Finck (LPARAM)DevInstData->drvInfoData.Description);
1309c2c66affSColin Finck
1310c2c66affSColin Finck /* Set title font */
1311c2c66affSColin Finck SendDlgItemMessage(
1312c2c66affSColin Finck hwndDlg,
1313c2c66affSColin Finck IDC_FINISHTITLE,
1314c2c66affSColin Finck WM_SETFONT,
1315c2c66affSColin Finck (WPARAM)DevInstData->hTitleFont,
1316c2c66affSColin Finck (LPARAM)TRUE);
1317c2c66affSColin Finck break;
1318c2c66affSColin Finck }
1319c2c66affSColin Finck
1320c2c66affSColin Finck case WM_NOTIFY:
1321c2c66affSColin Finck {
1322c2c66affSColin Finck LPNMHDR lpnm = (LPNMHDR)lParam;
1323c2c66affSColin Finck
1324c2c66affSColin Finck switch (lpnm->code)
1325c2c66affSColin Finck {
1326c2c66affSColin Finck case PSN_SETACTIVE:
1327c2c66affSColin Finck /* Enable the correct buttons on for the active page */
1328c2c66affSColin Finck PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH);
1329c2c66affSColin Finck break;
1330c2c66affSColin Finck
1331c2c66affSColin Finck case PSN_WIZBACK:
1332c2c66affSColin Finck /* Handle a Back button click, if necessary */
1333c2c66affSColin Finck break;
1334c2c66affSColin Finck
1335c2c66affSColin Finck case PSN_WIZFINISH:
1336c2c66affSColin Finck /* Handle a Finish button click, if necessary */
1337c2c66affSColin Finck break;
1338c2c66affSColin Finck
1339c2c66affSColin Finck default:
1340c2c66affSColin Finck break;
1341c2c66affSColin Finck }
1342c2c66affSColin Finck break;
1343c2c66affSColin Finck }
1344c2c66affSColin Finck
1345c2c66affSColin Finck default:
1346c2c66affSColin Finck break;
1347c2c66affSColin Finck }
1348c2c66affSColin Finck
1349c2c66affSColin Finck return FALSE;
1350c2c66affSColin Finck }
1351c2c66affSColin Finck
1352c2c66affSColin Finck static HFONT
CreateTitleFont(VOID)1353c2c66affSColin Finck CreateTitleFont(VOID)
1354c2c66affSColin Finck {
1355c2c66affSColin Finck NONCLIENTMETRICSW ncm;
1356c2c66affSColin Finck LOGFONTW LogFont;
1357c2c66affSColin Finck HDC hdc;
1358c2c66affSColin Finck INT FontSize;
1359c2c66affSColin Finck HFONT hFont;
1360c2c66affSColin Finck
1361c2c66affSColin Finck ncm.cbSize = sizeof(NONCLIENTMETRICSW);
1362c2c66affSColin Finck SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
1363c2c66affSColin Finck
1364c2c66affSColin Finck LogFont = ncm.lfMessageFont;
1365c2c66affSColin Finck LogFont.lfWeight = FW_BOLD;
1366c2c66affSColin Finck wcscpy(LogFont.lfFaceName, L"MS Shell Dlg");
1367c2c66affSColin Finck
1368c2c66affSColin Finck hdc = GetDC(NULL);
1369c2c66affSColin Finck FontSize = 12;
1370c2c66affSColin Finck LogFont.lfHeight = 0 - GetDeviceCaps (hdc, LOGPIXELSY) * FontSize / 72;
1371c2c66affSColin Finck hFont = CreateFontIndirectW(&LogFont);
1372c2c66affSColin Finck ReleaseDC(NULL, hdc);
1373c2c66affSColin Finck
1374c2c66affSColin Finck return hFont;
1375c2c66affSColin Finck }
1376c2c66affSColin Finck
1377c2c66affSColin Finck BOOL
DisplayWizard(IN PDEVINSTDATA DevInstData,IN HWND hwndParent,IN UINT startPage)1378c2c66affSColin Finck DisplayWizard(
1379c2c66affSColin Finck IN PDEVINSTDATA DevInstData,
1380c2c66affSColin Finck IN HWND hwndParent,
1381c2c66affSColin Finck IN UINT startPage)
1382c2c66affSColin Finck {
1383097355dbSMark Jansen PROPSHEETHEADER psh = {0};
1384c2c66affSColin Finck HPROPSHEETPAGE ahpsp[IDD_MAXIMUMPAGE + 1];
1385097355dbSMark Jansen PROPSHEETPAGE psp = {0};
138662b13979SKatayama Hirofumi MZ HRESULT hr = CoInitialize(NULL); /* for SHAutoComplete */
1387c2c66affSColin Finck
1388c2c66affSColin Finck /* zero based index */
1389c2c66affSColin Finck startPage -= IDD_FIRSTPAGE;
1390c2c66affSColin Finck
1391c2c66affSColin Finck /* Create the Welcome page */
1392c2c66affSColin Finck ZeroMemory(&psp, sizeof(PROPSHEETPAGE));
1393c2c66affSColin Finck psp.dwSize = sizeof(PROPSHEETPAGE);
1394c2c66affSColin Finck psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER | PSP_USETITLE;
1395c2c66affSColin Finck psp.hInstance = hDllInstance;
1396c2c66affSColin Finck psp.lParam = (LPARAM)DevInstData;
1397c2c66affSColin Finck psp.pszTitle = MAKEINTRESOURCE(DevInstData->bUpdate ? IDS_UPDATEWIZARDTITLE : IDS_INSTALLWIZARDTITLE);
1398c2c66affSColin Finck psp.pfnDlgProc = WelcomeDlgProc;
1399c2c66affSColin Finck psp.pszTemplate = MAKEINTRESOURCE(IDD_WELCOMEPAGE);
1400c2c66affSColin Finck ahpsp[IDD_WELCOMEPAGE-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp);
1401c2c66affSColin Finck
1402c2c66affSColin Finck /* Create the Select Source page */
1403c2c66affSColin Finck psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USETITLE;
1404c2c66affSColin Finck psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_CHSOURCE_TITLE);
1405c2c66affSColin Finck psp.pfnDlgProc = CHSourceDlgProc;
1406c2c66affSColin Finck psp.pszTemplate = MAKEINTRESOURCE(IDD_CHSOURCE);
1407c2c66affSColin Finck ahpsp[IDD_CHSOURCE-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp);
1408c2c66affSColin Finck
1409c2c66affSColin Finck /* Create the Search driver page */
1410c2c66affSColin Finck psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USETITLE;
1411c2c66affSColin Finck psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_SEARCHDRV_TITLE);
1412c2c66affSColin Finck psp.pfnDlgProc = SearchDrvDlgProc;
1413c2c66affSColin Finck psp.pszTemplate = MAKEINTRESOURCE(IDD_SEARCHDRV);
1414c2c66affSColin Finck ahpsp[IDD_SEARCHDRV-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp);
1415c2c66affSColin Finck
1416c2c66affSColin Finck /* Create the Install driver page */
1417c2c66affSColin Finck psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USETITLE;
1418c2c66affSColin Finck psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_INSTALLDRV_TITLE);
1419c2c66affSColin Finck psp.pfnDlgProc = InstallDrvDlgProc;
1420c2c66affSColin Finck psp.pszTemplate = MAKEINTRESOURCE(IDD_INSTALLDRV);
1421c2c66affSColin Finck ahpsp[IDD_INSTALLDRV-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp);
1422c2c66affSColin Finck
1423c2c66affSColin Finck /* Create the No driver page */
1424c2c66affSColin Finck psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER | PSP_USETITLE;
1425c2c66affSColin Finck psp.pfnDlgProc = NoDriverDlgProc;
1426c2c66affSColin Finck psp.pszTemplate = MAKEINTRESOURCE(IDD_NODRIVER);
1427c2c66affSColin Finck ahpsp[IDD_NODRIVER-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp);
1428c2c66affSColin Finck
1429c2c66affSColin Finck /* Create the Install failed page */
1430c2c66affSColin Finck psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER | PSP_USETITLE;
1431c2c66affSColin Finck psp.pfnDlgProc = InstallFailedDlgProc;
1432c2c66affSColin Finck psp.pszTemplate = MAKEINTRESOURCE(IDD_INSTALLFAILED);
1433c2c66affSColin Finck ahpsp[IDD_INSTALLFAILED-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp);
1434c2c66affSColin Finck
1435c2c66affSColin Finck /* Create the Need reboot page */
1436c2c66affSColin Finck psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER | PSP_USETITLE;
1437c2c66affSColin Finck psp.pfnDlgProc = NeedRebootDlgProc;
1438c2c66affSColin Finck psp.pszTemplate = MAKEINTRESOURCE(IDD_NEEDREBOOT);
1439c2c66affSColin Finck ahpsp[IDD_NEEDREBOOT-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp);
1440c2c66affSColin Finck
1441c2c66affSColin Finck /* Create the Finish page */
1442c2c66affSColin Finck psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER | PSP_USETITLE;
1443c2c66affSColin Finck psp.pfnDlgProc = FinishDlgProc;
1444c2c66affSColin Finck psp.pszTemplate = MAKEINTRESOURCE(IDD_FINISHPAGE);
1445c2c66affSColin Finck ahpsp[IDD_FINISHPAGE-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp);
1446c2c66affSColin Finck
1447c2c66affSColin Finck /* Create the property sheet */
1448c2c66affSColin Finck psh.dwSize = sizeof(PROPSHEETHEADER);
1449c2c66affSColin Finck psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER;
1450c2c66affSColin Finck psh.hInstance = hDllInstance;
1451c2c66affSColin Finck psh.hwndParent = hwndParent;
1452c2c66affSColin Finck psh.nPages = IDD_MAXIMUMPAGE + 1;
1453c2c66affSColin Finck psh.nStartPage = startPage;
1454c2c66affSColin Finck psh.phpage = ahpsp;
1455c2c66affSColin Finck psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
1456c2c66affSColin Finck psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER);
1457c2c66affSColin Finck
1458c2c66affSColin Finck /* Create title font */
1459c2c66affSColin Finck DevInstData->hTitleFont = CreateTitleFont();
1460c2c66affSColin Finck
1461c2c66affSColin Finck /* Display the wizard */
1462c2c66affSColin Finck PropertySheet(&psh);
1463c2c66affSColin Finck
1464c2c66affSColin Finck DeleteObject(DevInstData->hTitleFont);
1465c2c66affSColin Finck
146662b13979SKatayama Hirofumi MZ if (SUCCEEDED(hr))
146762b13979SKatayama Hirofumi MZ CoUninitialize();
1468c2c66affSColin Finck return TRUE;
1469c2c66affSColin Finck }
1470