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 /* hpoussin, Dec 2005. I've disabled this code because
60 * ntoskrnl never sets the DN_DISABLEABLE flag.
63 ULONG Status
, ProblemNumber
;
66 cr
= CM_Get_DevNode_Status_Ex(
74 *CanDisable
= ((Status
& DN_DISABLEABLE
) != 0);
92 ULONG Status
, ProblemNumber
;
95 cr
= CM_Get_DevNode_Status_Ex(
101 if (cr
== CR_SUCCESS
)
103 *IsEnabled
= ((Status
& DN_STARTED
) != 0);
112 IN HDEVINFO DeviceInfoSet
,
113 IN PSP_DEVINFO_DATA DevInfoData OPTIONAL
,
115 IN DWORD HardwareProfile OPTIONAL
,
116 OUT BOOL
*bNeedReboot OPTIONAL
)
118 SP_PROPCHANGE_PARAMS pcp
;
119 SP_DEVINSTALL_PARAMS dp
;
123 pcp
.ClassInstallHeader
.cbSize
= sizeof(SP_CLASSINSTALL_HEADER
);
124 pcp
.ClassInstallHeader
.InstallFunction
= DIF_PROPERTYCHANGE
;
125 pcp
.HwProfile
= HardwareProfile
;
129 /* try to enable the device on the global profile */
130 pcp
.StateChange
= DICS_ENABLE
;
131 pcp
.Scope
= DICS_FLAG_GLOBAL
;
134 LastErr
= GetLastError();
135 if (SetupDiSetClassInstallParams(
138 &pcp
.ClassInstallHeader
,
139 sizeof(SP_PROPCHANGE_PARAMS
)))
141 SetupDiCallClassInstaller(
146 SetLastError(LastErr
);
149 /* try config-specific */
150 pcp
.StateChange
= (bEnable
? DICS_ENABLE
: DICS_DISABLE
);
151 pcp
.Scope
= DICS_FLAG_CONFIGSPECIFIC
;
153 if (SetupDiSetClassInstallParams(
156 &pcp
.ClassInstallHeader
,
157 sizeof(SP_PROPCHANGE_PARAMS
)) &&
158 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE
,
162 dp
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
163 if (SetupDiGetDeviceInstallParams(
168 if (bNeedReboot
!= NULL
)
170 *bNeedReboot
= ((dp
.Flags
& (DI_NEEDRESTART
| DI_NEEDREBOOT
)) != 0);
183 PDEVINSTDATA DevInstData
;
187 DevInstData
= (PDEVINSTDATA
)lpParam
;
189 result
= ScanFoldersForDriver(DevInstData
);
193 PostMessage(DevInstData
->hDialog
, WM_SEARCH_FINISHED
, 1, 0);
197 /* Update device configuration */
198 if (SetupDiGetDeviceRegistryProperty(
199 DevInstData
->hDevInfo
,
200 &DevInstData
->devInfoData
,
203 (BYTE
*)&config_flags
,
204 sizeof(config_flags
),
207 config_flags
|= CONFIGFLAG_FAILEDINSTALL
;
208 SetupDiSetDeviceRegistryPropertyW(
209 DevInstData
->hDevInfo
,
210 &DevInstData
->devInfoData
,
212 (BYTE
*)&config_flags
, sizeof(config_flags
));
215 PostMessage(DevInstData
->hDialog
, WM_SEARCH_FINISHED
, 0, 0);
224 PDEVINSTDATA DevInstData
;
227 DevInstData
= (PDEVINSTDATA
)lpParam
;
228 res
= InstallCurrentDriver(DevInstData
);
229 PostMessage(DevInstData
->hDialog
, WM_INSTALL_FINISHED
, res
? 0 : 1, 0);
234 PopulateCustomPathCombo(
239 DWORD dwPathLength
= 0;
240 LPWSTR Buffer
= NULL
;
244 (void)ComboBox_ResetContent(hwndCombo
);
246 /* RegGetValue would have been better... */
249 REGSTR_PATH_SETUP REGSTR_KEY_SETUP
,
253 if (rc
!= ERROR_SUCCESS
)
255 TRACE("RegOpenKeyEx() failed with error 0x%lx\n", rc
);
258 rc
= RegQueryValueExW(
260 L
"Installation Sources",
265 if (rc
!= ERROR_SUCCESS
|| dwRegType
!= REG_MULTI_SZ
)
267 TRACE("RegQueryValueEx() failed with error 0x%lx\n", rc
);
271 /* Allocate enough space to add 2 NULL chars at the end of the string */
272 Buffer
= HeapAlloc(GetProcessHeap(), 0, dwPathLength
+ 2 * sizeof(WCHAR
));
275 TRACE("HeapAlloc() failed\n");
278 rc
= RegQueryValueExW(
280 L
"Installation Sources",
285 if (rc
!= ERROR_SUCCESS
)
287 TRACE("RegQueryValueEx() failed with error 0x%lx\n", rc
);
290 Buffer
[dwPathLength
] = Buffer
[dwPathLength
+ 1] = '\0';
292 /* Populate combo box */
293 for (Path
= Buffer
; *Path
; Path
+= wcslen(Path
) + 1)
295 (void)ComboBox_AddString(hwndCombo
, Path
);
297 (void)ComboBox_SetCurSel(hwndCombo
, 0);
303 HeapFree(GetProcessHeap(), 0, Buffer
);
310 LPWSTR CustomPath
= NULL
;
311 DWORD CustomPathLength
;
312 LPWSTR Buffer
= NULL
;
313 LPWSTR pBuffer
; /* Pointer into Buffer */
314 int ItemsCount
, Length
;
316 DWORD TotalLength
= 0;
317 BOOL UseCustomPath
= TRUE
;
321 /* Get custom path */
322 Length
= ComboBox_GetTextLength(hwndCombo
) + 1;
323 CustomPath
= HeapAlloc(GetProcessHeap(), 0, Length
* sizeof(WCHAR
));
326 TRACE("HeapAlloc() failed\n");
329 CustomPathLength
= GetWindowTextW(hwndCombo
, CustomPath
, Length
) + 1;
331 /* Calculate length of the buffer */
332 ItemsCount
= ComboBox_GetCount(hwndCombo
);
333 if (ItemsCount
== CB_ERR
)
335 TRACE("ComboBox_GetCount() failed\n");
338 for (i
= 0; i
< ItemsCount
; i
++)
340 Length
= ComboBox_GetLBTextLen(hwndCombo
, i
);
341 if (Length
== CB_ERR
)
343 TRACE("ComboBox_GetLBTextLen() failed\n");
346 TotalLength
+= Length
+ 1;
348 TotalLength
++; /* Final NULL char */
350 /* Allocate buffer */
351 Buffer
= HeapAlloc(GetProcessHeap(), 0, (CustomPathLength
+ TotalLength
+ 1) * sizeof(WCHAR
));
354 TRACE("HeapAlloc() failed\n");
358 /* Fill the buffer */
359 pBuffer
= &Buffer
[CustomPathLength
];
360 for (i
= 0; i
< ItemsCount
; i
++)
362 Length
= ComboBox_GetLBText(hwndCombo
, i
, pBuffer
);
363 if (Length
== CB_ERR
)
365 TRACE("ComboBox_GetLBText() failed\n");
368 else if (UseCustomPath
&& _wcsicmp(CustomPath
, pBuffer
) == 0)
369 UseCustomPath
= FALSE
;
370 pBuffer
+= 1 + Length
;
372 *pBuffer
= '\0'; /* Add final NULL char */
376 /* Nothing to save to registry */
380 TotalLength
+= CustomPathLength
;
381 wcscpy(Buffer
, CustomPath
);
383 /* Save the buffer */
384 /* RegSetKeyValue would have been better... */
387 REGSTR_PATH_SETUP REGSTR_KEY_SETUP
,
391 if (rc
!= ERROR_SUCCESS
)
393 TRACE("RegOpenKeyEx() failed with error 0x%lx\n", rc
);
398 L
"Installation Sources",
402 TotalLength
* sizeof(WCHAR
));
403 if (rc
!= ERROR_SUCCESS
)
405 TRACE("RegSetValueEx() failed with error 0x%lx\n", rc
);
412 HeapFree(GetProcessHeap(), 0, CustomPath
);
413 HeapFree(GetProcessHeap(), 0, Buffer
);
416 static INT_PTR CALLBACK
423 PDEVINSTDATA DevInstData
;
424 UNREFERENCED_PARAMETER(wParam
);
426 /* Retrieve pointer to the global setup data */
427 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
436 /* Get pointer to the global setup data */
437 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
438 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
440 hwndControl
= GetParent(hwndDlg
);
442 /* Center the wizard window */
443 CenterWindow(hwndControl
);
445 /* Hide the system menu */
446 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
447 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
454 (WPARAM
)DevInstData
->hTitleFont
,
462 (LPARAM
)DevInstData
->buffer
);
475 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
480 /* Enable the Next button */
481 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
485 /* Handle a Next button click, if necessary */
486 if (SendDlgItemMessage(hwndDlg
, IDC_RADIO_AUTO
, BM_GETCHECK
, (WPARAM
)0, (LPARAM
)0) == BST_CHECKED
)
488 if (PrepareFoldersToScan(DevInstData
, TRUE
, FALSE
, NULL
))
489 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_SEARCHDRV
);
491 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_INSTALLFAILED
);
505 return DefWindowProc(hwndDlg
, uMsg
, wParam
, lParam
);
509 IncludePath(HWND Dlg
, BOOL Enabled
)
511 EnableWindow(GetDlgItem(Dlg
, IDC_COMBO_PATH
), Enabled
);
512 EnableWindow(GetDlgItem(Dlg
, IDC_BROWSE
), Enabled
);
516 AutoDriver(HWND Dlg
, BOOL Enabled
)
518 EnableWindow(GetDlgItem(Dlg
, IDC_CHECK_MEDIA
), Enabled
);
519 EnableWindow(GetDlgItem(Dlg
, IDC_CHECK_PATH
), Enabled
);
520 IncludePath(Dlg
, Enabled
& IsDlgButtonChecked(Dlg
, IDC_CHECK_PATH
));
523 static INT_PTR CALLBACK
530 PDEVINSTDATA DevInstData
;
532 /* Retrieve pointer to the global setup data */
533 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
542 /* Get pointer to the global setup data */
543 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
544 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
546 hwndControl
= GetParent(hwndDlg
);
548 /* Center the wizard window */
549 CenterWindow(hwndControl
);
551 /* Hide the system menu */
552 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
553 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
555 PopulateCustomPathCombo(GetDlgItem(hwndDlg
, IDC_COMBO_PATH
));
559 IDC_RADIO_SEARCHHERE
,
563 AutoDriver(hwndDlg
, TRUE
);
564 IncludePath(hwndDlg
, FALSE
);
566 /* Disable manual driver choice for now */
567 EnableWindow(GetDlgItem(hwndDlg
, IDC_RADIO_CHOOSE
), FALSE
);
574 switch (LOWORD(wParam
))
576 case IDC_RADIO_SEARCHHERE
:
577 AutoDriver(hwndDlg
, TRUE
);
580 case IDC_RADIO_CHOOSE
:
581 AutoDriver(hwndDlg
, FALSE
);
585 IncludePath(hwndDlg
, IsDlgButtonChecked(hwndDlg
, IDC_CHECK_PATH
));
590 BROWSEINFO bi
= { 0 };
593 bi
.hwndOwner
= hwndDlg
;
594 bi
.ulFlags
= BIF_RETURNONLYFSDIRS
;
595 pidl
= SHBrowseForFolder(&bi
);
598 WCHAR Directory
[MAX_PATH
];
601 if (SHGetPathFromIDListW(pidl
, Directory
))
603 /* Set the IDC_COMBO_PATH text */
604 SetWindowTextW(GetDlgItem(hwndDlg
, IDC_COMBO_PATH
), Directory
);
607 /* Free memory, if possible */
608 if (SUCCEEDED(SHGetMalloc(&malloc
)))
610 IMalloc_Free(malloc
, pidl
);
611 IMalloc_Release(malloc
);
623 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
628 /* Enable the Next and Back buttons */
629 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
| PSWIZB_BACK
);
633 /* Handle a Next button click, if necessary */
634 if (IsDlgButtonChecked(hwndDlg
, IDC_RADIO_SEARCHHERE
))
636 SaveCustomPath(GetDlgItem(hwndDlg
, IDC_COMBO_PATH
));
637 HeapFree(GetProcessHeap(), 0, DevInstData
->CustomSearchPath
);
638 DevInstData
->CustomSearchPath
= NULL
;
639 if (PrepareFoldersToScan(
641 IsDlgButtonChecked(hwndDlg
, IDC_CHECK_MEDIA
),
642 IsDlgButtonChecked(hwndDlg
, IDC_CHECK_PATH
),
643 GetDlgItem(hwndDlg
, IDC_COMBO_PATH
)))
645 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_SEARCHDRV
);
649 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_INSTALLFAILED
);
668 return DefWindowProc(hwndDlg
, uMsg
, wParam
, lParam
);
671 static INT_PTR CALLBACK
678 PDEVINSTDATA DevInstData
;
681 /* Retrieve pointer to the global setup data */
682 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
691 /* Get pointer to the global setup data */
692 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
693 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
695 DevInstData
->hDialog
= hwndDlg
;
696 hwndControl
= GetParent(hwndDlg
);
698 /* Center the wizard window */
699 CenterWindow(hwndControl
);
706 (LPARAM
)DevInstData
->buffer
);
708 /* Hide the system menu */
709 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
710 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
714 case WM_SEARCH_FINISHED
:
716 CloseHandle(hThread
);
719 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_NODRIVER
);
721 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_INSTALLDRV
);
727 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
732 PropSheet_SetWizButtons(GetParent(hwndDlg
), !PSWIZB_NEXT
| !PSWIZB_BACK
);
733 /* Yes, we can safely ignore the problem (if any) */
734 SetupDiDestroyDriverInfoList(
735 DevInstData
->hDevInfo
,
736 &DevInstData
->devInfoData
,
738 hThread
= CreateThread(NULL
, 0, FindDriverProc
, DevInstData
, 0, &dwThreadId
);
744 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, TRUE
);
750 /* Handle a Next button click, if necessary */
763 return DefWindowProc(hwndDlg
, uMsg
, wParam
, lParam
);
766 static INT_PTR CALLBACK
773 PDEVINSTDATA DevInstData
;
776 /* Retrieve pointer to the global setup data */
777 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
786 /* Get pointer to the global setup data */
787 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
788 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
790 DevInstData
->hDialog
= hwndDlg
;
791 hwndControl
= GetParent(hwndDlg
);
793 /* Center the wizard window */
794 CenterWindow(hwndControl
);
801 (LPARAM
)DevInstData
->drvInfoData
.Description
);
803 /* Hide the system menu */
804 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
805 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
809 case WM_INSTALL_FINISHED
:
811 CloseHandle(hThread
);
815 /* Should we reboot? */
816 SP_DEVINSTALL_PARAMS installParams
;
817 installParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
818 if (SetupDiGetDeviceInstallParams(
819 DevInstData
->hDevInfo
,
820 &DevInstData
->devInfoData
,
823 if (installParams
.Flags
& (DI_NEEDRESTART
| DI_NEEDREBOOT
))
825 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_NEEDREBOOT
);
828 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_FINISHPAGE
);
832 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_INSTALLFAILED
);
838 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
843 PropSheet_SetWizButtons(GetParent(hwndDlg
), !PSWIZB_NEXT
| !PSWIZB_BACK
);
844 hThread
= CreateThread(NULL
, 0, InstallDriverProc
, DevInstData
, 0, &dwThreadId
);
850 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, TRUE
);
856 /* Handle a Next button click, if necessary */
869 return DefWindowProc(hwndDlg
, uMsg
, wParam
, lParam
);
872 static INT_PTR CALLBACK
879 PDEVINSTDATA DevInstData
;
882 UNREFERENCED_PARAMETER(wParam
);
884 /* Get pointer to the global setup data */
885 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
891 BOOL DisableableDevice
= FALSE
;
893 /* Get pointer to the global setup data */
894 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
895 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
897 /* Center the wizard window */
898 CenterWindow(GetParent(hwndDlg
));
900 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
901 ShowWindow(hwndControl
, SW_HIDE
);
902 EnableWindow(hwndControl
, FALSE
);
909 (WPARAM
)DevInstData
->hTitleFont
,
912 /* disable the "do not show this dialog anymore" checkbox
913 if the device cannot be disabled */
915 DevInstData
->devInfoData
.DevInst
,
919 GetDlgItem(hwndDlg
, IDC_DONOTSHOWDLG
),
926 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
931 /* Enable the correct buttons on for the active page */
932 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_FINISH
);
936 /* Handle a Back button click, if necessary */
937 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
938 ShowWindow(hwndControl
, SW_SHOW
);
939 EnableWindow(hwndControl
, TRUE
);
940 PropSheet_SetCurSelByID(GetParent(hwndDlg
), IDD_CHSOURCE
);
945 BOOL DisableableDevice
= FALSE
;
946 BOOL IsStarted
= FALSE
;
948 if (CanDisableDevice(DevInstData
->devInfoData
.DevInst
,
950 &DisableableDevice
) &&
953 DevInstData
->devInfoData
.DevInst
,
961 (WPARAM
)0, (LPARAM
)0) == BST_CHECKED
)
963 /* disable the device */
965 DevInstData
->hDevInfo
,
966 &DevInstData
->devInfoData
,
984 return DefWindowProc(hwndDlg
, uMsg
, wParam
, lParam
);
987 static INT_PTR CALLBACK
988 InstallFailedDlgProc(
994 PDEVINSTDATA DevInstData
;
995 UNREFERENCED_PARAMETER(wParam
);
997 /* Retrieve pointer to the global setup data */
998 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
1006 /* Get pointer to the global setup data */
1007 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1008 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
1010 /* Center the wizard window */
1011 CenterWindow(GetParent(hwndDlg
));
1013 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
1014 ShowWindow(hwndControl
, SW_HIDE
);
1015 EnableWindow(hwndControl
, FALSE
);
1022 (LPARAM
)DevInstData
->drvInfoData
.Description
);
1024 /* Set title font */
1029 (WPARAM
)DevInstData
->hTitleFont
,
1036 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1041 /* Enable the correct buttons on for the active page */
1042 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
1046 /* Handle a Back button click, if necessary */
1050 /* Handle a Finish button click, if necessary */
1063 return DefWindowProc(hwndDlg
, uMsg
, wParam
, lParam
);
1066 static INT_PTR CALLBACK
1073 PDEVINSTDATA DevInstData
;
1074 UNREFERENCED_PARAMETER(wParam
);
1076 /* Retrieve pointer to the global setup data */
1077 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
1085 /* Get pointer to the global setup data */
1086 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1087 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
1089 /* Center the wizard window */
1090 CenterWindow(GetParent(hwndDlg
));
1092 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
1093 ShowWindow(hwndControl
, SW_HIDE
);
1094 EnableWindow(hwndControl
, FALSE
);
1101 (LPARAM
)DevInstData
->drvInfoData
.Description
);
1103 /* Set title font */
1108 (WPARAM
)DevInstData
->hTitleFont
,
1115 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1120 /* Enable the correct buttons on for the active page */
1121 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
1125 /* Handle a Back button click, if necessary */
1129 /* Handle a Finish button click, if necessary */
1142 return DefWindowProc(hwndDlg
, uMsg
, wParam
, lParam
);
1145 static INT_PTR CALLBACK
1152 PDEVINSTDATA DevInstData
;
1153 UNREFERENCED_PARAMETER(wParam
);
1155 /* Retrieve pointer to the global setup data */
1156 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
1164 /* Get pointer to the global setup data */
1165 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1166 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
1168 /* Center the wizard window */
1169 CenterWindow(GetParent(hwndDlg
));
1171 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
1172 ShowWindow(hwndControl
, SW_HIDE
);
1173 EnableWindow(hwndControl
, FALSE
);
1180 (LPARAM
)DevInstData
->drvInfoData
.Description
);
1182 /* Set title font */
1187 (WPARAM
)DevInstData
->hTitleFont
,
1194 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1199 /* Enable the correct buttons on for the active page */
1200 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
1204 /* Handle a Back button click, if necessary */
1208 /* Handle a Finish button click, if necessary */
1221 return DefWindowProc(hwndDlg
, uMsg
, wParam
, lParam
);
1225 CreateTitleFont(VOID
)
1227 NONCLIENTMETRICSW ncm
;
1233 ncm
.cbSize
= sizeof(NONCLIENTMETRICSW
);
1234 SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, 0, &ncm
, 0);
1236 LogFont
= ncm
.lfMessageFont
;
1237 LogFont
.lfWeight
= FW_BOLD
;
1238 wcscpy(LogFont
.lfFaceName
, L
"MS Shell Dlg");
1242 LogFont
.lfHeight
= 0 - GetDeviceCaps (hdc
, LOGPIXELSY
) * FontSize
/ 72;
1243 hFont
= CreateFontIndirectW(&LogFont
);
1244 ReleaseDC(NULL
, hdc
);
1251 IN PDEVINSTDATA DevInstData
,
1255 PROPSHEETHEADER psh
;
1256 HPROPSHEETPAGE ahpsp
[IDD_MAXIMUMPAGE
+ 1];
1259 /* Create the Welcome page */
1260 ZeroMemory(&psp
, sizeof(PROPSHEETPAGE
));
1261 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
1262 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1263 psp
.hInstance
= hDllInstance
;
1264 psp
.lParam
= (LPARAM
)DevInstData
;
1265 psp
.pfnDlgProc
= (DLGPROC
) WelcomeDlgProc
;
1266 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_WELCOMEPAGE
);
1267 ahpsp
[IDD_WELCOMEPAGE
] = CreatePropertySheetPage(&psp
);
1269 /* Create the Select Source page */
1270 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
1271 psp
.pfnDlgProc
= (DLGPROC
) CHSourceDlgProc
;
1272 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_CHSOURCE
);
1273 ahpsp
[IDD_CHSOURCE
] = CreatePropertySheetPage(&psp
);
1275 /* Create the Search driver page */
1276 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
1277 psp
.pfnDlgProc
= (DLGPROC
) SearchDrvDlgProc
;
1278 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_SEARCHDRV
);
1279 ahpsp
[IDD_SEARCHDRV
] = CreatePropertySheetPage(&psp
);
1281 /* Create the Install driver page */
1282 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
1283 psp
.pfnDlgProc
= (DLGPROC
) InstallDrvDlgProc
;
1284 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_INSTALLDRV
);
1285 ahpsp
[IDD_INSTALLDRV
] = CreatePropertySheetPage(&psp
);
1287 /* Create the No driver page */
1288 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1289 psp
.pfnDlgProc
= (DLGPROC
) NoDriverDlgProc
;
1290 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_NODRIVER
);
1291 ahpsp
[IDD_NODRIVER
] = CreatePropertySheetPage(&psp
);
1293 /* Create the Install failed page */
1294 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1295 psp
.pfnDlgProc
= (DLGPROC
) InstallFailedDlgProc
;
1296 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_INSTALLFAILED
);
1297 ahpsp
[IDD_INSTALLFAILED
] = CreatePropertySheetPage(&psp
);
1299 /* Create the Need reboot page */
1300 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1301 psp
.pfnDlgProc
= (DLGPROC
) NeedRebootDlgProc
;
1302 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_NEEDREBOOT
);
1303 ahpsp
[IDD_NEEDREBOOT
] = CreatePropertySheetPage(&psp
);
1305 /* Create the Finish page */
1306 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1307 psp
.pfnDlgProc
= (DLGPROC
) FinishDlgProc
;
1308 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_FINISHPAGE
);
1309 ahpsp
[IDD_FINISHPAGE
] = CreatePropertySheetPage(&psp
);
1311 /* Create the property sheet */
1312 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
1313 psh
.dwFlags
= PSH_WIZARD97
| PSH_WATERMARK
| PSH_HEADER
;
1314 psh
.hInstance
= hDllInstance
;
1315 psh
.hwndParent
= hwndParent
;
1316 psh
.nPages
= IDD_MAXIMUMPAGE
+ 1;
1317 psh
.nStartPage
= startPage
;
1319 psh
.pszbmWatermark
= MAKEINTRESOURCE(IDB_WATERMARK
);
1320 psh
.pszbmHeader
= MAKEINTRESOURCE(IDB_HEADER
);
1322 /* Create title font */
1323 DevInstData
->hTitleFont
= CreateTitleFont();
1325 /* Display the wizard */
1326 PropertySheet(&psh
);
1328 DeleteObject(DevInstData
->hTitleFont
);