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"
37 hWndParent
= GetParent(hWnd
);
38 if (hWndParent
== NULL
)
39 hWndParent
= GetDesktopWindow();
41 GetWindowRect(hWndParent
, &rcParent
);
42 GetWindowRect(hWnd
, &rcWindow
);
47 ((rcParent
.right
- rcParent
.left
) - (rcWindow
.right
- rcWindow
.left
)) / 2,
48 ((rcParent
.bottom
- rcParent
.top
) - (rcWindow
.bottom
- rcWindow
.top
)) / 2,
61 ULONG Status
, ProblemNumber
;
64 cr
= CM_Get_DevNode_Status_Ex(&Status
,
71 *CanDisable
= ((Status
& DN_DISABLEABLE
) != 0);
85 ULONG Status
, ProblemNumber
;
88 cr
= CM_Get_DevNode_Status_Ex(
96 *IsEnabled
= ((Status
& DN_STARTED
) != 0);
105 IN HDEVINFO DeviceInfoSet
,
106 IN PSP_DEVINFO_DATA DevInfoData OPTIONAL
,
108 IN DWORD HardwareProfile OPTIONAL
,
109 OUT BOOL
*bNeedReboot OPTIONAL
)
111 SP_PROPCHANGE_PARAMS pcp
;
112 SP_DEVINSTALL_PARAMS dp
;
116 pcp
.ClassInstallHeader
.cbSize
= sizeof(SP_CLASSINSTALL_HEADER
);
117 pcp
.ClassInstallHeader
.InstallFunction
= DIF_PROPERTYCHANGE
;
118 pcp
.HwProfile
= HardwareProfile
;
122 /* try to enable the device on the global profile */
123 pcp
.StateChange
= DICS_ENABLE
;
124 pcp
.Scope
= DICS_FLAG_GLOBAL
;
127 LastErr
= GetLastError();
128 if (SetupDiSetClassInstallParams(
131 &pcp
.ClassInstallHeader
,
132 sizeof(SP_PROPCHANGE_PARAMS
)))
134 SetupDiCallClassInstaller(
139 SetLastError(LastErr
);
142 /* try config-specific */
143 pcp
.StateChange
= (bEnable
? DICS_ENABLE
: DICS_DISABLE
);
144 pcp
.Scope
= DICS_FLAG_CONFIGSPECIFIC
;
146 if (SetupDiSetClassInstallParams(
149 &pcp
.ClassInstallHeader
,
150 sizeof(SP_PROPCHANGE_PARAMS
)) &&
151 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE
,
155 dp
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
156 if (SetupDiGetDeviceInstallParams(
161 if (bNeedReboot
!= NULL
)
163 *bNeedReboot
= ((dp
.Flags
& (DI_NEEDRESTART
| DI_NEEDREBOOT
)) != 0);
176 PDEVINSTDATA DevInstData
;
180 DevInstData
= (PDEVINSTDATA
)lpParam
;
182 result
= ScanFoldersForDriver(DevInstData
);
186 PostMessage(DevInstData
->hDialog
, WM_SEARCH_FINISHED
, 1, 0);
190 /* Update device configuration */
191 if (SetupDiGetDeviceRegistryProperty(
192 DevInstData
->hDevInfo
,
193 &DevInstData
->devInfoData
,
196 (BYTE
*)&config_flags
,
197 sizeof(config_flags
),
200 config_flags
|= CONFIGFLAG_FAILEDINSTALL
;
201 SetupDiSetDeviceRegistryPropertyW(
202 DevInstData
->hDevInfo
,
203 &DevInstData
->devInfoData
,
205 (BYTE
*)&config_flags
, sizeof(config_flags
));
208 PostMessage(DevInstData
->hDialog
, WM_SEARCH_FINISHED
, 0, 0);
217 PDEVINSTDATA DevInstData
;
220 DevInstData
= (PDEVINSTDATA
)lpParam
;
221 res
= InstallCurrentDriver(DevInstData
);
222 PostMessage(DevInstData
->hDialog
, WM_INSTALL_FINISHED
, res
? 0 : 1, 0);
227 PopulateCustomPathCombo(
232 DWORD dwPathLength
= 0;
233 LPWSTR Buffer
= NULL
;
237 (void)ComboBox_ResetContent(hwndCombo
);
239 /* RegGetValue would have been better... */
242 REGSTR_PATH_SETUP REGSTR_KEY_SETUP
,
246 if (rc
!= ERROR_SUCCESS
)
248 TRACE("RegOpenKeyEx() failed with error 0x%lx\n", rc
);
251 rc
= RegQueryValueExW(
253 L
"Installation Sources",
258 if (rc
!= ERROR_SUCCESS
|| dwRegType
!= REG_MULTI_SZ
)
260 TRACE("RegQueryValueEx() failed with error 0x%lx\n", rc
);
264 /* Allocate enough space to add 2 NULL chars at the end of the string */
265 Buffer
= HeapAlloc(GetProcessHeap(), 0, dwPathLength
+ 2 * sizeof(WCHAR
));
268 TRACE("HeapAlloc() failed\n");
271 rc
= RegQueryValueExW(
273 L
"Installation Sources",
278 if (rc
!= ERROR_SUCCESS
)
280 TRACE("RegQueryValueEx() failed with error 0x%lx\n", rc
);
283 Buffer
[dwPathLength
] = Buffer
[dwPathLength
+ 1] = '\0';
285 /* Populate combo box */
286 for (Path
= Buffer
; *Path
; Path
+= wcslen(Path
) + 1)
288 (void)ComboBox_AddString(hwndCombo
, Path
);
290 (void)ComboBox_SetCurSel(hwndCombo
, 0);
296 HeapFree(GetProcessHeap(), 0, Buffer
);
303 LPWSTR CustomPath
= NULL
;
304 DWORD CustomPathLength
;
305 LPWSTR Buffer
= NULL
;
306 LPWSTR pBuffer
; /* Pointer into Buffer */
307 int ItemsCount
, Length
;
309 DWORD TotalLength
= 0;
310 BOOL UseCustomPath
= TRUE
;
314 /* Get custom path */
315 Length
= ComboBox_GetTextLength(hwndCombo
) + 1;
316 CustomPath
= HeapAlloc(GetProcessHeap(), 0, Length
* sizeof(WCHAR
));
319 TRACE("HeapAlloc() failed\n");
322 CustomPathLength
= GetWindowTextW(hwndCombo
, CustomPath
, Length
) + 1;
324 /* Calculate length of the buffer */
325 ItemsCount
= ComboBox_GetCount(hwndCombo
);
326 if (ItemsCount
== CB_ERR
)
328 TRACE("ComboBox_GetCount() failed\n");
331 for (i
= 0; i
< ItemsCount
; i
++)
333 Length
= ComboBox_GetLBTextLen(hwndCombo
, i
);
334 if (Length
== CB_ERR
)
336 TRACE("ComboBox_GetLBTextLen() failed\n");
339 TotalLength
+= Length
+ 1;
341 TotalLength
++; /* Final NULL char */
343 /* Allocate buffer */
344 Buffer
= HeapAlloc(GetProcessHeap(), 0, (CustomPathLength
+ TotalLength
+ 1) * sizeof(WCHAR
));
347 TRACE("HeapAlloc() failed\n");
351 /* Fill the buffer */
352 pBuffer
= &Buffer
[CustomPathLength
];
353 for (i
= 0; i
< ItemsCount
; i
++)
355 Length
= ComboBox_GetLBText(hwndCombo
, i
, pBuffer
);
356 if (Length
== CB_ERR
)
358 TRACE("ComboBox_GetLBText() failed\n");
361 else if (UseCustomPath
&& _wcsicmp(CustomPath
, pBuffer
) == 0)
362 UseCustomPath
= FALSE
;
363 pBuffer
+= 1 + Length
;
365 *pBuffer
= '\0'; /* Add final NULL char */
369 /* Nothing to save to registry */
373 TotalLength
+= CustomPathLength
;
374 wcscpy(Buffer
, CustomPath
);
376 /* Save the buffer */
377 /* RegSetKeyValue would have been better... */
380 REGSTR_PATH_SETUP REGSTR_KEY_SETUP
,
384 if (rc
!= ERROR_SUCCESS
)
386 TRACE("RegOpenKeyEx() failed with error 0x%lx\n", rc
);
391 L
"Installation Sources",
395 TotalLength
* sizeof(WCHAR
));
396 if (rc
!= ERROR_SUCCESS
)
398 TRACE("RegSetValueEx() failed with error 0x%lx\n", rc
);
405 HeapFree(GetProcessHeap(), 0, CustomPath
);
406 HeapFree(GetProcessHeap(), 0, Buffer
);
409 static INT_PTR CALLBACK
416 PDEVINSTDATA DevInstData
;
417 UNREFERENCED_PARAMETER(wParam
);
419 /* Retrieve pointer to the global setup data */
420 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
429 /* Get pointer to the global setup data */
430 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
431 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
433 hwndControl
= GetParent(hwndDlg
);
435 /* Center the wizard window */
436 CenterWindow(hwndControl
);
438 /* Hide the system menu */
439 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
440 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
447 (WPARAM
)DevInstData
->hTitleFont
,
455 (LPARAM
)DevInstData
->buffer
);
468 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
473 /* Enable the Next button */
474 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
478 /* Handle a Next button click, if necessary */
479 if (SendDlgItemMessage(hwndDlg
, IDC_RADIO_AUTO
, BM_GETCHECK
, (WPARAM
)0, (LPARAM
)0) == BST_CHECKED
)
481 if (PrepareFoldersToScan(DevInstData
, TRUE
, FALSE
, NULL
))
482 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_SEARCHDRV
);
484 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_INSTALLFAILED
);
502 IncludePath(HWND Dlg
, BOOL Enabled
)
504 EnableWindow(GetDlgItem(Dlg
, IDC_COMBO_PATH
), Enabled
);
505 EnableWindow(GetDlgItem(Dlg
, IDC_BROWSE
), Enabled
);
509 AutoDriver(HWND Dlg
, BOOL Enabled
)
511 EnableWindow(GetDlgItem(Dlg
, IDC_CHECK_MEDIA
), Enabled
);
512 EnableWindow(GetDlgItem(Dlg
, IDC_CHECK_PATH
), Enabled
);
513 IncludePath(Dlg
, Enabled
& IsDlgButtonChecked(Dlg
, IDC_CHECK_PATH
));
516 static INT_PTR CALLBACK
523 PDEVINSTDATA DevInstData
;
525 /* Retrieve pointer to the global setup data */
526 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
535 /* Get pointer to the global setup data */
536 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
537 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
539 hwndControl
= GetParent(hwndDlg
);
541 /* Center the wizard window */
542 CenterWindow(hwndControl
);
544 /* Hide the system menu */
545 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
546 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
548 PopulateCustomPathCombo(GetDlgItem(hwndDlg
, IDC_COMBO_PATH
));
552 IDC_RADIO_SEARCHHERE
,
556 AutoDriver(hwndDlg
, TRUE
);
557 IncludePath(hwndDlg
, FALSE
);
559 /* Disable manual driver choice for now */
560 EnableWindow(GetDlgItem(hwndDlg
, IDC_RADIO_CHOOSE
), FALSE
);
567 switch (LOWORD(wParam
))
569 case IDC_RADIO_SEARCHHERE
:
570 AutoDriver(hwndDlg
, TRUE
);
573 case IDC_RADIO_CHOOSE
:
574 AutoDriver(hwndDlg
, FALSE
);
578 IncludePath(hwndDlg
, IsDlgButtonChecked(hwndDlg
, IDC_CHECK_PATH
));
583 BROWSEINFO bi
= { 0 };
586 bi
.hwndOwner
= hwndDlg
;
587 bi
.ulFlags
= BIF_RETURNONLYFSDIRS
;
588 pidl
= SHBrowseForFolder(&bi
);
591 WCHAR Directory
[MAX_PATH
];
594 if (SHGetPathFromIDListW(pidl
, Directory
))
596 /* Set the IDC_COMBO_PATH text */
597 SetWindowTextW(GetDlgItem(hwndDlg
, IDC_COMBO_PATH
), Directory
);
600 /* Free memory, if possible */
601 if (SUCCEEDED(SHGetMalloc(&malloc
)))
603 IMalloc_Free(malloc
, pidl
);
604 IMalloc_Release(malloc
);
616 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
621 /* Enable the Next and Back buttons */
622 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
| PSWIZB_BACK
);
626 /* Handle a Next button click, if necessary */
627 if (IsDlgButtonChecked(hwndDlg
, IDC_RADIO_SEARCHHERE
))
629 SaveCustomPath(GetDlgItem(hwndDlg
, IDC_COMBO_PATH
));
630 HeapFree(GetProcessHeap(), 0, DevInstData
->CustomSearchPath
);
631 DevInstData
->CustomSearchPath
= NULL
;
632 if (PrepareFoldersToScan(
634 IsDlgButtonChecked(hwndDlg
, IDC_CHECK_MEDIA
),
635 IsDlgButtonChecked(hwndDlg
, IDC_CHECK_PATH
),
636 GetDlgItem(hwndDlg
, IDC_COMBO_PATH
)))
638 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_SEARCHDRV
);
642 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_INSTALLFAILED
);
664 static INT_PTR CALLBACK
671 PDEVINSTDATA DevInstData
;
674 /* Retrieve pointer to the global setup data */
675 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
684 /* Get pointer to the global setup data */
685 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
686 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
688 DevInstData
->hDialog
= hwndDlg
;
689 hwndControl
= GetParent(hwndDlg
);
691 /* Center the wizard window */
692 CenterWindow(hwndControl
);
699 (LPARAM
)DevInstData
->buffer
);
701 /* Hide the system menu */
702 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
703 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
707 case WM_SEARCH_FINISHED
:
709 CloseHandle(hThread
);
712 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_NODRIVER
);
714 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_INSTALLDRV
);
720 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
725 PropSheet_SetWizButtons(GetParent(hwndDlg
), !PSWIZB_NEXT
| !PSWIZB_BACK
);
726 /* Yes, we can safely ignore the problem (if any) */
727 SetupDiDestroyDriverInfoList(
728 DevInstData
->hDevInfo
,
729 &DevInstData
->devInfoData
,
731 hThread
= CreateThread(NULL
, 0, FindDriverProc
, DevInstData
, 0, &dwThreadId
);
737 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, TRUE
);
743 /* Handle a Next button click, if necessary */
759 static INT_PTR CALLBACK
766 PDEVINSTDATA DevInstData
;
769 /* Retrieve pointer to the global setup data */
770 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
779 /* Get pointer to the global setup data */
780 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
781 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
783 DevInstData
->hDialog
= hwndDlg
;
784 hwndControl
= GetParent(hwndDlg
);
786 /* Center the wizard window */
787 CenterWindow(hwndControl
);
794 (LPARAM
)DevInstData
->drvInfoData
.Description
);
796 /* Hide the system menu */
797 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
798 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
802 case WM_INSTALL_FINISHED
:
804 CloseHandle(hThread
);
808 /* Should we reboot? */
809 SP_DEVINSTALL_PARAMS installParams
;
810 installParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
811 if (SetupDiGetDeviceInstallParams(
812 DevInstData
->hDevInfo
,
813 &DevInstData
->devInfoData
,
816 if (installParams
.Flags
& (DI_NEEDRESTART
| DI_NEEDREBOOT
))
818 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_NEEDREBOOT
);
821 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_FINISHPAGE
);
825 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_INSTALLFAILED
);
831 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
836 PropSheet_SetWizButtons(GetParent(hwndDlg
), !PSWIZB_NEXT
| !PSWIZB_BACK
);
837 hThread
= CreateThread(NULL
, 0, InstallDriverProc
, DevInstData
, 0, &dwThreadId
);
843 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, TRUE
);
849 /* Handle a Next button click, if necessary */
865 static INT_PTR CALLBACK
872 PDEVINSTDATA DevInstData
;
875 UNREFERENCED_PARAMETER(wParam
);
877 /* Get pointer to the global setup data */
878 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
884 BOOL DisableableDevice
= FALSE
;
886 /* Get pointer to the global setup data */
887 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
888 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
890 /* Center the wizard window */
891 CenterWindow(GetParent(hwndDlg
));
893 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
894 ShowWindow(hwndControl
, SW_HIDE
);
895 EnableWindow(hwndControl
, FALSE
);
902 (WPARAM
)DevInstData
->hTitleFont
,
905 /* disable the "do not show this dialog anymore" checkbox
906 if the device cannot be disabled */
908 DevInstData
->devInfoData
.DevInst
,
912 GetDlgItem(hwndDlg
, IDC_DONOTSHOWDLG
),
919 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
924 /* Enable the correct buttons on for the active page */
925 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_FINISH
);
929 /* Handle a Back button click, if necessary */
930 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
931 ShowWindow(hwndControl
, SW_SHOW
);
932 EnableWindow(hwndControl
, TRUE
);
933 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_CHSOURCE
);
938 BOOL DisableableDevice
= FALSE
;
939 BOOL IsStarted
= FALSE
;
941 if (CanDisableDevice(DevInstData
->devInfoData
.DevInst
,
943 &DisableableDevice
) &&
946 DevInstData
->devInfoData
.DevInst
,
954 (WPARAM
)0, (LPARAM
)0) == BST_CHECKED
)
956 /* disable the device */
958 DevInstData
->hDevInfo
,
959 &DevInstData
->devInfoData
,
980 static INT_PTR CALLBACK
981 InstallFailedDlgProc(
987 PDEVINSTDATA DevInstData
;
988 UNREFERENCED_PARAMETER(wParam
);
990 /* Retrieve pointer to the global setup data */
991 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
999 /* Get pointer to the global setup data */
1000 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1001 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
1003 /* Center the wizard window */
1004 CenterWindow(GetParent(hwndDlg
));
1006 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
1007 ShowWindow(hwndControl
, SW_HIDE
);
1008 EnableWindow(hwndControl
, FALSE
);
1015 (LPARAM
)DevInstData
->drvInfoData
.Description
);
1017 /* Set title font */
1022 (WPARAM
)DevInstData
->hTitleFont
,
1029 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1034 /* Enable the correct buttons on for the active page */
1035 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
1039 /* Handle a Back button click, if necessary */
1043 /* Handle a Finish button click, if necessary */
1059 static INT_PTR CALLBACK
1066 PDEVINSTDATA DevInstData
;
1067 UNREFERENCED_PARAMETER(wParam
);
1069 /* Retrieve pointer to the global setup data */
1070 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
1078 /* Get pointer to the global setup data */
1079 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1080 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
1082 /* Center the wizard window */
1083 CenterWindow(GetParent(hwndDlg
));
1085 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
1086 ShowWindow(hwndControl
, SW_HIDE
);
1087 EnableWindow(hwndControl
, FALSE
);
1094 (LPARAM
)DevInstData
->drvInfoData
.Description
);
1096 /* Set title font */
1101 (WPARAM
)DevInstData
->hTitleFont
,
1108 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1113 /* Enable the correct buttons on for the active page */
1114 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
1118 /* Handle a Back button click, if necessary */
1122 /* Handle a Finish button click, if necessary */
1138 static INT_PTR CALLBACK
1145 PDEVINSTDATA DevInstData
;
1146 UNREFERENCED_PARAMETER(wParam
);
1148 /* Retrieve pointer to the global setup data */
1149 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
1157 /* Get pointer to the global setup data */
1158 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1159 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
1161 /* Center the wizard window */
1162 CenterWindow(GetParent(hwndDlg
));
1164 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
1165 ShowWindow(hwndControl
, SW_HIDE
);
1166 EnableWindow(hwndControl
, FALSE
);
1173 (LPARAM
)DevInstData
->drvInfoData
.Description
);
1175 /* Set title font */
1180 (WPARAM
)DevInstData
->hTitleFont
,
1187 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1192 /* Enable the correct buttons on for the active page */
1193 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
1197 /* Handle a Back button click, if necessary */
1201 /* Handle a Finish button click, if necessary */
1218 CreateTitleFont(VOID
)
1220 NONCLIENTMETRICSW ncm
;
1226 ncm
.cbSize
= sizeof(NONCLIENTMETRICSW
);
1227 SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, 0, &ncm
, 0);
1229 LogFont
= ncm
.lfMessageFont
;
1230 LogFont
.lfWeight
= FW_BOLD
;
1231 wcscpy(LogFont
.lfFaceName
, L
"MS Shell Dlg");
1235 LogFont
.lfHeight
= 0 - GetDeviceCaps (hdc
, LOGPIXELSY
) * FontSize
/ 72;
1236 hFont
= CreateFontIndirectW(&LogFont
);
1237 ReleaseDC(NULL
, hdc
);
1244 IN PDEVINSTDATA DevInstData
,
1248 PROPSHEETHEADER psh
;
1249 HPROPSHEETPAGE ahpsp
[IDD_MAXIMUMPAGE
+ 1];
1252 /* Create the Welcome page */
1253 ZeroMemory(&psp
, sizeof(PROPSHEETPAGE
));
1254 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
1255 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1256 psp
.hInstance
= hDllInstance
;
1257 psp
.lParam
= (LPARAM
)DevInstData
;
1258 psp
.pfnDlgProc
= (DLGPROC
) WelcomeDlgProc
;
1259 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_WELCOMEPAGE
);
1260 ahpsp
[IDD_WELCOMEPAGE
] = CreatePropertySheetPage(&psp
);
1262 /* Create the Select Source page */
1263 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
1264 psp
.pfnDlgProc
= (DLGPROC
) CHSourceDlgProc
;
1265 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_CHSOURCE
);
1266 ahpsp
[IDD_CHSOURCE
] = CreatePropertySheetPage(&psp
);
1268 /* Create the Search driver page */
1269 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
1270 psp
.pfnDlgProc
= (DLGPROC
) SearchDrvDlgProc
;
1271 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_SEARCHDRV
);
1272 ahpsp
[IDD_SEARCHDRV
] = CreatePropertySheetPage(&psp
);
1274 /* Create the Install driver page */
1275 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
1276 psp
.pfnDlgProc
= (DLGPROC
) InstallDrvDlgProc
;
1277 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_INSTALLDRV
);
1278 ahpsp
[IDD_INSTALLDRV
] = CreatePropertySheetPage(&psp
);
1280 /* Create the No driver page */
1281 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1282 psp
.pfnDlgProc
= (DLGPROC
) NoDriverDlgProc
;
1283 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_NODRIVER
);
1284 ahpsp
[IDD_NODRIVER
] = CreatePropertySheetPage(&psp
);
1286 /* Create the Install failed page */
1287 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1288 psp
.pfnDlgProc
= (DLGPROC
) InstallFailedDlgProc
;
1289 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_INSTALLFAILED
);
1290 ahpsp
[IDD_INSTALLFAILED
] = CreatePropertySheetPage(&psp
);
1292 /* Create the Need reboot page */
1293 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1294 psp
.pfnDlgProc
= (DLGPROC
) NeedRebootDlgProc
;
1295 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_NEEDREBOOT
);
1296 ahpsp
[IDD_NEEDREBOOT
] = CreatePropertySheetPage(&psp
);
1298 /* Create the Finish page */
1299 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1300 psp
.pfnDlgProc
= (DLGPROC
) FinishDlgProc
;
1301 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_FINISHPAGE
);
1302 ahpsp
[IDD_FINISHPAGE
] = CreatePropertySheetPage(&psp
);
1304 /* Create the property sheet */
1305 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
1306 psh
.dwFlags
= PSH_WIZARD97
| PSH_WATERMARK
| PSH_HEADER
;
1307 psh
.hInstance
= hDllInstance
;
1308 psh
.hwndParent
= hwndParent
;
1309 psh
.nPages
= IDD_MAXIMUMPAGE
+ 1;
1310 psh
.nStartPage
= startPage
;
1312 psh
.pszbmWatermark
= MAKEINTRESOURCE(IDB_WATERMARK
);
1313 psh
.pszbmHeader
= MAKEINTRESOURCE(IDB_HEADER
);
1315 /* Create title font */
1316 DevInstData
->hTitleFont
= CreateTitleFont();
1318 /* Display the wizard */
1319 PropertySheet(&psh
);
1321 DeleteObject(DevInstData
->hTitleFont
);