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"
33 hWndParent
= GetParent(hWnd
);
34 if (hWndParent
== NULL
)
35 hWndParent
= GetDesktopWindow();
37 GetWindowRect(hWndParent
, &rcParent
);
38 GetWindowRect(hWnd
, &rcWindow
);
43 ((rcParent
.right
- rcParent
.left
) - (rcWindow
.right
- rcWindow
.left
)) / 2,
44 ((rcParent
.bottom
- rcParent
.top
) - (rcWindow
.bottom
- rcWindow
.top
)) / 2,
57 ULONG Status
, ProblemNumber
;
60 cr
= CM_Get_DevNode_Status_Ex(&Status
,
67 *CanDisable
= ((Status
& DN_DISABLEABLE
) != 0);
81 ULONG Status
, ProblemNumber
;
84 cr
= CM_Get_DevNode_Status_Ex(
92 *IsEnabled
= ((Status
& DN_STARTED
) != 0);
101 IN HDEVINFO DeviceInfoSet
,
102 IN PSP_DEVINFO_DATA DevInfoData OPTIONAL
,
104 IN DWORD HardwareProfile OPTIONAL
,
105 OUT BOOL
*bNeedReboot OPTIONAL
)
107 SP_PROPCHANGE_PARAMS pcp
;
108 SP_DEVINSTALL_PARAMS dp
;
112 pcp
.ClassInstallHeader
.cbSize
= sizeof(SP_CLASSINSTALL_HEADER
);
113 pcp
.ClassInstallHeader
.InstallFunction
= DIF_PROPERTYCHANGE
;
114 pcp
.HwProfile
= HardwareProfile
;
118 /* try to enable the device on the global profile */
119 pcp
.StateChange
= DICS_ENABLE
;
120 pcp
.Scope
= DICS_FLAG_GLOBAL
;
123 LastErr
= GetLastError();
124 if (SetupDiSetClassInstallParams(
127 &pcp
.ClassInstallHeader
,
128 sizeof(SP_PROPCHANGE_PARAMS
)))
130 SetupDiCallClassInstaller(
135 SetLastError(LastErr
);
138 /* try config-specific */
139 pcp
.StateChange
= (bEnable
? DICS_ENABLE
: DICS_DISABLE
);
140 pcp
.Scope
= DICS_FLAG_CONFIGSPECIFIC
;
142 if (SetupDiSetClassInstallParams(
145 &pcp
.ClassInstallHeader
,
146 sizeof(SP_PROPCHANGE_PARAMS
)) &&
147 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE
,
151 dp
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
152 if (SetupDiGetDeviceInstallParams(
157 if (bNeedReboot
!= NULL
)
159 *bNeedReboot
= ((dp
.Flags
& (DI_NEEDRESTART
| DI_NEEDREBOOT
)) != 0);
172 PDEVINSTDATA DevInstData
;
176 DevInstData
= (PDEVINSTDATA
)lpParam
;
178 result
= ScanFoldersForDriver(DevInstData
);
182 PostMessage(DevInstData
->hDialog
, WM_SEARCH_FINISHED
, 1, 0);
186 /* Update device configuration */
187 if (SetupDiGetDeviceRegistryProperty(
188 DevInstData
->hDevInfo
,
189 &DevInstData
->devInfoData
,
192 (BYTE
*)&config_flags
,
193 sizeof(config_flags
),
196 config_flags
|= CONFIGFLAG_FAILEDINSTALL
;
197 SetupDiSetDeviceRegistryPropertyW(
198 DevInstData
->hDevInfo
,
199 &DevInstData
->devInfoData
,
201 (BYTE
*)&config_flags
, sizeof(config_flags
));
204 PostMessage(DevInstData
->hDialog
, WM_SEARCH_FINISHED
, 0, 0);
213 PDEVINSTDATA DevInstData
;
216 DevInstData
= (PDEVINSTDATA
)lpParam
;
217 res
= InstallCurrentDriver(DevInstData
);
218 PostMessage(DevInstData
->hDialog
, WM_INSTALL_FINISHED
, res
? 0 : 1, 0);
223 PopulateCustomPathCombo(
228 DWORD dwPathLength
= 0;
229 LPWSTR Buffer
= NULL
;
233 (void)ComboBox_ResetContent(hwndCombo
);
235 /* RegGetValue would have been better... */
238 REGSTR_PATH_SETUP REGSTR_KEY_SETUP
,
242 if (rc
!= ERROR_SUCCESS
)
244 TRACE("RegOpenKeyEx() failed with error 0x%lx\n", rc
);
247 rc
= RegQueryValueExW(
249 L
"Installation Sources",
254 if (rc
!= ERROR_SUCCESS
|| dwRegType
!= REG_MULTI_SZ
)
256 TRACE("RegQueryValueEx() failed with error 0x%lx\n", rc
);
260 /* Allocate enough space to add 2 NULL chars at the end of the string */
261 Buffer
= HeapAlloc(GetProcessHeap(), 0, dwPathLength
+ 2 * sizeof(WCHAR
));
264 TRACE("HeapAlloc() failed\n");
267 rc
= RegQueryValueExW(
269 L
"Installation Sources",
274 if (rc
!= ERROR_SUCCESS
)
276 TRACE("RegQueryValueEx() failed with error 0x%lx\n", rc
);
279 Buffer
[dwPathLength
] = Buffer
[dwPathLength
+ 1] = '\0';
281 /* Populate combo box */
282 for (Path
= Buffer
; *Path
; Path
+= wcslen(Path
) + 1)
284 (void)ComboBox_AddString(hwndCombo
, Path
);
286 (void)ComboBox_SetCurSel(hwndCombo
, 0);
292 HeapFree(GetProcessHeap(), 0, Buffer
);
299 LPWSTR CustomPath
= NULL
;
300 DWORD CustomPathLength
;
301 LPWSTR Buffer
= NULL
;
302 LPWSTR pBuffer
; /* Pointer into Buffer */
303 int ItemsCount
, Length
;
305 DWORD TotalLength
= 0;
306 BOOL UseCustomPath
= TRUE
;
310 /* Get custom path */
311 Length
= ComboBox_GetTextLength(hwndCombo
) + 1;
312 CustomPath
= HeapAlloc(GetProcessHeap(), 0, Length
* sizeof(WCHAR
));
315 TRACE("HeapAlloc() failed\n");
318 CustomPathLength
= GetWindowTextW(hwndCombo
, CustomPath
, Length
) + 1;
320 /* Calculate length of the buffer */
321 ItemsCount
= ComboBox_GetCount(hwndCombo
);
322 if (ItemsCount
== CB_ERR
)
324 TRACE("ComboBox_GetCount() failed\n");
327 for (i
= 0; i
< ItemsCount
; i
++)
329 Length
= ComboBox_GetLBTextLen(hwndCombo
, i
);
330 if (Length
== CB_ERR
)
332 TRACE("ComboBox_GetLBTextLen() failed\n");
335 TotalLength
+= Length
+ 1;
337 TotalLength
++; /* Final NULL char */
339 /* Allocate buffer */
340 Buffer
= HeapAlloc(GetProcessHeap(), 0, (CustomPathLength
+ TotalLength
+ 1) * sizeof(WCHAR
));
343 TRACE("HeapAlloc() failed\n");
347 /* Fill the buffer */
348 pBuffer
= &Buffer
[CustomPathLength
];
349 for (i
= 0; i
< ItemsCount
; i
++)
351 Length
= ComboBox_GetLBText(hwndCombo
, i
, pBuffer
);
352 if (Length
== CB_ERR
)
354 TRACE("ComboBox_GetLBText() failed\n");
357 else if (UseCustomPath
&& _wcsicmp(CustomPath
, pBuffer
) == 0)
358 UseCustomPath
= FALSE
;
359 pBuffer
+= 1 + Length
;
361 *pBuffer
= '\0'; /* Add final NULL char */
365 /* Nothing to save to registry */
369 TotalLength
+= CustomPathLength
;
370 wcscpy(Buffer
, CustomPath
);
372 /* Save the buffer */
373 /* RegSetKeyValue would have been better... */
376 REGSTR_PATH_SETUP REGSTR_KEY_SETUP
,
380 if (rc
!= ERROR_SUCCESS
)
382 TRACE("RegOpenKeyEx() failed with error 0x%lx\n", rc
);
387 L
"Installation Sources",
391 TotalLength
* sizeof(WCHAR
));
392 if (rc
!= ERROR_SUCCESS
)
394 TRACE("RegSetValueEx() failed with error 0x%lx\n", rc
);
401 HeapFree(GetProcessHeap(), 0, CustomPath
);
402 HeapFree(GetProcessHeap(), 0, Buffer
);
405 static INT_PTR CALLBACK
412 PDEVINSTDATA DevInstData
;
413 UNREFERENCED_PARAMETER(wParam
);
415 /* Retrieve pointer to the global setup data */
416 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
425 /* Get pointer to the global setup data */
426 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
427 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
429 hwndControl
= GetParent(hwndDlg
);
431 /* Center the wizard window */
432 CenterWindow(hwndControl
);
434 /* Hide the system menu */
435 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
436 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
443 (WPARAM
)DevInstData
->hTitleFont
,
451 (LPARAM
)DevInstData
->buffer
);
464 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
469 /* Enable the Next button */
470 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
474 /* Handle a Next button click, if necessary */
475 if (SendDlgItemMessage(hwndDlg
, IDC_RADIO_AUTO
, BM_GETCHECK
, (WPARAM
)0, (LPARAM
)0) == BST_CHECKED
)
477 if (PrepareFoldersToScan(DevInstData
, TRUE
, FALSE
, NULL
))
478 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_SEARCHDRV
);
480 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_INSTALLFAILED
);
498 IncludePath(HWND Dlg
, BOOL Enabled
)
500 EnableWindow(GetDlgItem(Dlg
, IDC_COMBO_PATH
), Enabled
);
501 EnableWindow(GetDlgItem(Dlg
, IDC_BROWSE
), Enabled
);
505 AutoDriver(HWND Dlg
, BOOL Enabled
)
507 EnableWindow(GetDlgItem(Dlg
, IDC_CHECK_MEDIA
), Enabled
);
508 EnableWindow(GetDlgItem(Dlg
, IDC_CHECK_PATH
), Enabled
);
509 IncludePath(Dlg
, Enabled
& IsDlgButtonChecked(Dlg
, IDC_CHECK_PATH
));
512 static INT_PTR CALLBACK
519 PDEVINSTDATA DevInstData
;
521 /* Retrieve pointer to the global setup data */
522 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
531 /* Get pointer to the global setup data */
532 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
533 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
535 hwndControl
= GetParent(hwndDlg
);
537 /* Center the wizard window */
538 CenterWindow(hwndControl
);
540 /* Hide the system menu */
541 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
542 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
544 PopulateCustomPathCombo(GetDlgItem(hwndDlg
, IDC_COMBO_PATH
));
548 IDC_RADIO_SEARCHHERE
,
552 AutoDriver(hwndDlg
, TRUE
);
553 IncludePath(hwndDlg
, FALSE
);
555 /* Disable manual driver choice for now */
556 EnableWindow(GetDlgItem(hwndDlg
, IDC_RADIO_CHOOSE
), FALSE
);
563 switch (LOWORD(wParam
))
565 case IDC_RADIO_SEARCHHERE
:
566 AutoDriver(hwndDlg
, TRUE
);
569 case IDC_RADIO_CHOOSE
:
570 AutoDriver(hwndDlg
, FALSE
);
574 IncludePath(hwndDlg
, IsDlgButtonChecked(hwndDlg
, IDC_CHECK_PATH
));
579 BROWSEINFO bi
= { 0 };
582 bi
.hwndOwner
= hwndDlg
;
583 bi
.ulFlags
= BIF_RETURNONLYFSDIRS
;
584 pidl
= SHBrowseForFolder(&bi
);
587 WCHAR Directory
[MAX_PATH
];
590 if (SHGetPathFromIDListW(pidl
, Directory
))
592 /* Set the IDC_COMBO_PATH text */
593 SetWindowTextW(GetDlgItem(hwndDlg
, IDC_COMBO_PATH
), Directory
);
596 /* Free memory, if possible */
597 if (SUCCEEDED(SHGetMalloc(&malloc
)))
599 IMalloc_Free(malloc
, pidl
);
600 IMalloc_Release(malloc
);
612 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
617 /* Enable the Next and Back buttons */
618 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
| PSWIZB_BACK
);
622 /* Handle a Next button click, if necessary */
623 if (IsDlgButtonChecked(hwndDlg
, IDC_RADIO_SEARCHHERE
))
625 SaveCustomPath(GetDlgItem(hwndDlg
, IDC_COMBO_PATH
));
626 HeapFree(GetProcessHeap(), 0, DevInstData
->CustomSearchPath
);
627 DevInstData
->CustomSearchPath
= NULL
;
628 if (PrepareFoldersToScan(
630 IsDlgButtonChecked(hwndDlg
, IDC_CHECK_MEDIA
),
631 IsDlgButtonChecked(hwndDlg
, IDC_CHECK_PATH
),
632 GetDlgItem(hwndDlg
, IDC_COMBO_PATH
)))
634 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_SEARCHDRV
);
638 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_INSTALLFAILED
);
660 static INT_PTR CALLBACK
667 PDEVINSTDATA DevInstData
;
670 /* Retrieve pointer to the global setup data */
671 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
680 /* Get pointer to the global setup data */
681 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
682 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
684 DevInstData
->hDialog
= hwndDlg
;
685 hwndControl
= GetParent(hwndDlg
);
687 /* Center the wizard window */
688 CenterWindow(hwndControl
);
695 (LPARAM
)DevInstData
->buffer
);
697 /* Hide the system menu */
698 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
699 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
703 case WM_SEARCH_FINISHED
:
705 CloseHandle(hThread
);
708 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_NODRIVER
);
710 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_INSTALLDRV
);
716 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
721 PropSheet_SetWizButtons(GetParent(hwndDlg
), !PSWIZB_NEXT
| !PSWIZB_BACK
);
722 /* Yes, we can safely ignore the problem (if any) */
723 SetupDiDestroyDriverInfoList(
724 DevInstData
->hDevInfo
,
725 &DevInstData
->devInfoData
,
727 hThread
= CreateThread(NULL
, 0, FindDriverProc
, DevInstData
, 0, &dwThreadId
);
733 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, TRUE
);
739 /* Handle a Next button click, if necessary */
755 static INT_PTR CALLBACK
762 PDEVINSTDATA DevInstData
;
765 /* Retrieve pointer to the global setup data */
766 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
775 /* Get pointer to the global setup data */
776 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
777 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
779 DevInstData
->hDialog
= hwndDlg
;
780 hwndControl
= GetParent(hwndDlg
);
782 /* Center the wizard window */
783 CenterWindow(hwndControl
);
790 (LPARAM
)DevInstData
->drvInfoData
.Description
);
792 /* Hide the system menu */
793 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
794 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
798 case WM_INSTALL_FINISHED
:
800 CloseHandle(hThread
);
804 /* Should we reboot? */
805 SP_DEVINSTALL_PARAMS installParams
;
806 installParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
807 if (SetupDiGetDeviceInstallParams(
808 DevInstData
->hDevInfo
,
809 &DevInstData
->devInfoData
,
812 if (installParams
.Flags
& (DI_NEEDRESTART
| DI_NEEDREBOOT
))
814 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_NEEDREBOOT
);
817 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_FINISHPAGE
);
821 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_INSTALLFAILED
);
827 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
832 PropSheet_SetWizButtons(GetParent(hwndDlg
), !PSWIZB_NEXT
| !PSWIZB_BACK
);
833 hThread
= CreateThread(NULL
, 0, InstallDriverProc
, DevInstData
, 0, &dwThreadId
);
839 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, TRUE
);
845 /* Handle a Next button click, if necessary */
861 static INT_PTR CALLBACK
868 PDEVINSTDATA DevInstData
;
871 UNREFERENCED_PARAMETER(wParam
);
873 /* Get pointer to the global setup data */
874 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
880 BOOL DisableableDevice
= FALSE
;
882 /* Get pointer to the global setup data */
883 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
884 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
886 /* Center the wizard window */
887 CenterWindow(GetParent(hwndDlg
));
889 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
890 ShowWindow(hwndControl
, SW_HIDE
);
891 EnableWindow(hwndControl
, FALSE
);
898 (WPARAM
)DevInstData
->hTitleFont
,
901 /* disable the "do not show this dialog anymore" checkbox
902 if the device cannot be disabled */
904 DevInstData
->devInfoData
.DevInst
,
908 GetDlgItem(hwndDlg
, IDC_DONOTSHOWDLG
),
915 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
920 /* Enable the correct buttons on for the active page */
921 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_FINISH
);
925 /* Handle a Back button click, if necessary */
926 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
927 ShowWindow(hwndControl
, SW_SHOW
);
928 EnableWindow(hwndControl
, TRUE
);
929 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_CHSOURCE
);
934 BOOL DisableableDevice
= FALSE
;
935 BOOL IsStarted
= FALSE
;
937 if (CanDisableDevice(DevInstData
->devInfoData
.DevInst
,
939 &DisableableDevice
) &&
942 DevInstData
->devInfoData
.DevInst
,
950 (WPARAM
)0, (LPARAM
)0) == BST_CHECKED
)
952 /* disable the device */
954 DevInstData
->hDevInfo
,
955 &DevInstData
->devInfoData
,
976 static INT_PTR CALLBACK
977 InstallFailedDlgProc(
983 PDEVINSTDATA DevInstData
;
984 UNREFERENCED_PARAMETER(wParam
);
986 /* Retrieve pointer to the global setup data */
987 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
995 /* Get pointer to the global setup data */
996 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
997 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
999 /* Center the wizard window */
1000 CenterWindow(GetParent(hwndDlg
));
1002 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
1003 ShowWindow(hwndControl
, SW_HIDE
);
1004 EnableWindow(hwndControl
, FALSE
);
1011 (LPARAM
)DevInstData
->drvInfoData
.Description
);
1013 /* Set title font */
1018 (WPARAM
)DevInstData
->hTitleFont
,
1025 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1030 /* Enable the correct buttons on for the active page */
1031 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
1035 /* Handle a Back button click, if necessary */
1039 /* Handle a Finish button click, if necessary */
1055 static INT_PTR CALLBACK
1062 PDEVINSTDATA DevInstData
;
1063 UNREFERENCED_PARAMETER(wParam
);
1065 /* Retrieve pointer to the global setup data */
1066 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
1074 /* Get pointer to the global setup data */
1075 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1076 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
1078 /* Center the wizard window */
1079 CenterWindow(GetParent(hwndDlg
));
1081 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
1082 ShowWindow(hwndControl
, SW_HIDE
);
1083 EnableWindow(hwndControl
, FALSE
);
1090 (LPARAM
)DevInstData
->drvInfoData
.Description
);
1092 /* Set title font */
1097 (WPARAM
)DevInstData
->hTitleFont
,
1104 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1109 /* Enable the correct buttons on for the active page */
1110 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
1114 /* Handle a Back button click, if necessary */
1118 /* Handle a Finish button click, if necessary */
1134 static INT_PTR CALLBACK
1141 PDEVINSTDATA DevInstData
;
1142 UNREFERENCED_PARAMETER(wParam
);
1144 /* Retrieve pointer to the global setup data */
1145 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
1153 /* Get pointer to the global setup data */
1154 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1155 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
1157 /* Center the wizard window */
1158 CenterWindow(GetParent(hwndDlg
));
1160 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
1161 ShowWindow(hwndControl
, SW_HIDE
);
1162 EnableWindow(hwndControl
, FALSE
);
1169 (LPARAM
)DevInstData
->drvInfoData
.Description
);
1171 /* Set title font */
1176 (WPARAM
)DevInstData
->hTitleFont
,
1183 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1188 /* Enable the correct buttons on for the active page */
1189 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
1193 /* Handle a Back button click, if necessary */
1197 /* Handle a Finish button click, if necessary */
1214 CreateTitleFont(VOID
)
1216 NONCLIENTMETRICSW ncm
;
1222 ncm
.cbSize
= sizeof(NONCLIENTMETRICSW
);
1223 SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, 0, &ncm
, 0);
1225 LogFont
= ncm
.lfMessageFont
;
1226 LogFont
.lfWeight
= FW_BOLD
;
1227 wcscpy(LogFont
.lfFaceName
, L
"MS Shell Dlg");
1231 LogFont
.lfHeight
= 0 - GetDeviceCaps (hdc
, LOGPIXELSY
) * FontSize
/ 72;
1232 hFont
= CreateFontIndirectW(&LogFont
);
1233 ReleaseDC(NULL
, hdc
);
1240 IN PDEVINSTDATA DevInstData
,
1244 PROPSHEETHEADER psh
;
1245 HPROPSHEETPAGE ahpsp
[IDD_MAXIMUMPAGE
+ 1];
1248 /* Create the Welcome page */
1249 ZeroMemory(&psp
, sizeof(PROPSHEETPAGE
));
1250 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
1251 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1252 psp
.hInstance
= hDllInstance
;
1253 psp
.lParam
= (LPARAM
)DevInstData
;
1254 psp
.pfnDlgProc
= (DLGPROC
) WelcomeDlgProc
;
1255 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_WELCOMEPAGE
);
1256 ahpsp
[IDD_WELCOMEPAGE
] = CreatePropertySheetPage(&psp
);
1258 /* Create the Select Source page */
1259 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
1260 psp
.pfnDlgProc
= (DLGPROC
) CHSourceDlgProc
;
1261 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_CHSOURCE
);
1262 ahpsp
[IDD_CHSOURCE
] = CreatePropertySheetPage(&psp
);
1264 /* Create the Search driver page */
1265 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
1266 psp
.pfnDlgProc
= (DLGPROC
) SearchDrvDlgProc
;
1267 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_SEARCHDRV
);
1268 ahpsp
[IDD_SEARCHDRV
] = CreatePropertySheetPage(&psp
);
1270 /* Create the Install driver page */
1271 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
1272 psp
.pfnDlgProc
= (DLGPROC
) InstallDrvDlgProc
;
1273 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_INSTALLDRV
);
1274 ahpsp
[IDD_INSTALLDRV
] = CreatePropertySheetPage(&psp
);
1276 /* Create the No driver page */
1277 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1278 psp
.pfnDlgProc
= (DLGPROC
) NoDriverDlgProc
;
1279 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_NODRIVER
);
1280 ahpsp
[IDD_NODRIVER
] = CreatePropertySheetPage(&psp
);
1282 /* Create the Install failed page */
1283 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1284 psp
.pfnDlgProc
= (DLGPROC
) InstallFailedDlgProc
;
1285 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_INSTALLFAILED
);
1286 ahpsp
[IDD_INSTALLFAILED
] = CreatePropertySheetPage(&psp
);
1288 /* Create the Need reboot page */
1289 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1290 psp
.pfnDlgProc
= (DLGPROC
) NeedRebootDlgProc
;
1291 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_NEEDREBOOT
);
1292 ahpsp
[IDD_NEEDREBOOT
] = CreatePropertySheetPage(&psp
);
1294 /* Create the Finish page */
1295 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1296 psp
.pfnDlgProc
= (DLGPROC
) FinishDlgProc
;
1297 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_FINISHPAGE
);
1298 ahpsp
[IDD_FINISHPAGE
] = CreatePropertySheetPage(&psp
);
1300 /* Create the property sheet */
1301 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
1302 psh
.dwFlags
= PSH_WIZARD97
| PSH_WATERMARK
| PSH_HEADER
;
1303 psh
.hInstance
= hDllInstance
;
1304 psh
.hwndParent
= hwndParent
;
1305 psh
.nPages
= IDD_MAXIMUMPAGE
+ 1;
1306 psh
.nStartPage
= startPage
;
1308 psh
.pszbmWatermark
= MAKEINTRESOURCE(IDB_WATERMARK
);
1309 psh
.pszbmHeader
= MAKEINTRESOURCE(IDB_HEADER
);
1311 /* Create title font */
1312 DevInstData
->hTitleFont
= CreateTitleFont();
1314 /* Display the wizard */
1315 PropertySheet(&psh
);
1317 DeleteObject(DevInstData
->hTitleFont
);