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,
56 IN HDEVINFO DeviceInfoSet
,
57 IN PSP_DEVINFO_DATA DevInfoData OPTIONAL
,
60 DWORD dwType
, dwSize
, dwFlags
= 0;
62 dwSize
= sizeof(dwFlags
);
63 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet
,
75 dwFlags
|= CONFIGFLAG_FAILEDINSTALL
;
77 dwFlags
&= ~CONFIGFLAG_FAILEDINSTALL
;
79 if (!SetupDiSetDeviceRegistryProperty(DeviceInfoSet
,
99 ULONG Status
, ProblemNumber
;
102 cr
= CM_Get_DevNode_Status_Ex(&Status
,
107 if (cr
== CR_SUCCESS
)
109 *CanDisable
= ((Status
& DN_DISABLEABLE
) != 0);
119 IN HMACHINE hMachine
,
123 ULONG Status
, ProblemNumber
;
126 cr
= CM_Get_DevNode_Status_Ex(
132 if (cr
== CR_SUCCESS
)
134 *IsEnabled
= ((Status
& DN_STARTED
) != 0);
143 IN HDEVINFO DeviceInfoSet
,
144 IN PSP_DEVINFO_DATA DevInfoData OPTIONAL
,
146 IN DWORD HardwareProfile OPTIONAL
,
147 OUT BOOL
*bNeedReboot OPTIONAL
)
149 SP_PROPCHANGE_PARAMS pcp
;
150 SP_DEVINSTALL_PARAMS dp
;
154 pcp
.ClassInstallHeader
.cbSize
= sizeof(SP_CLASSINSTALL_HEADER
);
155 pcp
.ClassInstallHeader
.InstallFunction
= DIF_PROPERTYCHANGE
;
156 pcp
.HwProfile
= HardwareProfile
;
160 /* try to enable the device on the global profile */
161 pcp
.StateChange
= DICS_ENABLE
;
162 pcp
.Scope
= DICS_FLAG_GLOBAL
;
165 LastErr
= GetLastError();
166 if (SetupDiSetClassInstallParams(
169 &pcp
.ClassInstallHeader
,
170 sizeof(SP_PROPCHANGE_PARAMS
)))
172 SetupDiCallClassInstaller(
177 SetLastError(LastErr
);
180 /* try config-specific */
181 pcp
.StateChange
= (bEnable
? DICS_ENABLE
: DICS_DISABLE
);
182 pcp
.Scope
= DICS_FLAG_CONFIGSPECIFIC
;
184 if (SetupDiSetClassInstallParams(
187 &pcp
.ClassInstallHeader
,
188 sizeof(SP_PROPCHANGE_PARAMS
)) &&
189 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE
,
193 dp
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
194 if (SetupDiGetDeviceInstallParams(
199 if (bNeedReboot
!= NULL
)
201 *bNeedReboot
= ((dp
.Flags
& (DI_NEEDRESTART
| DI_NEEDREBOOT
)) != 0);
214 PDEVINSTDATA DevInstData
;
218 DevInstData
= (PDEVINSTDATA
)lpParam
;
220 result
= ScanFoldersForDriver(DevInstData
);
224 PostMessage(DevInstData
->hDialog
, WM_SEARCH_FINISHED
, 1, 0);
228 /* Update device configuration */
229 if (SetupDiGetDeviceRegistryProperty(
230 DevInstData
->hDevInfo
,
231 &DevInstData
->devInfoData
,
234 (BYTE
*)&config_flags
,
235 sizeof(config_flags
),
238 config_flags
|= CONFIGFLAG_FAILEDINSTALL
;
239 SetupDiSetDeviceRegistryPropertyW(
240 DevInstData
->hDevInfo
,
241 &DevInstData
->devInfoData
,
243 (BYTE
*)&config_flags
, sizeof(config_flags
));
246 PostMessage(DevInstData
->hDialog
, WM_SEARCH_FINISHED
, 0, 0);
255 PDEVINSTDATA DevInstData
;
258 DevInstData
= (PDEVINSTDATA
)lpParam
;
259 res
= InstallCurrentDriver(DevInstData
);
260 PostMessage(DevInstData
->hDialog
, WM_INSTALL_FINISHED
, res
? 0 : 1, 0);
265 PopulateCustomPathCombo(
270 DWORD dwPathLength
= 0;
271 LPWSTR Buffer
= NULL
;
275 (void)ComboBox_ResetContent(hwndCombo
);
277 /* RegGetValue would have been better... */
280 REGSTR_PATH_SETUP REGSTR_KEY_SETUP
,
284 if (rc
!= ERROR_SUCCESS
)
286 TRACE("RegOpenKeyEx() failed with error 0x%lx\n", rc
);
289 rc
= RegQueryValueExW(
291 L
"Installation Sources",
296 if (rc
!= ERROR_SUCCESS
|| dwRegType
!= REG_MULTI_SZ
)
298 TRACE("RegQueryValueEx() failed with error 0x%lx\n", rc
);
302 /* Allocate enough space to add 2 NULL chars at the end of the string */
303 Buffer
= HeapAlloc(GetProcessHeap(), 0, dwPathLength
+ 2 * sizeof(WCHAR
));
306 TRACE("HeapAlloc() failed\n");
309 rc
= RegQueryValueExW(
311 L
"Installation Sources",
316 if (rc
!= ERROR_SUCCESS
)
318 TRACE("RegQueryValueEx() failed with error 0x%lx\n", rc
);
322 Buffer
[dwPathLength
/ sizeof(WCHAR
)] = UNICODE_NULL
;
323 Buffer
[dwPathLength
/ sizeof(WCHAR
) + 1] = UNICODE_NULL
;
325 /* Populate combo box */
326 for (Path
= Buffer
; *Path
; Path
+= wcslen(Path
) + 1)
328 (void)ComboBox_AddString(hwndCombo
, Path
);
330 (void)ComboBox_SetCurSel(hwndCombo
, 0);
336 HeapFree(GetProcessHeap(), 0, Buffer
);
343 LPWSTR CustomPath
= NULL
;
344 DWORD CustomPathLength
;
345 LPWSTR Buffer
= NULL
;
346 LPWSTR pBuffer
; /* Pointer into Buffer */
347 int ItemsCount
, Length
;
349 DWORD TotalLength
= 0;
350 BOOL UseCustomPath
= TRUE
;
354 /* Get custom path */
355 Length
= ComboBox_GetTextLength(hwndCombo
) + 1;
356 CustomPath
= HeapAlloc(GetProcessHeap(), 0, Length
* sizeof(WCHAR
));
359 TRACE("HeapAlloc() failed\n");
362 CustomPathLength
= GetWindowTextW(hwndCombo
, CustomPath
, Length
) + 1;
364 /* Calculate length of the buffer */
365 ItemsCount
= ComboBox_GetCount(hwndCombo
);
366 if (ItemsCount
== CB_ERR
)
368 TRACE("ComboBox_GetCount() failed\n");
371 for (i
= 0; i
< ItemsCount
; i
++)
373 Length
= ComboBox_GetLBTextLen(hwndCombo
, i
);
374 if (Length
== CB_ERR
)
376 TRACE("ComboBox_GetLBTextLen() failed\n");
379 TotalLength
+= Length
+ 1;
381 TotalLength
++; /* Final NULL char */
383 /* Allocate buffer */
384 Buffer
= HeapAlloc(GetProcessHeap(), 0, (CustomPathLength
+ TotalLength
+ 1) * sizeof(WCHAR
));
387 TRACE("HeapAlloc() failed\n");
391 /* Fill the buffer */
392 pBuffer
= &Buffer
[CustomPathLength
];
393 for (i
= 0; i
< ItemsCount
; i
++)
395 Length
= ComboBox_GetLBText(hwndCombo
, i
, pBuffer
);
396 if (Length
== CB_ERR
)
398 TRACE("ComboBox_GetLBText() failed\n");
401 else if (UseCustomPath
&& _wcsicmp(CustomPath
, pBuffer
) == 0)
402 UseCustomPath
= FALSE
;
403 pBuffer
+= 1 + Length
;
405 *pBuffer
= '\0'; /* Add final NULL char */
409 /* Nothing to save to registry */
413 TotalLength
+= CustomPathLength
;
414 wcscpy(Buffer
, CustomPath
);
416 /* Save the buffer */
417 /* RegSetKeyValue would have been better... */
420 REGSTR_PATH_SETUP REGSTR_KEY_SETUP
,
424 if (rc
!= ERROR_SUCCESS
)
426 TRACE("RegOpenKeyEx() failed with error 0x%lx\n", rc
);
431 L
"Installation Sources",
435 TotalLength
* sizeof(WCHAR
));
436 if (rc
!= ERROR_SUCCESS
)
438 TRACE("RegSetValueEx() failed with error 0x%lx\n", rc
);
445 HeapFree(GetProcessHeap(), 0, CustomPath
);
446 HeapFree(GetProcessHeap(), 0, Buffer
);
449 static INT_PTR CALLBACK
456 PDEVINSTDATA DevInstData
;
457 UNREFERENCED_PARAMETER(wParam
);
459 /* Retrieve pointer to the global setup data */
460 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWLP_USERDATA
);
469 /* Get pointer to the global setup data */
470 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
471 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)DevInstData
);
473 hwndControl
= GetParent(hwndDlg
);
475 /* Center the wizard window */
476 CenterWindow(hwndControl
);
478 /* Hide the system menu */
479 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
480 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
487 (WPARAM
)DevInstData
->hTitleFont
,
495 (LPARAM
)DevInstData
->buffer
);
504 SetFailedInstall(DevInstData
->hDevInfo
,
505 &DevInstData
->devInfoData
,
512 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
517 /* Enable the Next button */
518 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
522 /* Handle a Next button click, if necessary */
523 if (SendDlgItemMessage(hwndDlg
, IDC_RADIO_AUTO
, BM_GETCHECK
, (WPARAM
)0, (LPARAM
)0) == BST_CHECKED
)
525 if (PrepareFoldersToScan(DevInstData
, TRUE
, FALSE
, NULL
))
526 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_SEARCHDRV
);
528 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_INSTALLFAILED
);
546 IncludePath(HWND Dlg
, BOOL Enabled
)
548 EnableWindow(GetDlgItem(Dlg
, IDC_COMBO_PATH
), Enabled
);
549 EnableWindow(GetDlgItem(Dlg
, IDC_BROWSE
), Enabled
);
553 AutoDriver(HWND Dlg
, BOOL Enabled
)
555 EnableWindow(GetDlgItem(Dlg
, IDC_CHECK_MEDIA
), Enabled
);
556 EnableWindow(GetDlgItem(Dlg
, IDC_CHECK_PATH
), Enabled
);
557 IncludePath(Dlg
, Enabled
& IsDlgButtonChecked(Dlg
, IDC_CHECK_PATH
));
560 static INT_PTR CALLBACK
567 PDEVINSTDATA DevInstData
;
569 /* Retrieve pointer to the global setup data */
570 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWLP_USERDATA
);
579 /* Get pointer to the global setup data */
580 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
581 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)DevInstData
);
583 hwndControl
= GetParent(hwndDlg
);
585 /* Center the wizard window */
586 CenterWindow(hwndControl
);
588 /* Hide the system menu */
589 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
590 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
592 PopulateCustomPathCombo(GetDlgItem(hwndDlg
, IDC_COMBO_PATH
));
596 IDC_RADIO_SEARCHHERE
,
600 AutoDriver(hwndDlg
, TRUE
);
601 IncludePath(hwndDlg
, FALSE
);
603 /* Disable manual driver choice for now */
604 EnableWindow(GetDlgItem(hwndDlg
, IDC_RADIO_CHOOSE
), FALSE
);
611 switch (LOWORD(wParam
))
613 case IDC_RADIO_SEARCHHERE
:
614 AutoDriver(hwndDlg
, TRUE
);
617 case IDC_RADIO_CHOOSE
:
618 AutoDriver(hwndDlg
, FALSE
);
622 IncludePath(hwndDlg
, IsDlgButtonChecked(hwndDlg
, IDC_CHECK_PATH
));
627 BROWSEINFO bi
= { 0 };
630 bi
.hwndOwner
= hwndDlg
;
631 bi
.ulFlags
= BIF_RETURNONLYFSDIRS
;
632 pidl
= SHBrowseForFolder(&bi
);
635 WCHAR Directory
[MAX_PATH
];
638 if (SHGetPathFromIDListW(pidl
, Directory
))
640 /* Set the IDC_COMBO_PATH text */
641 SetWindowTextW(GetDlgItem(hwndDlg
, IDC_COMBO_PATH
), Directory
);
644 /* Free memory, if possible */
645 if (SUCCEEDED(SHGetMalloc(&malloc
)))
647 IMalloc_Free(malloc
, pidl
);
648 IMalloc_Release(malloc
);
660 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
665 /* Enable the Next and Back buttons */
666 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
| PSWIZB_BACK
);
670 /* Handle a Next button click, if necessary */
671 if (IsDlgButtonChecked(hwndDlg
, IDC_RADIO_SEARCHHERE
))
673 SaveCustomPath(GetDlgItem(hwndDlg
, IDC_COMBO_PATH
));
674 HeapFree(GetProcessHeap(), 0, DevInstData
->CustomSearchPath
);
675 DevInstData
->CustomSearchPath
= NULL
;
676 if (PrepareFoldersToScan(
678 IsDlgButtonChecked(hwndDlg
, IDC_CHECK_MEDIA
),
679 IsDlgButtonChecked(hwndDlg
, IDC_CHECK_PATH
),
680 GetDlgItem(hwndDlg
, IDC_COMBO_PATH
)))
682 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_SEARCHDRV
);
686 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_INSTALLFAILED
);
708 static INT_PTR CALLBACK
715 PDEVINSTDATA DevInstData
;
718 /* Retrieve pointer to the global setup data */
719 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWLP_USERDATA
);
728 /* Get pointer to the global setup data */
729 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
730 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)DevInstData
);
732 DevInstData
->hDialog
= hwndDlg
;
733 hwndControl
= GetParent(hwndDlg
);
735 /* Center the wizard window */
736 CenterWindow(hwndControl
);
743 (LPARAM
)DevInstData
->buffer
);
745 /* Hide the system menu */
746 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
747 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
751 case WM_SEARCH_FINISHED
:
753 CloseHandle(hThread
);
756 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_NODRIVER
);
758 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_INSTALLDRV
);
764 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
769 PropSheet_SetWizButtons(GetParent(hwndDlg
), !PSWIZB_NEXT
| !PSWIZB_BACK
);
770 /* Yes, we can safely ignore the problem (if any) */
771 SetupDiDestroyDriverInfoList(
772 DevInstData
->hDevInfo
,
773 &DevInstData
->devInfoData
,
775 hThread
= CreateThread(NULL
, 0, FindDriverProc
, DevInstData
, 0, &dwThreadId
);
781 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, TRUE
);
787 /* Handle a Next button click, if necessary */
803 static INT_PTR CALLBACK
810 PDEVINSTDATA DevInstData
;
813 /* Retrieve pointer to the global setup data */
814 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWLP_USERDATA
);
823 /* Get pointer to the global setup data */
824 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
825 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)DevInstData
);
827 DevInstData
->hDialog
= hwndDlg
;
828 hwndControl
= GetParent(hwndDlg
);
830 /* Center the wizard window */
831 CenterWindow(hwndControl
);
838 (LPARAM
)DevInstData
->drvInfoData
.Description
);
840 /* Hide the system menu */
841 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
842 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
846 case WM_INSTALL_FINISHED
:
848 CloseHandle(hThread
);
852 SP_DEVINSTALL_PARAMS installParams
;
854 SetFailedInstall(DevInstData
->hDevInfo
,
855 &DevInstData
->devInfoData
,
858 /* Should we reboot? */
859 installParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
860 if (SetupDiGetDeviceInstallParams(
861 DevInstData
->hDevInfo
,
862 &DevInstData
->devInfoData
,
865 if (installParams
.Flags
& (DI_NEEDRESTART
| DI_NEEDREBOOT
))
867 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_NEEDREBOOT
);
870 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_FINISHPAGE
);
874 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_INSTALLFAILED
);
880 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
885 PropSheet_SetWizButtons(GetParent(hwndDlg
), !PSWIZB_NEXT
| !PSWIZB_BACK
);
886 hThread
= CreateThread(NULL
, 0, InstallDriverProc
, DevInstData
, 0, &dwThreadId
);
892 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, TRUE
);
898 /* Handle a Next button click, if necessary */
914 static INT_PTR CALLBACK
921 PDEVINSTDATA DevInstData
;
924 UNREFERENCED_PARAMETER(wParam
);
926 /* Get pointer to the global setup data */
927 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWLP_USERDATA
);
933 BOOL DisableableDevice
= FALSE
;
935 /* Get pointer to the global setup data */
936 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
937 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)DevInstData
);
939 /* Center the wizard window */
940 CenterWindow(GetParent(hwndDlg
));
942 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
943 ShowWindow(hwndControl
, SW_HIDE
);
944 EnableWindow(hwndControl
, FALSE
);
951 (WPARAM
)DevInstData
->hTitleFont
,
954 /* disable the "do not show this dialog anymore" checkbox
955 if the device cannot be disabled */
957 DevInstData
->devInfoData
.DevInst
,
961 GetDlgItem(hwndDlg
, IDC_DONOTSHOWDLG
),
968 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
973 /* Enable the correct buttons on for the active page */
974 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_FINISH
);
978 /* Handle a Back button click, if necessary */
979 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
980 ShowWindow(hwndControl
, SW_SHOW
);
981 EnableWindow(hwndControl
, TRUE
);
982 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_CHSOURCE
);
987 BOOL DisableableDevice
= FALSE
;
988 BOOL IsStarted
= FALSE
;
990 if (CanDisableDevice(DevInstData
->devInfoData
.DevInst
,
992 &DisableableDevice
) &&
995 DevInstData
->devInfoData
.DevInst
,
1003 (WPARAM
)0, (LPARAM
)0) == BST_CHECKED
)
1005 /* disable the device */
1007 DevInstData
->hDevInfo
,
1008 &DevInstData
->devInfoData
,
1015 SetFailedInstall(DevInstData
->hDevInfo
,
1016 &DevInstData
->devInfoData
,
1035 static INT_PTR CALLBACK
1036 InstallFailedDlgProc(
1042 PDEVINSTDATA DevInstData
;
1043 UNREFERENCED_PARAMETER(wParam
);
1045 /* Retrieve pointer to the global setup data */
1046 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWLP_USERDATA
);
1054 /* Get pointer to the global setup data */
1055 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1056 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)DevInstData
);
1058 /* Center the wizard window */
1059 CenterWindow(GetParent(hwndDlg
));
1061 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
1062 ShowWindow(hwndControl
, SW_HIDE
);
1063 EnableWindow(hwndControl
, FALSE
);
1070 (LPARAM
)DevInstData
->drvInfoData
.Description
);
1072 /* Set title font */
1077 (WPARAM
)DevInstData
->hTitleFont
,
1084 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1089 /* Enable the correct buttons on for the active page */
1090 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
1094 /* Handle a Back button click, if necessary */
1098 /* Handle a Finish button click, if necessary */
1114 static INT_PTR CALLBACK
1121 PDEVINSTDATA DevInstData
;
1122 UNREFERENCED_PARAMETER(wParam
);
1124 /* Retrieve pointer to the global setup data */
1125 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWLP_USERDATA
);
1133 /* Get pointer to the global setup data */
1134 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1135 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)DevInstData
);
1137 /* Center the wizard window */
1138 CenterWindow(GetParent(hwndDlg
));
1140 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
1141 ShowWindow(hwndControl
, SW_HIDE
);
1142 EnableWindow(hwndControl
, FALSE
);
1149 (LPARAM
)DevInstData
->drvInfoData
.Description
);
1151 /* Set title font */
1156 (WPARAM
)DevInstData
->hTitleFont
,
1163 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1168 /* Enable the correct buttons on for the active page */
1169 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
1173 /* Handle a Back button click, if necessary */
1177 /* Handle a Finish button click, if necessary */
1193 static INT_PTR CALLBACK
1200 PDEVINSTDATA DevInstData
;
1201 UNREFERENCED_PARAMETER(wParam
);
1203 /* Retrieve pointer to the global setup data */
1204 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWLP_USERDATA
);
1212 /* Get pointer to the global setup data */
1213 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1214 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)DevInstData
);
1216 /* Center the wizard window */
1217 CenterWindow(GetParent(hwndDlg
));
1219 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
1220 ShowWindow(hwndControl
, SW_HIDE
);
1221 EnableWindow(hwndControl
, FALSE
);
1228 (LPARAM
)DevInstData
->drvInfoData
.Description
);
1230 /* Set title font */
1235 (WPARAM
)DevInstData
->hTitleFont
,
1242 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1247 /* Enable the correct buttons on for the active page */
1248 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
1252 /* Handle a Back button click, if necessary */
1256 /* Handle a Finish button click, if necessary */
1273 CreateTitleFont(VOID
)
1275 NONCLIENTMETRICSW ncm
;
1281 ncm
.cbSize
= sizeof(NONCLIENTMETRICSW
);
1282 SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, 0, &ncm
, 0);
1284 LogFont
= ncm
.lfMessageFont
;
1285 LogFont
.lfWeight
= FW_BOLD
;
1286 wcscpy(LogFont
.lfFaceName
, L
"MS Shell Dlg");
1290 LogFont
.lfHeight
= 0 - GetDeviceCaps (hdc
, LOGPIXELSY
) * FontSize
/ 72;
1291 hFont
= CreateFontIndirectW(&LogFont
);
1292 ReleaseDC(NULL
, hdc
);
1299 IN PDEVINSTDATA DevInstData
,
1303 PROPSHEETHEADER psh
;
1304 HPROPSHEETPAGE ahpsp
[IDD_MAXIMUMPAGE
+ 1];
1307 /* zero based index */
1308 startPage
-= IDD_FIRSTPAGE
;
1310 /* Create the Welcome page */
1311 ZeroMemory(&psp
, sizeof(PROPSHEETPAGE
));
1312 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
1313 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
| PSP_USETITLE
;
1314 psp
.hInstance
= hDllInstance
;
1315 psp
.lParam
= (LPARAM
)DevInstData
;
1316 psp
.pszTitle
= MAKEINTRESOURCE(DevInstData
->bUpdate
? IDS_UPDATEWIZARDTITLE
: IDS_INSTALLWIZARDTITLE
);
1317 psp
.pfnDlgProc
= WelcomeDlgProc
;
1318 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_WELCOMEPAGE
);
1319 ahpsp
[IDD_WELCOMEPAGE
-IDD_FIRSTPAGE
] = CreatePropertySheetPage(&psp
);
1321 /* Create the Select Source page */
1322 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USETITLE
;
1323 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_CHSOURCE_TITLE
);
1324 psp
.pfnDlgProc
= CHSourceDlgProc
;
1325 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_CHSOURCE
);
1326 ahpsp
[IDD_CHSOURCE
-IDD_FIRSTPAGE
] = CreatePropertySheetPage(&psp
);
1328 /* Create the Search driver page */
1329 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USETITLE
;
1330 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_SEARCHDRV_TITLE
);
1331 psp
.pfnDlgProc
= SearchDrvDlgProc
;
1332 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_SEARCHDRV
);
1333 ahpsp
[IDD_SEARCHDRV
-IDD_FIRSTPAGE
] = CreatePropertySheetPage(&psp
);
1335 /* Create the Install driver page */
1336 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USETITLE
;
1337 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_INSTALLDRV_TITLE
);
1338 psp
.pfnDlgProc
= InstallDrvDlgProc
;
1339 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_INSTALLDRV
);
1340 ahpsp
[IDD_INSTALLDRV
-IDD_FIRSTPAGE
] = CreatePropertySheetPage(&psp
);
1342 /* Create the No driver page */
1343 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
| PSP_USETITLE
;
1344 psp
.pfnDlgProc
= NoDriverDlgProc
;
1345 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_NODRIVER
);
1346 ahpsp
[IDD_NODRIVER
-IDD_FIRSTPAGE
] = CreatePropertySheetPage(&psp
);
1348 /* Create the Install failed page */
1349 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
| PSP_USETITLE
;
1350 psp
.pfnDlgProc
= InstallFailedDlgProc
;
1351 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_INSTALLFAILED
);
1352 ahpsp
[IDD_INSTALLFAILED
-IDD_FIRSTPAGE
] = CreatePropertySheetPage(&psp
);
1354 /* Create the Need reboot page */
1355 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
| PSP_USETITLE
;
1356 psp
.pfnDlgProc
= NeedRebootDlgProc
;
1357 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_NEEDREBOOT
);
1358 ahpsp
[IDD_NEEDREBOOT
-IDD_FIRSTPAGE
] = CreatePropertySheetPage(&psp
);
1360 /* Create the Finish page */
1361 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
| PSP_USETITLE
;
1362 psp
.pfnDlgProc
= FinishDlgProc
;
1363 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_FINISHPAGE
);
1364 ahpsp
[IDD_FINISHPAGE
-IDD_FIRSTPAGE
] = CreatePropertySheetPage(&psp
);
1366 /* Create the property sheet */
1367 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
1368 psh
.dwFlags
= PSH_WIZARD97
| PSH_WATERMARK
| PSH_HEADER
;
1369 psh
.hInstance
= hDllInstance
;
1370 psh
.hwndParent
= hwndParent
;
1371 psh
.nPages
= IDD_MAXIMUMPAGE
+ 1;
1372 psh
.nStartPage
= startPage
;
1374 psh
.pszbmWatermark
= MAKEINTRESOURCE(IDB_WATERMARK
);
1375 psh
.pszbmHeader
= MAKEINTRESOURCE(IDB_HEADER
);
1377 /* Create title font */
1378 DevInstData
->hTitleFont
= CreateTitleFont();
1380 /* Display the wizard */
1381 PropertySheet(&psh
);
1383 DeleteObject(DevInstData
->hTitleFont
);