2 * New device installer (newdev.dll)
4 * Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
5 * 2005 Christoph von Wittich (Christoph@ActiveVB.de)
6 * 2009 Colin Finck (colin@reactos.org)
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "newdev_private.h"
25 /* Global variables */
26 HINSTANCE hDllInstance
;
30 IN PDEVINSTDATA DevInstData
,
31 IN LPCWSTR Directory OPTIONAL
,
32 IN LPCWSTR InfFile OPTIONAL
);
38 UpdateDriverForPlugAndPlayDevicesW(
40 IN LPCWSTR HardwareId
,
41 IN LPCWSTR FullInfPath
,
42 IN DWORD InstallFlags
,
43 OUT PBOOL bRebootRequired OPTIONAL
)
45 DEVINSTDATA DevInstData
;
49 LPCWSTR CurrentHardwareId
; /* Pointer into Buffer */
50 BOOL FoundHardwareId
, FoundAtLeastOneDevice
= FALSE
;
53 DevInstData
.hDevInfo
= INVALID_HANDLE_VALUE
;
55 TRACE("UpdateDriverForPlugAndPlayDevicesW(%p %s %s 0x%x %p)\n",
56 hwndParent
, debugstr_w(HardwareId
), debugstr_w(FullInfPath
), InstallFlags
, bRebootRequired
);
58 /* FIXME: InstallFlags bRebootRequired ignored! */
61 if (InstallFlags
& ~(INSTALLFLAG_FORCE
| INSTALLFLAG_READONLY
| INSTALLFLAG_NONINTERACTIVE
))
63 TRACE("Unknown flags: 0x%08lx\n", InstallFlags
& ~(INSTALLFLAG_FORCE
| INSTALLFLAG_READONLY
| INSTALLFLAG_NONINTERACTIVE
));
64 SetLastError(ERROR_INVALID_FLAGS
);
68 /* Enumerate all devices of the system */
69 DevInstData
.hDevInfo
= SetupDiGetClassDevsW(NULL
, NULL
, hwndParent
, DIGCF_ALLCLASSES
| DIGCF_PRESENT
);
70 if (DevInstData
.hDevInfo
== INVALID_HANDLE_VALUE
)
72 DevInstData
.devInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
75 if (!SetupDiEnumDeviceInfo(DevInstData
.hDevInfo
, i
, &DevInstData
.devInfoData
))
77 if (GetLastError() != ERROR_NO_MORE_ITEMS
)
79 TRACE("SetupDiEnumDeviceInfo() failed with error 0x%x\n", GetLastError());
82 /* This error was expected */
87 HeapFree(GetProcessHeap(), 0, Buffer
);
90 while (!SetupDiGetDeviceRegistryPropertyW(
92 &DevInstData
.devInfoData
,
99 if (GetLastError() == ERROR_FILE_NOT_FOUND
)
104 else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
106 TRACE("SetupDiGetDeviceRegistryPropertyW() failed with error 0x%x\n", GetLastError());
109 /* This error was expected */
110 HeapFree(GetProcessHeap(), 0, Buffer
);
111 Buffer
= HeapAlloc(GetProcessHeap(), 0, BufferSize
);
114 TRACE("HeapAlloc() failed\n", GetLastError());
115 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
122 /* Check if we match the given hardware ID */
123 FoundHardwareId
= FALSE
;
124 for (CurrentHardwareId
= Buffer
; *CurrentHardwareId
!= UNICODE_NULL
; CurrentHardwareId
+= wcslen(CurrentHardwareId
) + 1)
126 if (wcscmp(CurrentHardwareId
, HardwareId
) == 0)
128 FoundHardwareId
= TRUE
;
132 if (!FoundHardwareId
)
135 /* We need to try to update the driver of this device */
137 /* Get Instance ID */
138 HeapFree(GetProcessHeap(), 0, Buffer
);
140 if (SetupDiGetDeviceInstanceIdW(DevInstData
.hDevInfo
, &DevInstData
.devInfoData
, NULL
, 0, &BufferSize
))
142 /* Error, as the output buffer should be too small */
143 SetLastError(ERROR_GEN_FAILURE
);
146 else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
148 TRACE("SetupDiGetDeviceInstanceIdW() failed with error 0x%x\n", GetLastError());
151 else if ((Buffer
= HeapAlloc(GetProcessHeap(), 0, BufferSize
* sizeof(WCHAR
))) == NULL
)
153 TRACE("HeapAlloc() failed\n", GetLastError());
154 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
157 else if (!SetupDiGetDeviceInstanceIdW(DevInstData
.hDevInfo
, &DevInstData
.devInfoData
, Buffer
, BufferSize
, NULL
))
159 TRACE("SetupDiGetDeviceInstanceIdW() failed with error 0x%x\n", GetLastError());
162 TRACE("Trying to update the driver of %s\n", debugstr_w(Buffer
));
164 /* Search driver in the specified .inf file */
165 if (!SearchDriver(&DevInstData
, NULL
, FullInfPath
))
167 TRACE("SearchDriver() failed with error 0x%x\n", GetLastError());
171 /* FIXME: HACK! We shouldn't check of ERROR_PRIVILEGE_NOT_HELD */
172 //if (!InstallCurrentDriver(&DevInstData))
173 if (!InstallCurrentDriver(&DevInstData
) && GetLastError() != ERROR_PRIVILEGE_NOT_HELD
)
175 TRACE("InstallCurrentDriver() failed with error 0x%x\n", GetLastError());
179 FoundAtLeastOneDevice
= TRUE
;
182 if (FoundAtLeastOneDevice
)
184 SetLastError(NO_ERROR
);
189 TRACE("No device found with HardwareID %s\n", debugstr_w(HardwareId
));
190 SetLastError(ERROR_NO_SUCH_DEVINST
);
194 if (DevInstData
.hDevInfo
!= INVALID_HANDLE_VALUE
)
195 SetupDiDestroyDeviceInfoList(DevInstData
.hDevInfo
);
196 HeapFree(GetProcessHeap(), 0, Buffer
);
204 UpdateDriverForPlugAndPlayDevicesA(
206 IN LPCSTR HardwareId
,
207 IN LPCSTR FullInfPath
,
208 IN DWORD InstallFlags
,
209 OUT PBOOL bRebootRequired OPTIONAL
)
212 LPWSTR HardwareIdW
= NULL
;
213 LPWSTR FullInfPathW
= NULL
;
215 int len
= MultiByteToWideChar(CP_ACP
, 0, HardwareId
, -1, NULL
, 0);
216 HardwareIdW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
219 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
222 MultiByteToWideChar(CP_ACP
, 0, HardwareId
, -1, HardwareIdW
, len
);
224 len
= MultiByteToWideChar(CP_ACP
, 0, FullInfPath
, -1, NULL
, 0);
225 FullInfPathW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
228 HeapFree(GetProcessHeap(), 0, HardwareIdW
);
229 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
232 MultiByteToWideChar(CP_ACP
, 0, FullInfPath
, -1, FullInfPathW
, len
);
234 Result
= UpdateDriverForPlugAndPlayDevicesW(
241 HeapFree(GetProcessHeap(), 0, HardwareIdW
);
242 HeapFree(GetProcessHeap(), 0, FullInfPathW
);
247 /* Directory and InfFile MUST NOT be specified simultaneously */
250 IN PDEVINSTDATA DevInstData
,
251 IN LPCWSTR Directory OPTIONAL
,
252 IN LPCWSTR InfFile OPTIONAL
)
254 SP_DEVINSTALL_PARAMS_W DevInstallParams
= {0,};
257 DevInstallParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS_W
);
258 if (!SetupDiGetDeviceInstallParamsW(DevInstData
->hDevInfo
, &DevInstData
->devInfoData
, &DevInstallParams
))
260 TRACE("SetupDiGetDeviceInstallParams() failed with error 0x%x\n", GetLastError());
263 DevInstallParams
.FlagsEx
|= DI_FLAGSEX_ALLOWEXCLUDEDDRVS
;
267 DevInstallParams
.Flags
|= DI_ENUMSINGLEINF
;
268 wcsncpy(DevInstallParams
.DriverPath
, InfFile
, MAX_PATH
);
272 DevInstallParams
.Flags
&= ~DI_ENUMSINGLEINF
;
273 wcsncpy(DevInstallParams
.DriverPath
, Directory
, MAX_PATH
);
277 DevInstallParams
.Flags
&= ~DI_ENUMSINGLEINF
;
278 *DevInstallParams
.DriverPath
= '\0';
281 ret
= SetupDiSetDeviceInstallParamsW(
282 DevInstData
->hDevInfo
,
283 &DevInstData
->devInfoData
,
287 TRACE("SetupDiSetDeviceInstallParams() failed with error 0x%x\n", GetLastError());
291 ret
= SetupDiBuildDriverInfoList(
292 DevInstData
->hDevInfo
,
293 &DevInstData
->devInfoData
,
297 TRACE("SetupDiBuildDriverInfoList() failed with error 0x%x\n", GetLastError());
301 DevInstData
->drvInfoData
.cbSize
= sizeof(SP_DRVINFO_DATA
);
302 ret
= SetupDiEnumDriverInfoW(
303 DevInstData
->hDevInfo
,
304 &DevInstData
->devInfoData
,
307 &DevInstData
->drvInfoData
);
310 if (GetLastError() == ERROR_NO_MORE_ITEMS
)
312 TRACE("SetupDiEnumDriverInfo() failed with error 0x%x\n", GetLastError());
320 IsDots(IN LPCWSTR str
)
322 if(wcscmp(str
, L
".") && wcscmp(str
, L
"..")) return FALSE
;
327 GetFileExt(IN LPWSTR FileName
)
331 Dot
= wcsrchr(FileName
, '.');
339 SearchDriverRecursive(
340 IN PDEVINSTDATA DevInstData
,
343 WIN32_FIND_DATAW wfd
;
344 WCHAR DirPath
[MAX_PATH
];
345 WCHAR FileName
[MAX_PATH
];
346 WCHAR FullPath
[MAX_PATH
];
347 WCHAR LastDirPath
[MAX_PATH
] = L
"";
348 WCHAR PathWithPattern
[MAX_PATH
];
351 HANDLE hFindFile
= INVALID_HANDLE_VALUE
;
353 wcscpy(DirPath
, Path
);
355 if (DirPath
[wcslen(DirPath
) - 1] != '\\')
356 wcscat(DirPath
, L
"\\");
358 wcscpy(PathWithPattern
, DirPath
);
359 wcscat(PathWithPattern
, L
"\\*");
361 for (hFindFile
= FindFirstFileW(PathWithPattern
, &wfd
);
362 ok
&& hFindFile
!= INVALID_HANDLE_VALUE
;
363 ok
= FindNextFileW(hFindFile
, &wfd
))
366 wcscpy(FileName
, wfd
.cFileName
);
367 if (IsDots(FileName
))
370 if (wfd
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
372 /* Recursive search */
373 wcscpy(FullPath
, DirPath
);
374 wcscat(FullPath
, FileName
);
375 if (SearchDriverRecursive(DevInstData
, FullPath
))
378 /* We continue the search for a better driver */
383 LPCWSTR pszExtension
= GetFileExt(FileName
);
385 if ((_wcsicmp(pszExtension
, L
".inf") == 0) && (wcscmp(LastDirPath
, DirPath
) != 0))
387 wcscpy(LastDirPath
, DirPath
);
389 if (wcslen(DirPath
) > MAX_PATH
)
390 /* Path is too long to be searched */
393 if (SearchDriver(DevInstData
, DirPath
, NULL
))
396 /* We continue the search for a better driver */
403 if (hFindFile
!= INVALID_HANDLE_VALUE
)
404 FindClose(hFindFile
);
409 ScanFoldersForDriver(
410 IN PDEVINSTDATA DevInstData
)
414 /* Search in default location */
415 result
= SearchDriver(DevInstData
, NULL
, NULL
);
417 if (DevInstData
->CustomSearchPath
)
419 /* Search only in specified paths */
420 /* We need to check all specified directories to be
421 * sure to find the best driver for the device.
424 for (Path
= DevInstData
->CustomSearchPath
; *Path
!= '\0'; Path
+= wcslen(Path
) + 1)
426 TRACE("Search driver in %s\n", debugstr_w(Path
));
427 if (wcslen(Path
) == 2 && Path
[1] == ':')
429 if (SearchDriverRecursive(DevInstData
, Path
))
434 if (SearchDriver(DevInstData
, Path
, NULL
))
444 PrepareFoldersToScan(
445 IN PDEVINSTDATA DevInstData
,
446 IN BOOL IncludeRemovableDevices
,
447 IN BOOL IncludeCustomPath
,
448 IN HWND hwndCombo OPTIONAL
)
450 WCHAR drive
[] = {'?',':',0};
454 DWORD CustomTextLength
= 0;
455 DWORD LengthNeeded
= 0;
458 /* Calculate length needed to store the search paths */
459 if (IncludeRemovableDevices
)
461 dwDrives
= GetLogicalDrives();
462 for (drive
[0] = 'A', i
= 1; drive
[0] <= 'Z'; drive
[0]++, i
<<= 1)
466 nType
= GetDriveTypeW(drive
);
467 if (nType
== DRIVE_REMOVABLE
|| nType
== DRIVE_CDROM
)
474 if (IncludeCustomPath
)
476 CustomTextLength
= 1 + ComboBox_GetTextLength(hwndCombo
);
477 LengthNeeded
+= CustomTextLength
;
480 /* Allocate space for search paths */
481 HeapFree(GetProcessHeap(), 0, DevInstData
->CustomSearchPath
);
482 DevInstData
->CustomSearchPath
= Buffer
= HeapAlloc(
485 (LengthNeeded
+ 1) * sizeof(WCHAR
));
488 TRACE("HeapAlloc() failed\n");
489 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
493 /* Fill search paths */
494 if (IncludeRemovableDevices
)
496 for (drive
[0] = 'A', i
= 1; drive
[0] <= 'Z'; drive
[0]++, i
<<= 1)
500 nType
= GetDriveTypeW(drive
);
501 if (nType
== DRIVE_REMOVABLE
|| nType
== DRIVE_CDROM
)
503 Buffer
+= 1 + swprintf(Buffer
, drive
);
508 if (IncludeCustomPath
)
510 Buffer
+= 1 + GetWindowTextW(hwndCombo
, Buffer
, CustomTextLength
);
518 InstallCurrentDriver(
519 IN PDEVINSTDATA DevInstData
)
523 TRACE("Installing driver %s: %s\n",
524 debugstr_w(DevInstData
->drvInfoData
.MfgName
),
525 debugstr_w(DevInstData
->drvInfoData
.Description
));
527 ret
= SetupDiCallClassInstaller(
528 DIF_SELECTBESTCOMPATDRV
,
529 DevInstData
->hDevInfo
,
530 &DevInstData
->devInfoData
);
533 TRACE("SetupDiCallClassInstaller(DIF_SELECTBESTCOMPATDRV) failed with error 0x%x\n", GetLastError());
537 ret
= SetupDiCallClassInstaller(
539 DevInstData
->hDevInfo
,
540 &DevInstData
->devInfoData
);
543 TRACE("SetupDiCallClassInstaller(DIF_ALLOW_INSTALL) failed with error 0x%x\n", GetLastError());
547 ret
= SetupDiCallClassInstaller(
548 DIF_NEWDEVICEWIZARD_PREANALYZE
,
549 DevInstData
->hDevInfo
,
550 &DevInstData
->devInfoData
);
553 TRACE("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_PREANALYZE) failed with error 0x%x\n", GetLastError());
557 ret
= SetupDiCallClassInstaller(
558 DIF_NEWDEVICEWIZARD_POSTANALYZE
,
559 DevInstData
->hDevInfo
,
560 &DevInstData
->devInfoData
);
563 TRACE("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_POSTANALYZE) failed with error 0x%x\n", GetLastError());
567 ret
= SetupDiCallClassInstaller(
568 DIF_INSTALLDEVICEFILES
,
569 DevInstData
->hDevInfo
,
570 &DevInstData
->devInfoData
);
573 TRACE("SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES) failed with error 0x%x\n", GetLastError());
577 ret
= SetupDiCallClassInstaller(
578 DIF_REGISTER_COINSTALLERS
,
579 DevInstData
->hDevInfo
,
580 &DevInstData
->devInfoData
);
583 TRACE("SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS) failed with error 0x%x\n", GetLastError());
587 ret
= SetupDiCallClassInstaller(
588 DIF_INSTALLINTERFACES
,
589 DevInstData
->hDevInfo
,
590 &DevInstData
->devInfoData
);
593 TRACE("SetupDiCallClassInstaller(DIF_INSTALLINTERFACES) failed with error 0x%x\n", GetLastError());
597 ret
= SetupDiCallClassInstaller(
599 DevInstData
->hDevInfo
,
600 &DevInstData
->devInfoData
);
603 TRACE("SetupDiCallClassInstaller(DIF_INSTALLDEVICE) failed with error 0x%x\n", GetLastError());
607 ret
= SetupDiCallClassInstaller(
608 DIF_NEWDEVICEWIZARD_FINISHINSTALL
,
609 DevInstData
->hDevInfo
,
610 &DevInstData
->devInfoData
);
613 TRACE("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_FINISHINSTALL) failed with error 0x%x\n", GetLastError());
617 ret
= SetupDiCallClassInstaller(
618 DIF_DESTROYPRIVATEDATA
,
619 DevInstData
->hDevInfo
,
620 &DevInstData
->devInfoData
);
623 TRACE("SetupDiCallClassInstaller(DIF_DESTROYPRIVATEDATA) failed with error 0x%x\n", GetLastError());
636 IN HINSTANCE hInstance
,
637 IN LPCWSTR InstanceId
,
640 PDEVINSTDATA DevInstData
= NULL
;
645 TRACE("(%p, %p, %s, %d)\n", hWndParent
, hInstance
, debugstr_w(InstanceId
), Show
);
649 /* XP kills the process... */
650 ExitProcess(ERROR_ACCESS_DENIED
);
653 DevInstData
= HeapAlloc(GetProcessHeap(), 0, sizeof(DEVINSTDATA
));
656 TRACE("HeapAlloc() failed\n");
657 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
661 /* Clear devinst data */
662 ZeroMemory(DevInstData
, sizeof(DEVINSTDATA
));
663 DevInstData
->devInfoData
.cbSize
= 0; /* Tell if the devInfoData is valid */
665 /* Fill devinst data */
666 DevInstData
->hDevInfo
= SetupDiCreateDeviceInfoListExW(NULL
, NULL
, NULL
, NULL
);
667 if (DevInstData
->hDevInfo
== INVALID_HANDLE_VALUE
)
669 TRACE("SetupDiCreateDeviceInfoListExW() failed with error 0x%x\n", GetLastError());
673 DevInstData
->devInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
674 ret
= SetupDiOpenDeviceInfoW(
675 DevInstData
->hDevInfo
,
679 &DevInstData
->devInfoData
);
682 TRACE("SetupDiOpenDeviceInfoW() failed with error 0x%x (InstanceId %s)\n",
683 GetLastError(), debugstr_w(InstanceId
));
684 DevInstData
->devInfoData
.cbSize
= 0;
688 SetLastError(ERROR_GEN_FAILURE
);
689 ret
= SetupDiGetDeviceRegistryProperty(
690 DevInstData
->hDevInfo
,
691 &DevInstData
->devInfoData
,
693 &DevInstData
->regDataType
,
695 &DevInstData
->requiredSize
);
697 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
&& DevInstData
->regDataType
== REG_SZ
)
699 DevInstData
->buffer
= HeapAlloc(GetProcessHeap(), 0, DevInstData
->requiredSize
);
700 if (!DevInstData
->buffer
)
702 TRACE("HeapAlloc() failed\n");
703 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
707 ret
= SetupDiGetDeviceRegistryPropertyW(
708 DevInstData
->hDevInfo
,
709 &DevInstData
->devInfoData
,
711 &DevInstData
->regDataType
,
712 DevInstData
->buffer
, DevInstData
->requiredSize
,
713 &DevInstData
->requiredSize
);
718 TRACE("SetupDiGetDeviceRegistryProperty() failed with error 0x%x (InstanceId %s)\n",
719 GetLastError(), debugstr_w(InstanceId
));
723 if (SetupDiGetDeviceRegistryPropertyW(
724 DevInstData
->hDevInfo
,
725 &DevInstData
->devInfoData
,
728 (BYTE
*)&config_flags
,
729 sizeof(config_flags
),
732 if (config_flags
& CONFIGFLAG_FAILEDINSTALL
)
734 /* The device is disabled */
735 TRACE("Device is disabled\n");
741 TRACE("Installing %s (%s)\n", debugstr_w((PCWSTR
)DevInstData
->buffer
), debugstr_w(InstanceId
));
743 /* Search driver in default location and removable devices */
744 if (!PrepareFoldersToScan(DevInstData
, FALSE
, FALSE
, NULL
))
746 TRACE("PrepareFoldersToScan() failed with error 0x%lx\n", GetLastError());
749 if (ScanFoldersForDriver(DevInstData
))
751 /* Driver found ; install it */
752 retval
= InstallCurrentDriver(DevInstData
);
753 TRACE("InstallCurrentDriver() returned %d\n", retval
);
754 if (retval
&& Show
!= SW_HIDE
)
756 /* Should we display the 'Need to reboot' page? */
757 SP_DEVINSTALL_PARAMS installParams
;
758 installParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
759 if (SetupDiGetDeviceInstallParams(
760 DevInstData
->hDevInfo
,
761 &DevInstData
->devInfoData
,
764 if (installParams
.Flags
& (DI_NEEDRESTART
| DI_NEEDREBOOT
))
766 TRACE("Displaying 'Reboot' wizard page\n");
767 retval
= DisplayWizard(DevInstData
, hWndParent
, IDD_NEEDREBOOT
);
773 else if (Show
== SW_HIDE
)
775 /* We can't show the wizard. Fail the install */
776 TRACE("No wizard\n");
780 /* Prepare the wizard, and display it */
781 TRACE("Need to show install wizard\n");
782 retval
= DisplayWizard(DevInstData
, hWndParent
, IDD_WELCOMEPAGE
);
787 if (DevInstData
->devInfoData
.cbSize
!= 0)
789 if (!SetupDiDestroyDriverInfoList(DevInstData
->hDevInfo
, &DevInstData
->devInfoData
, SPDIT_COMPATDRIVER
))
790 TRACE("SetupDiDestroyDriverInfoList() failed with error 0x%lx\n", GetLastError());
792 if (DevInstData
->hDevInfo
!= INVALID_HANDLE_VALUE
)
794 if (!SetupDiDestroyDeviceInfoList(DevInstData
->hDevInfo
))
795 TRACE("SetupDiDestroyDeviceInfoList() failed with error 0x%lx\n", GetLastError());
797 HeapFree(GetProcessHeap(), 0, DevInstData
->buffer
);
798 HeapFree(GetProcessHeap(), 0, DevInstData
);
810 IN DWORD dwUnknownFlags
,
811 IN LPWSTR lpNamedPipeName
)
813 BOOL ReturnValue
= FALSE
;
817 HANDLE hPipe
= INVALID_HANDLE_VALUE
;
818 PWSTR DeviceInstance
= NULL
;
819 PWSTR InstallEventName
= NULL
;
822 hPipe
= CreateFileW(lpNamedPipeName
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
824 if(hPipe
== INVALID_HANDLE_VALUE
)
826 ERR("CreateFileW failed with error %u\n", GetLastError());
830 /* Read the data. Some is just included for compatibility with Windows right now and not yet used by ReactOS.
831 See umpnpmgr for more details. */
832 if(!ReadFile(hPipe
, &Value
, sizeof(Value
), &BytesRead
, NULL
))
834 ERR("ReadFile failed with error %u\n", GetLastError());
838 InstallEventName
= (PWSTR
)HeapAlloc(GetProcessHeap(), 0, Value
);
840 if(!ReadFile(hPipe
, InstallEventName
, Value
, &BytesRead
, NULL
))
842 ERR("ReadFile failed with error %u\n", GetLastError());
846 /* I couldn't figure out what the following value means under Windows XP.
847 Therefore I used it in umpnpmgr to pass the ShowWizard variable. */
848 if(!ReadFile(hPipe
, &ShowWizard
, sizeof(ShowWizard
), &BytesRead
, NULL
))
850 ERR("ReadFile failed with error %u\n", GetLastError());
854 /* Next one is again size in bytes of the following string */
855 if(!ReadFile(hPipe
, &Value
, sizeof(Value
), &BytesRead
, NULL
))
857 ERR("ReadFile failed with error %u\n", GetLastError());
861 DeviceInstance
= (PWSTR
)HeapAlloc(GetProcessHeap(), 0, Value
);
863 if(!ReadFile(hPipe
, DeviceInstance
, Value
, &BytesRead
, NULL
))
865 ERR("ReadFile failed with error %u\n", GetLastError());
869 ReturnValue
= DevInstallW(NULL
, NULL
, DeviceInstance
, ShowWizard
? SW_SHOWNOACTIVATE
: SW_HIDE
);
872 if(hPipe
!= INVALID_HANDLE_VALUE
)
876 HeapFree(GetProcessHeap(), 0, InstallEventName
);
879 HeapFree(GetProcessHeap(), 0, DeviceInstance
);
886 IN HINSTANCE hInstance
,
888 IN LPVOID lpReserved
)
890 if (dwReason
== DLL_PROCESS_ATTACH
)
892 INITCOMMONCONTROLSEX InitControls
;
894 DisableThreadLibraryCalls(hInstance
);
896 InitControls
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
897 InitControls
.dwICC
= ICC_PROGRESS_CLASS
;
898 InitCommonControlsEx(&InitControls
);
899 hDllInstance
= hInstance
;