2 * SetupAPI device installer
4 * Copyright 2000 Andreas Mohr for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/port.h"
35 #include "wine/debug.h"
36 #include "wine/unicode.h"
43 #include "setupapi_private.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(setupapi
);
48 /* Unicode constants */
49 static const WCHAR ClassGUID
[] = {'C','l','a','s','s','G','U','I','D',0};
50 static const WCHAR Class
[] = {'C','l','a','s','s',0};
51 static const WCHAR ClassInstall32
[] = {'C','l','a','s','s','I','n','s','t','a','l','l','3','2',0};
52 static const WCHAR NoDisplayClass
[] = {'N','o','D','i','s','p','l','a','y','C','l','a','s','s',0};
53 static const WCHAR NoInstallClass
[] = {'N','o','I','n','s','t','a','l','l','C','l','a','s','s',0};
54 static const WCHAR NoUseClass
[] = {'N','o','U','s','e','C','l','a','s','s',0};
55 static const WCHAR NtExtension
[] = {'.','N','T',0};
56 static const WCHAR NtPlatformExtension
[] = {'.','N','T','x','8','6',0};
57 static const WCHAR Version
[] = {'V','e','r','s','i','o','n',0};
58 static const WCHAR WinExtension
[] = {'.','W','i','n',0};
60 /* Registry key and value names */
61 static const WCHAR ControlClass
[] = {'S','y','s','t','e','m','\\',
62 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
63 'C','o','n','t','r','o','l','\\',
64 'C','l','a','s','s',0};
66 static const WCHAR DeviceClasses
[] = {'S','y','s','t','e','m','\\',
67 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
68 'C','o','n','t','r','o','l','\\',
69 'D','e','v','i','c','e','C','l','a','s','s','e','s',0};
70 static const WCHAR Enum
[] = {'S','y','s','t','e','m','\\',
71 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
73 static const WCHAR DeviceDesc
[] = {'D','e','v','i','c','e','D','e','s','c',0};
74 static const WCHAR HardwareId
[] = {'H','a','r','d','w','a','r','e','I','D',0};
75 static const WCHAR CompatibleIDs
[] = {'C','o','m','p','a','t','i','b','l','e','I','d','s',0};
76 static const WCHAR Service
[] = {'S','e','r','v','i','c','e',0};
77 static const WCHAR Driver
[] = {'D','r','i','v','e','r',0};
78 static const WCHAR ConfigFlags
[] = {'C','o','n','f','i','g','F','l','a','g','s',0};
79 static const WCHAR Mfg
[] = {'M','f','g',0};
80 static const WCHAR FriendlyName
[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
81 static const WCHAR LocationInformation
[] = {'L','o','c','a','t','i','o','n','I','n','f','o','r','m','a','t','i','o','n',0};
82 static const WCHAR Capabilities
[] = {'C','a','p','a','b','i','l','i','t','i','e','s',0};
83 static const WCHAR UINumber
[] = {'U','I','N','u','m','b','e','r',0};
84 static const WCHAR UpperFilters
[] = {'U','p','p','e','r','F','i','l','t','e','r','s',0};
85 static const WCHAR LowerFilters
[] = {'L','o','w','e','r','F','i','l','t','e','r','s',0};
86 static const WCHAR Phantom
[] = {'P','h','a','n','t','o','m',0};
88 /* is used to identify if a DeviceInfoSet pointer is
90 #define SETUP_DEVICE_INFO_SET_MAGIC 0xd00ff056
94 DWORD magic
; /* if is equal to SETUP_DEVICE_INFO_SET_MAGIC struct is okay */
98 SP_DEVINFO_DATA
*devices
;
101 /* Pointed to by SP_DEVINFO_DATA's Reserved member */
109 static struct DeviceInfo
*SETUPDI_AllocateDeviceInfo(LPCWSTR instanceId
,
112 struct DeviceInfo
*devInfo
= HeapAlloc(GetProcessHeap(), 0,
113 sizeof(struct DeviceInfo
));
117 devInfo
->instanceId
= HeapAlloc(GetProcessHeap(), 0,
118 (lstrlenW(instanceId
) + 1) * sizeof(WCHAR
));
119 if (devInfo
->instanceId
)
124 devInfo
->key
= INVALID_HANDLE_VALUE
;
125 devInfo
->phantom
= phantom
;
126 lstrcpyW(devInfo
->instanceId
, instanceId
);
127 struprW(devInfo
->instanceId
);
128 l
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
, Enum
, 0, NULL
, 0,
129 KEY_ALL_ACCESS
, NULL
, &enumKey
, NULL
);
132 RegCreateKeyExW(enumKey
, devInfo
->instanceId
, 0, NULL
, 0,
133 KEY_ALL_ACCESS
, NULL
, &devInfo
->key
, NULL
);
135 RegSetValueExW(devInfo
->key
, Phantom
, 0, REG_DWORD
,
136 (LPBYTE
)&phantom
, sizeof(phantom
));
137 RegCloseKey(enumKey
);
142 HeapFree(GetProcessHeap(), 0, devInfo
);
149 static void SETUPDI_FreeDeviceInfo(struct DeviceInfo
*devInfo
)
151 if (devInfo
->key
!= INVALID_HANDLE_VALUE
)
152 RegCloseKey(devInfo
->key
);
153 if (devInfo
->phantom
)
158 l
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
, Enum
, 0, NULL
, 0,
159 KEY_ALL_ACCESS
, NULL
, &enumKey
, NULL
);
162 RegDeleteTreeW(enumKey
, devInfo
->instanceId
);
163 RegCloseKey(enumKey
);
166 HeapFree(GetProcessHeap(), 0, devInfo
->instanceId
);
167 HeapFree(GetProcessHeap(), 0, devInfo
);
170 static void SETUPDI_GuidToString(const GUID
*guid
, LPWSTR guidStr
)
172 static const WCHAR fmt
[] = {'{','%','0','8','X','-','%','0','4','X','-',
173 '%','0','4','X','-','%','0','2','X','%','0','2','X','-','%','0','2',
174 'X','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','%',
177 sprintfW(guidStr
, fmt
, guid
->Data1
, guid
->Data2
, guid
->Data3
,
178 guid
->Data4
[0], guid
->Data4
[1], guid
->Data4
[2], guid
->Data4
[3],
179 guid
->Data4
[4], guid
->Data4
[5], guid
->Data4
[6], guid
->Data4
[7]);
182 /* Adds a device with GUID guid and identifer devInst to set. Allocates a
183 * struct DeviceInfo, and points the returned device info's Reserved member
184 * to it. "Phantom" devices are deleted from the registry when closed.
185 * Returns a pointer to the newly allocated device info.
187 static BOOL
SETUPDI_AddDeviceToSet(struct DeviceInfoSet
*set
,
192 SP_DEVINFO_DATA
**dev
)
195 struct DeviceInfo
*devInfo
= SETUPDI_AllocateDeviceInfo(instanceId
,
201 set
->devices
= HeapReAlloc(GetProcessHeap(), 0, set
->devices
,
202 (set
->cDevices
+ 1) * sizeof(SP_DEVINFO_DATA
));
204 set
->devices
= HeapAlloc(GetProcessHeap(), 0,
205 sizeof(SP_DEVINFO_DATA
));
208 WCHAR classGuidStr
[39];
210 *dev
= &set
->devices
[set
->cDevices
++];
211 (*dev
)->cbSize
= sizeof(SP_DEVINFO_DATA
);
212 memcpy(&(*dev
)->ClassGuid
, guid
, sizeof(GUID
));
213 (*dev
)->DevInst
= devInst
;
214 (*dev
)->Reserved
= (ULONG_PTR
)devInfo
;
215 SETUPDI_GuidToString(guid
, classGuidStr
);
216 SetupDiSetDeviceRegistryPropertyW((HDEVINFO
)set
,
217 *dev
, SPDRP_CLASSGUID
, (const BYTE
*)classGuidStr
,
218 lstrlenW(classGuidStr
) * sizeof(WCHAR
));
223 HeapFree(GetProcessHeap(), 0, devInfo
);
224 SetLastError(ERROR_OUTOFMEMORY
);
230 /***********************************************************************
231 * SetupDiBuildClassInfoList (SETUPAPI.@)
233 * Returns a list of setup class GUIDs that identify the classes
234 * that are installed on a local machine.
237 * Flags [I] control exclusion of classes from the list.
238 * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
239 * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
240 * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
246 BOOL WINAPI
SetupDiBuildClassInfoList(
248 LPGUID ClassGuidList
,
249 DWORD ClassGuidListSize
,
253 return SetupDiBuildClassInfoListExW(Flags
, ClassGuidList
,
254 ClassGuidListSize
, RequiredSize
,
258 /***********************************************************************
259 * SetupDiBuildClassInfoListExA (SETUPAPI.@)
261 * Returns a list of setup class GUIDs that identify the classes
262 * that are installed on a local or remote macine.
265 * Flags [I] control exclusion of classes from the list.
266 * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
267 * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
268 * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
269 * MachineName [I] name of a remote machine.
270 * Reserved [I] must be NULL.
276 BOOL WINAPI
SetupDiBuildClassInfoListExA(
278 LPGUID ClassGuidList
,
279 DWORD ClassGuidListSize
,
284 LPWSTR MachineNameW
= NULL
;
291 MachineNameW
= MultiByteToUnicode(MachineName
, CP_ACP
);
292 if (MachineNameW
== NULL
) return FALSE
;
295 bResult
= SetupDiBuildClassInfoListExW(Flags
, ClassGuidList
,
296 ClassGuidListSize
, RequiredSize
,
297 MachineNameW
, Reserved
);
299 MyFree(MachineNameW
);
304 /***********************************************************************
305 * SetupDiBuildClassInfoListExW (SETUPAPI.@)
307 * Returns a list of setup class GUIDs that identify the classes
308 * that are installed on a local or remote macine.
311 * Flags [I] control exclusion of classes from the list.
312 * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
313 * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
314 * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
315 * MachineName [I] name of a remote machine.
316 * Reserved [I] must be NULL.
322 BOOL WINAPI
SetupDiBuildClassInfoListExW(
324 LPGUID ClassGuidList
,
325 DWORD ClassGuidListSize
,
336 DWORD dwGuidListIndex
= 0;
340 if (RequiredSize
!= NULL
)
343 hClassesKey
= SetupDiOpenClassRegKeyExW(NULL
,
348 if (hClassesKey
== INVALID_HANDLE_VALUE
)
353 for (dwIndex
= 0; ; dwIndex
++)
356 lError
= RegEnumKeyExW(hClassesKey
,
364 TRACE("RegEnumKeyExW() returns %d\n", lError
);
365 if (lError
== ERROR_SUCCESS
|| lError
== ERROR_MORE_DATA
)
367 TRACE("Key name: %p\n", szKeyName
);
369 if (RegOpenKeyExW(hClassesKey
,
375 RegCloseKey(hClassesKey
);
379 if (!RegQueryValueExW(hClassKey
,
386 TRACE("'NoUseClass' value found!\n");
387 RegCloseKey(hClassKey
);
391 if ((Flags
& DIBCI_NOINSTALLCLASS
) &&
392 (!RegQueryValueExW(hClassKey
,
399 TRACE("'NoInstallClass' value found!\n");
400 RegCloseKey(hClassKey
);
404 if ((Flags
& DIBCI_NODISPLAYCLASS
) &&
405 (!RegQueryValueExW(hClassKey
,
412 TRACE("'NoDisplayClass' value found!\n");
413 RegCloseKey(hClassKey
);
417 RegCloseKey(hClassKey
);
419 TRACE("Guid: %p\n", szKeyName
);
420 if (dwGuidListIndex
< ClassGuidListSize
)
422 if (szKeyName
[0] == '{' && szKeyName
[37] == '}')
426 TRACE("Guid: %p\n", &szKeyName
[1]);
428 UuidFromStringW(&szKeyName
[1],
429 &ClassGuidList
[dwGuidListIndex
]);
435 if (lError
!= ERROR_SUCCESS
)
439 RegCloseKey(hClassesKey
);
441 if (RequiredSize
!= NULL
)
442 *RequiredSize
= dwGuidListIndex
;
444 if (ClassGuidListSize
< dwGuidListIndex
)
446 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
453 /***********************************************************************
454 * SetupDiClassGuidsFromNameA (SETUPAPI.@)
456 BOOL WINAPI
SetupDiClassGuidsFromNameA(
458 LPGUID ClassGuidList
,
459 DWORD ClassGuidListSize
,
462 return SetupDiClassGuidsFromNameExA(ClassName
, ClassGuidList
,
463 ClassGuidListSize
, RequiredSize
,
467 /***********************************************************************
468 * SetupDiClassGuidsFromNameW (SETUPAPI.@)
470 BOOL WINAPI
SetupDiClassGuidsFromNameW(
472 LPGUID ClassGuidList
,
473 DWORD ClassGuidListSize
,
476 return SetupDiClassGuidsFromNameExW(ClassName
, ClassGuidList
,
477 ClassGuidListSize
, RequiredSize
,
481 /***********************************************************************
482 * SetupDiClassGuidsFromNameExA (SETUPAPI.@)
484 BOOL WINAPI
SetupDiClassGuidsFromNameExA(
486 LPGUID ClassGuidList
,
487 DWORD ClassGuidListSize
,
492 LPWSTR ClassNameW
= NULL
;
493 LPWSTR MachineNameW
= NULL
;
498 ClassNameW
= MultiByteToUnicode(ClassName
, CP_ACP
);
499 if (ClassNameW
== NULL
)
504 MachineNameW
= MultiByteToUnicode(MachineName
, CP_ACP
);
505 if (MachineNameW
== NULL
)
512 bResult
= SetupDiClassGuidsFromNameExW(ClassNameW
, ClassGuidList
,
513 ClassGuidListSize
, RequiredSize
,
514 MachineNameW
, Reserved
);
516 MyFree(MachineNameW
);
522 /***********************************************************************
523 * SetupDiClassGuidsFromNameExW (SETUPAPI.@)
525 BOOL WINAPI
SetupDiClassGuidsFromNameExW(
527 LPGUID ClassGuidList
,
528 DWORD ClassGuidListSize
,
534 WCHAR szClassName
[256];
540 DWORD dwGuidListIndex
= 0;
542 if (RequiredSize
!= NULL
)
545 hClassesKey
= SetupDiOpenClassRegKeyExW(NULL
,
550 if (hClassesKey
== INVALID_HANDLE_VALUE
)
555 for (dwIndex
= 0; ; dwIndex
++)
558 lError
= RegEnumKeyExW(hClassesKey
,
566 TRACE("RegEnumKeyExW() returns %d\n", lError
);
567 if (lError
== ERROR_SUCCESS
|| lError
== ERROR_MORE_DATA
)
569 TRACE("Key name: %p\n", szKeyName
);
571 if (RegOpenKeyExW(hClassesKey
,
577 RegCloseKey(hClassesKey
);
581 dwLength
= 256 * sizeof(WCHAR
);
582 if (!RegQueryValueExW(hClassKey
,
589 TRACE("Class name: %p\n", szClassName
);
591 if (strcmpiW(szClassName
, ClassName
) == 0)
593 TRACE("Found matching class name\n");
595 TRACE("Guid: %p\n", szKeyName
);
596 if (dwGuidListIndex
< ClassGuidListSize
)
598 if (szKeyName
[0] == '{' && szKeyName
[37] == '}')
602 TRACE("Guid: %p\n", &szKeyName
[1]);
604 UuidFromStringW(&szKeyName
[1],
605 &ClassGuidList
[dwGuidListIndex
]);
612 RegCloseKey(hClassKey
);
615 if (lError
!= ERROR_SUCCESS
)
619 RegCloseKey(hClassesKey
);
621 if (RequiredSize
!= NULL
)
622 *RequiredSize
= dwGuidListIndex
;
624 if (ClassGuidListSize
< dwGuidListIndex
)
626 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
633 /***********************************************************************
634 * SetupDiClassNameFromGuidA (SETUPAPI.@)
636 BOOL WINAPI
SetupDiClassNameFromGuidA(
637 const GUID
* ClassGuid
,
642 return SetupDiClassNameFromGuidExA(ClassGuid
, ClassName
,
643 ClassNameSize
, RequiredSize
,
647 /***********************************************************************
648 * SetupDiClassNameFromGuidW (SETUPAPI.@)
650 BOOL WINAPI
SetupDiClassNameFromGuidW(
651 const GUID
* ClassGuid
,
656 return SetupDiClassNameFromGuidExW(ClassGuid
, ClassName
,
657 ClassNameSize
, RequiredSize
,
661 /***********************************************************************
662 * SetupDiClassNameFromGuidExA (SETUPAPI.@)
664 BOOL WINAPI
SetupDiClassNameFromGuidExA(
665 const GUID
* ClassGuid
,
672 WCHAR ClassNameW
[MAX_CLASS_NAME_LEN
];
673 LPWSTR MachineNameW
= NULL
;
677 MachineNameW
= MultiByteToUnicode(MachineName
, CP_ACP
);
678 ret
= SetupDiClassNameFromGuidExW(ClassGuid
, ClassNameW
, MAX_CLASS_NAME_LEN
,
679 NULL
, MachineNameW
, Reserved
);
682 int len
= WideCharToMultiByte(CP_ACP
, 0, ClassNameW
, -1, ClassName
,
683 ClassNameSize
, NULL
, NULL
);
685 if (!ClassNameSize
&& RequiredSize
)
688 MyFree(MachineNameW
);
692 /***********************************************************************
693 * SetupDiClassNameFromGuidExW (SETUPAPI.@)
695 BOOL WINAPI
SetupDiClassNameFromGuidExW(
696 const GUID
* ClassGuid
,
706 hKey
= SetupDiOpenClassRegKeyExW(ClassGuid
,
711 if (hKey
== INVALID_HANDLE_VALUE
)
716 if (RequiredSize
!= NULL
)
719 if (RegQueryValueExW(hKey
,
730 *RequiredSize
= dwLength
/ sizeof(WCHAR
);
733 dwLength
= ClassNameSize
* sizeof(WCHAR
);
734 if (RegQueryValueExW(hKey
,
750 /***********************************************************************
751 * SetupDiCreateDeviceInfoList (SETUPAPI.@)
754 SetupDiCreateDeviceInfoList(const GUID
*ClassGuid
,
757 return SetupDiCreateDeviceInfoListExW(ClassGuid
, hwndParent
, NULL
, NULL
);
760 /***********************************************************************
761 * SetupDiCreateDeviceInfoListExA (SETUPAPI.@)
764 SetupDiCreateDeviceInfoListExA(const GUID
*ClassGuid
,
769 LPWSTR MachineNameW
= NULL
;
776 MachineNameW
= MultiByteToUnicode(MachineName
, CP_ACP
);
777 if (MachineNameW
== NULL
)
778 return (HDEVINFO
)INVALID_HANDLE_VALUE
;
781 hDevInfo
= SetupDiCreateDeviceInfoListExW(ClassGuid
, hwndParent
,
782 MachineNameW
, Reserved
);
784 MyFree(MachineNameW
);
789 /***********************************************************************
790 * SetupDiCreateDeviceInfoListExW (SETUPAPI.@)
792 * Create an empty DeviceInfoSet list.
795 * ClassGuid [I] if not NULL only devices with GUID ClcassGuid are associated
797 * hwndParent [I] hwnd needed for interface related actions.
798 * MachineName [I] name of machine to create emtpy DeviceInfoSet list, if NULL
799 * local registry will be used.
800 * Reserved [I] must be NULL
803 * Success: empty list.
804 * Failure: INVALID_HANDLE_VALUE.
807 SetupDiCreateDeviceInfoListExW(const GUID
*ClassGuid
,
812 struct DeviceInfoSet
*list
= NULL
;
813 DWORD size
= sizeof(struct DeviceInfoSet
);
815 TRACE("%s %p %s %p\n", debugstr_guid(ClassGuid
), hwndParent
,
816 debugstr_w(MachineName
), Reserved
);
818 if (MachineName
!= NULL
)
820 FIXME("remote support is not implemented\n");
821 SetLastError(ERROR_INVALID_MACHINENAME
);
822 return (HDEVINFO
)INVALID_HANDLE_VALUE
;
825 if (Reserved
!= NULL
)
827 SetLastError(ERROR_INVALID_PARAMETER
);
828 return (HDEVINFO
)INVALID_HANDLE_VALUE
;
831 list
= HeapAlloc(GetProcessHeap(), 0, size
);
834 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
835 return (HDEVINFO
)INVALID_HANDLE_VALUE
;
838 list
->magic
= SETUP_DEVICE_INFO_SET_MAGIC
;
839 list
->hwndParent
= hwndParent
;
840 memcpy(&list
->ClassGuid
,
841 ClassGuid
? ClassGuid
: &GUID_NULL
,
842 sizeof(list
->ClassGuid
));
844 list
->devices
= NULL
;
846 return (HDEVINFO
)list
;
849 /***********************************************************************
850 * SetupDiCreateDeviceInfoA (SETUPAPI.@)
852 BOOL WINAPI
SetupDiCreateDeviceInfoA(
853 HDEVINFO DeviceInfoSet
,
855 CONST GUID
*ClassGuid
,
856 PCSTR DeviceDescription
,
859 PSP_DEVINFO_DATA DeviceInfoData
)
862 LPWSTR DeviceNameW
= NULL
;
863 LPWSTR DeviceDescriptionW
= NULL
;
867 DeviceNameW
= MultiByteToUnicode(DeviceName
, CP_ACP
);
868 if (DeviceNameW
== NULL
) return FALSE
;
870 if (DeviceDescription
)
872 DeviceDescriptionW
= MultiByteToUnicode(DeviceDescription
, CP_ACP
);
873 if (DeviceDescriptionW
== NULL
)
880 ret
= SetupDiCreateDeviceInfoW(DeviceInfoSet
, DeviceNameW
, ClassGuid
, DeviceDescriptionW
,
881 hwndParent
, CreationFlags
, DeviceInfoData
);
884 MyFree(DeviceDescriptionW
);
889 static DWORD
SETUPDI_DevNameToDevID(LPCWSTR devName
)
892 DWORD devNameLen
= lstrlenW(devName
), devInst
= 0;
895 TRACE("%s\n", debugstr_w(devName
));
896 for (ptr
= devName
; valid
&& *ptr
&& ptr
- devName
< devNameLen
; )
901 devInst
|= *ptr
- '0';
907 TRACE("%d\n", valid
? devInst
: 0xffffffff);
908 return valid
? devInst
: 0xffffffff;
911 /***********************************************************************
912 * SetupDiCreateDeviceInfoW (SETUPAPI.@)
914 BOOL WINAPI
SetupDiCreateDeviceInfoW(
915 HDEVINFO DeviceInfoSet
,
917 CONST GUID
*ClassGuid
,
918 PCWSTR DeviceDescription
,
921 PSP_DEVINFO_DATA DeviceInfoData
)
923 struct DeviceInfoSet
*set
= (struct DeviceInfoSet
*)DeviceInfoSet
;
924 BOOL ret
= FALSE
, allocatedInstanceId
= FALSE
;
925 LPCWSTR instanceId
= NULL
;
927 TRACE("%p %s %s %s %p %x %p\n", DeviceInfoSet
, debugstr_w(DeviceName
),
928 debugstr_guid(ClassGuid
), debugstr_w(DeviceDescription
),
929 hwndParent
, CreationFlags
, DeviceInfoData
);
933 SetLastError(ERROR_INVALID_DEVINST_NAME
);
936 if (!DeviceInfoSet
|| DeviceInfoSet
== (HDEVINFO
)INVALID_HANDLE_VALUE
)
938 SetLastError(ERROR_INVALID_HANDLE
);
943 SetLastError(ERROR_INVALID_PARAMETER
);
946 if (set
->magic
!= SETUP_DEVICE_INFO_SET_MAGIC
)
948 SetLastError(ERROR_INVALID_HANDLE
);
951 if (!IsEqualGUID(&set
->ClassGuid
, &GUID_NULL
) &&
952 !IsEqualGUID(ClassGuid
, &set
->ClassGuid
))
954 SetLastError(ERROR_CLASS_MISMATCH
);
957 if ((CreationFlags
& DICD_GENERATE_ID
))
959 if (strchrW(DeviceName
, '\\'))
960 SetLastError(ERROR_INVALID_DEVINST_NAME
);
963 static const WCHAR newDeviceFmt
[] = {'R','O','O','T','\\','%','s',
964 '\\','%','0','4','d',0};
969 DWORD i
, highestDevID
= 0;
971 for (i
= 0; i
< set
->cDevices
; i
++)
973 struct DeviceInfo
*devInfo
=
974 (struct DeviceInfo
*)set
->devices
[i
].Reserved
;
975 LPCWSTR devName
= strrchrW(devInfo
->instanceId
, '\\');
981 devName
= devInfo
->instanceId
;
982 id
= SETUPDI_DevNameToDevID(devName
);
983 if (id
!= 0xffffffff && id
> highestDevID
)
986 devId
= highestDevID
+ 1;
990 /* 17 == lstrlenW(L"Root\\") + lstrlenW("\\") + 1 + %d max size */
991 instanceId
= HeapAlloc(GetProcessHeap(), 0,
992 (17 + lstrlenW(DeviceName
)) * sizeof(WCHAR
));
995 sprintfW((LPWSTR
)instanceId
, newDeviceFmt
, DeviceName
,
997 allocatedInstanceId
= TRUE
;
1009 instanceId
= DeviceName
;
1010 for (i
= 0; ret
&& i
< set
->cDevices
; i
++)
1012 struct DeviceInfo
*devInfo
=
1013 (struct DeviceInfo
*)set
->devices
[i
].Reserved
;
1015 if (!lstrcmpiW(DeviceName
, devInfo
->instanceId
))
1017 SetLastError(ERROR_DEVINST_ALREADY_EXISTS
);
1024 SP_DEVINFO_DATA
*dev
= NULL
;
1026 ret
= SETUPDI_AddDeviceToSet(set
, ClassGuid
, 0 /* FIXME: DevInst */,
1027 instanceId
, TRUE
, &dev
);
1030 if (DeviceDescription
)
1031 SetupDiSetDeviceRegistryPropertyW(DeviceInfoSet
,
1032 dev
, SPDRP_DEVICEDESC
, (const BYTE
*)DeviceDescription
,
1033 lstrlenW(DeviceDescription
) * sizeof(WCHAR
));
1036 if (DeviceInfoData
->cbSize
!= sizeof(SP_DEVINFO_DATA
))
1038 SetLastError(ERROR_INVALID_USER_BUFFER
);
1042 memcpy(DeviceInfoData
, dev
, sizeof(SP_DEVINFO_DATA
));
1046 if (allocatedInstanceId
)
1047 HeapFree(GetProcessHeap(), 0, (LPWSTR
)instanceId
);
1052 /***********************************************************************
1053 * SetupDiEnumDeviceInfo (SETUPAPI.@)
1055 BOOL WINAPI
SetupDiEnumDeviceInfo(
1058 PSP_DEVINFO_DATA info
)
1062 TRACE("%p %d %p\n", devinfo
, index
, info
);
1066 if(info
->cbSize
< sizeof(*info
))
1068 if (devinfo
&& devinfo
!= (HDEVINFO
)INVALID_HANDLE_VALUE
)
1070 struct DeviceInfoSet
*list
= (struct DeviceInfoSet
*)devinfo
;
1071 if (list
->magic
== SETUP_DEVICE_INFO_SET_MAGIC
)
1073 if (index
< list
->cDevices
)
1075 if (info
->cbSize
== sizeof(SP_DEVINFO_DATA
))
1077 memcpy(info
, &list
->devices
[index
], info
->cbSize
);
1081 SetLastError(ERROR_INVALID_USER_BUFFER
);
1084 SetLastError(ERROR_NO_MORE_ITEMS
);
1087 SetLastError(ERROR_INVALID_HANDLE
);
1090 SetLastError(ERROR_INVALID_HANDLE
);
1094 /***********************************************************************
1095 * SetupDiGetDeviceInstanceIdA (SETUPAPI.@)
1097 BOOL WINAPI
SetupDiGetDeviceInstanceIdA(
1098 HDEVINFO DeviceInfoSet
,
1099 PSP_DEVINFO_DATA DeviceInfoData
,
1100 PSTR DeviceInstanceId
,
1101 DWORD DeviceInstanceIdSize
,
1102 PDWORD RequiredSize
)
1108 TRACE("%p %p %p %d %p\n", DeviceInfoSet
, DeviceInfoData
, DeviceInstanceId
,
1109 DeviceInstanceIdSize
, RequiredSize
);
1111 SetupDiGetDeviceInstanceIdW(DeviceInfoSet
,
1116 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
1118 instanceId
= HeapAlloc(GetProcessHeap(), 0, size
* sizeof(WCHAR
));
1121 ret
= SetupDiGetDeviceInstanceIdW(DeviceInfoSet
,
1128 int len
= WideCharToMultiByte(CP_ACP
, 0, instanceId
, -1,
1130 DeviceInstanceIdSize
, NULL
, NULL
);
1136 if (len
> DeviceInstanceIdSize
)
1138 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1142 *RequiredSize
= len
;
1145 HeapFree(GetProcessHeap(), 0, instanceId
);
1150 /***********************************************************************
1151 * SetupDiGetDeviceInstanceIdW (SETUPAPI.@)
1153 BOOL WINAPI
SetupDiGetDeviceInstanceIdW(
1154 HDEVINFO DeviceInfoSet
,
1155 PSP_DEVINFO_DATA DeviceInfoData
,
1156 PWSTR DeviceInstanceId
,
1157 DWORD DeviceInstanceIdSize
,
1158 PDWORD RequiredSize
)
1160 struct DeviceInfoSet
*set
= (struct DeviceInfoSet
*)DeviceInfoSet
;
1161 struct DeviceInfo
*devInfo
;
1163 TRACE("%p %p %p %d %p\n", DeviceInfoSet
, DeviceInfoData
, DeviceInstanceId
,
1164 DeviceInstanceIdSize
, RequiredSize
);
1166 if (!DeviceInfoSet
|| DeviceInfoSet
== INVALID_HANDLE_VALUE
)
1168 SetLastError(ERROR_INVALID_HANDLE
);
1171 if (set
->magic
!= SETUP_DEVICE_INFO_SET_MAGIC
)
1173 SetLastError(ERROR_INVALID_HANDLE
);
1176 if (!DeviceInfoData
|| DeviceInfoData
->cbSize
!= sizeof(SP_DEVINFO_DATA
)
1177 || !DeviceInfoData
->Reserved
)
1179 SetLastError(ERROR_INVALID_PARAMETER
);
1182 devInfo
= (struct DeviceInfo
*)DeviceInfoData
->Reserved
;
1183 TRACE("instance ID: %s\n", debugstr_w(devInfo
->instanceId
));
1184 if (DeviceInstanceIdSize
< lstrlenW(devInfo
->instanceId
) + 1)
1186 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1188 *RequiredSize
= lstrlenW(devInfo
->instanceId
) + 1;
1191 lstrcpyW(DeviceInstanceId
, devInfo
->instanceId
);
1193 *RequiredSize
= lstrlenW(devInfo
->instanceId
) + 1;
1197 /***********************************************************************
1198 * SetupDiGetActualSectionToInstallA (SETUPAPI.@)
1200 BOOL WINAPI
SetupDiGetActualSectionToInstallA(
1202 PCSTR InfSectionName
,
1203 PSTR InfSectionWithExt
,
1204 DWORD InfSectionWithExtSize
,
1205 PDWORD RequiredSize
,
1212 /***********************************************************************
1213 * SetupDiGetActualSectionToInstallW (SETUPAPI.@)
1215 BOOL WINAPI
SetupDiGetActualSectionToInstallW(
1217 PCWSTR InfSectionName
,
1218 PWSTR InfSectionWithExt
,
1219 DWORD InfSectionWithExtSize
,
1220 PDWORD RequiredSize
,
1223 WCHAR szBuffer
[MAX_PATH
];
1226 LONG lLineCount
= -1;
1228 lstrcpyW(szBuffer
, InfSectionName
);
1229 dwLength
= lstrlenW(szBuffer
);
1231 if (OsVersionInfo
.dwPlatformId
== VER_PLATFORM_WIN32_NT
)
1233 /* Test section name with '.NTx86' extension */
1234 lstrcpyW(&szBuffer
[dwLength
], NtPlatformExtension
);
1235 lLineCount
= SetupGetLineCountW(InfHandle
, szBuffer
);
1237 if (lLineCount
== -1)
1239 /* Test section name with '.NT' extension */
1240 lstrcpyW(&szBuffer
[dwLength
], NtExtension
);
1241 lLineCount
= SetupGetLineCountW(InfHandle
, szBuffer
);
1246 /* Test section name with '.Win' extension */
1247 lstrcpyW(&szBuffer
[dwLength
], WinExtension
);
1248 lLineCount
= SetupGetLineCountW(InfHandle
, szBuffer
);
1251 if (lLineCount
== -1)
1253 /* Test section name without extension */
1254 szBuffer
[dwLength
] = 0;
1255 lLineCount
= SetupGetLineCountW(InfHandle
, szBuffer
);
1258 if (lLineCount
== -1)
1260 SetLastError(ERROR_INVALID_PARAMETER
);
1264 dwFullLength
= lstrlenW(szBuffer
);
1266 if (InfSectionWithExt
!= NULL
&& InfSectionWithExtSize
!= 0)
1268 if (InfSectionWithExtSize
< (dwFullLength
+ 1))
1270 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1274 lstrcpyW(InfSectionWithExt
, szBuffer
);
1275 if (Extension
!= NULL
)
1277 *Extension
= (dwLength
== dwFullLength
) ? NULL
: &InfSectionWithExt
[dwLength
];
1281 if (RequiredSize
!= NULL
)
1283 *RequiredSize
= dwFullLength
+ 1;
1289 /***********************************************************************
1290 * SetupDiGetClassDescriptionA (SETUPAPI.@)
1292 BOOL WINAPI
SetupDiGetClassDescriptionA(
1293 const GUID
* ClassGuid
,
1294 PSTR ClassDescription
,
1295 DWORD ClassDescriptionSize
,
1296 PDWORD RequiredSize
)
1298 return SetupDiGetClassDescriptionExA(ClassGuid
, ClassDescription
,
1299 ClassDescriptionSize
,
1300 RequiredSize
, NULL
, NULL
);
1303 /***********************************************************************
1304 * SetupDiGetClassDescriptionW (SETUPAPI.@)
1306 BOOL WINAPI
SetupDiGetClassDescriptionW(
1307 const GUID
* ClassGuid
,
1308 PWSTR ClassDescription
,
1309 DWORD ClassDescriptionSize
,
1310 PDWORD RequiredSize
)
1312 return SetupDiGetClassDescriptionExW(ClassGuid
, ClassDescription
,
1313 ClassDescriptionSize
,
1314 RequiredSize
, NULL
, NULL
);
1317 /***********************************************************************
1318 * SetupDiGetClassDescriptionExA (SETUPAPI.@)
1320 BOOL WINAPI
SetupDiGetClassDescriptionExA(
1321 const GUID
* ClassGuid
,
1322 PSTR ClassDescription
,
1323 DWORD ClassDescriptionSize
,
1324 PDWORD RequiredSize
,
1332 /***********************************************************************
1333 * SetupDiGetClassDescriptionExW (SETUPAPI.@)
1335 BOOL WINAPI
SetupDiGetClassDescriptionExW(
1336 const GUID
* ClassGuid
,
1337 PWSTR ClassDescription
,
1338 DWORD ClassDescriptionSize
,
1339 PDWORD RequiredSize
,
1346 hKey
= SetupDiOpenClassRegKeyExW(ClassGuid
,
1351 if (hKey
== INVALID_HANDLE_VALUE
)
1353 WARN("SetupDiOpenClassRegKeyExW() failed (Error %u)\n", GetLastError());
1357 if (RequiredSize
!= NULL
)
1360 if (RegQueryValueExW(hKey
,
1371 *RequiredSize
= dwLength
/ sizeof(WCHAR
);
1374 dwLength
= ClassDescriptionSize
* sizeof(WCHAR
);
1375 if (RegQueryValueExW(hKey
,
1379 (LPBYTE
)ClassDescription
,
1391 /***********************************************************************
1392 * SetupDiGetClassDevsA (SETUPAPI.@)
1394 HDEVINFO WINAPI
SetupDiGetClassDevsA(
1401 LPWSTR enumstrW
= NULL
;
1405 int len
= MultiByteToWideChar(CP_ACP
, 0, enumstr
, -1, NULL
, 0);
1406 enumstrW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1409 ret
= (HDEVINFO
)INVALID_HANDLE_VALUE
;
1412 MultiByteToWideChar(CP_ACP
, 0, enumstr
, -1, enumstrW
, len
);
1414 ret
= SetupDiGetClassDevsW(class, enumstrW
, parent
, flags
);
1415 HeapFree(GetProcessHeap(), 0, enumstrW
);
1421 /***********************************************************************
1422 * SetupDiGetClassDevsW (SETUPAPI.@)
1424 HDEVINFO WINAPI
SetupDiGetClassDevsW(
1430 TRACE("%s %s %p 0x%08x\n", debugstr_guid(class), debugstr_w(enumstr
), parent
, flags
);
1432 /* WinXP always succeeds, returns empty list for unknown classes */
1433 FIXME("returning empty list\n");
1434 return SetupDiCreateDeviceInfoList(class, parent
);
1437 /***********************************************************************
1438 * SetupDiGetClassDevsExW (SETUPAPI.@)
1440 HDEVINFO WINAPI
SetupDiGetClassDevsExW(
1453 /***********************************************************************
1454 * SetupDiEnumDeviceInterfaces (SETUPAPI.@)
1456 BOOL WINAPI
SetupDiEnumDeviceInterfaces(
1458 PSP_DEVINFO_DATA DeviceInfoData
,
1459 CONST GUID
* InterfaceClassGuid
,
1461 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
)
1465 FIXME("%p, %p, %s, 0x%08x, %p\n", devinfo
, DeviceInfoData
,
1466 debugstr_guid(InterfaceClassGuid
), MemberIndex
, DeviceInterfaceData
);
1468 if (devinfo
&& devinfo
!= (HDEVINFO
)INVALID_HANDLE_VALUE
)
1470 struct DeviceInfoSet
*list
= (struct DeviceInfoSet
*)devinfo
;
1471 if (list
->magic
== SETUP_DEVICE_INFO_SET_MAGIC
)
1472 SetLastError(ERROR_NO_MORE_ITEMS
);
1474 SetLastError(ERROR_INVALID_HANDLE
);
1477 SetLastError(ERROR_INVALID_HANDLE
);
1481 /***********************************************************************
1482 * SetupDiDestroyDeviceInfoList (SETUPAPI.@)
1484 * Destroy a DeviceInfoList and free all used memory of the list.
1487 * devinfo [I] DeviceInfoList pointer to list to destroy
1490 * Success: non zero value.
1491 * Failure: zero value.
1493 BOOL WINAPI
SetupDiDestroyDeviceInfoList(HDEVINFO devinfo
)
1497 TRACE("%p\n", devinfo
);
1498 if (devinfo
&& devinfo
!= (HDEVINFO
)INVALID_HANDLE_VALUE
)
1500 struct DeviceInfoSet
*list
= (struct DeviceInfoSet
*)devinfo
;
1502 if (list
->magic
== SETUP_DEVICE_INFO_SET_MAGIC
)
1506 for (i
= 0; i
< list
->cDevices
; i
++)
1507 SETUPDI_FreeDeviceInfo(
1508 (struct DeviceInfo
*)list
->devices
[i
].Reserved
);
1509 HeapFree(GetProcessHeap(), 0, list
->devices
);
1510 HeapFree(GetProcessHeap(), 0, list
);
1516 SetLastError(ERROR_INVALID_HANDLE
);
1521 /***********************************************************************
1522 * SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@)
1524 BOOL WINAPI
SetupDiGetDeviceInterfaceDetailA(
1525 HDEVINFO DeviceInfoSet
,
1526 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
,
1527 PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData
,
1528 DWORD DeviceInterfaceDetailDataSize
,
1529 PDWORD RequiredSize
,
1530 PSP_DEVINFO_DATA DeviceInfoData
)
1534 FIXME("(%p, %p, %p, %d, %p, %p)\n", DeviceInfoSet
,
1535 DeviceInterfaceData
, DeviceInterfaceDetailData
,
1536 DeviceInterfaceDetailDataSize
, RequiredSize
, DeviceInfoData
);
1538 SetLastError(ERROR_INVALID_HANDLE
);
1542 /***********************************************************************
1543 * SetupDiGetDeviceInterfaceDetailW (SETUPAPI.@)
1545 BOOL WINAPI
SetupDiGetDeviceInterfaceDetailW(
1546 HDEVINFO DeviceInfoSet
,
1547 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
,
1548 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData
,
1549 DWORD DeviceInterfaceDetailDataSize
,
1550 PDWORD RequiredSize
,
1551 PSP_DEVINFO_DATA DeviceInfoData
)
1553 FIXME("(%p, %p, %p, %d, %p, %p): stub\n", DeviceInfoSet
,
1554 DeviceInterfaceData
, DeviceInterfaceDetailData
,
1555 DeviceInterfaceDetailDataSize
, RequiredSize
, DeviceInfoData
);
1559 struct PropertyMapEntry
1566 static struct PropertyMapEntry PropertyMap
[] = {
1567 { REG_SZ
, "DeviceDesc", DeviceDesc
},
1568 { REG_MULTI_SZ
, "HardwareId", HardwareId
},
1569 { REG_MULTI_SZ
, "CompatibleIDs", CompatibleIDs
},
1570 { 0, NULL
, NULL
}, /* SPDRP_UNUSED0 */
1571 { REG_SZ
, "Service", Service
},
1572 { 0, NULL
, NULL
}, /* SPDRP_UNUSED1 */
1573 { 0, NULL
, NULL
}, /* SPDRP_UNUSED2 */
1574 { REG_SZ
, "Class", Class
},
1575 { REG_SZ
, "ClassGUID", ClassGUID
},
1576 { REG_SZ
, "Driver", Driver
},
1577 { REG_DWORD
, "ConfigFlags", ConfigFlags
},
1578 { REG_SZ
, "Mfg", Mfg
},
1579 { REG_SZ
, "FriendlyName", FriendlyName
},
1580 { REG_SZ
, "LocationInformation", LocationInformation
},
1581 { 0, NULL
, NULL
}, /* SPDRP_PHYSICAL_DEVICE_OBJECT_NAME */
1582 { REG_DWORD
, "Capabilities", Capabilities
},
1583 { REG_DWORD
, "UINumber", UINumber
},
1584 { REG_MULTI_SZ
, "UpperFilters", UpperFilters
},
1585 { REG_MULTI_SZ
, "LowerFilters", LowerFilters
},
1588 /***********************************************************************
1589 * SetupDiGetDeviceRegistryPropertyA (SETUPAPI.@)
1591 BOOL WINAPI
SetupDiGetDeviceRegistryPropertyA(
1592 HDEVINFO DeviceInfoSet
,
1593 PSP_DEVINFO_DATA DeviceInfoData
,
1595 PDWORD PropertyRegDataType
,
1596 PBYTE PropertyBuffer
,
1597 DWORD PropertyBufferSize
,
1598 PDWORD RequiredSize
)
1601 struct DeviceInfoSet
*set
= (struct DeviceInfoSet
*)DeviceInfoSet
;
1602 struct DeviceInfo
*devInfo
;
1604 TRACE("%04x %p %d %p %p %d %p\n", (DWORD
)DeviceInfoSet
, DeviceInfoData
,
1605 Property
, PropertyRegDataType
, PropertyBuffer
, PropertyBufferSize
,
1608 if (!DeviceInfoSet
|| DeviceInfoSet
== INVALID_HANDLE_VALUE
)
1610 SetLastError(ERROR_INVALID_HANDLE
);
1613 if (set
->magic
!= SETUP_DEVICE_INFO_SET_MAGIC
)
1615 SetLastError(ERROR_INVALID_HANDLE
);
1618 if (!DeviceInfoData
|| DeviceInfoData
->cbSize
!= sizeof(SP_DEVINFO_DATA
)
1619 || !DeviceInfoData
->Reserved
)
1621 SetLastError(ERROR_INVALID_PARAMETER
);
1624 devInfo
= (struct DeviceInfo
*)DeviceInfoData
->Reserved
;
1625 if (Property
< sizeof(PropertyMap
) / sizeof(PropertyMap
[0])
1626 && PropertyMap
[Property
].nameA
)
1628 DWORD size
= PropertyBufferSize
;
1629 LONG l
= RegQueryValueExA(devInfo
->key
, PropertyMap
[Property
].nameA
,
1630 NULL
, PropertyRegDataType
, PropertyBuffer
, &size
);
1633 *RequiredSize
= size
;
1642 /***********************************************************************
1643 * SetupDiGetDeviceRegistryPropertyW (SETUPAPI.@)
1645 BOOL WINAPI
SetupDiGetDeviceRegistryPropertyW(
1646 HDEVINFO DeviceInfoSet
,
1647 PSP_DEVINFO_DATA DeviceInfoData
,
1649 PDWORD PropertyRegDataType
,
1650 PBYTE PropertyBuffer
,
1651 DWORD PropertyBufferSize
,
1652 PDWORD RequiredSize
)
1655 struct DeviceInfoSet
*set
= (struct DeviceInfoSet
*)DeviceInfoSet
;
1656 struct DeviceInfo
*devInfo
;
1658 TRACE("%04x %p %d %p %p %d %p\n", (DWORD
)DeviceInfoSet
, DeviceInfoData
,
1659 Property
, PropertyRegDataType
, PropertyBuffer
, PropertyBufferSize
,
1662 if (!DeviceInfoSet
|| DeviceInfoSet
== INVALID_HANDLE_VALUE
)
1664 SetLastError(ERROR_INVALID_HANDLE
);
1667 if (set
->magic
!= SETUP_DEVICE_INFO_SET_MAGIC
)
1669 SetLastError(ERROR_INVALID_HANDLE
);
1672 if (!DeviceInfoData
|| DeviceInfoData
->cbSize
!= sizeof(SP_DEVINFO_DATA
)
1673 || !DeviceInfoData
->Reserved
)
1675 SetLastError(ERROR_INVALID_PARAMETER
);
1678 devInfo
= (struct DeviceInfo
*)DeviceInfoData
->Reserved
;
1679 if (Property
< sizeof(PropertyMap
) / sizeof(PropertyMap
[0])
1680 && PropertyMap
[Property
].nameW
)
1682 DWORD size
= PropertyBufferSize
;
1683 LONG l
= RegQueryValueExW(devInfo
->key
, PropertyMap
[Property
].nameW
,
1684 NULL
, PropertyRegDataType
, PropertyBuffer
, &size
);
1687 *RequiredSize
= size
;
1696 /***********************************************************************
1697 * SetupDiSetDeviceRegistryPropertyA (SETUPAPI.@)
1699 BOOL WINAPI
SetupDiSetDeviceRegistryPropertyA(
1700 HDEVINFO DeviceInfoSet
,
1701 PSP_DEVINFO_DATA DeviceInfoData
,
1703 const BYTE
*PropertyBuffer
,
1704 DWORD PropertyBufferSize
)
1707 struct DeviceInfoSet
*set
= (struct DeviceInfoSet
*)DeviceInfoSet
;
1708 struct DeviceInfo
*devInfo
;
1710 TRACE("%p %p %d %p %d\n", DeviceInfoSet
, DeviceInfoData
, Property
,
1711 PropertyBuffer
, PropertyBufferSize
);
1713 if (!DeviceInfoSet
|| DeviceInfoSet
== INVALID_HANDLE_VALUE
)
1715 SetLastError(ERROR_INVALID_HANDLE
);
1718 if (set
->magic
!= SETUP_DEVICE_INFO_SET_MAGIC
)
1720 SetLastError(ERROR_INVALID_HANDLE
);
1723 if (!DeviceInfoData
|| DeviceInfoData
->cbSize
!= sizeof(SP_DEVINFO_DATA
)
1724 || !DeviceInfoData
->Reserved
)
1726 SetLastError(ERROR_INVALID_PARAMETER
);
1729 devInfo
= (struct DeviceInfo
*)DeviceInfoData
->Reserved
;
1730 if (Property
< sizeof(PropertyMap
) / sizeof(PropertyMap
[0])
1731 && PropertyMap
[Property
].nameA
)
1733 LONG l
= RegSetValueExA(devInfo
->key
, PropertyMap
[Property
].nameA
, 0,
1734 PropertyMap
[Property
].regType
, PropertyBuffer
,
1735 PropertyBufferSize
);
1744 /***********************************************************************
1745 * SetupDiSetDeviceRegistryPropertyW (SETUPAPI.@)
1747 BOOL WINAPI
SetupDiSetDeviceRegistryPropertyW(
1748 HDEVINFO DeviceInfoSet
,
1749 PSP_DEVINFO_DATA DeviceInfoData
,
1751 const BYTE
*PropertyBuffer
,
1752 DWORD PropertyBufferSize
)
1755 struct DeviceInfoSet
*set
= (struct DeviceInfoSet
*)DeviceInfoSet
;
1756 struct DeviceInfo
*devInfo
;
1758 TRACE("%p %p %d %p %d\n", DeviceInfoSet
, DeviceInfoData
, Property
,
1759 PropertyBuffer
, PropertyBufferSize
);
1761 if (!DeviceInfoSet
|| DeviceInfoSet
== INVALID_HANDLE_VALUE
)
1763 SetLastError(ERROR_INVALID_HANDLE
);
1766 if (set
->magic
!= SETUP_DEVICE_INFO_SET_MAGIC
)
1768 SetLastError(ERROR_INVALID_HANDLE
);
1771 if (!DeviceInfoData
|| DeviceInfoData
->cbSize
!= sizeof(SP_DEVINFO_DATA
)
1772 || !DeviceInfoData
->Reserved
)
1774 SetLastError(ERROR_INVALID_PARAMETER
);
1777 devInfo
= (struct DeviceInfo
*)DeviceInfoData
->Reserved
;
1778 if (Property
< sizeof(PropertyMap
) / sizeof(PropertyMap
[0])
1779 && PropertyMap
[Property
].nameW
)
1781 LONG l
= RegSetValueExW(devInfo
->key
, PropertyMap
[Property
].nameW
, 0,
1782 PropertyMap
[Property
].regType
, PropertyBuffer
,
1783 PropertyBufferSize
);
1792 /***********************************************************************
1793 * SetupDiInstallClassA (SETUPAPI.@)
1795 BOOL WINAPI
SetupDiInstallClassA(
1801 UNICODE_STRING FileNameW
;
1804 if (!RtlCreateUnicodeStringFromAsciiz(&FileNameW
, InfFileName
))
1806 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1810 Result
= SetupDiInstallClassW(hwndParent
, FileNameW
.Buffer
, Flags
, FileQueue
);
1812 RtlFreeUnicodeString(&FileNameW
);
1817 static HKEY
CreateClassKey(HINF hInf
)
1819 WCHAR FullBuffer
[MAX_PATH
];
1820 WCHAR Buffer
[MAX_PATH
];
1824 if (!SetupGetLineTextW(NULL
,
1832 return INVALID_HANDLE_VALUE
;
1835 lstrcpyW(FullBuffer
, ControlClass
);
1836 lstrcatW(FullBuffer
, Buffer
);
1838 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1844 if (!SetupGetLineTextW(NULL
,
1852 return INVALID_HANDLE_VALUE
;
1855 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
1859 REG_OPTION_NON_VOLATILE
,
1865 return INVALID_HANDLE_VALUE
;
1870 if (RegSetValueExW(hClassKey
,
1875 RequiredSize
* sizeof(WCHAR
)))
1877 RegCloseKey(hClassKey
);
1878 RegDeleteKeyW(HKEY_LOCAL_MACHINE
,
1880 return INVALID_HANDLE_VALUE
;
1886 /***********************************************************************
1887 * SetupDiInstallClassW (SETUPAPI.@)
1889 BOOL WINAPI
SetupDiInstallClassW(
1895 WCHAR SectionName
[MAX_PATH
];
1896 DWORD SectionNameLength
= 0;
1898 BOOL bFileQueueCreated
= FALSE
;
1904 if ((Flags
& DI_NOVCP
) && (FileQueue
== NULL
|| FileQueue
== INVALID_HANDLE_VALUE
))
1906 SetLastError(ERROR_INVALID_PARAMETER
);
1910 /* Open the .inf file */
1911 hInf
= SetupOpenInfFileW(InfFileName
,
1915 if (hInf
== INVALID_HANDLE_VALUE
)
1921 /* Create or open the class registry key 'HKLM\\CurrentControlSet\\Class\\{GUID}' */
1922 hClassKey
= CreateClassKey(hInf
);
1923 if (hClassKey
== INVALID_HANDLE_VALUE
)
1925 SetupCloseInfFile(hInf
);
1930 /* Try to append a layout file */
1932 SetupOpenAppendInfFileW(NULL
, hInf
, NULL
);
1935 /* Retrieve the actual section name */
1936 SetupDiGetActualSectionToInstallW(hInf
,
1944 if (!(Flags
& DI_NOVCP
))
1946 FileQueue
= SetupOpenFileQueue();
1947 if (FileQueue
== INVALID_HANDLE_VALUE
)
1949 SetupCloseInfFile(hInf
);
1953 bFileQueueCreated
= TRUE
;
1958 SetupInstallFromInfSectionW(NULL
,
1967 INVALID_HANDLE_VALUE
,
1970 /* FIXME: More code! */
1972 if (bFileQueueCreated
)
1973 SetupCloseFileQueue(FileQueue
);
1975 SetupCloseInfFile(hInf
);
1981 /***********************************************************************
1982 * SetupDiOpenClassRegKey (SETUPAPI.@)
1984 HKEY WINAPI
SetupDiOpenClassRegKey(
1985 const GUID
* ClassGuid
,
1988 return SetupDiOpenClassRegKeyExW(ClassGuid
, samDesired
,
1989 DIOCR_INSTALLER
, NULL
, NULL
);
1993 /***********************************************************************
1994 * SetupDiOpenClassRegKeyExA (SETUPAPI.@)
1996 HKEY WINAPI
SetupDiOpenClassRegKeyExA(
1997 const GUID
* ClassGuid
,
2003 PWSTR MachineNameW
= NULL
;
2010 MachineNameW
= MultiByteToUnicode(MachineName
, CP_ACP
);
2011 if (MachineNameW
== NULL
)
2012 return INVALID_HANDLE_VALUE
;
2015 hKey
= SetupDiOpenClassRegKeyExW(ClassGuid
, samDesired
,
2016 Flags
, MachineNameW
, Reserved
);
2018 MyFree(MachineNameW
);
2024 /***********************************************************************
2025 * SetupDiOpenClassRegKeyExW (SETUPAPI.@)
2027 HKEY WINAPI
SetupDiOpenClassRegKeyExW(
2028 const GUID
* ClassGuid
,
2034 WCHAR bracedGuidString
[39];
2039 if (MachineName
!= NULL
)
2041 FIXME("Remote access not supported yet!\n");
2042 return INVALID_HANDLE_VALUE
;
2045 if (Flags
== DIOCR_INSTALLER
)
2047 lpKeyName
= ControlClass
;
2049 else if (Flags
== DIOCR_INTERFACE
)
2051 lpKeyName
= DeviceClasses
;
2055 ERR("Invalid Flags parameter!\n");
2056 SetLastError(ERROR_INVALID_PARAMETER
);
2057 return INVALID_HANDLE_VALUE
;
2060 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2066 return INVALID_HANDLE_VALUE
;
2069 if (ClassGuid
== NULL
)
2072 SETUPDI_GuidToString(ClassGuid
, bracedGuidString
);
2074 if (RegOpenKeyExW(hClassesKey
,
2080 RegCloseKey(hClassesKey
);
2081 return INVALID_HANDLE_VALUE
;
2084 RegCloseKey(hClassesKey
);
2089 /***********************************************************************
2090 * SetupDiOpenDeviceInterfaceW (SETUPAPI.@)
2092 BOOL WINAPI
SetupDiOpenDeviceInterfaceW(
2093 HDEVINFO DeviceInfoSet
,
2096 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
)
2098 FIXME("%p %s %08x %p\n",
2099 DeviceInfoSet
, debugstr_w(DevicePath
), OpenFlags
, DeviceInterfaceData
);
2103 /***********************************************************************
2104 * SetupDiOpenDeviceInterfaceA (SETUPAPI.@)
2106 BOOL WINAPI
SetupDiOpenDeviceInterfaceA(
2107 HDEVINFO DeviceInfoSet
,
2110 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
)
2112 FIXME("%p %s %08x %p\n", DeviceInfoSet
,
2113 debugstr_a(DevicePath
), OpenFlags
, DeviceInterfaceData
);
2117 /***********************************************************************
2118 * SetupDiSetClassInstallParamsA (SETUPAPI.@)
2120 BOOL WINAPI
SetupDiSetClassInstallParamsA(
2121 HDEVINFO DeviceInfoSet
,
2122 PSP_DEVINFO_DATA DeviceInfoData
,
2123 PSP_CLASSINSTALL_HEADER ClassInstallParams
,
2124 DWORD ClassInstallParamsSize
)
2126 FIXME("%p %p %x %u\n",DeviceInfoSet
, DeviceInfoData
,
2127 ClassInstallParams
->InstallFunction
, ClassInstallParamsSize
);
2131 /***********************************************************************
2132 * SetupDiCallClassInstaller (SETUPAPI.@)
2134 BOOL WINAPI
SetupDiCallClassInstaller(
2135 DI_FUNCTION InstallFunction
,
2136 HDEVINFO DeviceInfoSet
,
2137 PSP_DEVINFO_DATA DeviceInfoData
)
2139 FIXME("%d %p %p\n", InstallFunction
, DeviceInfoSet
, DeviceInfoData
);
2143 /***********************************************************************
2144 * SetupDiGetDeviceInstallParamsA (SETUPAPI.@)
2146 BOOL WINAPI
SetupDiGetDeviceInstallParamsA(
2147 HDEVINFO DeviceInfoSet
,
2148 PSP_DEVINFO_DATA DeviceInfoData
,
2149 PSP_DEVINSTALL_PARAMS_A DeviceInstallParams
)
2151 FIXME("%p %p %p\n", DeviceInfoSet
, DeviceInfoData
, DeviceInstallParams
);
2155 /***********************************************************************
2156 * SetupDiOpenDevRegKey (SETUPAPI.@)
2158 HKEY WINAPI
SetupDiOpenDevRegKey(
2159 HDEVINFO DeviceInfoSet
,
2160 PSP_DEVINFO_DATA DeviceInfoData
,
2166 FIXME("%p %p %d %d %d %x\n", DeviceInfoSet
, DeviceInfoData
,
2167 Scope
, HwProfile
, KeyType
, samDesired
);
2168 return INVALID_HANDLE_VALUE
;