2 * New device installer (newdev.dll)
4 * Copyright 2006 Hervé Poussineau (hpoussin@reactos.org)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "newdev_private.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(newdev
);
35 hWndParent
= GetParent(hWnd
);
36 if (hWndParent
== NULL
)
37 hWndParent
= GetDesktopWindow();
39 GetWindowRect(hWndParent
, &rcParent
);
40 GetWindowRect(hWnd
, &rcWindow
);
45 ((rcParent
.right
- rcParent
.left
) - (rcWindow
.right
- rcWindow
.left
)) / 2,
46 ((rcParent
.bottom
- rcParent
.top
) - (rcWindow
.bottom
- rcWindow
.top
)) / 2,
59 ULONG Status
, ProblemNumber
;
62 cr
= CM_Get_DevNode_Status_Ex(&Status
,
69 *CanDisable
= ((Status
& DN_DISABLEABLE
) != 0);
83 ULONG Status
, ProblemNumber
;
86 cr
= CM_Get_DevNode_Status_Ex(
94 *IsEnabled
= ((Status
& DN_STARTED
) != 0);
103 IN HDEVINFO DeviceInfoSet
,
104 IN PSP_DEVINFO_DATA DevInfoData OPTIONAL
,
106 IN DWORD HardwareProfile OPTIONAL
,
107 OUT BOOL
*bNeedReboot OPTIONAL
)
109 SP_PROPCHANGE_PARAMS pcp
;
110 SP_DEVINSTALL_PARAMS dp
;
114 pcp
.ClassInstallHeader
.cbSize
= sizeof(SP_CLASSINSTALL_HEADER
);
115 pcp
.ClassInstallHeader
.InstallFunction
= DIF_PROPERTYCHANGE
;
116 pcp
.HwProfile
= HardwareProfile
;
120 /* try to enable the device on the global profile */
121 pcp
.StateChange
= DICS_ENABLE
;
122 pcp
.Scope
= DICS_FLAG_GLOBAL
;
125 LastErr
= GetLastError();
126 if (SetupDiSetClassInstallParams(
129 &pcp
.ClassInstallHeader
,
130 sizeof(SP_PROPCHANGE_PARAMS
)))
132 SetupDiCallClassInstaller(
137 SetLastError(LastErr
);
140 /* try config-specific */
141 pcp
.StateChange
= (bEnable
? DICS_ENABLE
: DICS_DISABLE
);
142 pcp
.Scope
= DICS_FLAG_CONFIGSPECIFIC
;
144 if (SetupDiSetClassInstallParams(
147 &pcp
.ClassInstallHeader
,
148 sizeof(SP_PROPCHANGE_PARAMS
)) &&
149 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE
,
153 dp
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
154 if (SetupDiGetDeviceInstallParams(
159 if (bNeedReboot
!= NULL
)
161 *bNeedReboot
= ((dp
.Flags
& (DI_NEEDRESTART
| DI_NEEDREBOOT
)) != 0);
174 PDEVINSTDATA DevInstData
;
178 DevInstData
= (PDEVINSTDATA
)lpParam
;
180 result
= ScanFoldersForDriver(DevInstData
);
184 PostMessage(DevInstData
->hDialog
, WM_SEARCH_FINISHED
, 1, 0);
188 /* Update device configuration */
189 if (SetupDiGetDeviceRegistryProperty(
190 DevInstData
->hDevInfo
,
191 &DevInstData
->devInfoData
,
194 (BYTE
*)&config_flags
,
195 sizeof(config_flags
),
198 config_flags
|= CONFIGFLAG_FAILEDINSTALL
;
199 SetupDiSetDeviceRegistryPropertyW(
200 DevInstData
->hDevInfo
,
201 &DevInstData
->devInfoData
,
203 (BYTE
*)&config_flags
, sizeof(config_flags
));
206 PostMessage(DevInstData
->hDialog
, WM_SEARCH_FINISHED
, 0, 0);
215 PDEVINSTDATA DevInstData
;
218 DevInstData
= (PDEVINSTDATA
)lpParam
;
219 res
= InstallCurrentDriver(DevInstData
);
220 PostMessage(DevInstData
->hDialog
, WM_INSTALL_FINISHED
, res
? 0 : 1, 0);
225 PopulateCustomPathCombo(
230 DWORD dwPathLength
= 0;
231 LPWSTR Buffer
= NULL
;
235 (void)ComboBox_ResetContent(hwndCombo
);
237 /* RegGetValue would have been better... */
240 REGSTR_PATH_SETUP REGSTR_KEY_SETUP
,
244 if (rc
!= ERROR_SUCCESS
)
246 TRACE("RegOpenKeyEx() failed with error 0x%lx\n", rc
);
249 rc
= RegQueryValueExW(
251 L
"Installation Sources",
256 if (rc
!= ERROR_SUCCESS
|| dwRegType
!= REG_MULTI_SZ
)
258 TRACE("RegQueryValueEx() failed with error 0x%lx\n", rc
);
262 /* Allocate enough space to add 2 NULL chars at the end of the string */
263 Buffer
= HeapAlloc(GetProcessHeap(), 0, dwPathLength
+ 2 * sizeof(WCHAR
));
266 TRACE("HeapAlloc() failed\n");
269 rc
= RegQueryValueExW(
271 L
"Installation Sources",
276 if (rc
!= ERROR_SUCCESS
)
278 TRACE("RegQueryValueEx() failed with error 0x%lx\n", rc
);
281 Buffer
[dwPathLength
] = Buffer
[dwPathLength
+ 1] = '\0';
283 /* Populate combo box */
284 for (Path
= Buffer
; *Path
; Path
+= wcslen(Path
) + 1)
286 (void)ComboBox_AddString(hwndCombo
, Path
);
288 (void)ComboBox_SetCurSel(hwndCombo
, 0);
294 HeapFree(GetProcessHeap(), 0, Buffer
);
301 LPWSTR CustomPath
= NULL
;
302 DWORD CustomPathLength
;
303 LPWSTR Buffer
= NULL
;
304 LPWSTR pBuffer
; /* Pointer into Buffer */
305 int ItemsCount
, Length
;
307 DWORD TotalLength
= 0;
308 BOOL UseCustomPath
= TRUE
;
312 /* Get custom path */
313 Length
= ComboBox_GetTextLength(hwndCombo
) + 1;
314 CustomPath
= HeapAlloc(GetProcessHeap(), 0, Length
* sizeof(WCHAR
));
317 TRACE("HeapAlloc() failed\n");
320 CustomPathLength
= GetWindowTextW(hwndCombo
, CustomPath
, Length
) + 1;
322 /* Calculate length of the buffer */
323 ItemsCount
= ComboBox_GetCount(hwndCombo
);
324 if (ItemsCount
== CB_ERR
)
326 TRACE("ComboBox_GetCount() failed\n");
329 for (i
= 0; i
< ItemsCount
; i
++)
331 Length
= ComboBox_GetLBTextLen(hwndCombo
, i
);
332 if (Length
== CB_ERR
)
334 TRACE("ComboBox_GetLBTextLen() failed\n");
337 TotalLength
+= Length
+ 1;
339 TotalLength
++; /* Final NULL char */
341 /* Allocate buffer */
342 Buffer
= HeapAlloc(GetProcessHeap(), 0, (CustomPathLength
+ TotalLength
+ 1) * sizeof(WCHAR
));
345 TRACE("HeapAlloc() failed\n");
349 /* Fill the buffer */
350 pBuffer
= &Buffer
[CustomPathLength
];
351 for (i
= 0; i
< ItemsCount
; i
++)
353 Length
= ComboBox_GetLBText(hwndCombo
, i
, pBuffer
);
354 if (Length
== CB_ERR
)
356 TRACE("ComboBox_GetLBText() failed\n");
359 else if (UseCustomPath
&& _wcsicmp(CustomPath
, pBuffer
) == 0)
360 UseCustomPath
= FALSE
;
361 pBuffer
+= 1 + Length
;
363 *pBuffer
= '\0'; /* Add final NULL char */
367 /* Nothing to save to registry */
371 TotalLength
+= CustomPathLength
;
372 wcscpy(Buffer
, CustomPath
);
374 /* Save the buffer */
375 /* RegSetKeyValue would have been better... */
378 REGSTR_PATH_SETUP REGSTR_KEY_SETUP
,
382 if (rc
!= ERROR_SUCCESS
)
384 TRACE("RegOpenKeyEx() failed with error 0x%lx\n", rc
);
389 L
"Installation Sources",
393 TotalLength
* sizeof(WCHAR
));
394 if (rc
!= ERROR_SUCCESS
)
396 TRACE("RegSetValueEx() failed with error 0x%lx\n", rc
);
403 HeapFree(GetProcessHeap(), 0, CustomPath
);
404 HeapFree(GetProcessHeap(), 0, Buffer
);
407 static INT_PTR CALLBACK
414 PDEVINSTDATA DevInstData
;
415 UNREFERENCED_PARAMETER(wParam
);
417 /* Retrieve pointer to the global setup data */
418 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
427 /* Get pointer to the global setup data */
428 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
429 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
431 hwndControl
= GetParent(hwndDlg
);
433 /* Center the wizard window */
434 CenterWindow(hwndControl
);
436 /* Hide the system menu */
437 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
438 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
445 (WPARAM
)DevInstData
->hTitleFont
,
453 (LPARAM
)DevInstData
->buffer
);
466 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
471 /* Enable the Next button */
472 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
476 /* Handle a Next button click, if necessary */
477 if (SendDlgItemMessage(hwndDlg
, IDC_RADIO_AUTO
, BM_GETCHECK
, (WPARAM
)0, (LPARAM
)0) == BST_CHECKED
)
479 if (PrepareFoldersToScan(DevInstData
, TRUE
, FALSE
, NULL
))
480 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_SEARCHDRV
);
482 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_INSTALLFAILED
);
500 IncludePath(HWND Dlg
, BOOL Enabled
)
502 EnableWindow(GetDlgItem(Dlg
, IDC_COMBO_PATH
), Enabled
);
503 EnableWindow(GetDlgItem(Dlg
, IDC_BROWSE
), Enabled
);
507 AutoDriver(HWND Dlg
, BOOL Enabled
)
509 EnableWindow(GetDlgItem(Dlg
, IDC_CHECK_MEDIA
), Enabled
);
510 EnableWindow(GetDlgItem(Dlg
, IDC_CHECK_PATH
), Enabled
);
511 IncludePath(Dlg
, Enabled
& IsDlgButtonChecked(Dlg
, IDC_CHECK_PATH
));
514 static INT_PTR CALLBACK
521 PDEVINSTDATA DevInstData
;
523 /* Retrieve pointer to the global setup data */
524 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
533 /* Get pointer to the global setup data */
534 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
535 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
537 hwndControl
= GetParent(hwndDlg
);
539 /* Center the wizard window */
540 CenterWindow(hwndControl
);
542 /* Hide the system menu */
543 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
544 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
546 PopulateCustomPathCombo(GetDlgItem(hwndDlg
, IDC_COMBO_PATH
));
550 IDC_RADIO_SEARCHHERE
,
554 AutoDriver(hwndDlg
, TRUE
);
555 IncludePath(hwndDlg
, FALSE
);
557 /* Disable manual driver choice for now */
558 EnableWindow(GetDlgItem(hwndDlg
, IDC_RADIO_CHOOSE
), FALSE
);
565 switch (LOWORD(wParam
))
567 case IDC_RADIO_SEARCHHERE
:
568 AutoDriver(hwndDlg
, TRUE
);
571 case IDC_RADIO_CHOOSE
:
572 AutoDriver(hwndDlg
, FALSE
);
576 IncludePath(hwndDlg
, IsDlgButtonChecked(hwndDlg
, IDC_CHECK_PATH
));
581 BROWSEINFO bi
= { 0 };
584 bi
.hwndOwner
= hwndDlg
;
585 bi
.ulFlags
= BIF_RETURNONLYFSDIRS
;
586 pidl
= SHBrowseForFolder(&bi
);
589 WCHAR Directory
[MAX_PATH
];
592 if (SHGetPathFromIDListW(pidl
, Directory
))
594 /* Set the IDC_COMBO_PATH text */
595 SetWindowTextW(GetDlgItem(hwndDlg
, IDC_COMBO_PATH
), Directory
);
598 /* Free memory, if possible */
599 if (SUCCEEDED(SHGetMalloc(&malloc
)))
601 IMalloc_Free(malloc
, pidl
);
602 IMalloc_Release(malloc
);
614 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
619 /* Enable the Next and Back buttons */
620 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
| PSWIZB_BACK
);
624 /* Handle a Next button click, if necessary */
625 if (IsDlgButtonChecked(hwndDlg
, IDC_RADIO_SEARCHHERE
))
627 SaveCustomPath(GetDlgItem(hwndDlg
, IDC_COMBO_PATH
));
628 HeapFree(GetProcessHeap(), 0, DevInstData
->CustomSearchPath
);
629 DevInstData
->CustomSearchPath
= NULL
;
630 if (PrepareFoldersToScan(
632 IsDlgButtonChecked(hwndDlg
, IDC_CHECK_MEDIA
),
633 IsDlgButtonChecked(hwndDlg
, IDC_CHECK_PATH
),
634 GetDlgItem(hwndDlg
, IDC_COMBO_PATH
)))
636 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_SEARCHDRV
);
640 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_INSTALLFAILED
);
662 static INT_PTR CALLBACK
669 PDEVINSTDATA DevInstData
;
672 /* Retrieve pointer to the global setup data */
673 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
682 /* Get pointer to the global setup data */
683 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
684 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
686 DevInstData
->hDialog
= hwndDlg
;
687 hwndControl
= GetParent(hwndDlg
);
689 /* Center the wizard window */
690 CenterWindow(hwndControl
);
697 (LPARAM
)DevInstData
->buffer
);
699 /* Hide the system menu */
700 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
701 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
705 case WM_SEARCH_FINISHED
:
707 CloseHandle(hThread
);
710 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_NODRIVER
);
712 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_INSTALLDRV
);
718 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
723 PropSheet_SetWizButtons(GetParent(hwndDlg
), !PSWIZB_NEXT
| !PSWIZB_BACK
);
724 /* Yes, we can safely ignore the problem (if any) */
725 SetupDiDestroyDriverInfoList(
726 DevInstData
->hDevInfo
,
727 &DevInstData
->devInfoData
,
729 hThread
= CreateThread(NULL
, 0, FindDriverProc
, DevInstData
, 0, &dwThreadId
);
735 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, TRUE
);
741 /* Handle a Next button click, if necessary */
757 static INT_PTR CALLBACK
764 PDEVINSTDATA DevInstData
;
767 /* Retrieve pointer to the global setup data */
768 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
777 /* Get pointer to the global setup data */
778 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
779 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
781 DevInstData
->hDialog
= hwndDlg
;
782 hwndControl
= GetParent(hwndDlg
);
784 /* Center the wizard window */
785 CenterWindow(hwndControl
);
792 (LPARAM
)DevInstData
->drvInfoData
.Description
);
794 /* Hide the system menu */
795 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
796 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
800 case WM_INSTALL_FINISHED
:
802 CloseHandle(hThread
);
806 /* Should we reboot? */
807 SP_DEVINSTALL_PARAMS installParams
;
808 installParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
809 if (SetupDiGetDeviceInstallParams(
810 DevInstData
->hDevInfo
,
811 &DevInstData
->devInfoData
,
814 if (installParams
.Flags
& (DI_NEEDRESTART
| DI_NEEDREBOOT
))
816 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_NEEDREBOOT
);
819 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_FINISHPAGE
);
823 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_INSTALLFAILED
);
829 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
834 PropSheet_SetWizButtons(GetParent(hwndDlg
), !PSWIZB_NEXT
| !PSWIZB_BACK
);
835 hThread
= CreateThread(NULL
, 0, InstallDriverProc
, DevInstData
, 0, &dwThreadId
);
841 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, TRUE
);
847 /* Handle a Next button click, if necessary */
863 static INT_PTR CALLBACK
870 PDEVINSTDATA DevInstData
;
873 UNREFERENCED_PARAMETER(wParam
);
875 /* Get pointer to the global setup data */
876 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
882 BOOL DisableableDevice
= FALSE
;
884 /* Get pointer to the global setup data */
885 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
886 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
888 /* Center the wizard window */
889 CenterWindow(GetParent(hwndDlg
));
891 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
892 ShowWindow(hwndControl
, SW_HIDE
);
893 EnableWindow(hwndControl
, FALSE
);
900 (WPARAM
)DevInstData
->hTitleFont
,
903 /* disable the "do not show this dialog anymore" checkbox
904 if the device cannot be disabled */
906 DevInstData
->devInfoData
.DevInst
,
910 GetDlgItem(hwndDlg
, IDC_DONOTSHOWDLG
),
917 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
922 /* Enable the correct buttons on for the active page */
923 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_FINISH
);
927 /* Handle a Back button click, if necessary */
928 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
929 ShowWindow(hwndControl
, SW_SHOW
);
930 EnableWindow(hwndControl
, TRUE
);
931 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_CHSOURCE
);
936 BOOL DisableableDevice
= FALSE
;
937 BOOL IsStarted
= FALSE
;
939 if (CanDisableDevice(DevInstData
->devInfoData
.DevInst
,
941 &DisableableDevice
) &&
944 DevInstData
->devInfoData
.DevInst
,
952 (WPARAM
)0, (LPARAM
)0) == BST_CHECKED
)
954 /* disable the device */
956 DevInstData
->hDevInfo
,
957 &DevInstData
->devInfoData
,
978 static INT_PTR CALLBACK
979 InstallFailedDlgProc(
985 PDEVINSTDATA DevInstData
;
986 UNREFERENCED_PARAMETER(wParam
);
988 /* Retrieve pointer to the global setup data */
989 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
997 /* Get pointer to the global setup data */
998 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
999 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
1001 /* Center the wizard window */
1002 CenterWindow(GetParent(hwndDlg
));
1004 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
1005 ShowWindow(hwndControl
, SW_HIDE
);
1006 EnableWindow(hwndControl
, FALSE
);
1013 (LPARAM
)DevInstData
->drvInfoData
.Description
);
1015 /* Set title font */
1020 (WPARAM
)DevInstData
->hTitleFont
,
1027 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1032 /* Enable the correct buttons on for the active page */
1033 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
1037 /* Handle a Back button click, if necessary */
1041 /* Handle a Finish button click, if necessary */
1057 static INT_PTR CALLBACK
1064 PDEVINSTDATA DevInstData
;
1065 UNREFERENCED_PARAMETER(wParam
);
1067 /* Retrieve pointer to the global setup data */
1068 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
1076 /* Get pointer to the global setup data */
1077 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1078 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
1080 /* Center the wizard window */
1081 CenterWindow(GetParent(hwndDlg
));
1083 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
1084 ShowWindow(hwndControl
, SW_HIDE
);
1085 EnableWindow(hwndControl
, FALSE
);
1092 (LPARAM
)DevInstData
->drvInfoData
.Description
);
1094 /* Set title font */
1099 (WPARAM
)DevInstData
->hTitleFont
,
1106 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1111 /* Enable the correct buttons on for the active page */
1112 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
1116 /* Handle a Back button click, if necessary */
1120 /* Handle a Finish button click, if necessary */
1136 static INT_PTR CALLBACK
1143 PDEVINSTDATA DevInstData
;
1144 UNREFERENCED_PARAMETER(wParam
);
1146 /* Retrieve pointer to the global setup data */
1147 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
1155 /* Get pointer to the global setup data */
1156 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1157 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
1159 /* Center the wizard window */
1160 CenterWindow(GetParent(hwndDlg
));
1162 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
1163 ShowWindow(hwndControl
, SW_HIDE
);
1164 EnableWindow(hwndControl
, FALSE
);
1171 (LPARAM
)DevInstData
->drvInfoData
.Description
);
1173 /* Set title font */
1178 (WPARAM
)DevInstData
->hTitleFont
,
1185 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1190 /* Enable the correct buttons on for the active page */
1191 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
1195 /* Handle a Back button click, if necessary */
1199 /* Handle a Finish button click, if necessary */
1216 CreateTitleFont(VOID
)
1218 NONCLIENTMETRICSW ncm
;
1224 ncm
.cbSize
= sizeof(NONCLIENTMETRICSW
);
1225 SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, 0, &ncm
, 0);
1227 LogFont
= ncm
.lfMessageFont
;
1228 LogFont
.lfWeight
= FW_BOLD
;
1229 wcscpy(LogFont
.lfFaceName
, L
"MS Shell Dlg");
1233 LogFont
.lfHeight
= 0 - GetDeviceCaps (hdc
, LOGPIXELSY
) * FontSize
/ 72;
1234 hFont
= CreateFontIndirectW(&LogFont
);
1235 ReleaseDC(NULL
, hdc
);
1242 IN PDEVINSTDATA DevInstData
,
1246 PROPSHEETHEADER psh
;
1247 HPROPSHEETPAGE ahpsp
[IDD_MAXIMUMPAGE
+ 1];
1250 /* Create the Welcome page */
1251 ZeroMemory(&psp
, sizeof(PROPSHEETPAGE
));
1252 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
1253 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1254 psp
.hInstance
= hDllInstance
;
1255 psp
.lParam
= (LPARAM
)DevInstData
;
1256 psp
.pfnDlgProc
= (DLGPROC
) WelcomeDlgProc
;
1257 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_WELCOMEPAGE
);
1258 ahpsp
[IDD_WELCOMEPAGE
] = CreatePropertySheetPage(&psp
);
1260 /* Create the Select Source page */
1261 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
1262 psp
.pfnDlgProc
= (DLGPROC
) CHSourceDlgProc
;
1263 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_CHSOURCE
);
1264 ahpsp
[IDD_CHSOURCE
] = CreatePropertySheetPage(&psp
);
1266 /* Create the Search driver page */
1267 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
1268 psp
.pfnDlgProc
= (DLGPROC
) SearchDrvDlgProc
;
1269 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_SEARCHDRV
);
1270 ahpsp
[IDD_SEARCHDRV
] = CreatePropertySheetPage(&psp
);
1272 /* Create the Install driver page */
1273 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
1274 psp
.pfnDlgProc
= (DLGPROC
) InstallDrvDlgProc
;
1275 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_INSTALLDRV
);
1276 ahpsp
[IDD_INSTALLDRV
] = CreatePropertySheetPage(&psp
);
1278 /* Create the No driver page */
1279 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1280 psp
.pfnDlgProc
= (DLGPROC
) NoDriverDlgProc
;
1281 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_NODRIVER
);
1282 ahpsp
[IDD_NODRIVER
] = CreatePropertySheetPage(&psp
);
1284 /* Create the Install failed page */
1285 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1286 psp
.pfnDlgProc
= (DLGPROC
) InstallFailedDlgProc
;
1287 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_INSTALLFAILED
);
1288 ahpsp
[IDD_INSTALLFAILED
] = CreatePropertySheetPage(&psp
);
1290 /* Create the Need reboot page */
1291 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1292 psp
.pfnDlgProc
= (DLGPROC
) NeedRebootDlgProc
;
1293 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_NEEDREBOOT
);
1294 ahpsp
[IDD_NEEDREBOOT
] = CreatePropertySheetPage(&psp
);
1296 /* Create the Finish page */
1297 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1298 psp
.pfnDlgProc
= (DLGPROC
) FinishDlgProc
;
1299 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_FINISHPAGE
);
1300 ahpsp
[IDD_FINISHPAGE
] = CreatePropertySheetPage(&psp
);
1302 /* Create the property sheet */
1303 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
1304 psh
.dwFlags
= PSH_WIZARD97
| PSH_WATERMARK
| PSH_HEADER
;
1305 psh
.hInstance
= hDllInstance
;
1306 psh
.hwndParent
= hwndParent
;
1307 psh
.nPages
= IDD_MAXIMUMPAGE
+ 1;
1308 psh
.nStartPage
= startPage
;
1310 psh
.pszbmWatermark
= MAKEINTRESOURCE(IDB_WATERMARK
);
1311 psh
.pszbmHeader
= MAKEINTRESOURCE(IDB_HEADER
);
1313 /* Create title font */
1314 DevInstData
->hTitleFont
= CreateTitleFont();
1316 /* Display the wizard */
1317 PropertySheet(&psh
);
1319 DeleteObject(DevInstData
->hTitleFont
);