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