2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS New devices installation
4 * FILE: lib/newdev/newdev.c
5 * PURPOSE: New devices installation
7 * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
8 * PROGRAMMERS: Christoph von Wittich (Christoph@ActiveVB.de)
16 static BOOL
SearchDriver ( PDEVINSTDATA DevInstData
, LPCTSTR Path
);
17 static BOOL
InstallDriver ( PDEVINSTDATA DevInstData
);
18 static DWORD WINAPI
FindDriverProc( LPVOID lpParam
);
19 static BOOL
FindDriver ( PDEVINSTDATA DevInstData
);
21 static DEVINSTDATA DevInstData
;
22 HINSTANCE hDllInstance
;
29 UpdateDriverForPlugAndPlayDevicesW(
31 IN LPCWSTR HardwareId
,
32 IN LPCWSTR FullInfPath
,
33 IN DWORD InstallFlags
,
34 OUT PBOOL bRebootRequired OPTIONAL
)
37 SetLastError(ERROR_GEN_FAILURE
);
45 UpdateDriverForPlugAndPlayDevicesA(
48 IN LPCSTR FullInfPath
,
49 IN DWORD InstallFlags
,
50 OUT PBOOL bRebootRequired OPTIONAL
)
53 LPWSTR HardwareIdW
= NULL
;
54 LPWSTR FullInfPathW
= NULL
;
56 int len
= MultiByteToWideChar(CP_ACP
, 0, HardwareId
, -1, NULL
, 0);
57 HardwareIdW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
60 SetLastError(ERROR_GEN_FAILURE
);
63 MultiByteToWideChar(CP_ACP
, 0, HardwareId
, -1, HardwareIdW
, len
);
65 len
= MultiByteToWideChar(CP_ACP
, 0, FullInfPath
, -1, NULL
, 0);
66 FullInfPathW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
69 HeapFree(GetProcessHeap(), 0, HardwareIdW
);
70 SetLastError(ERROR_GEN_FAILURE
);
73 MultiByteToWideChar(CP_ACP
, 0, FullInfPath
, -1, FullInfPathW
, len
);
75 Result
= UpdateDriverForPlugAndPlayDevicesW(hwndParent
,
81 HeapFree(GetProcessHeap(), 0, HardwareIdW
);
82 HeapFree(GetProcessHeap(), 0, FullInfPathW
);
97 ncm
.cbSize
= sizeof(NONCLIENTMETRICS
);
98 SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, 0, &ncm
, 0);
100 LogFont
= ncm
.lfMessageFont
;
101 LogFont
.lfWeight
= FW_BOLD
;
102 _tcscpy(LogFont
.lfFaceName
, _T("MS Shell Dlg"));
106 LogFont
.lfHeight
= 0 - GetDeviceCaps (hdc
, LOGPIXELSY
) * FontSize
/ 72;
107 hFont
= CreateFontIndirect(&LogFont
);
108 ReleaseDC(NULL
, hdc
);
114 CenterWindow(HWND hWnd
)
120 hWndParent
= GetParent(hWnd
);
121 if (hWndParent
== NULL
)
122 hWndParent
= GetDesktopWindow();
124 GetWindowRect(hWndParent
, &rcParent
);
125 GetWindowRect(hWnd
, &rcWindow
);
129 ((rcParent
.right
- rcParent
.left
) - (rcWindow
.right
- rcWindow
.left
)) / 2,
130 ((rcParent
.bottom
- rcParent
.top
) - (rcWindow
.bottom
- rcWindow
.top
)) / 2,
136 static INT_PTR CALLBACK
144 PDEVINSTDATA DevInstData
;
146 /* Retrieve pointer to the global setup data */
147 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
156 /* Get pointer to the global setup data */
157 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
158 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
160 hwndControl
= GetParent(hwndDlg
);
162 /* Center the wizard window */
163 CenterWindow (hwndControl
);
165 /* Hide the system menu */
166 dwStyle
= GetWindowLong(hwndControl
, GWL_STYLE
);
167 SetWindowLong(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
170 SendDlgItemMessage(hwndDlg
,
173 (WPARAM
)DevInstData
->hTitleFont
,
176 SendDlgItemMessage(hwndDlg
,
180 (LPARAM
) DevInstData
->buffer
);
182 SendDlgItemMessage(hwndDlg
,
195 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
200 /* Enable the Next button */
201 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
205 /* Handle a Next button click, if necessary */
207 if (SendDlgItemMessage(hwndDlg
, IDC_RADIO_AUTO
, BM_GETCHECK
, (WPARAM
) 0, (LPARAM
) 0) == BST_CHECKED
)
208 PropSheet_SetCurSel(GetParent(hwndDlg
), 0, IDD_SEARCHDRV
);
225 static INT_PTR CALLBACK
233 PDEVINSTDATA DevInstData
;
235 /* Retrieve pointer to the global setup data */
236 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
245 /* Get pointer to the global setup data */
246 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
247 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
249 hwndControl
= GetParent(hwndDlg
);
251 /* Center the wizard window */
252 CenterWindow (hwndControl
);
254 /* Hide the system menu */
255 dwStyle
= GetWindowLong(hwndControl
, GWL_STYLE
);
256 SetWindowLong(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
258 SendDlgItemMessage(hwndDlg
,
259 IDC_RADIO_SEARCHHERE
,
270 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
275 /* Enable the Next and Back buttons */
276 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
| PSWIZB_BACK
);
280 /* Handle a Next button click, if necessary */
281 PropSheet_SetCurSel(GetParent(hwndDlg
), 0, 4);
297 static INT_PTR CALLBACK
305 PDEVINSTDATA DevInstData
;
308 /* Retrieve pointer to the global setup data */
309 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
318 /* Get pointer to the global setup data */
319 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
320 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
322 DevInstData
->hDialog
= hwndDlg
;
323 hwndControl
= GetParent(hwndDlg
);
325 /* Center the wizard window */
326 CenterWindow (hwndControl
);
328 SendDlgItemMessage(hwndDlg
,
332 (LPARAM
) DevInstData
->buffer
);
334 /* Hide the system menu */
335 dwStyle
= GetWindowLong(hwndControl
, GWL_STYLE
);
336 SetWindowLong(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
340 case WM_SEARCH_FINISHED
:
342 CloseHandle(hThread
);
345 PropSheet_SetCurSel(GetParent(hwndDlg
), 0, IDD_NODRIVER
);
347 PropSheet_SetCurSel(GetParent(hwndDlg
), 0, IDD_FINISHPAGE
);
352 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
357 PropSheet_SetWizButtons(GetParent(hwndDlg
), !PSWIZB_NEXT
| !PSWIZB_BACK
);
358 hThread
= CreateThread( NULL
, 0, FindDriverProc
, DevInstData
, 0, &dwThreadId
);
364 SetWindowLong ( hwndDlg
, DWL_MSGRESULT
, TRUE
);
369 /* Handle a Next button click, if necessary */
389 TCHAR drive
[] = {'?',':',0};
392 PDEVINSTDATA DevInstData
;
395 DevInstData
= (PDEVINSTDATA
)lpParam
;
397 dwDrives
= GetLogicalDrives();
398 for (drive
[0] = 'A'; drive
[0] <= 'Z'; drive
[0]++)
402 nType
= GetDriveType( drive
);
403 if ((nType
== DRIVE_CDROM
))
404 //if ((nType == DRIVE_CDROM) || (nType == DRIVE_FIXED))
406 /* search for inf file */
407 if (SearchDriver ( DevInstData
, drive
))
409 /* if we found a valid driver inf... */
410 if (FindDriver ( DevInstData
))
412 InstallDriver ( DevInstData
);
413 PostMessage(DevInstData
->hDialog
, WM_SEARCH_FINISHED
, 1, 0);
422 PostMessage(DevInstData
->hDialog
, WM_SEARCH_FINISHED
, 0, 0);
426 static INT_PTR CALLBACK
434 PDEVINSTDATA DevInstData
;
436 /* Retrieve pointer to the global setup data */
437 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
445 /* Get pointer to the global setup data */
446 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
447 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
449 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
450 ShowWindow (hwndControl
, SW_HIDE
);
451 EnableWindow (hwndControl
, FALSE
);
453 SendDlgItemMessage(hwndDlg
,
457 (LPARAM
) DevInstData
->drvInfoData
.Description
);
460 SendDlgItemMessage(hwndDlg
,
463 (WPARAM
)DevInstData
->hTitleFont
,
470 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
475 /* Enable the correct buttons on for the active page */
476 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
480 /* Handle a Back button click, if necessary */
484 /* Handle a Finish button click, if necessary */
500 static INT_PTR CALLBACK
508 PDEVINSTDATA DevInstData
;
510 /* Get pointer to the global setup data */
511 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
519 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
520 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
522 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
523 ShowWindow (hwndControl
, SW_HIDE
);
524 EnableWindow (hwndControl
, FALSE
);
527 SendDlgItemMessage(hwndDlg
,
530 (WPARAM
)DevInstData
->hTitleFont
,
537 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
544 /* Enable the correct buttons on for the active page */
545 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_FINISH
);
549 PropSheet_SetCurSel(GetParent(hwndDlg
), 0, IDD_WELCOMEPAGE
);
550 /* Handle a Back button click, if necessary */
554 /* Handle a Finish button click, if necessary */
555 if (SendDlgItemMessage(hwndDlg
, IDC_DONOTSHOWDLG
, BM_GETCHECK
, (WPARAM
) 0, (LPARAM
) 0) == BST_CHECKED
)
558 if(SetupDiGetDeviceRegistryProperty(DevInstData
->hDevInfo
,
559 &DevInstData
->devInfoData
,
562 (BYTE
*)&config_flags
,
563 sizeof(config_flags
),
566 config_flags
|= CONFIGFLAG_FAILEDINSTALL
;
567 ret
= SetupDiSetDeviceRegistryProperty(
568 DevInstData
->hDevInfo
,
569 &DevInstData
->devInfoData
,
593 IN PDEVINSTDATA DevInstData
)
598 ret
= SetupDiBuildDriverInfoList(DevInstData
->hDevInfo
, &DevInstData
->devInfoData
, SPDIT_COMPATDRIVER
);
601 DPRINT("SetupDiBuildDriverInfoList() failed with error 0x%lx\n", GetLastError());
605 DevInstData
->drvInfoData
.cbSize
= sizeof(SP_DRVINFO_DATA
);
606 ret
= SetupDiEnumDriverInfo(
607 DevInstData
->hDevInfo
,
608 &DevInstData
->devInfoData
,
611 &DevInstData
->drvInfoData
);
614 if (GetLastError() == ERROR_NO_MORE_ITEMS
)
616 DPRINT("SetupDiEnumDriverInfo() failed with error 0x%lx\n", GetLastError());
619 DPRINT("Installing driver %S: %S\n", DevInstData
->drvInfoData
.MfgName
, DevInstData
->drvInfoData
.Description
);
626 IsDots(IN LPCTSTR str
)
628 if(_tcscmp(str
, _T(".")) && _tcscmp(str
, _T(".."))) return FALSE
;
633 GetFileExt(IN LPTSTR FileName
)
638 int i
= _tcsclen(FileName
);
639 while ((i
>= 0) && (FileName
[i
] != _T('.')))
642 FileName
= _tcslwr(FileName
);
652 IN PDEVINSTDATA DevInstData
,
656 SP_DEVINSTALL_PARAMS DevInstallParams
;
657 TCHAR DirPath
[MAX_PATH
];
658 TCHAR FileName
[MAX_PATH
];
659 TCHAR FullPath
[MAX_PATH
];
660 TCHAR LastDirPath
[MAX_PATH
] = _T("");
661 TCHAR PathWithPattern
[MAX_PATH
];
666 _tcscpy(DirPath
, Path
);
668 if (DirPath
[_tcsclen(DirPath
) - 1] != '\\')
669 _tcscat(DirPath
, _T("\\"));
671 _tcscpy(PathWithPattern
, DirPath
);
672 _tcscat(PathWithPattern
, _T("\\*"));
674 for (hFindFile
= FindFirstFile(PathWithPattern
, &wfd
); ((hFindFile
!= INVALID_HANDLE_VALUE
) && ok
); ok
= FindNextFile(hFindFile
, &wfd
))
677 _tcscpy(FileName
, wfd
.cFileName
);
678 if (IsDots(FileName
)) continue;
680 if((wfd
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
682 _tcscpy(FullPath
, DirPath
);
683 _tcscat(FullPath
, FileName
);
684 if(SearchDriver(DevInstData
, FullPath
))
689 LPCTSTR pszExtension
= GetFileExt(FileName
);
691 if ((_tcscmp(pszExtension
, _T(".inf")) == 0) && (_tcscmp(LastDirPath
, DirPath
) != 0))
693 _tcscpy(LastDirPath
, DirPath
);
694 ZeroMemory (&DevInstallParams
, sizeof(SP_DEVINSTALL_PARAMS
));
695 DevInstallParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
697 ret
= SetupDiGetDeviceInstallParams(
698 DevInstData
->hDevInfo
,
699 &DevInstData
->devInfoData
,
702 if (_tcsclen(DirPath
) <= MAX_PATH
)
704 memcpy(DevInstallParams
.DriverPath
, DirPath
, (_tcsclen(DirPath
) + 1) * sizeof(TCHAR
));
707 ret
= SetupDiSetDeviceInstallParams(
708 DevInstData
->hDevInfo
,
709 &DevInstData
->devInfoData
,
712 if ( FindDriver ( DevInstData
) )
714 if (hFindFile
!= INVALID_HANDLE_VALUE
)
715 FindClose(hFindFile
);
723 if (hFindFile
!= INVALID_HANDLE_VALUE
)
724 FindClose(hFindFile
);
731 IN PDEVINSTDATA DevInstData
)
736 ret
= SetupDiCallClassInstaller(
737 DIF_SELECTBESTCOMPATDRV
,
738 DevInstData
->hDevInfo
,
739 &DevInstData
->devInfoData
);
742 DPRINT("SetupDiCallClassInstaller(DIF_SELECTBESTCOMPATDRV) failed with error 0x%lx\n", GetLastError());
746 ret
= SetupDiCallClassInstaller(
748 DevInstData
->hDevInfo
,
749 &DevInstData
->devInfoData
);
752 DPRINT("SetupDiCallClassInstaller(DIF_ALLOW_INSTALL) failed with error 0x%lx\n", GetLastError());
756 ret
= SetupDiCallClassInstaller(
757 DIF_NEWDEVICEWIZARD_PREANALYZE
,
758 DevInstData
->hDevInfo
,
759 &DevInstData
->devInfoData
);
762 DPRINT("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_PREANALYZE) failed with error 0x%lx\n", GetLastError());
766 ret
= SetupDiCallClassInstaller(
767 DIF_NEWDEVICEWIZARD_POSTANALYZE
,
768 DevInstData
->hDevInfo
,
769 &DevInstData
->devInfoData
);
772 DPRINT("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_POSTANALYZE) failed with error 0x%lx\n", GetLastError());
776 ret
= SetupDiCallClassInstaller(
777 DIF_INSTALLDEVICEFILES
,
778 DevInstData
->hDevInfo
,
779 &DevInstData
->devInfoData
);
782 DPRINT("SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES) failed with error 0x%lx\n", GetLastError());
786 ret
= SetupDiCallClassInstaller(
787 DIF_REGISTER_COINSTALLERS
,
788 DevInstData
->hDevInfo
,
789 &DevInstData
->devInfoData
);
792 DPRINT("SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS) failed with error 0x%lx\n", GetLastError());
796 ret
= SetupDiCallClassInstaller(
797 DIF_INSTALLINTERFACES
,
798 DevInstData
->hDevInfo
,
799 &DevInstData
->devInfoData
);
802 DPRINT("SetupDiCallClassInstaller(DIF_INSTALLINTERFACES) failed with error 0x%lx\n", GetLastError());
806 ret
= SetupDiCallClassInstaller(
808 DevInstData
->hDevInfo
,
809 &DevInstData
->devInfoData
);
812 DPRINT("SetupDiCallClassInstaller(DIF_INSTALLDEVICE) failed with error 0x%lx\n", GetLastError());
816 ret
= SetupDiCallClassInstaller(
817 DIF_NEWDEVICEWIZARD_FINISHINSTALL
,
818 DevInstData
->hDevInfo
,
819 &DevInstData
->devInfoData
);
822 DPRINT("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_FINISHINSTALL) failed with error 0x%lx\n", GetLastError());
826 ret
= SetupDiCallClassInstaller(
827 DIF_DESTROYPRIVATEDATA
,
828 DevInstData
->hDevInfo
,
829 &DevInstData
->devInfoData
);
832 DPRINT("SetupDiCallClassInstaller(DIF_DESTROYPRIVATEDATA) failed with error 0x%lx\n", GetLastError());
844 if (DevInstData
.devInfoData
.cbSize
!= 0)
846 if (!SetupDiDestroyDriverInfoList(DevInstData
.hDevInfo
, &DevInstData
.devInfoData
, SPDIT_COMPATDRIVER
))
847 DPRINT("SetupDiDestroyDriverInfoList() failed with error 0x%lx\n", GetLastError());
850 if (DevInstData
.hDevInfo
!= INVALID_HANDLE_VALUE
)
852 if (!SetupDiDestroyDeviceInfoList(DevInstData
.hDevInfo
))
853 DPRINT("SetupDiDestroyDeviceInfoList() failed with error 0x%lx\n", GetLastError());
856 if (DevInstData
.buffer
)
857 HeapFree(GetProcessHeap(), 0, DevInstData
.buffer
);
864 IN HINSTANCE hInstance
,
865 IN LPCWSTR InstanceId
,
870 HPROPSHEETPAGE ahpsp
[5];
876 /* Clear devinst data */
877 ZeroMemory(&DevInstData
, sizeof(DEVINSTDATA
));
878 DevInstData
.devInfoData
.cbSize
= 0; /* Tell if the devInfoData is valid */
881 DevInstData
.hDevInfo
= SetupDiCreateDeviceInfoListExW(NULL
, NULL
, NULL
, NULL
);
882 if (DevInstData
.hDevInfo
== INVALID_HANDLE_VALUE
)
884 DPRINT("SetupDiCreateDeviceInfoListExW() failed with error 0x%lx\n", GetLastError());
889 DevInstData
.devInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
890 ret
= SetupDiOpenDeviceInfoW(
891 DevInstData
.hDevInfo
,
895 &DevInstData
.devInfoData
);
898 DPRINT("SetupDiOpenDeviceInfoW() failed with error 0x%lx (InstanceId %S)\n", GetLastError(), InstanceId
);
899 DevInstData
.devInfoData
.cbSize
= 0;
904 SetLastError(ERROR_GEN_FAILURE
);
905 ret
= SetupDiGetDeviceRegistryProperty(
906 DevInstData
.hDevInfo
,
907 &DevInstData
.devInfoData
,
909 &DevInstData
.regDataType
,
911 &DevInstData
.requiredSize
);
913 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
&& DevInstData
.regDataType
== REG_SZ
)
915 DevInstData
.buffer
= HeapAlloc(GetProcessHeap(), 0, DevInstData
.requiredSize
);
916 if (!DevInstData
.buffer
)
918 DPRINT("HeapAlloc() failed\n");
919 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
923 ret
= SetupDiGetDeviceRegistryProperty(
924 DevInstData
.hDevInfo
,
925 &DevInstData
.devInfoData
,
927 &DevInstData
.regDataType
,
928 DevInstData
.buffer
, DevInstData
.requiredSize
,
929 &DevInstData
.requiredSize
);
934 DPRINT("SetupDiGetDeviceRegistryProperty() failed with error 0x%lx (InstanceId %S)\n", GetLastError(), InstanceId
);
939 if(SetupDiGetDeviceRegistryProperty(DevInstData
.hDevInfo
,
940 &DevInstData
.devInfoData
,
943 (BYTE
*)&config_flags
,
944 sizeof(config_flags
),
947 if (config_flags
& CONFIGFLAG_FAILEDINSTALL
)
956 swprintf(buf, _T("%ld"), GetLastError());
957 MessageBox(0,buf,buf,0);
961 DPRINT("Installing %S (%S)\n", DevInstData
.buffer
, InstanceId
);
963 if ((!FindDriver(&DevInstData
)) && (Show
!= SW_HIDE
))
966 /* Create the Welcome page */
967 ZeroMemory (&psp
, sizeof(PROPSHEETPAGE
));
968 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
969 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
970 psp
.hInstance
= hDllInstance
;
971 psp
.lParam
= (LPARAM
)&DevInstData
;
972 psp
.pfnDlgProc
= WelcomeDlgProc
;
973 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_WELCOMEPAGE
);
974 ahpsp
[IDD_WELCOMEPAGE
] = CreatePropertySheetPage(&psp
);
976 /* Create the Select Source page */
977 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
978 psp
.pfnDlgProc
= CHSourceDlgProc
;
979 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_CHSOURCE
);
980 ahpsp
[IDD_CHSOURCE
] = CreatePropertySheetPage(&psp
);
982 /* Create the Search driver page */
983 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
984 psp
.pfnDlgProc
= SearchDrvDlgProc
;
985 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_SEARCHDRV
);
986 ahpsp
[IDD_SEARCHDRV
] = CreatePropertySheetPage(&psp
);
988 /* Create the Finish page */
989 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
990 psp
.pfnDlgProc
= FinishDlgProc
;
991 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_FINISHPAGE
);
992 ahpsp
[IDD_FINISHPAGE
] = CreatePropertySheetPage(&psp
);
994 /* Create the Install failed page */
995 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
996 psp
.pfnDlgProc
= InstFailDlgProc
;
997 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_NODRIVER
);
998 ahpsp
[IDD_NODRIVER
] = CreatePropertySheetPage(&psp
);
1000 /* Create the property sheet */
1001 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
1002 psh
.dwFlags
= PSH_WIZARD97
| PSH_WATERMARK
| PSH_HEADER
;
1003 psh
.hInstance
= hDllInstance
;
1004 psh
.hwndParent
= NULL
;
1008 psh
.pszbmWatermark
= MAKEINTRESOURCE(IDB_WATERMARK
);
1009 psh
.pszbmHeader
= MAKEINTRESOURCE(IDB_HEADER
);
1011 /* Create title font */
1012 DevInstData
.hTitleFont
= CreateTitleFont();
1014 /* Display the wizard */
1015 PropertySheet(&psh
);
1017 DeleteObject(DevInstData
.hTitleFont
);
1022 InstallDriver ( &DevInstData
);
1031 IN HINSTANCE hInstance
,
1033 IN LPVOID lpReserved
)
1035 if (dwReason
== DLL_PROCESS_ATTACH
)
1037 INITCOMMONCONTROLSEX InitControls
;
1039 InitControls
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
1040 InitControls
.dwICC
= ICC_PROGRESS_CLASS
;
1041 InitCommonControlsEx(&InitControls
);
1042 hDllInstance
= hInstance
;