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 WINE_DEFAULT_DEBUG_CHANNEL(newdev
);
27 /* Global variables */
28 HINSTANCE hDllInstance
;
32 IN PDEVINSTDATA DevInstData
,
33 IN LPCWSTR Directory OPTIONAL
,
34 IN LPCWSTR InfFile OPTIONAL
);
40 UpdateDriverForPlugAndPlayDevicesW(
42 IN LPCWSTR HardwareId
,
43 IN LPCWSTR FullInfPath
,
44 IN DWORD InstallFlags
,
45 OUT PBOOL bRebootRequired OPTIONAL
)
47 DEVINSTDATA DevInstData
;
51 LPCWSTR CurrentHardwareId
; /* Pointer into Buffer */
52 BOOL FoundHardwareId
, FoundAtLeastOneDevice
= FALSE
;
55 DevInstData
.hDevInfo
= INVALID_HANDLE_VALUE
;
57 TRACE("UpdateDriverForPlugAndPlayDevicesW(%p %s %s 0x%x %p)\n",
58 hwndParent
, debugstr_w(HardwareId
), debugstr_w(FullInfPath
), InstallFlags
, bRebootRequired
);
60 /* FIXME: InstallFlags bRebootRequired ignored! */
63 if (InstallFlags
& ~(INSTALLFLAG_FORCE
| INSTALLFLAG_READONLY
| INSTALLFLAG_NONINTERACTIVE
))
65 TRACE("Unknown flags: 0x%08lx\n", InstallFlags
& ~(INSTALLFLAG_FORCE
| INSTALLFLAG_READONLY
| INSTALLFLAG_NONINTERACTIVE
));
66 SetLastError(ERROR_INVALID_FLAGS
);
70 /* Enumerate all devices of the system */
71 DevInstData
.hDevInfo
= SetupDiGetClassDevsW(NULL
, NULL
, hwndParent
, DIGCF_ALLCLASSES
| DIGCF_PRESENT
);
72 if (DevInstData
.hDevInfo
== INVALID_HANDLE_VALUE
)
74 DevInstData
.devInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
77 if (!SetupDiEnumDeviceInfo(DevInstData
.hDevInfo
, i
, &DevInstData
.devInfoData
))
79 if (GetLastError() != ERROR_NO_MORE_ITEMS
)
81 TRACE("SetupDiEnumDeviceInfo() failed with error 0x%x\n", GetLastError());
84 /* This error was expected */
89 HeapFree(GetProcessHeap(), 0, Buffer
);
92 while (!SetupDiGetDeviceRegistryPropertyW(
94 &DevInstData
.devInfoData
,
101 if (GetLastError() == ERROR_FILE_NOT_FOUND
)
106 else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
108 TRACE("SetupDiGetDeviceRegistryPropertyW() failed with error 0x%x\n", GetLastError());
111 /* This error was expected */
112 HeapFree(GetProcessHeap(), 0, Buffer
);
113 Buffer
= HeapAlloc(GetProcessHeap(), 0, BufferSize
);
116 TRACE("HeapAlloc() failed\n", GetLastError());
117 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
124 /* Check if we match the given hardware ID */
125 FoundHardwareId
= FALSE
;
126 for (CurrentHardwareId
= Buffer
; *CurrentHardwareId
!= UNICODE_NULL
; CurrentHardwareId
+= wcslen(CurrentHardwareId
) + 1)
128 if (wcscmp(CurrentHardwareId
, HardwareId
) == 0)
130 FoundHardwareId
= TRUE
;
134 if (!FoundHardwareId
)
137 /* We need to try to update the driver of this device */
139 /* Get Instance ID */
140 HeapFree(GetProcessHeap(), 0, Buffer
);
142 if (SetupDiGetDeviceInstanceIdW(DevInstData
.hDevInfo
, &DevInstData
.devInfoData
, NULL
, 0, &BufferSize
))
144 /* Error, as the output buffer should be too small */
145 SetLastError(ERROR_GEN_FAILURE
);
148 else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
150 TRACE("SetupDiGetDeviceInstanceIdW() failed with error 0x%x\n", GetLastError());
153 else if ((Buffer
= HeapAlloc(GetProcessHeap(), 0, BufferSize
* sizeof(WCHAR
))) == NULL
)
155 TRACE("HeapAlloc() failed\n", GetLastError());
156 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
159 else if (!SetupDiGetDeviceInstanceIdW(DevInstData
.hDevInfo
, &DevInstData
.devInfoData
, Buffer
, BufferSize
, NULL
))
161 TRACE("SetupDiGetDeviceInstanceIdW() failed with error 0x%x\n", GetLastError());
164 TRACE("Trying to update the driver of %s\n", debugstr_w(Buffer
));
166 /* Search driver in the specified .inf file */
167 if (!SearchDriver(&DevInstData
, NULL
, FullInfPath
))
169 TRACE("SearchDriver() failed with error 0x%x\n", GetLastError());
173 /* FIXME: HACK! We shouldn't check of ERROR_PRIVILEGE_NOT_HELD */
174 //if (!InstallCurrentDriver(&DevInstData))
175 if (!InstallCurrentDriver(&DevInstData
) && GetLastError() != ERROR_PRIVILEGE_NOT_HELD
)
177 TRACE("InstallCurrentDriver() failed with error 0x%x\n", GetLastError());
181 FoundAtLeastOneDevice
= TRUE
;
184 if (FoundAtLeastOneDevice
)
186 SetLastError(NO_ERROR
);
191 TRACE("No device found with HardwareID %s\n", debugstr_w(HardwareId
));
192 SetLastError(ERROR_NO_SUCH_DEVINST
);
196 if (DevInstData
.hDevInfo
!= INVALID_HANDLE_VALUE
)
197 SetupDiDestroyDeviceInfoList(DevInstData
.hDevInfo
);
198 HeapFree(GetProcessHeap(), 0, Buffer
);
206 UpdateDriverForPlugAndPlayDevicesA(
208 IN LPCSTR HardwareId
,
209 IN LPCSTR FullInfPath
,
210 IN DWORD InstallFlags
,
211 OUT PBOOL bRebootRequired OPTIONAL
)
214 LPWSTR HardwareIdW
= NULL
;
215 LPWSTR FullInfPathW
= NULL
;
217 int len
= MultiByteToWideChar(CP_ACP
, 0, HardwareId
, -1, NULL
, 0);
218 HardwareIdW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
221 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
224 MultiByteToWideChar(CP_ACP
, 0, HardwareId
, -1, HardwareIdW
, len
);
226 len
= MultiByteToWideChar(CP_ACP
, 0, FullInfPath
, -1, NULL
, 0);
227 FullInfPathW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
230 HeapFree(GetProcessHeap(), 0, HardwareIdW
);
231 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
234 MultiByteToWideChar(CP_ACP
, 0, FullInfPath
, -1, FullInfPathW
, len
);
236 Result
= UpdateDriverForPlugAndPlayDevicesW(
243 HeapFree(GetProcessHeap(), 0, HardwareIdW
);
244 HeapFree(GetProcessHeap(), 0, FullInfPathW
);
249 /* Directory and InfFile MUST NOT be specified simultaneously */
252 IN PDEVINSTDATA DevInstData
,
253 IN LPCWSTR Directory OPTIONAL
,
254 IN LPCWSTR InfFile OPTIONAL
)
256 SP_DEVINSTALL_PARAMS_W DevInstallParams
= {0,};
259 DevInstallParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS_W
);
260 if (!SetupDiGetDeviceInstallParamsW(DevInstData
->hDevInfo
, &DevInstData
->devInfoData
, &DevInstallParams
))
262 TRACE("SetupDiGetDeviceInstallParams() failed with error 0x%x\n", GetLastError());
265 DevInstallParams
.FlagsEx
|= DI_FLAGSEX_ALLOWEXCLUDEDDRVS
;
269 DevInstallParams
.Flags
|= DI_ENUMSINGLEINF
;
270 wcsncpy(DevInstallParams
.DriverPath
, InfFile
, MAX_PATH
);
274 DevInstallParams
.Flags
&= ~DI_ENUMSINGLEINF
;
275 wcsncpy(DevInstallParams
.DriverPath
, Directory
, MAX_PATH
);
279 DevInstallParams
.Flags
&= ~DI_ENUMSINGLEINF
;
280 *DevInstallParams
.DriverPath
= '\0';
283 ret
= SetupDiSetDeviceInstallParamsW(
284 DevInstData
->hDevInfo
,
285 &DevInstData
->devInfoData
,
289 TRACE("SetupDiSetDeviceInstallParams() failed with error 0x%x\n", GetLastError());
293 ret
= SetupDiBuildDriverInfoList(
294 DevInstData
->hDevInfo
,
295 &DevInstData
->devInfoData
,
299 TRACE("SetupDiBuildDriverInfoList() failed with error 0x%x\n", GetLastError());
303 DevInstData
->drvInfoData
.cbSize
= sizeof(SP_DRVINFO_DATA
);
304 ret
= SetupDiEnumDriverInfoW(
305 DevInstData
->hDevInfo
,
306 &DevInstData
->devInfoData
,
309 &DevInstData
->drvInfoData
);
312 if (GetLastError() == ERROR_NO_MORE_ITEMS
)
314 TRACE("SetupDiEnumDriverInfo() failed with error 0x%x\n", GetLastError());
322 IsDots(IN LPCWSTR str
)
324 if(wcscmp(str
, L
".") && wcscmp(str
, L
"..")) return FALSE
;
329 GetFileExt(IN LPWSTR FileName
)
333 Dot
= wcsrchr(FileName
, '.');
341 SearchDriverRecursive(
342 IN PDEVINSTDATA DevInstData
,
345 WIN32_FIND_DATAW wfd
;
346 WCHAR DirPath
[MAX_PATH
];
347 WCHAR FileName
[MAX_PATH
];
348 WCHAR FullPath
[MAX_PATH
];
349 WCHAR LastDirPath
[MAX_PATH
] = L
"";
350 WCHAR PathWithPattern
[MAX_PATH
];
353 HANDLE hFindFile
= INVALID_HANDLE_VALUE
;
355 wcscpy(DirPath
, Path
);
357 if (DirPath
[wcslen(DirPath
) - 1] != '\\')
358 wcscat(DirPath
, L
"\\");
360 wcscpy(PathWithPattern
, DirPath
);
361 wcscat(PathWithPattern
, L
"\\*");
363 for (hFindFile
= FindFirstFileW(PathWithPattern
, &wfd
);
364 ok
&& hFindFile
!= INVALID_HANDLE_VALUE
;
365 ok
= FindNextFileW(hFindFile
, &wfd
))
368 wcscpy(FileName
, wfd
.cFileName
);
369 if (IsDots(FileName
))
372 if (wfd
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
374 /* Recursive search */
375 wcscpy(FullPath
, DirPath
);
376 wcscat(FullPath
, FileName
);
377 if (SearchDriverRecursive(DevInstData
, FullPath
))
380 /* We continue the search for a better driver */
385 LPCWSTR pszExtension
= GetFileExt(FileName
);
387 if ((_wcsicmp(pszExtension
, L
".inf") == 0) && (wcscmp(LastDirPath
, DirPath
) != 0))
389 wcscpy(LastDirPath
, DirPath
);
391 if (wcslen(DirPath
) > MAX_PATH
)
392 /* Path is too long to be searched */
395 if (SearchDriver(DevInstData
, DirPath
, NULL
))
398 /* We continue the search for a better driver */
405 if (hFindFile
!= INVALID_HANDLE_VALUE
)
406 FindClose(hFindFile
);
411 ScanFoldersForDriver(
412 IN PDEVINSTDATA DevInstData
)
416 /* Search in default location */
417 result
= SearchDriver(DevInstData
, NULL
, NULL
);
419 if (DevInstData
->CustomSearchPath
)
421 /* Search only in specified paths */
422 /* We need to check all specified directories to be
423 * sure to find the best driver for the device.
426 for (Path
= DevInstData
->CustomSearchPath
; *Path
!= '\0'; Path
+= wcslen(Path
) + 1)
428 TRACE("Search driver in %s\n", debugstr_w(Path
));
429 if (wcslen(Path
) == 2 && Path
[1] == ':')
431 if (SearchDriverRecursive(DevInstData
, Path
))
436 if (SearchDriver(DevInstData
, Path
, NULL
))
446 PrepareFoldersToScan(
447 IN PDEVINSTDATA DevInstData
,
448 IN BOOL IncludeRemovableDevices
,
449 IN BOOL IncludeCustomPath
,
450 IN HWND hwndCombo OPTIONAL
)
452 WCHAR drive
[] = {'?',':',0};
456 DWORD CustomTextLength
= 0;
457 DWORD LengthNeeded
= 0;
460 /* Calculate length needed to store the search paths */
461 if (IncludeRemovableDevices
)
463 dwDrives
= GetLogicalDrives();
464 for (drive
[0] = 'A', i
= 1; drive
[0] <= 'Z'; drive
[0]++, i
<<= 1)
468 nType
= GetDriveTypeW(drive
);
469 if (nType
== DRIVE_REMOVABLE
|| nType
== DRIVE_CDROM
)
476 if (IncludeCustomPath
)
478 CustomTextLength
= 1 + ComboBox_GetTextLength(hwndCombo
);
479 LengthNeeded
+= CustomTextLength
;
482 /* Allocate space for search paths */
483 HeapFree(GetProcessHeap(), 0, DevInstData
->CustomSearchPath
);
484 DevInstData
->CustomSearchPath
= Buffer
= HeapAlloc(
487 (LengthNeeded
+ 1) * sizeof(WCHAR
));
490 TRACE("HeapAlloc() failed\n");
491 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
495 /* Fill search paths */
496 if (IncludeRemovableDevices
)
498 for (drive
[0] = 'A', i
= 1; drive
[0] <= 'Z'; drive
[0]++, i
<<= 1)
502 nType
= GetDriveTypeW(drive
);
503 if (nType
== DRIVE_REMOVABLE
|| nType
== DRIVE_CDROM
)
505 Buffer
+= 1 + swprintf(Buffer
, drive
);
510 if (IncludeCustomPath
)
512 Buffer
+= 1 + GetWindowTextW(hwndCombo
, Buffer
, CustomTextLength
);
520 InstallCurrentDriver(
521 IN PDEVINSTDATA DevInstData
)
525 TRACE("Installing driver %s: %s\n",
526 debugstr_w(DevInstData
->drvInfoData
.MfgName
),
527 debugstr_w(DevInstData
->drvInfoData
.Description
));
529 ret
= SetupDiCallClassInstaller(
530 DIF_SELECTBESTCOMPATDRV
,
531 DevInstData
->hDevInfo
,
532 &DevInstData
->devInfoData
);
535 TRACE("SetupDiCallClassInstaller(DIF_SELECTBESTCOMPATDRV) failed with error 0x%x\n", GetLastError());
539 ret
= SetupDiCallClassInstaller(
541 DevInstData
->hDevInfo
,
542 &DevInstData
->devInfoData
);
545 TRACE("SetupDiCallClassInstaller(DIF_ALLOW_INSTALL) failed with error 0x%x\n", GetLastError());
549 ret
= SetupDiCallClassInstaller(
550 DIF_NEWDEVICEWIZARD_PREANALYZE
,
551 DevInstData
->hDevInfo
,
552 &DevInstData
->devInfoData
);
555 TRACE("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_PREANALYZE) failed with error 0x%x\n", GetLastError());
559 ret
= SetupDiCallClassInstaller(
560 DIF_NEWDEVICEWIZARD_POSTANALYZE
,
561 DevInstData
->hDevInfo
,
562 &DevInstData
->devInfoData
);
565 TRACE("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_POSTANALYZE) failed with error 0x%x\n", GetLastError());
569 ret
= SetupDiCallClassInstaller(
570 DIF_INSTALLDEVICEFILES
,
571 DevInstData
->hDevInfo
,
572 &DevInstData
->devInfoData
);
575 TRACE("SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES) failed with error 0x%x\n", GetLastError());
579 ret
= SetupDiCallClassInstaller(
580 DIF_REGISTER_COINSTALLERS
,
581 DevInstData
->hDevInfo
,
582 &DevInstData
->devInfoData
);
585 TRACE("SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS) failed with error 0x%x\n", GetLastError());
589 ret
= SetupDiCallClassInstaller(
590 DIF_INSTALLINTERFACES
,
591 DevInstData
->hDevInfo
,
592 &DevInstData
->devInfoData
);
595 TRACE("SetupDiCallClassInstaller(DIF_INSTALLINTERFACES) failed with error 0x%x\n", GetLastError());
599 ret
= SetupDiCallClassInstaller(
601 DevInstData
->hDevInfo
,
602 &DevInstData
->devInfoData
);
605 TRACE("SetupDiCallClassInstaller(DIF_INSTALLDEVICE) failed with error 0x%x\n", GetLastError());
609 ret
= SetupDiCallClassInstaller(
610 DIF_NEWDEVICEWIZARD_FINISHINSTALL
,
611 DevInstData
->hDevInfo
,
612 &DevInstData
->devInfoData
);
615 TRACE("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_FINISHINSTALL) failed with error 0x%x\n", GetLastError());
619 ret
= SetupDiCallClassInstaller(
620 DIF_DESTROYPRIVATEDATA
,
621 DevInstData
->hDevInfo
,
622 &DevInstData
->devInfoData
);
625 TRACE("SetupDiCallClassInstaller(DIF_DESTROYPRIVATEDATA) failed with error 0x%x\n", GetLastError());
638 IN HINSTANCE hInstance
,
639 IN LPCWSTR InstanceId
,
642 PDEVINSTDATA DevInstData
= NULL
;
647 TRACE("(%p, %p, %s, %d)\n", hWndParent
, hInstance
, debugstr_w(InstanceId
), Show
);
651 /* XP kills the process... */
652 ExitProcess(ERROR_ACCESS_DENIED
);
655 DevInstData
= HeapAlloc(GetProcessHeap(), 0, sizeof(DEVINSTDATA
));
658 TRACE("HeapAlloc() failed\n");
659 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
663 /* Clear devinst data */
664 ZeroMemory(DevInstData
, sizeof(DEVINSTDATA
));
665 DevInstData
->devInfoData
.cbSize
= 0; /* Tell if the devInfoData is valid */
667 /* Fill devinst data */
668 DevInstData
->hDevInfo
= SetupDiCreateDeviceInfoListExW(NULL
, NULL
, NULL
, NULL
);
669 if (DevInstData
->hDevInfo
== INVALID_HANDLE_VALUE
)
671 TRACE("SetupDiCreateDeviceInfoListExW() failed with error 0x%x\n", GetLastError());
675 DevInstData
->devInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
676 ret
= SetupDiOpenDeviceInfoW(
677 DevInstData
->hDevInfo
,
681 &DevInstData
->devInfoData
);
684 TRACE("SetupDiOpenDeviceInfoW() failed with error 0x%x (InstanceId %s)\n",
685 GetLastError(), debugstr_w(InstanceId
));
686 DevInstData
->devInfoData
.cbSize
= 0;
690 SetLastError(ERROR_GEN_FAILURE
);
691 ret
= SetupDiGetDeviceRegistryProperty(
692 DevInstData
->hDevInfo
,
693 &DevInstData
->devInfoData
,
695 &DevInstData
->regDataType
,
697 &DevInstData
->requiredSize
);
699 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
&& DevInstData
->regDataType
== REG_SZ
)
701 DevInstData
->buffer
= HeapAlloc(GetProcessHeap(), 0, DevInstData
->requiredSize
);
702 if (!DevInstData
->buffer
)
704 TRACE("HeapAlloc() failed\n");
705 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
709 ret
= SetupDiGetDeviceRegistryPropertyW(
710 DevInstData
->hDevInfo
,
711 &DevInstData
->devInfoData
,
713 &DevInstData
->regDataType
,
714 DevInstData
->buffer
, DevInstData
->requiredSize
,
715 &DevInstData
->requiredSize
);
720 TRACE("SetupDiGetDeviceRegistryProperty() failed with error 0x%x (InstanceId %s)\n",
721 GetLastError(), debugstr_w(InstanceId
));
725 if (SetupDiGetDeviceRegistryPropertyW(
726 DevInstData
->hDevInfo
,
727 &DevInstData
->devInfoData
,
730 (BYTE
*)&config_flags
,
731 sizeof(config_flags
),
734 if (config_flags
& CONFIGFLAG_FAILEDINSTALL
)
736 /* The device is disabled */
737 TRACE("Device is disabled\n");
743 TRACE("Installing %s (%s)\n", debugstr_w((PCWSTR
)DevInstData
->buffer
), debugstr_w(InstanceId
));
745 /* Search driver in default location and removable devices */
746 if (!PrepareFoldersToScan(DevInstData
, FALSE
, FALSE
, NULL
))
748 TRACE("PrepareFoldersToScan() failed with error 0x%lx\n", GetLastError());
751 if (ScanFoldersForDriver(DevInstData
))
753 /* Driver found ; install it */
754 retval
= InstallCurrentDriver(DevInstData
);
755 TRACE("InstallCurrentDriver() returned %d\n", retval
);
756 if (retval
&& Show
!= SW_HIDE
)
758 /* Should we display the 'Need to reboot' page? */
759 SP_DEVINSTALL_PARAMS installParams
;
760 installParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
761 if (SetupDiGetDeviceInstallParams(
762 DevInstData
->hDevInfo
,
763 &DevInstData
->devInfoData
,
766 if (installParams
.Flags
& (DI_NEEDRESTART
| DI_NEEDREBOOT
))
768 TRACE("Displaying 'Reboot' wizard page\n");
769 retval
= DisplayWizard(DevInstData
, hWndParent
, IDD_NEEDREBOOT
);
775 else if (Show
== SW_HIDE
)
777 /* We can't show the wizard. Fail the install */
778 TRACE("No wizard\n");
782 /* Prepare the wizard, and display it */
783 TRACE("Need to show install wizard\n");
784 retval
= DisplayWizard(DevInstData
, hWndParent
, IDD_WELCOMEPAGE
);
789 if (DevInstData
->devInfoData
.cbSize
!= 0)
791 if (!SetupDiDestroyDriverInfoList(DevInstData
->hDevInfo
, &DevInstData
->devInfoData
, SPDIT_COMPATDRIVER
))
792 TRACE("SetupDiDestroyDriverInfoList() failed with error 0x%lx\n", GetLastError());
794 if (DevInstData
->hDevInfo
!= INVALID_HANDLE_VALUE
)
796 if (!SetupDiDestroyDeviceInfoList(DevInstData
->hDevInfo
))
797 TRACE("SetupDiDestroyDeviceInfoList() failed with error 0x%lx\n", GetLastError());
799 HeapFree(GetProcessHeap(), 0, DevInstData
->buffer
);
800 HeapFree(GetProcessHeap(), 0, DevInstData
);
812 IN DWORD dwUnknownFlags
,
813 IN LPWSTR lpNamedPipeName
)
815 BOOL ReturnValue
= FALSE
;
819 HANDLE hPipe
= INVALID_HANDLE_VALUE
;
820 PWSTR DeviceInstance
= NULL
;
821 PWSTR InstallEventName
= NULL
;
824 hPipe
= CreateFileW(lpNamedPipeName
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
826 if(hPipe
== INVALID_HANDLE_VALUE
)
828 ERR("CreateFileW failed with error %u\n", GetLastError());
832 /* Read the data. Some is just included for compatibility with Windows right now and not yet used by ReactOS.
833 See umpnpmgr for more details. */
834 if(!ReadFile(hPipe
, &Value
, sizeof(Value
), &BytesRead
, NULL
))
836 ERR("ReadFile failed with error %u\n", GetLastError());
840 InstallEventName
= (PWSTR
)HeapAlloc(GetProcessHeap(), 0, Value
);
842 if(!ReadFile(hPipe
, InstallEventName
, Value
, &BytesRead
, NULL
))
844 ERR("ReadFile failed with error %u\n", GetLastError());
848 /* I couldn't figure out what the following value means under Windows XP.
849 Therefore I used it in umpnpmgr to pass the ShowWizard variable. */
850 if(!ReadFile(hPipe
, &ShowWizard
, sizeof(ShowWizard
), &BytesRead
, NULL
))
852 ERR("ReadFile failed with error %u\n", GetLastError());
856 /* Next one is again size in bytes of the following string */
857 if(!ReadFile(hPipe
, &Value
, sizeof(Value
), &BytesRead
, NULL
))
859 ERR("ReadFile failed with error %u\n", GetLastError());
863 DeviceInstance
= (PWSTR
)HeapAlloc(GetProcessHeap(), 0, Value
);
865 if(!ReadFile(hPipe
, DeviceInstance
, Value
, &BytesRead
, NULL
))
867 ERR("ReadFile failed with error %u\n", GetLastError());
871 ReturnValue
= DevInstallW(NULL
, NULL
, DeviceInstance
, ShowWizard
? SW_SHOWNOACTIVATE
: SW_HIDE
);
874 if(hPipe
!= INVALID_HANDLE_VALUE
)
878 HeapFree(GetProcessHeap(), 0, InstallEventName
);
881 HeapFree(GetProcessHeap(), 0, DeviceInstance
);
888 IN HINSTANCE hInstance
,
890 IN LPVOID lpReserved
)
892 if (dwReason
== DLL_PROCESS_ATTACH
)
894 INITCOMMONCONTROLSEX InitControls
;
896 DisableThreadLibraryCalls(hInstance
);
898 InitControls
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
899 InitControls
.dwICC
= ICC_PROGRESS_CLASS
;
900 InitCommonControlsEx(&InitControls
);
901 hDllInstance
= hInstance
;