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 regestry 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
))
778 /***********************************************************************
779 * SetupDiGetActualSectionToInstallA (SETUPAPI.@)
781 BOOL WINAPI
SetupDiGetActualSectionToInstallA(
783 PCSTR InfSectionName
,
784 PSTR InfSectionWithExt
,
785 DWORD InfSectionWithExtSize
,
793 /***********************************************************************
794 * SetupDiGetActualSectionToInstallW (SETUPAPI.@)
796 BOOL WINAPI
SetupDiGetActualSectionToInstallW(
798 PCWSTR InfSectionName
,
799 PWSTR InfSectionWithExt
,
800 DWORD InfSectionWithExtSize
,
804 WCHAR szBuffer
[MAX_PATH
];
807 LONG lLineCount
= -1;
809 lstrcpyW(szBuffer
, InfSectionName
);
810 dwLength
= lstrlenW(szBuffer
);
812 if (OsVersionInfo
.dwPlatformId
== VER_PLATFORM_WIN32_NT
)
814 /* Test section name with '.NTx86' extension */
815 lstrcpyW(&szBuffer
[dwLength
], NtPlatformExtension
);
816 lLineCount
= SetupGetLineCountW(InfHandle
, szBuffer
);
818 if (lLineCount
== -1)
820 /* Test section name with '.NT' extension */
821 lstrcpyW(&szBuffer
[dwLength
], NtExtension
);
822 lLineCount
= SetupGetLineCountW(InfHandle
, szBuffer
);
827 /* Test section name with '.Win' extension */
828 lstrcpyW(&szBuffer
[dwLength
], WinExtension
);
829 lLineCount
= SetupGetLineCountW(InfHandle
, szBuffer
);
832 if (lLineCount
== -1)
834 /* Test section name without extension */
835 szBuffer
[dwLength
] = 0;
836 lLineCount
= SetupGetLineCountW(InfHandle
, szBuffer
);
839 if (lLineCount
== -1)
841 SetLastError(ERROR_INVALID_PARAMETER
);
845 dwFullLength
= lstrlenW(szBuffer
);
847 if (InfSectionWithExt
!= NULL
&& InfSectionWithExtSize
!= 0)
849 if (InfSectionWithExtSize
< (dwFullLength
+ 1))
851 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
855 lstrcpyW(InfSectionWithExt
, szBuffer
);
856 if (Extension
!= NULL
)
858 *Extension
= (dwLength
== dwFullLength
) ? NULL
: &InfSectionWithExt
[dwLength
];
862 if (RequiredSize
!= NULL
)
864 *RequiredSize
= dwFullLength
+ 1;
870 /***********************************************************************
871 * SetupDiGetClassDescriptionA (SETUPAPI.@)
873 BOOL WINAPI
SetupDiGetClassDescriptionA(
874 const GUID
* ClassGuid
,
875 PSTR ClassDescription
,
876 DWORD ClassDescriptionSize
,
879 return SetupDiGetClassDescriptionExA(ClassGuid
, ClassDescription
,
880 ClassDescriptionSize
,
881 RequiredSize
, NULL
, NULL
);
884 /***********************************************************************
885 * SetupDiGetClassDescriptionW (SETUPAPI.@)
887 BOOL WINAPI
SetupDiGetClassDescriptionW(
888 const GUID
* ClassGuid
,
889 PWSTR ClassDescription
,
890 DWORD ClassDescriptionSize
,
893 return SetupDiGetClassDescriptionExW(ClassGuid
, ClassDescription
,
894 ClassDescriptionSize
,
895 RequiredSize
, NULL
, NULL
);
898 /***********************************************************************
899 * SetupDiGetClassDescriptionExA (SETUPAPI.@)
901 BOOL WINAPI
SetupDiGetClassDescriptionExA(
902 const GUID
* ClassGuid
,
903 PSTR ClassDescription
,
904 DWORD ClassDescriptionSize
,
913 /***********************************************************************
914 * SetupDiGetClassDescriptionExW (SETUPAPI.@)
916 BOOL WINAPI
SetupDiGetClassDescriptionExW(
917 const GUID
* ClassGuid
,
918 PWSTR ClassDescription
,
919 DWORD ClassDescriptionSize
,
927 hKey
= SetupDiOpenClassRegKeyExW(ClassGuid
,
932 if (hKey
== INVALID_HANDLE_VALUE
)
934 WARN("SetupDiOpenClassRegKeyExW() failed (Error %u)\n", GetLastError());
938 if (RequiredSize
!= NULL
)
941 if (RegQueryValueExW(hKey
,
952 *RequiredSize
= dwLength
/ sizeof(WCHAR
);
955 dwLength
= ClassDescriptionSize
* sizeof(WCHAR
);
956 if (RegQueryValueExW(hKey
,
960 (LPBYTE
)ClassDescription
,
972 /***********************************************************************
973 * SetupDiGetClassDevsA (SETUPAPI.@)
975 HDEVINFO WINAPI
SetupDiGetClassDevsA(
982 LPWSTR enumstrW
= NULL
;
986 int len
= MultiByteToWideChar(CP_ACP
, 0, enumstr
, -1, NULL
, 0);
987 enumstrW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
990 ret
= (HDEVINFO
)INVALID_HANDLE_VALUE
;
993 MultiByteToWideChar(CP_ACP
, 0, enumstr
, -1, enumstrW
, len
);
995 ret
= SetupDiGetClassDevsW(class, enumstrW
, parent
, flags
);
996 HeapFree(GetProcessHeap(), 0, enumstrW
);
1002 /***********************************************************************
1003 * SetupDiGetClassDevsW (SETUPAPI.@)
1005 HDEVINFO WINAPI
SetupDiGetClassDevsW(
1011 HDEVINFO ret
= (HDEVINFO
)INVALID_HANDLE_VALUE
;
1013 TRACE("%s %s %p 0x%08x\n", debugstr_guid(class), debugstr_w(enumstr
),
1016 if(flags
& DIGCF_DEVICEINTERFACE
)
1019 SetLastError(ERROR_INVALID_PARAMETER
);
1022 /* WinXP always succeeds, returns empty list for unknown classes */
1023 FIXME(": returning empty list\n");
1024 ret
= SetupDiCreateDeviceInfoList(class, parent
);
1028 FIXME(": unimplemented for enumerator strings (%s)\n",
1029 debugstr_w(enumstr
));
1030 else if (flags
& DIGCF_ALLCLASSES
)
1031 FIXME(": unimplemented for DIGCF_ALLCLASSES\n");
1034 FIXME("(%s): stub\n", debugstr_guid(class));
1039 /***********************************************************************
1040 * SetupDiGetClassDevsExW (SETUPAPI.@)
1042 HDEVINFO WINAPI
SetupDiGetClassDevsExW(
1055 /***********************************************************************
1056 * SetupDiEnumDeviceInterfaces (SETUPAPI.@)
1058 BOOL WINAPI
SetupDiEnumDeviceInterfaces(
1060 PSP_DEVINFO_DATA DeviceInfoData
,
1061 CONST GUID
* InterfaceClassGuid
,
1063 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
)
1067 FIXME("%p, %p, %s, 0x%08x, %p\n", devinfo
, DeviceInfoData
,
1068 debugstr_guid(InterfaceClassGuid
), MemberIndex
, DeviceInterfaceData
);
1070 if (devinfo
&& devinfo
!= (HDEVINFO
)INVALID_HANDLE_VALUE
)
1072 struct DeviceInfoSet
*list
= (struct DeviceInfoSet
*)devinfo
;
1073 if (list
->magic
== SETUP_DEVICE_INFO_SET_MAGIC
)
1074 SetLastError(ERROR_NO_MORE_ITEMS
);
1076 SetLastError(ERROR_INVALID_HANDLE
);
1079 SetLastError(ERROR_INVALID_HANDLE
);
1083 /***********************************************************************
1084 * SetupDiDestroyDeviceInfoList (SETUPAPI.@)
1086 * Destroy a DeviceInfoList and free all used memory of the list.
1089 * devinfo [I] DeviceInfoList pointer to list to destroy
1092 * Success: non zero value.
1093 * Failure: zero value.
1095 BOOL WINAPI
SetupDiDestroyDeviceInfoList(HDEVINFO devinfo
)
1099 TRACE("%p\n", devinfo
);
1100 if (devinfo
&& devinfo
!= (HDEVINFO
)INVALID_HANDLE_VALUE
)
1102 struct DeviceInfoSet
*list
= (struct DeviceInfoSet
*)devinfo
;
1104 if (list
->magic
== SETUP_DEVICE_INFO_SET_MAGIC
)
1106 HeapFree(GetProcessHeap(), 0, list
);
1112 SetLastError(ERROR_INVALID_HANDLE
);
1117 /***********************************************************************
1118 * SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@)
1120 BOOL WINAPI
SetupDiGetDeviceInterfaceDetailA(
1121 HDEVINFO DeviceInfoSet
,
1122 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
,
1123 PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData
,
1124 DWORD DeviceInterfaceDetailDataSize
,
1125 PDWORD RequiredSize
,
1126 PSP_DEVINFO_DATA DeviceInfoData
)
1130 FIXME("(%p, %p, %p, %d, %p, %p)\n", DeviceInfoSet
,
1131 DeviceInterfaceData
, DeviceInterfaceDetailData
,
1132 DeviceInterfaceDetailDataSize
, RequiredSize
, DeviceInfoData
);
1134 SetLastError(ERROR_INVALID_HANDLE
);
1138 /***********************************************************************
1139 * SetupDiGetDeviceInterfaceDetailW (SETUPAPI.@)
1141 BOOL WINAPI
SetupDiGetDeviceInterfaceDetailW(
1142 HDEVINFO DeviceInfoSet
,
1143 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
,
1144 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData
,
1145 DWORD DeviceInterfaceDetailDataSize
,
1146 PDWORD RequiredSize
,
1147 PSP_DEVINFO_DATA DeviceInfoData
)
1149 FIXME("(%p, %p, %p, %d, %p, %p): stub\n", DeviceInfoSet
,
1150 DeviceInterfaceData
, DeviceInterfaceDetailData
,
1151 DeviceInterfaceDetailDataSize
, RequiredSize
, DeviceInfoData
);
1155 /***********************************************************************
1156 * SetupDiGetDeviceRegistryPropertyA (SETUPAPI.@)
1158 BOOL WINAPI
SetupDiGetDeviceRegistryPropertyA(
1160 PSP_DEVINFO_DATA DeviceInfoData
,
1162 PDWORD PropertyRegDataType
,
1163 PBYTE PropertyBuffer
,
1164 DWORD PropertyBufferSize
,
1165 PDWORD RequiredSize
)
1167 FIXME("%04x %p %d %p %p %d %p\n", (DWORD
)devinfo
, DeviceInfoData
,
1168 Property
, PropertyRegDataType
, PropertyBuffer
, PropertyBufferSize
,
1173 /***********************************************************************
1174 * SetupDiInstallClassA (SETUPAPI.@)
1176 BOOL WINAPI
SetupDiInstallClassA(
1182 UNICODE_STRING FileNameW
;
1185 if (!RtlCreateUnicodeStringFromAsciiz(&FileNameW
, InfFileName
))
1187 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1191 Result
= SetupDiInstallClassW(hwndParent
, FileNameW
.Buffer
, Flags
, FileQueue
);
1193 RtlFreeUnicodeString(&FileNameW
);
1198 static HKEY
CreateClassKey(HINF hInf
)
1200 WCHAR FullBuffer
[MAX_PATH
];
1201 WCHAR Buffer
[MAX_PATH
];
1205 if (!SetupGetLineTextW(NULL
,
1213 return INVALID_HANDLE_VALUE
;
1216 lstrcpyW(FullBuffer
, ControlClass
);
1217 lstrcatW(FullBuffer
, Buffer
);
1219 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1225 if (!SetupGetLineTextW(NULL
,
1233 return INVALID_HANDLE_VALUE
;
1236 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
1240 REG_OPTION_NON_VOLATILE
,
1246 return INVALID_HANDLE_VALUE
;
1251 if (RegSetValueExW(hClassKey
,
1256 RequiredSize
* sizeof(WCHAR
)))
1258 RegCloseKey(hClassKey
);
1259 RegDeleteKeyW(HKEY_LOCAL_MACHINE
,
1261 return INVALID_HANDLE_VALUE
;
1267 /***********************************************************************
1268 * SetupDiInstallClassW (SETUPAPI.@)
1270 BOOL WINAPI
SetupDiInstallClassW(
1276 WCHAR SectionName
[MAX_PATH
];
1277 DWORD SectionNameLength
= 0;
1279 BOOL bFileQueueCreated
= FALSE
;
1285 if ((Flags
& DI_NOVCP
) && (FileQueue
== NULL
|| FileQueue
== INVALID_HANDLE_VALUE
))
1287 SetLastError(ERROR_INVALID_PARAMETER
);
1291 /* Open the .inf file */
1292 hInf
= SetupOpenInfFileW(InfFileName
,
1296 if (hInf
== INVALID_HANDLE_VALUE
)
1302 /* Create or open the class registry key 'HKLM\\CurrentControlSet\\Class\\{GUID}' */
1303 hClassKey
= CreateClassKey(hInf
);
1304 if (hClassKey
== INVALID_HANDLE_VALUE
)
1306 SetupCloseInfFile(hInf
);
1311 /* Try to append a layout file */
1313 SetupOpenAppendInfFileW(NULL
, hInf
, NULL
);
1316 /* Retrieve the actual section name */
1317 SetupDiGetActualSectionToInstallW(hInf
,
1325 if (!(Flags
& DI_NOVCP
))
1327 FileQueue
= SetupOpenFileQueue();
1328 if (FileQueue
== INVALID_HANDLE_VALUE
)
1330 SetupCloseInfFile(hInf
);
1334 bFileQueueCreated
= TRUE
;
1339 SetupInstallFromInfSectionW(NULL
,
1348 INVALID_HANDLE_VALUE
,
1351 /* FIXME: More code! */
1353 if (bFileQueueCreated
)
1354 SetupCloseFileQueue(FileQueue
);
1356 SetupCloseInfFile(hInf
);
1362 /***********************************************************************
1363 * SetupDiOpenClassRegKey (SETUPAPI.@)
1365 HKEY WINAPI
SetupDiOpenClassRegKey(
1366 const GUID
* ClassGuid
,
1369 return SetupDiOpenClassRegKeyExW(ClassGuid
, samDesired
,
1370 DIOCR_INSTALLER
, NULL
, NULL
);
1374 /***********************************************************************
1375 * SetupDiOpenClassRegKeyExA (SETUPAPI.@)
1377 HKEY WINAPI
SetupDiOpenClassRegKeyExA(
1378 const GUID
* ClassGuid
,
1384 PWSTR MachineNameW
= NULL
;
1391 MachineNameW
= MultiByteToUnicode(MachineName
, CP_ACP
);
1392 if (MachineNameW
== NULL
)
1393 return INVALID_HANDLE_VALUE
;
1396 hKey
= SetupDiOpenClassRegKeyExW(ClassGuid
, samDesired
,
1397 Flags
, MachineNameW
, Reserved
);
1399 MyFree(MachineNameW
);
1405 /***********************************************************************
1406 * SetupDiOpenClassRegKeyExW (SETUPAPI.@)
1408 HKEY WINAPI
SetupDiOpenClassRegKeyExW(
1409 const GUID
* ClassGuid
,
1415 LPWSTR lpGuidString
;
1416 WCHAR bracedGuidString
[39];
1421 if (MachineName
!= NULL
)
1423 FIXME("Remote access not supported yet!\n");
1424 return INVALID_HANDLE_VALUE
;
1427 if (Flags
== DIOCR_INSTALLER
)
1429 lpKeyName
= ControlClass
;
1431 else if (Flags
== DIOCR_INTERFACE
)
1433 lpKeyName
= DeviceClasses
;
1437 ERR("Invalid Flags parameter!\n");
1438 SetLastError(ERROR_INVALID_PARAMETER
);
1439 return INVALID_HANDLE_VALUE
;
1442 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1448 return INVALID_HANDLE_VALUE
;
1451 if (ClassGuid
== NULL
)
1454 if (UuidToStringW((UUID
*)ClassGuid
, &lpGuidString
) != RPC_S_OK
)
1456 RegCloseKey(hClassesKey
);
1457 return INVALID_HANDLE_VALUE
;
1459 bracedGuidString
[0] = '{';
1460 memcpy(&bracedGuidString
[1], lpGuidString
, 36*sizeof(WCHAR
));
1461 bracedGuidString
[37] = '}';
1462 bracedGuidString
[38] = 0;
1463 RpcStringFreeW(&lpGuidString
);
1465 if (RegOpenKeyExW(hClassesKey
,
1471 RegCloseKey(hClassesKey
);
1472 return INVALID_HANDLE_VALUE
;
1475 RegCloseKey(hClassesKey
);
1480 /***********************************************************************
1481 * SetupDiOpenDeviceInterfaceW (SETUPAPI.@)
1483 BOOL WINAPI
SetupDiOpenDeviceInterfaceW(
1484 HDEVINFO DeviceInfoSet
,
1487 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
)
1489 FIXME("%p %s %08x %p\n",
1490 DeviceInfoSet
, debugstr_w(DevicePath
), OpenFlags
, DeviceInterfaceData
);
1494 /***********************************************************************
1495 * SetupDiOpenDeviceInterfaceA (SETUPAPI.@)
1497 BOOL WINAPI
SetupDiOpenDeviceInterfaceA(
1498 HDEVINFO DeviceInfoSet
,
1501 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
)
1503 FIXME("%p %s %08x %p\n", DeviceInfoSet
,
1504 debugstr_a(DevicePath
), OpenFlags
, DeviceInterfaceData
);
1508 /***********************************************************************
1509 * SetupDiSetClassInstallParamsA (SETUPAPI.@)
1511 BOOL WINAPI
SetupDiSetClassInstallParamsA(
1512 HDEVINFO DeviceInfoSet
,
1513 PSP_DEVINFO_DATA DeviceInfoData
,
1514 PSP_CLASSINSTALL_HEADER ClassInstallParams
,
1515 DWORD ClassInstallParamsSize
)
1517 FIXME("%p %p %x %u\n",DeviceInfoSet
, DeviceInfoData
,
1518 ClassInstallParams
->InstallFunction
, ClassInstallParamsSize
);
1522 /***********************************************************************
1523 * SetupDiCallClassInstaller (SETUPAPI.@)
1525 BOOL WINAPI
SetupDiCallClassInstaller(
1526 DI_FUNCTION InstallFunction
,
1527 HDEVINFO DeviceInfoSet
,
1528 PSP_DEVINFO_DATA DeviceInfoData
)
1530 FIXME("%d %p %p\n", InstallFunction
, DeviceInfoSet
, DeviceInfoData
);
1534 /***********************************************************************
1535 * SetupDiGetDeviceInstallParamsA (SETUPAPI.@)
1537 BOOL WINAPI
SetupDiGetDeviceInstallParamsA(
1538 HDEVINFO DeviceInfoSet
,
1539 PSP_DEVINFO_DATA DeviceInfoData
,
1540 PSP_DEVINSTALL_PARAMS_A DeviceInstallParams
)
1542 FIXME("%p %p %p\n", DeviceInfoSet
, DeviceInfoData
, DeviceInstallParams
);
1546 /***********************************************************************
1547 * SetupDiOpenDevRegKey (SETUPAPI.@)
1549 HKEY WINAPI
SetupDiOpenDevRegKey(
1550 HDEVINFO DeviceInfoSet
,
1551 PSP_DEVINFO_DATA DeviceInfoData
,
1557 FIXME("%p %p %d %d %d %x\n", DeviceInfoSet
, DeviceInfoData
,
1558 Scope
, HwProfile
, KeyType
, samDesired
);
1559 return INVALID_HANDLE_VALUE
;