2 * New device installer (newdev.dll)
4 * Copyright 2005-2006 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
22 #include "newdev_private.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(newdev
);
26 /* Global variables */
27 HINSTANCE hDllInstance
;
31 IN PDEVINSTDATA DevInstData
,
32 IN LPCWSTR Directory OPTIONAL
,
33 IN LPCWSTR InfFile OPTIONAL
);
39 UpdateDriverForPlugAndPlayDevicesW(
41 IN LPCWSTR HardwareId
,
42 IN LPCWSTR FullInfPath
,
43 IN DWORD InstallFlags
,
44 OUT PBOOL bRebootRequired OPTIONAL
)
46 DEVINSTDATA DevInstData
;
50 LPCWSTR CurrentHardwareId
; /* Pointer into Buffer */
51 BOOL FoundHardwareId
, FoundAtLeastOneDevice
= FALSE
;
54 DevInstData
.hDevInfo
= INVALID_HANDLE_VALUE
;
56 TRACE("UpdateDriverForPlugAndPlayDevicesW(%p %s %s 0x%x %p)\n",
57 hwndParent
, debugstr_w(HardwareId
), debugstr_w(FullInfPath
), InstallFlags
, bRebootRequired
);
59 /* FIXME: InstallFlags bRebootRequired ignored! */
62 if (InstallFlags
& ~(INSTALLFLAG_FORCE
| INSTALLFLAG_READONLY
| INSTALLFLAG_NONINTERACTIVE
))
64 TRACE("Unknown flags: 0x%08lx\n", InstallFlags
& ~(INSTALLFLAG_FORCE
| INSTALLFLAG_READONLY
| INSTALLFLAG_NONINTERACTIVE
));
65 SetLastError(ERROR_INVALID_FLAGS
);
69 /* Enumerate all devices of the system */
70 DevInstData
.hDevInfo
= SetupDiGetClassDevsW(NULL
, NULL
, hwndParent
, DIGCF_ALLCLASSES
| DIGCF_PRESENT
);
71 if (DevInstData
.hDevInfo
== INVALID_HANDLE_VALUE
)
73 DevInstData
.devInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
76 if (!SetupDiEnumDeviceInfo(DevInstData
.hDevInfo
, i
, &DevInstData
.devInfoData
))
78 if (GetLastError() != ERROR_NO_MORE_ITEMS
)
80 TRACE("SetupDiEnumDeviceInfo() failed with error 0x%x\n", GetLastError());
83 /* This error was expected */
88 HeapFree(GetProcessHeap(), 0, Buffer
);
91 while (!SetupDiGetDeviceRegistryPropertyW(
93 &DevInstData
.devInfoData
,
100 if (GetLastError() == ERROR_FILE_NOT_FOUND
)
105 else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
107 TRACE("SetupDiGetDeviceRegistryPropertyW() failed with error 0x%x\n", GetLastError());
110 /* This error was expected */
111 HeapFree(GetProcessHeap(), 0, Buffer
);
112 Buffer
= HeapAlloc(GetProcessHeap(), 0, BufferSize
);
115 TRACE("HeapAlloc() failed\n", GetLastError());
116 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
123 /* Check if we match the given hardware ID */
124 FoundHardwareId
= FALSE
;
125 for (CurrentHardwareId
= Buffer
; *CurrentHardwareId
!= UNICODE_NULL
; CurrentHardwareId
+= wcslen(CurrentHardwareId
) + 1)
127 if (wcscmp(CurrentHardwareId
, HardwareId
) == 0)
129 FoundHardwareId
= TRUE
;
133 if (!FoundHardwareId
)
136 /* We need to try to update the driver of this device */
138 /* Get Instance ID */
139 HeapFree(GetProcessHeap(), 0, Buffer
);
141 if (SetupDiGetDeviceInstanceIdW(DevInstData
.hDevInfo
, &DevInstData
.devInfoData
, NULL
, 0, &BufferSize
))
143 /* Error, as the output buffer should be too small */
144 SetLastError(ERROR_GEN_FAILURE
);
147 else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
149 TRACE("SetupDiGetDeviceInstanceIdW() failed with error 0x%x\n", GetLastError());
152 else if ((Buffer
= HeapAlloc(GetProcessHeap(), 0, BufferSize
* sizeof(WCHAR
))) == NULL
)
154 TRACE("HeapAlloc() failed\n", GetLastError());
155 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
158 else if (!SetupDiGetDeviceInstanceIdW(DevInstData
.hDevInfo
, &DevInstData
.devInfoData
, Buffer
, BufferSize
, NULL
))
160 TRACE("SetupDiGetDeviceInstanceIdW() failed with error 0x%x\n", GetLastError());
163 TRACE("Trying to update the driver of %s\n", debugstr_w(Buffer
));
165 /* Search driver in the specified .inf file */
166 if (!SearchDriver(&DevInstData
, NULL
, FullInfPath
))
168 TRACE("SearchDriver() failed with error 0x%x\n", GetLastError());
172 /* FIXME: HACK! We shouldn't check of ERROR_PRIVILEGE_NOT_HELD */
173 //if (!InstallCurrentDriver(&DevInstData))
174 if (!InstallCurrentDriver(&DevInstData
) && GetLastError() != ERROR_PRIVILEGE_NOT_HELD
)
176 TRACE("InstallCurrentDriver() failed with error 0x%x\n", GetLastError());
180 FoundAtLeastOneDevice
= TRUE
;
183 if (FoundAtLeastOneDevice
)
185 SetLastError(NO_ERROR
);
190 TRACE("No device found with HardwareID %s\n", debugstr_w(HardwareId
));
191 SetLastError(ERROR_NO_SUCH_DEVINST
);
195 if (DevInstData
.hDevInfo
!= INVALID_HANDLE_VALUE
)
196 SetupDiDestroyDeviceInfoList(DevInstData
.hDevInfo
);
197 HeapFree(GetProcessHeap(), 0, Buffer
);
205 UpdateDriverForPlugAndPlayDevicesA(
207 IN LPCSTR HardwareId
,
208 IN LPCSTR FullInfPath
,
209 IN DWORD InstallFlags
,
210 OUT PBOOL bRebootRequired OPTIONAL
)
213 LPWSTR HardwareIdW
= NULL
;
214 LPWSTR FullInfPathW
= NULL
;
216 int len
= MultiByteToWideChar(CP_ACP
, 0, HardwareId
, -1, NULL
, 0);
217 HardwareIdW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
220 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
223 MultiByteToWideChar(CP_ACP
, 0, HardwareId
, -1, HardwareIdW
, len
);
225 len
= MultiByteToWideChar(CP_ACP
, 0, FullInfPath
, -1, NULL
, 0);
226 FullInfPathW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
229 HeapFree(GetProcessHeap(), 0, HardwareIdW
);
230 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
233 MultiByteToWideChar(CP_ACP
, 0, FullInfPath
, -1, FullInfPathW
, len
);
235 Result
= UpdateDriverForPlugAndPlayDevicesW(
242 HeapFree(GetProcessHeap(), 0, HardwareIdW
);
243 HeapFree(GetProcessHeap(), 0, FullInfPathW
);
248 /* Directory and InfFile MUST NOT be specified simultaneously */
251 IN PDEVINSTDATA DevInstData
,
252 IN LPCWSTR Directory OPTIONAL
,
253 IN LPCWSTR InfFile OPTIONAL
)
255 SP_DEVINSTALL_PARAMS_W DevInstallParams
= {0,};
258 DevInstallParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS_W
);
259 if (!SetupDiGetDeviceInstallParamsW(DevInstData
->hDevInfo
, &DevInstData
->devInfoData
, &DevInstallParams
))
261 TRACE("SetupDiGetDeviceInstallParams() failed with error 0x%x\n", GetLastError());
264 DevInstallParams
.FlagsEx
|= DI_FLAGSEX_ALLOWEXCLUDEDDRVS
;
268 DevInstallParams
.Flags
|= DI_ENUMSINGLEINF
;
269 wcsncpy(DevInstallParams
.DriverPath
, InfFile
, MAX_PATH
);
273 DevInstallParams
.Flags
&= ~DI_ENUMSINGLEINF
;
274 wcsncpy(DevInstallParams
.DriverPath
, Directory
, MAX_PATH
);
278 DevInstallParams
.Flags
&= ~DI_ENUMSINGLEINF
;
279 *DevInstallParams
.DriverPath
= '\0';
282 ret
= SetupDiSetDeviceInstallParamsW(
283 DevInstData
->hDevInfo
,
284 &DevInstData
->devInfoData
,
288 TRACE("SetupDiSetDeviceInstallParams() failed with error 0x%x\n", GetLastError());
292 ret
= SetupDiBuildDriverInfoList(
293 DevInstData
->hDevInfo
,
294 &DevInstData
->devInfoData
,
298 TRACE("SetupDiBuildDriverInfoList() failed with error 0x%x\n", GetLastError());
302 DevInstData
->drvInfoData
.cbSize
= sizeof(SP_DRVINFO_DATA
);
303 ret
= SetupDiEnumDriverInfoW(
304 DevInstData
->hDevInfo
,
305 &DevInstData
->devInfoData
,
308 &DevInstData
->drvInfoData
);
311 if (GetLastError() == ERROR_NO_MORE_ITEMS
)
313 TRACE("SetupDiEnumDriverInfo() failed with error 0x%x\n", GetLastError());
321 IsDots(IN LPCWSTR str
)
323 if(wcscmp(str
, L
".") && wcscmp(str
, L
"..")) return FALSE
;
328 GetFileExt(IN LPWSTR FileName
)
332 Dot
= wcsrchr(FileName
, '.');
340 SearchDriverRecursive(
341 IN PDEVINSTDATA DevInstData
,
344 WIN32_FIND_DATAW wfd
;
345 WCHAR DirPath
[MAX_PATH
];
346 WCHAR FileName
[MAX_PATH
];
347 WCHAR FullPath
[MAX_PATH
];
348 WCHAR LastDirPath
[MAX_PATH
] = L
"";
349 WCHAR PathWithPattern
[MAX_PATH
];
352 HANDLE hFindFile
= INVALID_HANDLE_VALUE
;
354 wcscpy(DirPath
, Path
);
356 if (DirPath
[wcslen(DirPath
) - 1] != '\\')
357 wcscat(DirPath
, L
"\\");
359 wcscpy(PathWithPattern
, DirPath
);
360 wcscat(PathWithPattern
, L
"\\*");
362 for (hFindFile
= FindFirstFileW(PathWithPattern
, &wfd
);
363 ok
&& hFindFile
!= INVALID_HANDLE_VALUE
;
364 ok
= FindNextFileW(hFindFile
, &wfd
))
367 wcscpy(FileName
, wfd
.cFileName
);
368 if (IsDots(FileName
))
371 if (wfd
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
373 /* Recursive search */
374 wcscpy(FullPath
, DirPath
);
375 wcscat(FullPath
, FileName
);
376 if (SearchDriverRecursive(DevInstData
, FullPath
))
379 /* We continue the search for a better driver */
384 LPCWSTR pszExtension
= GetFileExt(FileName
);
386 if ((_wcsicmp(pszExtension
, L
".inf") == 0) && (wcscmp(LastDirPath
, DirPath
) != 0))
388 wcscpy(LastDirPath
, DirPath
);
390 if (wcslen(DirPath
) > MAX_PATH
)
391 /* Path is too long to be searched */
394 if (SearchDriver(DevInstData
, DirPath
, NULL
))
397 /* We continue the search for a better driver */
404 if (hFindFile
!= INVALID_HANDLE_VALUE
)
405 FindClose(hFindFile
);
410 ScanFoldersForDriver(
411 IN PDEVINSTDATA DevInstData
)
415 /* Search in default location */
416 result
= SearchDriver(DevInstData
, NULL
, NULL
);
418 if (DevInstData
->CustomSearchPath
)
420 /* Search only in specified paths */
421 /* We need to check all specified directories to be
422 * sure to find the best driver for the device.
425 for (Path
= DevInstData
->CustomSearchPath
; *Path
!= '\0'; Path
+= wcslen(Path
) + 1)
427 TRACE("Search driver in %s\n", debugstr_w(Path
));
428 if (wcslen(Path
) == 2 && Path
[1] == ':')
430 if (SearchDriverRecursive(DevInstData
, Path
))
435 if (SearchDriver(DevInstData
, Path
, NULL
))
445 PrepareFoldersToScan(
446 IN PDEVINSTDATA DevInstData
,
447 IN BOOL IncludeRemovableDevices
,
448 IN BOOL IncludeCustomPath
,
449 IN HWND hwndCombo OPTIONAL
)
451 WCHAR drive
[] = {'?',':',0};
455 DWORD CustomTextLength
= 0;
456 DWORD LengthNeeded
= 0;
459 /* Calculate length needed to store the search paths */
460 if (IncludeRemovableDevices
)
462 dwDrives
= GetLogicalDrives();
463 for (drive
[0] = 'A', i
= 1; drive
[0] <= 'Z'; drive
[0]++, i
<<= 1)
467 nType
= GetDriveTypeW(drive
);
468 if (nType
== DRIVE_REMOVABLE
|| nType
== DRIVE_CDROM
)
475 if (IncludeCustomPath
)
477 CustomTextLength
= 1 + ComboBox_GetTextLength(hwndCombo
);
478 LengthNeeded
+= CustomTextLength
;
481 /* Allocate space for search paths */
482 HeapFree(GetProcessHeap(), 0, DevInstData
->CustomSearchPath
);
483 DevInstData
->CustomSearchPath
= Buffer
= HeapAlloc(
486 (LengthNeeded
+ 1) * sizeof(WCHAR
));
489 TRACE("HeapAlloc() failed\n");
490 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
494 /* Fill search paths */
495 if (IncludeRemovableDevices
)
497 for (drive
[0] = 'A', i
= 1; drive
[0] <= 'Z'; drive
[0]++, i
<<= 1)
501 nType
= GetDriveTypeW(drive
);
502 if (nType
== DRIVE_REMOVABLE
|| nType
== DRIVE_CDROM
)
504 Buffer
+= 1 + swprintf(Buffer
, drive
);
509 if (IncludeCustomPath
)
511 Buffer
+= 1 + GetWindowTextW(hwndCombo
, Buffer
, CustomTextLength
);
519 InstallCurrentDriver(
520 IN PDEVINSTDATA DevInstData
)
524 TRACE("Installing driver %s: %s\n",
525 debugstr_w(DevInstData
->drvInfoData
.MfgName
),
526 debugstr_w(DevInstData
->drvInfoData
.Description
));
528 ret
= SetupDiCallClassInstaller(
529 DIF_SELECTBESTCOMPATDRV
,
530 DevInstData
->hDevInfo
,
531 &DevInstData
->devInfoData
);
534 TRACE("SetupDiCallClassInstaller(DIF_SELECTBESTCOMPATDRV) failed with error 0x%x\n", GetLastError());
538 ret
= SetupDiCallClassInstaller(
540 DevInstData
->hDevInfo
,
541 &DevInstData
->devInfoData
);
544 TRACE("SetupDiCallClassInstaller(DIF_ALLOW_INSTALL) failed with error 0x%x\n", GetLastError());
548 ret
= SetupDiCallClassInstaller(
549 DIF_NEWDEVICEWIZARD_PREANALYZE
,
550 DevInstData
->hDevInfo
,
551 &DevInstData
->devInfoData
);
554 TRACE("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_PREANALYZE) failed with error 0x%x\n", GetLastError());
558 ret
= SetupDiCallClassInstaller(
559 DIF_NEWDEVICEWIZARD_POSTANALYZE
,
560 DevInstData
->hDevInfo
,
561 &DevInstData
->devInfoData
);
564 TRACE("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_POSTANALYZE) failed with error 0x%x\n", GetLastError());
568 ret
= SetupDiCallClassInstaller(
569 DIF_INSTALLDEVICEFILES
,
570 DevInstData
->hDevInfo
,
571 &DevInstData
->devInfoData
);
574 TRACE("SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES) failed with error 0x%x\n", GetLastError());
578 ret
= SetupDiCallClassInstaller(
579 DIF_REGISTER_COINSTALLERS
,
580 DevInstData
->hDevInfo
,
581 &DevInstData
->devInfoData
);
584 TRACE("SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS) failed with error 0x%x\n", GetLastError());
588 ret
= SetupDiCallClassInstaller(
589 DIF_INSTALLINTERFACES
,
590 DevInstData
->hDevInfo
,
591 &DevInstData
->devInfoData
);
594 TRACE("SetupDiCallClassInstaller(DIF_INSTALLINTERFACES) failed with error 0x%x\n", GetLastError());
598 ret
= SetupDiCallClassInstaller(
600 DevInstData
->hDevInfo
,
601 &DevInstData
->devInfoData
);
604 TRACE("SetupDiCallClassInstaller(DIF_INSTALLDEVICE) failed with error 0x%x\n", GetLastError());
608 ret
= SetupDiCallClassInstaller(
609 DIF_NEWDEVICEWIZARD_FINISHINSTALL
,
610 DevInstData
->hDevInfo
,
611 &DevInstData
->devInfoData
);
614 TRACE("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_FINISHINSTALL) failed with error 0x%x\n", GetLastError());
618 ret
= SetupDiCallClassInstaller(
619 DIF_DESTROYPRIVATEDATA
,
620 DevInstData
->hDevInfo
,
621 &DevInstData
->devInfoData
);
624 TRACE("SetupDiCallClassInstaller(DIF_DESTROYPRIVATEDATA) failed with error 0x%x\n", GetLastError());
637 IN HINSTANCE hInstance
,
638 IN LPCWSTR InstanceId
,
641 PDEVINSTDATA DevInstData
= NULL
;
646 TRACE("(%p, %p, %s, %d)\n", hWndParent
, hInstance
, debugstr_w(InstanceId
), Show
);
650 /* XP kills the process... */
651 ExitProcess(ERROR_ACCESS_DENIED
);
654 DevInstData
= HeapAlloc(GetProcessHeap(), 0, sizeof(DEVINSTDATA
));
657 TRACE("HeapAlloc() failed\n");
658 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
662 /* Clear devinst data */
663 ZeroMemory(DevInstData
, sizeof(DEVINSTDATA
));
664 DevInstData
->devInfoData
.cbSize
= 0; /* Tell if the devInfoData is valid */
666 /* Fill devinst data */
667 DevInstData
->hDevInfo
= SetupDiCreateDeviceInfoListExW(NULL
, NULL
, NULL
, NULL
);
668 if (DevInstData
->hDevInfo
== INVALID_HANDLE_VALUE
)
670 TRACE("SetupDiCreateDeviceInfoListExW() failed with error 0x%x\n", GetLastError());
674 DevInstData
->devInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
675 ret
= SetupDiOpenDeviceInfoW(
676 DevInstData
->hDevInfo
,
680 &DevInstData
->devInfoData
);
683 TRACE("SetupDiOpenDeviceInfoW() failed with error 0x%x (InstanceId %s)\n",
684 GetLastError(), debugstr_w(InstanceId
));
685 DevInstData
->devInfoData
.cbSize
= 0;
689 SetLastError(ERROR_GEN_FAILURE
);
690 ret
= SetupDiGetDeviceRegistryProperty(
691 DevInstData
->hDevInfo
,
692 &DevInstData
->devInfoData
,
694 &DevInstData
->regDataType
,
696 &DevInstData
->requiredSize
);
698 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
&& DevInstData
->regDataType
== REG_SZ
)
700 DevInstData
->buffer
= HeapAlloc(GetProcessHeap(), 0, DevInstData
->requiredSize
);
701 if (!DevInstData
->buffer
)
703 TRACE("HeapAlloc() failed\n");
704 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
708 ret
= SetupDiGetDeviceRegistryPropertyW(
709 DevInstData
->hDevInfo
,
710 &DevInstData
->devInfoData
,
712 &DevInstData
->regDataType
,
713 DevInstData
->buffer
, DevInstData
->requiredSize
,
714 &DevInstData
->requiredSize
);
719 TRACE("SetupDiGetDeviceRegistryProperty() failed with error 0x%x (InstanceId %s)\n",
720 GetLastError(), debugstr_w(InstanceId
));
724 if (SetupDiGetDeviceRegistryPropertyW(
725 DevInstData
->hDevInfo
,
726 &DevInstData
->devInfoData
,
729 (BYTE
*)&config_flags
,
730 sizeof(config_flags
),
733 if (config_flags
& CONFIGFLAG_FAILEDINSTALL
)
735 /* The device is disabled */
736 TRACE("Device is disabled\n");
742 TRACE("Installing %s (%s)\n", debugstr_w((PCWSTR
)DevInstData
->buffer
), debugstr_w(InstanceId
));
744 /* Search driver in default location and removable devices */
745 if (!PrepareFoldersToScan(DevInstData
, FALSE
, FALSE
, NULL
))
747 TRACE("PrepareFoldersToScan() failed with error 0x%lx\n", GetLastError());
750 if (ScanFoldersForDriver(DevInstData
))
752 /* Driver found ; install it */
753 retval
= InstallCurrentDriver(DevInstData
);
754 TRACE("InstallCurrentDriver() returned %d\n", retval
);
755 if (retval
&& Show
!= SW_HIDE
)
757 /* Should we display the 'Need to reboot' page? */
758 SP_DEVINSTALL_PARAMS installParams
;
759 installParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
760 if (SetupDiGetDeviceInstallParams(
761 DevInstData
->hDevInfo
,
762 &DevInstData
->devInfoData
,
765 if (installParams
.Flags
& (DI_NEEDRESTART
| DI_NEEDREBOOT
))
767 TRACE("Displaying 'Reboot' wizard page\n");
768 retval
= DisplayWizard(DevInstData
, hWndParent
, IDD_NEEDREBOOT
);
774 else if (Show
== SW_HIDE
)
776 /* We can't show the wizard. Fail the install */
777 TRACE("No wizard\n");
781 /* Prepare the wizard, and display it */
782 TRACE("Need to show install wizard\n");
783 retval
= DisplayWizard(DevInstData
, hWndParent
, IDD_WELCOMEPAGE
);
788 if (DevInstData
->devInfoData
.cbSize
!= 0)
790 if (!SetupDiDestroyDriverInfoList(DevInstData
->hDevInfo
, &DevInstData
->devInfoData
, SPDIT_COMPATDRIVER
))
791 TRACE("SetupDiDestroyDriverInfoList() failed with error 0x%lx\n", GetLastError());
793 if (DevInstData
->hDevInfo
!= INVALID_HANDLE_VALUE
)
795 if (!SetupDiDestroyDeviceInfoList(DevInstData
->hDevInfo
))
796 TRACE("SetupDiDestroyDeviceInfoList() failed with error 0x%lx\n", GetLastError());
798 HeapFree(GetProcessHeap(), 0, DevInstData
->buffer
);
799 HeapFree(GetProcessHeap(), 0, DevInstData
);
811 IN DWORD dwUnknownFlags
,
812 IN LPWSTR lpNamedPipeName
)
814 /* NOTE: pNamedPipeName is in the format:
815 * "\\.\pipe\PNP_Device_Install_Pipe_0.{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"
823 IN HINSTANCE hInstance
,
825 IN LPVOID lpReserved
)
827 if (dwReason
== DLL_PROCESS_ATTACH
)
829 INITCOMMONCONTROLSEX InitControls
;
831 DisableThreadLibraryCalls(hInstance
);
833 InitControls
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
834 InitControls
.dwICC
= ICC_PROGRESS_CLASS
;
835 InitCommonControlsEx(&InitControls
);
836 hDllInstance
= hInstance
;