2 * New device installer (newdev.dll)
4 * Copyright 2005 Hervé Poussineau (hpoussin@reactos.org)
5 * 2005 Christoph von Wittich (Christoph@ActiveVB.de)
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 WINE_DEFAULT_DEBUG_CHANNEL(newdev
);
27 static BOOL
SearchDriver ( PDEVINSTDATA DevInstData
, LPCTSTR Path
);
28 static BOOL
InstallDriver ( PDEVINSTDATA DevInstData
);
29 static DWORD WINAPI
FindDriverProc( LPVOID lpParam
);
30 static BOOL
FindDriver ( PDEVINSTDATA DevInstData
);
32 static DEVINSTDATA DevInstData
;
33 HINSTANCE hDllInstance
;
37 CanDisableDevice(IN DEVINST DevInst
,
42 /* hpoussin, Dec 2005. I've disabled this code because
43 * ntoskrnl never sets the DN_DISABLEABLE flag.
46 ULONG Status
, ProblemNumber
;
49 cr
= CM_Get_DevNode_Status_Ex(&Status
,
56 *CanDisable
= ((Status
& DN_DISABLEABLE
) != 0);
69 IsDeviceStarted(IN DEVINST DevInst
,
74 ULONG Status
, ProblemNumber
;
77 cr
= CM_Get_DevNode_Status_Ex(&Status
,
84 *IsEnabled
= ((Status
& DN_STARTED
) != 0);
93 StartDevice(IN HDEVINFO DeviceInfoSet
,
94 IN PSP_DEVINFO_DATA DevInfoData OPTIONAL
,
96 IN DWORD HardwareProfile OPTIONAL
,
97 OUT BOOL
*bNeedReboot OPTIONAL
)
99 SP_PROPCHANGE_PARAMS pcp
;
100 SP_DEVINSTALL_PARAMS dp
;
104 pcp
.ClassInstallHeader
.cbSize
= sizeof(SP_CLASSINSTALL_HEADER
);
105 pcp
.ClassInstallHeader
.InstallFunction
= DIF_PROPERTYCHANGE
;
106 pcp
.HwProfile
= HardwareProfile
;
110 /* try to enable the device on the global profile */
111 pcp
.StateChange
= DICS_ENABLE
;
112 pcp
.Scope
= DICS_FLAG_GLOBAL
;
115 LastErr
= GetLastError();
116 if (SetupDiSetClassInstallParams(DeviceInfoSet
,
118 &pcp
.ClassInstallHeader
,
119 sizeof(SP_PROPCHANGE_PARAMS
)))
121 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE
,
125 SetLastError(LastErr
);
128 /* try config-specific */
129 pcp
.StateChange
= (bEnable
? DICS_ENABLE
: DICS_DISABLE
);
130 pcp
.Scope
= DICS_FLAG_CONFIGSPECIFIC
;
132 if (SetupDiSetClassInstallParams(DeviceInfoSet
,
134 &pcp
.ClassInstallHeader
,
135 sizeof(SP_PROPCHANGE_PARAMS
)) &&
136 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE
,
140 dp
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
141 if (SetupDiGetDeviceInstallParams(DeviceInfoSet
,
145 if (bNeedReboot
!= NULL
)
147 *bNeedReboot
= ((dp
.Flags
& (DI_NEEDRESTART
| DI_NEEDREBOOT
)) != 0);
160 UpdateDriverForPlugAndPlayDevicesW(
162 IN LPCWSTR HardwareId
,
163 IN LPCWSTR FullInfPath
,
164 IN DWORD InstallFlags
,
165 OUT PBOOL bRebootRequired OPTIONAL
)
168 SetLastError(ERROR_GEN_FAILURE
);
176 UpdateDriverForPlugAndPlayDevicesA(
178 IN LPCSTR HardwareId
,
179 IN LPCSTR FullInfPath
,
180 IN DWORD InstallFlags
,
181 OUT PBOOL bRebootRequired OPTIONAL
)
184 LPWSTR HardwareIdW
= NULL
;
185 LPWSTR FullInfPathW
= NULL
;
187 int len
= MultiByteToWideChar(CP_ACP
, 0, HardwareId
, -1, NULL
, 0);
188 HardwareIdW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
191 SetLastError(ERROR_GEN_FAILURE
);
194 MultiByteToWideChar(CP_ACP
, 0, HardwareId
, -1, HardwareIdW
, len
);
196 len
= MultiByteToWideChar(CP_ACP
, 0, FullInfPath
, -1, NULL
, 0);
197 FullInfPathW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
200 HeapFree(GetProcessHeap(), 0, HardwareIdW
);
201 SetLastError(ERROR_GEN_FAILURE
);
204 MultiByteToWideChar(CP_ACP
, 0, FullInfPath
, -1, FullInfPathW
, len
);
206 Result
= UpdateDriverForPlugAndPlayDevicesW(hwndParent
,
212 HeapFree(GetProcessHeap(), 0, HardwareIdW
);
213 HeapFree(GetProcessHeap(), 0, FullInfPathW
);
220 CreateTitleFont(VOID
)
222 NONCLIENTMETRICS ncm
;
228 ncm
.cbSize
= sizeof(NONCLIENTMETRICS
);
229 SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, 0, &ncm
, 0);
231 LogFont
= ncm
.lfMessageFont
;
232 LogFont
.lfWeight
= FW_BOLD
;
233 _tcscpy(LogFont
.lfFaceName
, _T("MS Shell Dlg"));
237 LogFont
.lfHeight
= 0 - GetDeviceCaps (hdc
, LOGPIXELSY
) * FontSize
/ 72;
238 hFont
= CreateFontIndirect(&LogFont
);
239 ReleaseDC(NULL
, hdc
);
245 CenterWindow(HWND hWnd
)
251 hWndParent
= GetParent(hWnd
);
252 if (hWndParent
== NULL
)
253 hWndParent
= GetDesktopWindow();
255 GetWindowRect(hWndParent
, &rcParent
);
256 GetWindowRect(hWnd
, &rcWindow
);
260 ((rcParent
.right
- rcParent
.left
) - (rcWindow
.right
- rcWindow
.left
)) / 2,
261 ((rcParent
.bottom
- rcParent
.top
) - (rcWindow
.bottom
- rcWindow
.top
)) / 2,
267 static INT_PTR CALLBACK
275 PDEVINSTDATA DevInstData
;
277 /* Retrieve pointer to the global setup data */
278 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
287 /* Get pointer to the global setup data */
288 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
289 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
291 hwndControl
= GetParent(hwndDlg
);
293 /* Center the wizard window */
294 CenterWindow (hwndControl
);
296 /* Hide the system menu */
297 dwStyle
= GetWindowLong(hwndControl
, GWL_STYLE
);
298 SetWindowLong(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
301 SendDlgItemMessage(hwndDlg
,
304 (WPARAM
)DevInstData
->hTitleFont
,
307 SendDlgItemMessage(hwndDlg
,
311 (LPARAM
) DevInstData
->buffer
);
313 SendDlgItemMessage(hwndDlg
,
326 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
331 /* Enable the Next button */
332 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
336 /* Handle a Next button click, if necessary */
338 if (SendDlgItemMessage(hwndDlg
, IDC_RADIO_AUTO
, BM_GETCHECK
, (WPARAM
) 0, (LPARAM
) 0) == BST_CHECKED
)
339 PropSheet_SetCurSel(GetParent(hwndDlg
), 0, IDD_SEARCHDRV
);
356 static INT_PTR CALLBACK
364 PDEVINSTDATA DevInstData
;
366 /* Retrieve pointer to the global setup data */
367 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
376 /* Get pointer to the global setup data */
377 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
378 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
380 hwndControl
= GetParent(hwndDlg
);
382 /* Center the wizard window */
383 CenterWindow (hwndControl
);
385 /* Hide the system menu */
386 dwStyle
= GetWindowLong(hwndControl
, GWL_STYLE
);
387 SetWindowLong(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
389 SendDlgItemMessage(hwndDlg
,
390 IDC_RADIO_SEARCHHERE
,
401 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
406 /* Enable the Next and Back buttons */
407 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
| PSWIZB_BACK
);
411 /* Handle a Next button click, if necessary */
412 PropSheet_SetCurSel(GetParent(hwndDlg
), 0, 4);
428 static INT_PTR CALLBACK
436 PDEVINSTDATA DevInstData
;
439 /* Retrieve pointer to the global setup data */
440 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
449 /* Get pointer to the global setup data */
450 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
451 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
453 DevInstData
->hDialog
= hwndDlg
;
454 hwndControl
= GetParent(hwndDlg
);
456 /* Center the wizard window */
457 CenterWindow (hwndControl
);
459 SendDlgItemMessage(hwndDlg
,
463 (LPARAM
) DevInstData
->buffer
);
465 /* Hide the system menu */
466 dwStyle
= GetWindowLong(hwndControl
, GWL_STYLE
);
467 SetWindowLong(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
471 case WM_SEARCH_FINISHED
:
473 CloseHandle(hThread
);
476 PropSheet_SetCurSel(GetParent(hwndDlg
), 0, IDD_NODRIVER
);
478 PropSheet_SetCurSel(GetParent(hwndDlg
), 0, IDD_FINISHPAGE
);
483 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
488 PropSheet_SetWizButtons(GetParent(hwndDlg
), !PSWIZB_NEXT
| !PSWIZB_BACK
);
489 hThread
= CreateThread( NULL
, 0, FindDriverProc
, DevInstData
, 0, &dwThreadId
);
495 SetWindowLong ( hwndDlg
, DWL_MSGRESULT
, TRUE
);
500 /* Handle a Next button click, if necessary */
520 TCHAR drive
[] = {'?',':',0};
523 PDEVINSTDATA DevInstData
;
527 DevInstData
= (PDEVINSTDATA
)lpParam
;
529 dwDrives
= GetLogicalDrives();
530 for (drive
[0] = 'A'; drive
[0] <= 'Z'; drive
[0]++)
534 nType
= GetDriveType( drive
);
535 if ((nType
== DRIVE_CDROM
))
536 //if ((nType == DRIVE_CDROM) || (nType == DRIVE_FIXED))
538 /* search for inf file */
539 if (SearchDriver ( DevInstData
, drive
))
541 /* if we found a valid driver inf... */
542 if (FindDriver ( DevInstData
))
544 InstallDriver ( DevInstData
);
545 PostMessage(DevInstData
->hDialog
, WM_SEARCH_FINISHED
, 1, 0);
554 /* update device configuration */
555 if(SetupDiGetDeviceRegistryProperty(DevInstData
->hDevInfo
,
556 &DevInstData
->devInfoData
,
559 (BYTE
*)&config_flags
,
560 sizeof(config_flags
),
563 config_flags
|= CONFIGFLAG_FAILEDINSTALL
;
564 SetupDiSetDeviceRegistryProperty(
565 DevInstData
->hDevInfo
,
566 &DevInstData
->devInfoData
,
568 (BYTE
*)&config_flags
, sizeof(config_flags
) );
571 PostMessage(DevInstData
->hDialog
, WM_SEARCH_FINISHED
, 0, 0);
575 static INT_PTR CALLBACK
583 PDEVINSTDATA DevInstData
;
585 /* Retrieve pointer to the global setup data */
586 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
594 /* Get pointer to the global setup data */
595 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
596 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
598 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
599 ShowWindow (hwndControl
, SW_HIDE
);
600 EnableWindow (hwndControl
, FALSE
);
602 SendDlgItemMessage(hwndDlg
,
606 (LPARAM
) DevInstData
->drvInfoData
.Description
);
609 SendDlgItemMessage(hwndDlg
,
612 (WPARAM
)DevInstData
->hTitleFont
,
619 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
624 /* Enable the correct buttons on for the active page */
625 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
629 /* Handle a Back button click, if necessary */
633 /* Handle a Finish button click, if necessary */
649 static INT_PTR CALLBACK
657 PDEVINSTDATA DevInstData
;
659 /* Get pointer to the global setup data */
660 DevInstData
= (PDEVINSTDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
667 BOOL DisableableDevice
= FALSE
;
669 DevInstData
= (PDEVINSTDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
670 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)DevInstData
);
672 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
673 ShowWindow (hwndControl
, SW_HIDE
);
674 EnableWindow (hwndControl
, FALSE
);
677 SendDlgItemMessage(hwndDlg
,
680 (WPARAM
)DevInstData
->hTitleFont
,
683 /* disable the "do not show this dialog anymore" checkbox
684 if the device cannot be disabled */
685 CanDisableDevice(DevInstData
->devInfoData
.DevInst
,
688 EnableWindow(GetDlgItem(hwndDlg
,
696 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
701 /* Enable the correct buttons on for the active page */
702 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_FINISH
);
706 PropSheet_SetCurSel(GetParent(hwndDlg
), 0, IDD_WELCOMEPAGE
);
707 /* Handle a Back button click, if necessary */
712 BOOL DisableableDevice
= FALSE
;
713 BOOL IsStarted
= FALSE
;
715 if (CanDisableDevice(DevInstData
->devInfoData
.DevInst
,
717 &DisableableDevice
) &&
719 IsDeviceStarted(DevInstData
->devInfoData
.DevInst
,
723 SendDlgItemMessage(hwndDlg
, IDC_DONOTSHOWDLG
, BM_GETCHECK
, (WPARAM
) 0, (LPARAM
) 0) == BST_CHECKED
)
725 /* disable the device */
726 StartDevice(DevInstData
->hDevInfo
,
727 &DevInstData
->devInfoData
,
751 IN PDEVINSTDATA DevInstData
)
753 SP_DEVINSTALL_PARAMS DevInstallParams
= {0,};
756 DevInstallParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
757 if (!SetupDiGetDeviceInstallParams(DevInstData
->hDevInfo
, &DevInstData
->devInfoData
, &DevInstallParams
))
759 TRACE("SetupDiGetDeviceInstallParams() failed with error 0x%lx\n", GetLastError());
762 DevInstallParams
.FlagsEx
|= DI_FLAGSEX_ALLOWEXCLUDEDDRVS
;
763 if (!SetupDiSetDeviceInstallParams(DevInstData
->hDevInfo
, &DevInstData
->devInfoData
, &DevInstallParams
))
765 TRACE("SetupDiSetDeviceInstallParams() failed with error 0x%lx\n", GetLastError());
769 ret
= SetupDiBuildDriverInfoList(DevInstData
->hDevInfo
, &DevInstData
->devInfoData
, SPDIT_COMPATDRIVER
);
772 TRACE("SetupDiBuildDriverInfoList() failed with error 0x%lx\n", GetLastError());
776 DevInstData
->drvInfoData
.cbSize
= sizeof(SP_DRVINFO_DATA
);
777 ret
= SetupDiEnumDriverInfo(
778 DevInstData
->hDevInfo
,
779 &DevInstData
->devInfoData
,
782 &DevInstData
->drvInfoData
);
785 if (GetLastError() == ERROR_NO_MORE_ITEMS
)
787 TRACE("SetupDiEnumDriverInfo() failed with error 0x%lx\n", GetLastError());
790 TRACE("Installing driver %S: %S\n", DevInstData
->drvInfoData
.MfgName
, DevInstData
->drvInfoData
.Description
);
797 IsDots(IN LPCTSTR str
)
799 if(_tcscmp(str
, _T(".")) && _tcscmp(str
, _T(".."))) return FALSE
;
804 GetFileExt(IN LPTSTR FileName
)
809 int i
= _tcsclen(FileName
);
810 while ((i
>= 0) && (FileName
[i
] != _T('.')))
813 FileName
= _tcslwr(FileName
);
823 IN PDEVINSTDATA DevInstData
,
827 SP_DEVINSTALL_PARAMS DevInstallParams
;
828 TCHAR DirPath
[MAX_PATH
];
829 TCHAR FileName
[MAX_PATH
];
830 TCHAR FullPath
[MAX_PATH
];
831 TCHAR LastDirPath
[MAX_PATH
] = _T("");
832 TCHAR PathWithPattern
[MAX_PATH
];
837 _tcscpy(DirPath
, Path
);
839 if (DirPath
[_tcsclen(DirPath
) - 1] != '\\')
840 _tcscat(DirPath
, _T("\\"));
842 _tcscpy(PathWithPattern
, DirPath
);
843 _tcscat(PathWithPattern
, _T("\\*"));
845 for (hFindFile
= FindFirstFile(PathWithPattern
, &wfd
); ((hFindFile
!= INVALID_HANDLE_VALUE
) && ok
); ok
= FindNextFile(hFindFile
, &wfd
))
848 _tcscpy(FileName
, wfd
.cFileName
);
849 if (IsDots(FileName
)) continue;
851 if((wfd
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
853 _tcscpy(FullPath
, DirPath
);
854 _tcscat(FullPath
, FileName
);
855 if(SearchDriver(DevInstData
, FullPath
))
860 LPCTSTR pszExtension
= GetFileExt(FileName
);
862 if ((_tcscmp(pszExtension
, _T(".inf")) == 0) && (_tcscmp(LastDirPath
, DirPath
) != 0))
864 _tcscpy(LastDirPath
, DirPath
);
865 ZeroMemory (&DevInstallParams
, sizeof(SP_DEVINSTALL_PARAMS
));
866 DevInstallParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
868 ret
= SetupDiGetDeviceInstallParams(
869 DevInstData
->hDevInfo
,
870 &DevInstData
->devInfoData
,
873 if (_tcsclen(DirPath
) <= MAX_PATH
)
875 memcpy(DevInstallParams
.DriverPath
, DirPath
, (_tcsclen(DirPath
) + 1) * sizeof(TCHAR
));
878 ret
= SetupDiSetDeviceInstallParams(
879 DevInstData
->hDevInfo
,
880 &DevInstData
->devInfoData
,
883 if ( FindDriver ( DevInstData
) )
885 if (hFindFile
!= INVALID_HANDLE_VALUE
)
886 FindClose(hFindFile
);
894 if (hFindFile
!= INVALID_HANDLE_VALUE
)
895 FindClose(hFindFile
);
902 IN PDEVINSTDATA DevInstData
)
907 ret
= SetupDiCallClassInstaller(
908 DIF_SELECTBESTCOMPATDRV
,
909 DevInstData
->hDevInfo
,
910 &DevInstData
->devInfoData
);
913 TRACE("SetupDiCallClassInstaller(DIF_SELECTBESTCOMPATDRV) failed with error 0x%lx\n", GetLastError());
917 ret
= SetupDiCallClassInstaller(
919 DevInstData
->hDevInfo
,
920 &DevInstData
->devInfoData
);
923 TRACE("SetupDiCallClassInstaller(DIF_ALLOW_INSTALL) failed with error 0x%lx\n", GetLastError());
927 ret
= SetupDiCallClassInstaller(
928 DIF_NEWDEVICEWIZARD_PREANALYZE
,
929 DevInstData
->hDevInfo
,
930 &DevInstData
->devInfoData
);
933 TRACE("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_PREANALYZE) failed with error 0x%lx\n", GetLastError());
937 ret
= SetupDiCallClassInstaller(
938 DIF_NEWDEVICEWIZARD_POSTANALYZE
,
939 DevInstData
->hDevInfo
,
940 &DevInstData
->devInfoData
);
943 TRACE("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_POSTANALYZE) failed with error 0x%lx\n", GetLastError());
947 ret
= SetupDiCallClassInstaller(
948 DIF_INSTALLDEVICEFILES
,
949 DevInstData
->hDevInfo
,
950 &DevInstData
->devInfoData
);
953 TRACE("SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES) failed with error 0x%lx\n", GetLastError());
957 ret
= SetupDiCallClassInstaller(
958 DIF_REGISTER_COINSTALLERS
,
959 DevInstData
->hDevInfo
,
960 &DevInstData
->devInfoData
);
963 TRACE("SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS) failed with error 0x%lx\n", GetLastError());
967 ret
= SetupDiCallClassInstaller(
968 DIF_INSTALLINTERFACES
,
969 DevInstData
->hDevInfo
,
970 &DevInstData
->devInfoData
);
973 TRACE("SetupDiCallClassInstaller(DIF_INSTALLINTERFACES) failed with error 0x%lx\n", GetLastError());
977 ret
= SetupDiCallClassInstaller(
979 DevInstData
->hDevInfo
,
980 &DevInstData
->devInfoData
);
983 TRACE("SetupDiCallClassInstaller(DIF_INSTALLDEVICE) failed with error 0x%lx\n", GetLastError());
987 ret
= SetupDiCallClassInstaller(
988 DIF_NEWDEVICEWIZARD_FINISHINSTALL
,
989 DevInstData
->hDevInfo
,
990 &DevInstData
->devInfoData
);
993 TRACE("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_FINISHINSTALL) failed with error 0x%lx\n", GetLastError());
997 ret
= SetupDiCallClassInstaller(
998 DIF_DESTROYPRIVATEDATA
,
999 DevInstData
->hDevInfo
,
1000 &DevInstData
->devInfoData
);
1003 TRACE("SetupDiCallClassInstaller(DIF_DESTROYPRIVATEDATA) failed with error 0x%lx\n", GetLastError());
1015 if (DevInstData
.devInfoData
.cbSize
!= 0)
1017 if (!SetupDiDestroyDriverInfoList(DevInstData
.hDevInfo
, &DevInstData
.devInfoData
, SPDIT_COMPATDRIVER
))
1018 TRACE("SetupDiDestroyDriverInfoList() failed with error 0x%lx\n", GetLastError());
1021 if (DevInstData
.hDevInfo
!= INVALID_HANDLE_VALUE
)
1023 if (!SetupDiDestroyDeviceInfoList(DevInstData
.hDevInfo
))
1024 TRACE("SetupDiDestroyDeviceInfoList() failed with error 0x%lx\n", GetLastError());
1027 if (DevInstData
.buffer
)
1028 HeapFree(GetProcessHeap(), 0, DevInstData
.buffer
);
1038 IN HINSTANCE hInstance
,
1039 IN LPCWSTR InstanceId
,
1043 PROPSHEETHEADER psh
;
1044 HPROPSHEETPAGE ahpsp
[5];
1051 /* XP kills the process... */
1052 ExitProcess(ERROR_ACCESS_DENIED
);
1055 /* Clear devinst data */
1056 ZeroMemory(&DevInstData
, sizeof(DEVINSTDATA
));
1057 DevInstData
.devInfoData
.cbSize
= 0; /* Tell if the devInfoData is valid */
1060 DevInstData
.hDevInfo
= SetupDiCreateDeviceInfoListExW(NULL
, NULL
, NULL
, NULL
);
1061 if (DevInstData
.hDevInfo
== INVALID_HANDLE_VALUE
)
1063 TRACE("SetupDiCreateDeviceInfoListExW() failed with error 0x%lx\n", GetLastError());
1068 DevInstData
.devInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
1069 ret
= SetupDiOpenDeviceInfoW(
1070 DevInstData
.hDevInfo
,
1074 &DevInstData
.devInfoData
);
1077 TRACE("SetupDiOpenDeviceInfoW() failed with error 0x%lx (InstanceId %S)\n", GetLastError(), InstanceId
);
1078 DevInstData
.devInfoData
.cbSize
= 0;
1083 SetLastError(ERROR_GEN_FAILURE
);
1084 ret
= SetupDiGetDeviceRegistryProperty(
1085 DevInstData
.hDevInfo
,
1086 &DevInstData
.devInfoData
,
1088 &DevInstData
.regDataType
,
1090 &DevInstData
.requiredSize
);
1092 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
&& DevInstData
.regDataType
== REG_SZ
)
1094 DevInstData
.buffer
= HeapAlloc(GetProcessHeap(), 0, DevInstData
.requiredSize
);
1095 if (!DevInstData
.buffer
)
1097 TRACE("HeapAlloc() failed\n");
1098 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1102 ret
= SetupDiGetDeviceRegistryProperty(
1103 DevInstData
.hDevInfo
,
1104 &DevInstData
.devInfoData
,
1106 &DevInstData
.regDataType
,
1107 DevInstData
.buffer
, DevInstData
.requiredSize
,
1108 &DevInstData
.requiredSize
);
1113 TRACE("SetupDiGetDeviceRegistryProperty() failed with error 0x%lx (InstanceId %S)\n", GetLastError(), InstanceId
);
1118 if(SetupDiGetDeviceRegistryProperty(DevInstData
.hDevInfo
,
1119 &DevInstData
.devInfoData
,
1122 (BYTE
*)&config_flags
,
1123 sizeof(config_flags
),
1126 if (config_flags
& CONFIGFLAG_FAILEDINSTALL
)
1135 swprintf(buf, _T("%ld"), GetLastError());
1136 MessageBox(0,buf,buf,0);
1140 TRACE("Installing %S (%S)\n", DevInstData
.buffer
, InstanceId
);
1142 if ((!FindDriver(&DevInstData
)) && (Show
!= SW_HIDE
))
1145 /* Create the Welcome page */
1146 ZeroMemory (&psp
, sizeof(PROPSHEETPAGE
));
1147 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
1148 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1149 psp
.hInstance
= hDllInstance
;
1150 psp
.lParam
= (LPARAM
)&DevInstData
;
1151 psp
.pfnDlgProc
= WelcomeDlgProc
;
1152 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_WELCOMEPAGE
);
1153 ahpsp
[IDD_WELCOMEPAGE
] = CreatePropertySheetPage(&psp
);
1155 /* Create the Select Source page */
1156 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
1157 psp
.pfnDlgProc
= CHSourceDlgProc
;
1158 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_CHSOURCE
);
1159 ahpsp
[IDD_CHSOURCE
] = CreatePropertySheetPage(&psp
);
1161 /* Create the Search driver page */
1162 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
1163 psp
.pfnDlgProc
= SearchDrvDlgProc
;
1164 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_SEARCHDRV
);
1165 ahpsp
[IDD_SEARCHDRV
] = CreatePropertySheetPage(&psp
);
1167 /* Create the Finish page */
1168 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1169 psp
.pfnDlgProc
= FinishDlgProc
;
1170 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_FINISHPAGE
);
1171 ahpsp
[IDD_FINISHPAGE
] = CreatePropertySheetPage(&psp
);
1173 /* Create the Install failed page */
1174 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1175 psp
.pfnDlgProc
= InstFailDlgProc
;
1176 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_NODRIVER
);
1177 ahpsp
[IDD_NODRIVER
] = CreatePropertySheetPage(&psp
);
1179 /* Create the property sheet */
1180 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
1181 psh
.dwFlags
= PSH_WIZARD97
| PSH_WATERMARK
| PSH_HEADER
;
1182 psh
.hInstance
= hDllInstance
;
1183 psh
.hwndParent
= NULL
;
1187 psh
.pszbmWatermark
= MAKEINTRESOURCE(IDB_WATERMARK
);
1188 psh
.pszbmHeader
= MAKEINTRESOURCE(IDB_HEADER
);
1190 /* Create title font */
1191 DevInstData
.hTitleFont
= CreateTitleFont();
1193 /* Display the wizard */
1194 PropertySheet(&psh
);
1196 DeleteObject(DevInstData
.hTitleFont
);
1201 InstallDriver ( &DevInstData
);
1212 ClientSideInstallW(IN HWND hWndOwner
,
1213 IN DWORD dwUnknownFlags
,
1214 IN LPWSTR lpNamedPipeName
)
1216 /* NOTE: pNamedPipeName is in the format:
1217 * "\\.\pipe\PNP_Device_Install_Pipe_0.{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"
1224 IN HINSTANCE hInstance
,
1226 IN LPVOID lpReserved
)
1228 if (dwReason
== DLL_PROCESS_ATTACH
)
1230 INITCOMMONCONTROLSEX InitControls
;
1232 DisableThreadLibraryCalls(hInstance
);
1234 InitControls
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
1235 InitControls
.dwICC
= ICC_PROGRESS_CLASS
;
1236 InitCommonControlsEx(&InitControls
);
1237 hDllInstance
= hInstance
;