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','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};
71 /* is used to identify if a DeviceInfoSet pointer is
73 #define SETUP_DEVICE_INFO_SET_MAGIC 0xd00ff056
77 DWORD magic
; /* if is equal to SETUP_DEVICE_INFO_SET_MAGIC struct is okay */
82 /***********************************************************************
83 * SetupDiBuildClassInfoList (SETUPAPI.@)
85 * Returns a list of setup class GUIDs that identify the classes
86 * that are installed on a local machine.
89 * Flags [I] control exclusion of classes from the list.
90 * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
91 * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
92 * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
98 BOOL WINAPI
SetupDiBuildClassInfoList(
100 LPGUID ClassGuidList
,
101 DWORD ClassGuidListSize
,
105 return SetupDiBuildClassInfoListExW(Flags
, ClassGuidList
,
106 ClassGuidListSize
, RequiredSize
,
110 /***********************************************************************
111 * SetupDiBuildClassInfoListExA (SETUPAPI.@)
113 * Returns a list of setup class GUIDs that identify the classes
114 * that are installed on a local or remote macine.
117 * Flags [I] control exclusion of classes from the list.
118 * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
119 * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
120 * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
121 * MachineName [I] name of a remote machine.
122 * Reserved [I] must be NULL.
128 BOOL WINAPI
SetupDiBuildClassInfoListExA(
130 LPGUID ClassGuidList
,
131 DWORD ClassGuidListSize
,
136 LPWSTR MachineNameW
= NULL
;
143 MachineNameW
= MultiByteToUnicode(MachineName
, CP_ACP
);
144 if (MachineNameW
== NULL
) return FALSE
;
147 bResult
= SetupDiBuildClassInfoListExW(Flags
, ClassGuidList
,
148 ClassGuidListSize
, RequiredSize
,
149 MachineNameW
, Reserved
);
151 MyFree(MachineNameW
);
156 /***********************************************************************
157 * SetupDiBuildClassInfoListExW (SETUPAPI.@)
159 * Returns a list of setup class GUIDs that identify the classes
160 * that are installed on a local or remote macine.
163 * Flags [I] control exclusion of classes from the list.
164 * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
165 * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
166 * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
167 * MachineName [I] name of a remote machine.
168 * Reserved [I] must be NULL.
174 BOOL WINAPI
SetupDiBuildClassInfoListExW(
176 LPGUID ClassGuidList
,
177 DWORD ClassGuidListSize
,
188 DWORD dwGuidListIndex
= 0;
192 if (RequiredSize
!= NULL
)
195 hClassesKey
= SetupDiOpenClassRegKeyExW(NULL
,
200 if (hClassesKey
== INVALID_HANDLE_VALUE
)
205 for (dwIndex
= 0; ; dwIndex
++)
208 lError
= RegEnumKeyExW(hClassesKey
,
216 TRACE("RegEnumKeyExW() returns %d\n", lError
);
217 if (lError
== ERROR_SUCCESS
|| lError
== ERROR_MORE_DATA
)
219 TRACE("Key name: %p\n", szKeyName
);
221 if (RegOpenKeyExW(hClassesKey
,
227 RegCloseKey(hClassesKey
);
231 if (!RegQueryValueExW(hClassKey
,
238 TRACE("'NoUseClass' value found!\n");
239 RegCloseKey(hClassKey
);
243 if ((Flags
& DIBCI_NOINSTALLCLASS
) &&
244 (!RegQueryValueExW(hClassKey
,
251 TRACE("'NoInstallClass' value found!\n");
252 RegCloseKey(hClassKey
);
256 if ((Flags
& DIBCI_NODISPLAYCLASS
) &&
257 (!RegQueryValueExW(hClassKey
,
264 TRACE("'NoDisplayClass' value found!\n");
265 RegCloseKey(hClassKey
);
269 RegCloseKey(hClassKey
);
271 TRACE("Guid: %p\n", szKeyName
);
272 if (dwGuidListIndex
< ClassGuidListSize
)
274 if (szKeyName
[0] == L
'{' && szKeyName
[37] == L
'}')
278 TRACE("Guid: %p\n", &szKeyName
[1]);
280 UuidFromStringW(&szKeyName
[1],
281 &ClassGuidList
[dwGuidListIndex
]);
287 if (lError
!= ERROR_SUCCESS
)
291 RegCloseKey(hClassesKey
);
293 if (RequiredSize
!= NULL
)
294 *RequiredSize
= dwGuidListIndex
;
296 if (ClassGuidListSize
< dwGuidListIndex
)
298 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
305 /***********************************************************************
306 * SetupDiClassGuidsFromNameA (SETUPAPI.@)
308 BOOL WINAPI
SetupDiClassGuidsFromNameA(
310 LPGUID ClassGuidList
,
311 DWORD ClassGuidListSize
,
314 return SetupDiClassGuidsFromNameExA(ClassName
, ClassGuidList
,
315 ClassGuidListSize
, RequiredSize
,
319 /***********************************************************************
320 * SetupDiClassGuidsFromNameW (SETUPAPI.@)
322 BOOL WINAPI
SetupDiClassGuidsFromNameW(
324 LPGUID ClassGuidList
,
325 DWORD ClassGuidListSize
,
328 return SetupDiClassGuidsFromNameExW(ClassName
, ClassGuidList
,
329 ClassGuidListSize
, RequiredSize
,
333 /***********************************************************************
334 * SetupDiClassGuidsFromNameExA (SETUPAPI.@)
336 BOOL WINAPI
SetupDiClassGuidsFromNameExA(
338 LPGUID ClassGuidList
,
339 DWORD ClassGuidListSize
,
344 LPWSTR ClassNameW
= NULL
;
345 LPWSTR MachineNameW
= NULL
;
350 ClassNameW
= MultiByteToUnicode(ClassName
, CP_ACP
);
351 if (ClassNameW
== NULL
)
356 MachineNameW
= MultiByteToUnicode(MachineName
, CP_ACP
);
357 if (MachineNameW
== NULL
)
364 bResult
= SetupDiClassGuidsFromNameExW(ClassNameW
, ClassGuidList
,
365 ClassGuidListSize
, RequiredSize
,
366 MachineNameW
, Reserved
);
368 MyFree(MachineNameW
);
374 /***********************************************************************
375 * SetupDiClassGuidsFromNameExW (SETUPAPI.@)
377 BOOL WINAPI
SetupDiClassGuidsFromNameExW(
379 LPGUID ClassGuidList
,
380 DWORD ClassGuidListSize
,
386 WCHAR szClassName
[256];
392 DWORD dwGuidListIndex
= 0;
394 if (RequiredSize
!= NULL
)
397 hClassesKey
= SetupDiOpenClassRegKeyExW(NULL
,
402 if (hClassesKey
== INVALID_HANDLE_VALUE
)
407 for (dwIndex
= 0; ; dwIndex
++)
410 lError
= RegEnumKeyExW(hClassesKey
,
418 TRACE("RegEnumKeyExW() returns %d\n", lError
);
419 if (lError
== ERROR_SUCCESS
|| lError
== ERROR_MORE_DATA
)
421 TRACE("Key name: %p\n", szKeyName
);
423 if (RegOpenKeyExW(hClassesKey
,
429 RegCloseKey(hClassesKey
);
433 dwLength
= 256 * sizeof(WCHAR
);
434 if (!RegQueryValueExW(hClassKey
,
441 TRACE("Class name: %p\n", szClassName
);
443 if (strcmpiW(szClassName
, ClassName
) == 0)
445 TRACE("Found matching class name\n");
447 TRACE("Guid: %p\n", szKeyName
);
448 if (dwGuidListIndex
< ClassGuidListSize
)
450 if (szKeyName
[0] == L
'{' && szKeyName
[37] == L
'}')
454 TRACE("Guid: %p\n", &szKeyName
[1]);
456 UuidFromStringW(&szKeyName
[1],
457 &ClassGuidList
[dwGuidListIndex
]);
464 RegCloseKey(hClassKey
);
467 if (lError
!= ERROR_SUCCESS
)
471 RegCloseKey(hClassesKey
);
473 if (RequiredSize
!= NULL
)
474 *RequiredSize
= dwGuidListIndex
;
476 if (ClassGuidListSize
< dwGuidListIndex
)
478 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
485 /***********************************************************************
486 * SetupDiClassNameFromGuidA (SETUPAPI.@)
488 BOOL WINAPI
SetupDiClassNameFromGuidA(
489 const GUID
* ClassGuid
,
494 return SetupDiClassNameFromGuidExA(ClassGuid
, ClassName
,
495 ClassNameSize
, RequiredSize
,
499 /***********************************************************************
500 * SetupDiClassNameFromGuidW (SETUPAPI.@)
502 BOOL WINAPI
SetupDiClassNameFromGuidW(
503 const GUID
* ClassGuid
,
508 return SetupDiClassNameFromGuidExW(ClassGuid
, ClassName
,
509 ClassNameSize
, RequiredSize
,
513 /***********************************************************************
514 * SetupDiClassNameFromGuidExA (SETUPAPI.@)
516 BOOL WINAPI
SetupDiClassNameFromGuidExA(
517 const GUID
* ClassGuid
,
524 WCHAR ClassNameW
[MAX_CLASS_NAME_LEN
];
525 LPWSTR MachineNameW
= NULL
;
529 MachineNameW
= MultiByteToUnicode(MachineName
, CP_ACP
);
530 ret
= SetupDiClassNameFromGuidExW(ClassGuid
, ClassNameW
, MAX_CLASS_NAME_LEN
,
531 NULL
, MachineNameW
, Reserved
);
534 int len
= WideCharToMultiByte(CP_ACP
, 0, ClassNameW
, -1, ClassName
,
535 ClassNameSize
, NULL
, NULL
);
537 if (!ClassNameSize
&& RequiredSize
)
540 MyFree(MachineNameW
);
544 /***********************************************************************
545 * SetupDiClassNameFromGuidExW (SETUPAPI.@)
547 BOOL WINAPI
SetupDiClassNameFromGuidExW(
548 const GUID
* ClassGuid
,
558 hKey
= SetupDiOpenClassRegKeyExW(ClassGuid
,
563 if (hKey
== INVALID_HANDLE_VALUE
)
568 if (RequiredSize
!= NULL
)
571 if (RegQueryValueExW(hKey
,
582 *RequiredSize
= dwLength
/ sizeof(WCHAR
);
585 dwLength
= ClassNameSize
* sizeof(WCHAR
);
586 if (RegQueryValueExW(hKey
,
602 /***********************************************************************
603 * SetupDiCreateDeviceInfoList (SETUPAPI.@)
606 SetupDiCreateDeviceInfoList(const GUID
*ClassGuid
,
609 return SetupDiCreateDeviceInfoListExW(ClassGuid
, hwndParent
, NULL
, NULL
);
612 /***********************************************************************
613 * SetupDiCreateDeviceInfoListExA (SETUPAPI.@)
616 SetupDiCreateDeviceInfoListExA(const GUID
*ClassGuid
,
621 LPWSTR MachineNameW
= NULL
;
628 MachineNameW
= MultiByteToUnicode(MachineName
, CP_ACP
);
629 if (MachineNameW
== NULL
)
630 return (HDEVINFO
)INVALID_HANDLE_VALUE
;
633 hDevInfo
= SetupDiCreateDeviceInfoListExW(ClassGuid
, hwndParent
,
634 MachineNameW
, Reserved
);
636 MyFree(MachineNameW
);
641 /***********************************************************************
642 * SetupDiCreateDeviceInfoListExW (SETUPAPI.@)
644 * Create an empty DeviceInfoSet list.
647 * ClassGuid [I] if not NULL only devices with GUID ClcassGuid are associated
649 * hwndParent [I] hwnd needed for interface related actions.
650 * MachineName [I] name of machine to create emtpy DeviceInfoSet list, if NULL
651 * local registry will be used.
652 * Reserved [I] must be NULL
655 * Success: empty list.
656 * Failure: INVALID_HANDLE_VALUE.
659 SetupDiCreateDeviceInfoListExW(const GUID
*ClassGuid
,
664 struct DeviceInfoSet
*list
= NULL
;
665 DWORD size
= sizeof(struct DeviceInfoSet
);
667 TRACE("%s %p %s %p\n", debugstr_guid(ClassGuid
), hwndParent
,
668 debugstr_w(MachineName
), Reserved
);
670 if (MachineName
!= NULL
)
672 FIXME("remote support is not implemented\n");
673 SetLastError(ERROR_INVALID_MACHINENAME
);
674 return (HDEVINFO
)INVALID_HANDLE_VALUE
;
677 if (Reserved
!= NULL
)
679 SetLastError(ERROR_INVALID_PARAMETER
);
680 return (HDEVINFO
)INVALID_HANDLE_VALUE
;
683 list
= HeapAlloc(GetProcessHeap(), 0, size
);
686 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
687 return (HDEVINFO
)INVALID_HANDLE_VALUE
;
690 list
->magic
= SETUP_DEVICE_INFO_SET_MAGIC
;
691 list
->hwndParent
= hwndParent
;
692 memcpy(&list
->ClassGuid
,
693 ClassGuid
? ClassGuid
: &GUID_NULL
,
694 sizeof(list
->ClassGuid
));
696 return (HDEVINFO
)list
;
699 /***********************************************************************
700 * SetupDiCreateDeviceInfoA (SETUPAPI.@)
702 BOOL WINAPI
SetupDiCreateDeviceInfoA(
703 HDEVINFO DeviceInfoSet
,
705 CONST GUID
*ClassGuid
,
706 PCSTR DeviceDescription
,
709 PSP_DEVINFO_DATA DeviceInfoData
)
712 LPWSTR DeviceNameW
= NULL
;
713 LPWSTR DeviceDescriptionW
= NULL
;
717 DeviceNameW
= MultiByteToUnicode(DeviceName
, CP_ACP
);
718 if (DeviceNameW
== NULL
) return FALSE
;
720 if (DeviceDescription
)
722 DeviceDescriptionW
= MultiByteToUnicode(DeviceDescription
, CP_ACP
);
723 if (DeviceDescriptionW
== NULL
)
730 ret
= SetupDiCreateDeviceInfoW(DeviceInfoSet
, DeviceNameW
, ClassGuid
, DeviceDescriptionW
,
731 hwndParent
, CreationFlags
, DeviceInfoData
);
734 MyFree(DeviceDescriptionW
);
739 /***********************************************************************
740 * SetupDiCreateDeviceInfoW (SETUPAPI.@)
742 BOOL WINAPI
SetupDiCreateDeviceInfoW(
743 HDEVINFO DeviceInfoSet
,
745 CONST GUID
*ClassGuid
,
746 PCWSTR DeviceDescription
,
749 PSP_DEVINFO_DATA DeviceInfoData
)
751 TRACE("%p %s %s %s %p %x %p\n", DeviceInfoSet
, debugstr_w(DeviceName
),
752 debugstr_guid(ClassGuid
), debugstr_w(DeviceDescription
),
753 hwndParent
, CreationFlags
, DeviceInfoData
);
760 /***********************************************************************
761 * SetupDiEnumDeviceInfo (SETUPAPI.@)
763 BOOL WINAPI
SetupDiEnumDeviceInfo(
766 PSP_DEVINFO_DATA info
)
768 FIXME("%p %d %p\n", devinfo
, index
, info
);
772 if(info
->cbSize
< sizeof(*info
))
775 SetLastError(ERROR_NO_MORE_ITEMS
);
779 /***********************************************************************
780 * SetupDiGetActualSectionToInstallA (SETUPAPI.@)
782 BOOL WINAPI
SetupDiGetActualSectionToInstallA(
784 PCSTR InfSectionName
,
785 PSTR InfSectionWithExt
,
786 DWORD InfSectionWithExtSize
,
794 /***********************************************************************
795 * SetupDiGetActualSectionToInstallW (SETUPAPI.@)
797 BOOL WINAPI
SetupDiGetActualSectionToInstallW(
799 PCWSTR InfSectionName
,
800 PWSTR InfSectionWithExt
,
801 DWORD InfSectionWithExtSize
,
805 WCHAR szBuffer
[MAX_PATH
];
808 LONG lLineCount
= -1;
810 lstrcpyW(szBuffer
, InfSectionName
);
811 dwLength
= lstrlenW(szBuffer
);
813 if (OsVersionInfo
.dwPlatformId
== VER_PLATFORM_WIN32_NT
)
815 /* Test section name with '.NTx86' extension */
816 lstrcpyW(&szBuffer
[dwLength
], NtPlatformExtension
);
817 lLineCount
= SetupGetLineCountW(InfHandle
, szBuffer
);
819 if (lLineCount
== -1)
821 /* Test section name with '.NT' extension */
822 lstrcpyW(&szBuffer
[dwLength
], NtExtension
);
823 lLineCount
= SetupGetLineCountW(InfHandle
, szBuffer
);
828 /* Test section name with '.Win' extension */
829 lstrcpyW(&szBuffer
[dwLength
], WinExtension
);
830 lLineCount
= SetupGetLineCountW(InfHandle
, szBuffer
);
833 if (lLineCount
== -1)
835 /* Test section name without extension */
836 szBuffer
[dwLength
] = 0;
837 lLineCount
= SetupGetLineCountW(InfHandle
, szBuffer
);
840 if (lLineCount
== -1)
842 SetLastError(ERROR_INVALID_PARAMETER
);
846 dwFullLength
= lstrlenW(szBuffer
);
848 if (InfSectionWithExt
!= NULL
&& InfSectionWithExtSize
!= 0)
850 if (InfSectionWithExtSize
< (dwFullLength
+ 1))
852 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
856 lstrcpyW(InfSectionWithExt
, szBuffer
);
857 if (Extension
!= NULL
)
859 *Extension
= (dwLength
== dwFullLength
) ? NULL
: &InfSectionWithExt
[dwLength
];
863 if (RequiredSize
!= NULL
)
865 *RequiredSize
= dwFullLength
+ 1;
871 /***********************************************************************
872 * SetupDiGetClassDescriptionA (SETUPAPI.@)
874 BOOL WINAPI
SetupDiGetClassDescriptionA(
875 const GUID
* ClassGuid
,
876 PSTR ClassDescription
,
877 DWORD ClassDescriptionSize
,
880 return SetupDiGetClassDescriptionExA(ClassGuid
, ClassDescription
,
881 ClassDescriptionSize
,
882 RequiredSize
, NULL
, NULL
);
885 /***********************************************************************
886 * SetupDiGetClassDescriptionW (SETUPAPI.@)
888 BOOL WINAPI
SetupDiGetClassDescriptionW(
889 const GUID
* ClassGuid
,
890 PWSTR ClassDescription
,
891 DWORD ClassDescriptionSize
,
894 return SetupDiGetClassDescriptionExW(ClassGuid
, ClassDescription
,
895 ClassDescriptionSize
,
896 RequiredSize
, NULL
, NULL
);
899 /***********************************************************************
900 * SetupDiGetClassDescriptionExA (SETUPAPI.@)
902 BOOL WINAPI
SetupDiGetClassDescriptionExA(
903 const GUID
* ClassGuid
,
904 PSTR ClassDescription
,
905 DWORD ClassDescriptionSize
,
914 /***********************************************************************
915 * SetupDiGetClassDescriptionExW (SETUPAPI.@)
917 BOOL WINAPI
SetupDiGetClassDescriptionExW(
918 const GUID
* ClassGuid
,
919 PWSTR ClassDescription
,
920 DWORD ClassDescriptionSize
,
928 hKey
= SetupDiOpenClassRegKeyExW(ClassGuid
,
933 if (hKey
== INVALID_HANDLE_VALUE
)
935 WARN("SetupDiOpenClassRegKeyExW() failed (Error %u)\n", GetLastError());
939 if (RequiredSize
!= NULL
)
942 if (RegQueryValueExW(hKey
,
953 *RequiredSize
= dwLength
/ sizeof(WCHAR
);
956 dwLength
= ClassDescriptionSize
* sizeof(WCHAR
);
957 if (RegQueryValueExW(hKey
,
961 (LPBYTE
)ClassDescription
,
973 /***********************************************************************
974 * SetupDiGetClassDevsA (SETUPAPI.@)
976 HDEVINFO WINAPI
SetupDiGetClassDevsA(
983 LPWSTR enumstrW
= NULL
;
987 int len
= MultiByteToWideChar(CP_ACP
, 0, enumstr
, -1, NULL
, 0);
988 enumstrW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
991 ret
= (HDEVINFO
)INVALID_HANDLE_VALUE
;
994 MultiByteToWideChar(CP_ACP
, 0, enumstr
, -1, enumstrW
, len
);
996 ret
= SetupDiGetClassDevsW(class, enumstrW
, parent
, flags
);
997 HeapFree(GetProcessHeap(), 0, enumstrW
);
1003 /***********************************************************************
1004 * SetupDiGetClassDevsW (SETUPAPI.@)
1006 HDEVINFO WINAPI
SetupDiGetClassDevsW(
1012 TRACE("%s %s %p 0x%08x\n", debugstr_guid(class), debugstr_w(enumstr
), parent
, flags
);
1014 /* WinXP always succeeds, returns empty list for unknown classes */
1015 FIXME("returning empty list\n");
1016 return SetupDiCreateDeviceInfoList(class, parent
);
1019 /***********************************************************************
1020 * SetupDiGetClassDevsExW (SETUPAPI.@)
1022 HDEVINFO WINAPI
SetupDiGetClassDevsExW(
1035 /***********************************************************************
1036 * SetupDiEnumDeviceInterfaces (SETUPAPI.@)
1038 BOOL WINAPI
SetupDiEnumDeviceInterfaces(
1040 PSP_DEVINFO_DATA DeviceInfoData
,
1041 CONST GUID
* InterfaceClassGuid
,
1043 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
)
1047 FIXME("%p, %p, %s, 0x%08x, %p\n", devinfo
, DeviceInfoData
,
1048 debugstr_guid(InterfaceClassGuid
), MemberIndex
, DeviceInterfaceData
);
1050 if (devinfo
&& devinfo
!= (HDEVINFO
)INVALID_HANDLE_VALUE
)
1052 struct DeviceInfoSet
*list
= (struct DeviceInfoSet
*)devinfo
;
1053 if (list
->magic
== SETUP_DEVICE_INFO_SET_MAGIC
)
1054 SetLastError(ERROR_NO_MORE_ITEMS
);
1056 SetLastError(ERROR_INVALID_HANDLE
);
1059 SetLastError(ERROR_INVALID_HANDLE
);
1063 /***********************************************************************
1064 * SetupDiDestroyDeviceInfoList (SETUPAPI.@)
1066 * Destroy a DeviceInfoList and free all used memory of the list.
1069 * devinfo [I] DeviceInfoList pointer to list to destroy
1072 * Success: non zero value.
1073 * Failure: zero value.
1075 BOOL WINAPI
SetupDiDestroyDeviceInfoList(HDEVINFO devinfo
)
1079 TRACE("%p\n", devinfo
);
1080 if (devinfo
&& devinfo
!= (HDEVINFO
)INVALID_HANDLE_VALUE
)
1082 struct DeviceInfoSet
*list
= (struct DeviceInfoSet
*)devinfo
;
1084 if (list
->magic
== SETUP_DEVICE_INFO_SET_MAGIC
)
1086 HeapFree(GetProcessHeap(), 0, list
);
1092 SetLastError(ERROR_INVALID_HANDLE
);
1097 /***********************************************************************
1098 * SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@)
1100 BOOL WINAPI
SetupDiGetDeviceInterfaceDetailA(
1101 HDEVINFO DeviceInfoSet
,
1102 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
,
1103 PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData
,
1104 DWORD DeviceInterfaceDetailDataSize
,
1105 PDWORD RequiredSize
,
1106 PSP_DEVINFO_DATA DeviceInfoData
)
1110 FIXME("(%p, %p, %p, %d, %p, %p)\n", DeviceInfoSet
,
1111 DeviceInterfaceData
, DeviceInterfaceDetailData
,
1112 DeviceInterfaceDetailDataSize
, RequiredSize
, DeviceInfoData
);
1114 SetLastError(ERROR_INVALID_HANDLE
);
1118 /***********************************************************************
1119 * SetupDiGetDeviceInterfaceDetailW (SETUPAPI.@)
1121 BOOL WINAPI
SetupDiGetDeviceInterfaceDetailW(
1122 HDEVINFO DeviceInfoSet
,
1123 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
,
1124 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData
,
1125 DWORD DeviceInterfaceDetailDataSize
,
1126 PDWORD RequiredSize
,
1127 PSP_DEVINFO_DATA DeviceInfoData
)
1129 FIXME("(%p, %p, %p, %d, %p, %p): stub\n", DeviceInfoSet
,
1130 DeviceInterfaceData
, DeviceInterfaceDetailData
,
1131 DeviceInterfaceDetailDataSize
, RequiredSize
, DeviceInfoData
);
1135 /***********************************************************************
1136 * SetupDiGetDeviceRegistryPropertyA (SETUPAPI.@)
1138 BOOL WINAPI
SetupDiGetDeviceRegistryPropertyA(
1140 PSP_DEVINFO_DATA DeviceInfoData
,
1142 PDWORD PropertyRegDataType
,
1143 PBYTE PropertyBuffer
,
1144 DWORD PropertyBufferSize
,
1145 PDWORD RequiredSize
)
1147 FIXME("%04x %p %d %p %p %d %p\n", (DWORD
)devinfo
, DeviceInfoData
,
1148 Property
, PropertyRegDataType
, PropertyBuffer
, PropertyBufferSize
,
1153 /***********************************************************************
1154 * SetupDiInstallClassA (SETUPAPI.@)
1156 BOOL WINAPI
SetupDiInstallClassA(
1162 UNICODE_STRING FileNameW
;
1165 if (!RtlCreateUnicodeStringFromAsciiz(&FileNameW
, InfFileName
))
1167 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1171 Result
= SetupDiInstallClassW(hwndParent
, FileNameW
.Buffer
, Flags
, FileQueue
);
1173 RtlFreeUnicodeString(&FileNameW
);
1178 static HKEY
CreateClassKey(HINF hInf
)
1180 WCHAR FullBuffer
[MAX_PATH
];
1181 WCHAR Buffer
[MAX_PATH
];
1185 if (!SetupGetLineTextW(NULL
,
1193 return INVALID_HANDLE_VALUE
;
1196 lstrcpyW(FullBuffer
, ControlClass
);
1197 lstrcatW(FullBuffer
, Buffer
);
1199 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1205 if (!SetupGetLineTextW(NULL
,
1213 return INVALID_HANDLE_VALUE
;
1216 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
1220 REG_OPTION_NON_VOLATILE
,
1226 return INVALID_HANDLE_VALUE
;
1231 if (RegSetValueExW(hClassKey
,
1236 RequiredSize
* sizeof(WCHAR
)))
1238 RegCloseKey(hClassKey
);
1239 RegDeleteKeyW(HKEY_LOCAL_MACHINE
,
1241 return INVALID_HANDLE_VALUE
;
1247 /***********************************************************************
1248 * SetupDiInstallClassW (SETUPAPI.@)
1250 BOOL WINAPI
SetupDiInstallClassW(
1256 WCHAR SectionName
[MAX_PATH
];
1257 DWORD SectionNameLength
= 0;
1259 BOOL bFileQueueCreated
= FALSE
;
1265 if ((Flags
& DI_NOVCP
) && (FileQueue
== NULL
|| FileQueue
== INVALID_HANDLE_VALUE
))
1267 SetLastError(ERROR_INVALID_PARAMETER
);
1271 /* Open the .inf file */
1272 hInf
= SetupOpenInfFileW(InfFileName
,
1276 if (hInf
== INVALID_HANDLE_VALUE
)
1282 /* Create or open the class registry key 'HKLM\\CurrentControlSet\\Class\\{GUID}' */
1283 hClassKey
= CreateClassKey(hInf
);
1284 if (hClassKey
== INVALID_HANDLE_VALUE
)
1286 SetupCloseInfFile(hInf
);
1291 /* Try to append a layout file */
1293 SetupOpenAppendInfFileW(NULL
, hInf
, NULL
);
1296 /* Retrieve the actual section name */
1297 SetupDiGetActualSectionToInstallW(hInf
,
1305 if (!(Flags
& DI_NOVCP
))
1307 FileQueue
= SetupOpenFileQueue();
1308 if (FileQueue
== INVALID_HANDLE_VALUE
)
1310 SetupCloseInfFile(hInf
);
1314 bFileQueueCreated
= TRUE
;
1319 SetupInstallFromInfSectionW(NULL
,
1328 INVALID_HANDLE_VALUE
,
1331 /* FIXME: More code! */
1333 if (bFileQueueCreated
)
1334 SetupCloseFileQueue(FileQueue
);
1336 SetupCloseInfFile(hInf
);
1342 /***********************************************************************
1343 * SetupDiOpenClassRegKey (SETUPAPI.@)
1345 HKEY WINAPI
SetupDiOpenClassRegKey(
1346 const GUID
* ClassGuid
,
1349 return SetupDiOpenClassRegKeyExW(ClassGuid
, samDesired
,
1350 DIOCR_INSTALLER
, NULL
, NULL
);
1354 /***********************************************************************
1355 * SetupDiOpenClassRegKeyExA (SETUPAPI.@)
1357 HKEY WINAPI
SetupDiOpenClassRegKeyExA(
1358 const GUID
* ClassGuid
,
1364 PWSTR MachineNameW
= NULL
;
1371 MachineNameW
= MultiByteToUnicode(MachineName
, CP_ACP
);
1372 if (MachineNameW
== NULL
)
1373 return INVALID_HANDLE_VALUE
;
1376 hKey
= SetupDiOpenClassRegKeyExW(ClassGuid
, samDesired
,
1377 Flags
, MachineNameW
, Reserved
);
1379 MyFree(MachineNameW
);
1385 /***********************************************************************
1386 * SetupDiOpenClassRegKeyExW (SETUPAPI.@)
1388 HKEY WINAPI
SetupDiOpenClassRegKeyExW(
1389 const GUID
* ClassGuid
,
1395 LPWSTR lpGuidString
;
1396 WCHAR bracedGuidString
[39];
1401 if (MachineName
!= NULL
)
1403 FIXME("Remote access not supported yet!\n");
1404 return INVALID_HANDLE_VALUE
;
1407 if (Flags
== DIOCR_INSTALLER
)
1409 lpKeyName
= ControlClass
;
1411 else if (Flags
== DIOCR_INTERFACE
)
1413 lpKeyName
= DeviceClasses
;
1417 ERR("Invalid Flags parameter!\n");
1418 SetLastError(ERROR_INVALID_PARAMETER
);
1419 return INVALID_HANDLE_VALUE
;
1422 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1428 return INVALID_HANDLE_VALUE
;
1431 if (ClassGuid
== NULL
)
1434 if (UuidToStringW((UUID
*)ClassGuid
, &lpGuidString
) != RPC_S_OK
)
1436 RegCloseKey(hClassesKey
);
1437 return INVALID_HANDLE_VALUE
;
1439 bracedGuidString
[0] = '{';
1440 memcpy(&bracedGuidString
[1], lpGuidString
, 36*sizeof(WCHAR
));
1441 bracedGuidString
[37] = '}';
1442 bracedGuidString
[38] = 0;
1443 RpcStringFreeW(&lpGuidString
);
1445 if (RegOpenKeyExW(hClassesKey
,
1451 RegCloseKey(hClassesKey
);
1452 return INVALID_HANDLE_VALUE
;
1455 RegCloseKey(hClassesKey
);
1460 /***********************************************************************
1461 * SetupDiOpenDeviceInterfaceW (SETUPAPI.@)
1463 BOOL WINAPI
SetupDiOpenDeviceInterfaceW(
1464 HDEVINFO DeviceInfoSet
,
1467 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
)
1469 FIXME("%p %s %08x %p\n",
1470 DeviceInfoSet
, debugstr_w(DevicePath
), OpenFlags
, DeviceInterfaceData
);
1474 /***********************************************************************
1475 * SetupDiOpenDeviceInterfaceA (SETUPAPI.@)
1477 BOOL WINAPI
SetupDiOpenDeviceInterfaceA(
1478 HDEVINFO DeviceInfoSet
,
1481 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
)
1483 FIXME("%p %s %08x %p\n", DeviceInfoSet
,
1484 debugstr_a(DevicePath
), OpenFlags
, DeviceInterfaceData
);
1488 /***********************************************************************
1489 * SetupDiSetClassInstallParamsA (SETUPAPI.@)
1491 BOOL WINAPI
SetupDiSetClassInstallParamsA(
1492 HDEVINFO DeviceInfoSet
,
1493 PSP_DEVINFO_DATA DeviceInfoData
,
1494 PSP_CLASSINSTALL_HEADER ClassInstallParams
,
1495 DWORD ClassInstallParamsSize
)
1497 FIXME("%p %p %x %u\n",DeviceInfoSet
, DeviceInfoData
,
1498 ClassInstallParams
->InstallFunction
, ClassInstallParamsSize
);
1502 /***********************************************************************
1503 * SetupDiCallClassInstaller (SETUPAPI.@)
1505 BOOL WINAPI
SetupDiCallClassInstaller(
1506 DI_FUNCTION InstallFunction
,
1507 HDEVINFO DeviceInfoSet
,
1508 PSP_DEVINFO_DATA DeviceInfoData
)
1510 FIXME("%d %p %p\n", InstallFunction
, DeviceInfoSet
, DeviceInfoData
);
1514 /***********************************************************************
1515 * SetupDiGetDeviceInstallParamsA (SETUPAPI.@)
1517 BOOL WINAPI
SetupDiGetDeviceInstallParamsA(
1518 HDEVINFO DeviceInfoSet
,
1519 PSP_DEVINFO_DATA DeviceInfoData
,
1520 PSP_DEVINSTALL_PARAMS_A DeviceInstallParams
)
1522 FIXME("%p %p %p\n", DeviceInfoSet
, DeviceInfoData
, DeviceInstallParams
);
1526 /***********************************************************************
1527 * SetupDiOpenDevRegKey (SETUPAPI.@)
1529 HKEY WINAPI
SetupDiOpenDevRegKey(
1530 HDEVINFO DeviceInfoSet
,
1531 PSP_DEVINFO_DATA DeviceInfoData
,
1537 FIXME("%p %p %d %d %d %x\n", DeviceInfoSet
, DeviceInfoData
,
1538 Scope
, HwProfile
, KeyType
, samDesired
);
1539 return INVALID_HANDLE_VALUE
;