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"
37 #include "ddk/cfgmgr32.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 %ld\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 %ld\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");
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 * SetupDiCreateDeviceInfoW (SETUPAPI.@)
702 BOOL WINAPI SetupDiCreateDeviceInfoW(
703 HDEVINFO DeviceInfoSet,
705 CONST GUID *ClassGuid,
706 PCWSTR DeviceDescription,
709 PSP_DEVINFO_DATA DeviceInfoData)
711 TRACE("%p %s %s %s %p %lx %p\n", DeviceInfoSet, debugstr_w(DeviceName),
712 debugstr_guid(ClassGuid), debugstr_w(DeviceDescription),
713 hwndParent, CreationFlags, DeviceInfoData);
720 /***********************************************************************
721 * SetupDiEnumDeviceInfo (SETUPAPI.@)
723 BOOL WINAPI SetupDiEnumDeviceInfo(
726 PSP_DEVINFO_DATA info)
728 FIXME("%p %ld %p\n", devinfo, index, info);
732 if(info->cbSize < sizeof(*info))
738 /***********************************************************************
739 * SetupDiGetActualSectionToInstallA (SETUPAPI.@)
741 BOOL WINAPI SetupDiGetActualSectionToInstallA(
743 PCSTR InfSectionName,
744 PSTR InfSectionWithExt,
745 DWORD InfSectionWithExtSize,
753 /***********************************************************************
754 * SetupDiGetActualSectionToInstallW (SETUPAPI.@)
756 BOOL WINAPI SetupDiGetActualSectionToInstallW(
758 PCWSTR InfSectionName,
759 PWSTR InfSectionWithExt,
760 DWORD InfSectionWithExtSize,
764 WCHAR szBuffer[MAX_PATH];
767 LONG lLineCount = -1;
769 lstrcpyW(szBuffer, InfSectionName);
770 dwLength = lstrlenW(szBuffer);
772 if (OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
774 /* Test section name with '.NTx86' extension */
775 lstrcpyW(&szBuffer[dwLength], NtPlatformExtension);
776 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
778 if (lLineCount == -1)
780 /* Test section name with '.NT' extension */
781 lstrcpyW(&szBuffer[dwLength], NtExtension);
782 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
787 /* Test section name with '.Win' extension */
788 lstrcpyW(&szBuffer[dwLength], WinExtension);
789 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
792 if (lLineCount == -1)
794 /* Test section name without extension */
795 szBuffer[dwLength] = 0;
796 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
799 if (lLineCount == -1)
801 SetLastError(ERROR_INVALID_PARAMETER);
805 dwFullLength = lstrlenW(szBuffer);
807 if (InfSectionWithExt != NULL && InfSectionWithExtSize != 0)
809 if (InfSectionWithExtSize < (dwFullLength + 1))
811 SetLastError(ERROR_INSUFFICIENT_BUFFER);
815 lstrcpyW(InfSectionWithExt, szBuffer);
816 if (Extension != NULL)
818 *Extension = (dwLength == dwFullLength) ? NULL : &InfSectionWithExt[dwLength];
822 if (RequiredSize != NULL)
824 *RequiredSize = dwFullLength + 1;
830 /***********************************************************************
831 * SetupDiGetClassDescriptionA (SETUPAPI.@)
833 BOOL WINAPI SetupDiGetClassDescriptionA(
834 const GUID* ClassGuid,
835 PSTR ClassDescription,
836 DWORD ClassDescriptionSize,
839 return SetupDiGetClassDescriptionExA(ClassGuid, ClassDescription,
840 ClassDescriptionSize,
841 RequiredSize, NULL, NULL);
844 /***********************************************************************
845 * SetupDiGetClassDescriptionW (SETUPAPI.@)
847 BOOL WINAPI SetupDiGetClassDescriptionW(
848 const GUID* ClassGuid,
849 PWSTR ClassDescription,
850 DWORD ClassDescriptionSize,
853 return SetupDiGetClassDescriptionExW(ClassGuid, ClassDescription,
854 ClassDescriptionSize,
855 RequiredSize, NULL, NULL);
858 /***********************************************************************
859 * SetupDiGetClassDescriptionExA (SETUPAPI.@)
861 BOOL WINAPI SetupDiGetClassDescriptionExA(
862 const GUID* ClassGuid,
863 PSTR ClassDescription,
864 DWORD ClassDescriptionSize,
873 /***********************************************************************
874 * SetupDiGetClassDescriptionExW (SETUPAPI.@)
876 BOOL WINAPI SetupDiGetClassDescriptionExW(
877 const GUID* ClassGuid,
878 PWSTR ClassDescription,
879 DWORD ClassDescriptionSize,
887 hKey = SetupDiOpenClassRegKeyExW(ClassGuid,
892 if (hKey == INVALID_HANDLE_VALUE)
894 WARN("SetupDiOpenClassRegKeyExW() failed (Error %lu)\n", GetLastError());
898 if (RequiredSize != NULL)
901 if (RegQueryValueExW(hKey,
912 *RequiredSize = dwLength / sizeof(WCHAR);
915 dwLength = ClassDescriptionSize * sizeof(WCHAR);
916 if (RegQueryValueExW(hKey,
920 (LPBYTE)ClassDescription,
932 /***********************************************************************
933 * SetupDiGetClassDevsA (SETUPAPI.@)
935 HDEVINFO WINAPI SetupDiGetClassDevsA(
942 LPWSTR enumstrW = NULL;
946 int len = MultiByteToWideChar(CP_ACP, 0, enumstr, -1, NULL, 0);
947 enumstrW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
950 ret = (HDEVINFO)INVALID_HANDLE_VALUE;
953 MultiByteToWideChar(CP_ACP, 0, enumstr, -1, enumstrW, len);
955 ret = SetupDiGetClassDevsW(class, enumstrW, parent, flags);
956 HeapFree(GetProcessHeap(), 0, enumstrW);
962 /***********************************************************************
963 * SetupDiGetClassDevsW (SETUPAPI.@)
965 HDEVINFO WINAPI SetupDiGetClassDevsW(
971 HDEVINFO ret = (HDEVINFO)INVALID_HANDLE_VALUE;
973 TRACE("%s %s %p 0x%08lx\n", debugstr_guid(class), debugstr_w(enumstr),
977 FIXME(": unimplemented for enumerator strings (%s)\n",
978 debugstr_w(enumstr));
979 else if (flags & DIGCF_ALLCLASSES)
980 FIXME(": unimplemented for DIGCF_ALLCLASSES\n");
983 FIXME("(%s): stub\n", debugstr_guid(class));
988 /***********************************************************************
989 * SetupDiEnumDeviceInterfaces (SETUPAPI.@)
991 BOOL WINAPI SetupDiEnumDeviceInterfaces(
992 HDEVINFO DeviceInfoSet,
993 PSP_DEVINFO_DATA DeviceInfoData,
994 CONST GUID * InterfaceClassGuid,
996 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
1000 FIXME("%p, %p, %s, 0x%08lx, %p\n", DeviceInfoSet, DeviceInfoData,
1001 debugstr_guid(InterfaceClassGuid), MemberIndex, DeviceInterfaceData);
1003 SetLastError(ERROR_INVALID_HANDLE);
1007 /***********************************************************************
1008 * SetupDiDestroyDeviceInfoList (SETUPAPI.@)
1010 * Destroy a DeviceInfoList and free all used memory of the list.
1013 * devinfo [I] DeviceInfoList pointer to list to destroy
1016 * Success: non zero value.
1017 * Failure: zero value.
1019 BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
1023 TRACE("%p\n", devinfo);
1024 if (devinfo && devinfo != (HDEVINFO)INVALID_HANDLE_VALUE)
1026 struct DeviceInfoSet *list = (struct DeviceInfoSet *)devinfo;
1028 if (list->magic == SETUP_DEVICE_INFO_SET_MAGIC)
1030 HeapFree(GetProcessHeap(), 0, list);
1036 SetLastError(ERROR_INVALID_HANDLE);
1041 /***********************************************************************
1042 * SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@)
1044 BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(
1045 HDEVINFO DeviceInfoSet,
1046 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
1047 PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData,
1048 DWORD DeviceInterfaceDetailDataSize,
1049 PDWORD RequiredSize,
1050 PSP_DEVINFO_DATA DeviceInfoData)
1054 FIXME("(%p, %p, %p, %ld, %p, %p)\n", DeviceInfoSet,
1055 DeviceInterfaceData, DeviceInterfaceDetailData,
1056 DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
1058 SetLastError(ERROR_INVALID_HANDLE);
1062 /***********************************************************************
1063 * SetupDiGetDeviceInterfaceDetailW (SETUPAPI.@)
1065 BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(
1066 HDEVINFO DeviceInfoSet,
1067 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
1068 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData,
1069 DWORD DeviceInterfaceDetailDataSize,
1070 PDWORD RequiredSize,
1071 PSP_DEVINFO_DATA DeviceInfoData)
1073 FIXME("(%p, %p, %p, %ld, %p, %p): stub\n", DeviceInfoSet,
1074 DeviceInterfaceData, DeviceInterfaceDetailData,
1075 DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
1079 /***********************************************************************
1080 * SetupDiGetDeviceRegistryPropertyA (SETUPAPI.@)
1082 BOOL WINAPI SetupDiGetDeviceRegistryPropertyA(
1084 PSP_DEVINFO_DATA DeviceInfoData,
1086 PDWORD PropertyRegDataType,
1087 PBYTE PropertyBuffer,
1088 DWORD PropertyBufferSize,
1089 PDWORD RequiredSize)
1091 FIXME("%04lx %p %ld %p %p %ld %p\n", (DWORD)devinfo, DeviceInfoData,
1092 Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize,
1097 /***********************************************************************
1098 * SetupDiInstallClassA (SETUPAPI.@)
1100 BOOL WINAPI SetupDiInstallClassA(
1106 UNICODE_STRING FileNameW;
1109 if (!RtlCreateUnicodeStringFromAsciiz(&FileNameW, InfFileName))
1111 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1115 Result = SetupDiInstallClassW(hwndParent, FileNameW.Buffer, Flags, FileQueue);
1117 RtlFreeUnicodeString(&FileNameW);
1122 static HKEY CreateClassKey(HINF hInf)
1124 WCHAR FullBuffer[MAX_PATH];
1125 WCHAR Buffer[MAX_PATH];
1129 if (!SetupGetLineTextW(NULL,
1137 return INVALID_HANDLE_VALUE;
1140 lstrcpyW(FullBuffer, ControlClass);
1141 lstrcatW(FullBuffer, Buffer);
1143 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1149 if (!SetupGetLineTextW(NULL,
1157 return INVALID_HANDLE_VALUE;
1160 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,
1164 REG_OPTION_NON_VOLATILE,
1170 return INVALID_HANDLE_VALUE;
1175 if (RegSetValueExW(hClassKey,
1180 RequiredSize * sizeof(WCHAR)))
1182 RegCloseKey(hClassKey);
1183 RegDeleteKeyW(HKEY_LOCAL_MACHINE,
1185 return INVALID_HANDLE_VALUE;
1191 /***********************************************************************
1192 * SetupDiInstallClassW (SETUPAPI.@)
1194 BOOL WINAPI SetupDiInstallClassW(
1200 WCHAR SectionName[MAX_PATH];
1201 DWORD SectionNameLength = 0;
1203 BOOL bFileQueueCreated = FALSE;
1209 if ((Flags & DI_NOVCP) && (FileQueue == NULL || FileQueue == INVALID_HANDLE_VALUE))
1211 SetLastError(ERROR_INVALID_PARAMETER);
1215 /* Open the .inf file */
1216 hInf = SetupOpenInfFileW(InfFileName,
1220 if (hInf == INVALID_HANDLE_VALUE)
1226 /* Create or open the class registry key 'HKLM\\CurrentControlSet\\Class\\{GUID}' */
1227 hClassKey = CreateClassKey(hInf);
1228 if (hClassKey == INVALID_HANDLE_VALUE)
1230 SetupCloseInfFile(hInf);
1235 /* Try to append a layout file */
1237 SetupOpenAppendInfFileW(NULL, hInf, NULL);
1240 /* Retrieve the actual section name */
1241 SetupDiGetActualSectionToInstallW(hInf,
1249 if (!(Flags & DI_NOVCP))
1251 FileQueue = SetupOpenFileQueue();
1252 if (FileQueue == INVALID_HANDLE_VALUE)
1254 SetupCloseInfFile(hInf);
1258 bFileQueueCreated = TRUE;
1263 SetupInstallFromInfSectionW(NULL,
1272 INVALID_HANDLE_VALUE,
1275 /* FIXME: More code! */
1277 if (bFileQueueCreated)
1278 SetupCloseFileQueue(FileQueue);
1280 SetupCloseInfFile(hInf);
1286 /***********************************************************************
1287 * SetupDiOpenClassRegKey (SETUPAPI.@)
1289 HKEY WINAPI SetupDiOpenClassRegKey(
1290 const GUID* ClassGuid,
1293 return SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
1294 DIOCR_INSTALLER, NULL, NULL);
1298 /***********************************************************************
1299 * SetupDiOpenClassRegKeyExA (SETUPAPI.@)
1301 HKEY WINAPI SetupDiOpenClassRegKeyExA(
1302 const GUID* ClassGuid,
1308 PWSTR MachineNameW = NULL;
1315 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
1316 if (MachineNameW == NULL)
1317 return INVALID_HANDLE_VALUE;
1320 hKey = SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
1321 Flags, MachineNameW, Reserved);
1323 MyFree(MachineNameW);
1329 /***********************************************************************
1330 * SetupDiOpenClassRegKeyExW (SETUPAPI.@)
1332 HKEY WINAPI SetupDiOpenClassRegKeyExW(
1333 const GUID* ClassGuid,
1339 LPWSTR lpGuidString;
1344 if (MachineName != NULL)
1346 FIXME("Remote access not supported yet!\n");
1347 return INVALID_HANDLE_VALUE;
1350 if (Flags == DIOCR_INSTALLER)
1352 lpKeyName = ControlClass;
1354 else if (Flags == DIOCR_INTERFACE)
1356 lpKeyName = DeviceClasses;
1360 ERR("Invalid Flags parameter!\n");
1361 SetLastError(ERROR_INVALID_PARAMETER);
1362 return INVALID_HANDLE_VALUE;
1365 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1371 return INVALID_HANDLE_VALUE;
1374 if (ClassGuid == NULL)
1377 if (UuidToStringW((UUID*)ClassGuid, &lpGuidString) != RPC_S_OK)
1379 RegCloseKey(hClassesKey);
1383 if (RegOpenKeyExW(hClassesKey,
1389 RpcStringFreeW(&lpGuidString);
1390 RegCloseKey(hClassesKey);
1394 RpcStringFreeW(&lpGuidString);
1395 RegCloseKey(hClassesKey);
1400 /***********************************************************************
1401 * SetupDiOpenDeviceInterfaceW (SETUPAPI.@)
1403 BOOL WINAPI SetupDiOpenDeviceInterfaceW(
1404 HDEVINFO DeviceInfoSet,
1407 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
1409 FIXME("%p %s %08lx %p\n",
1410 DeviceInfoSet, debugstr_w(DevicePath), OpenFlags, DeviceInterfaceData);
1414 /***********************************************************************
1415 * SetupDiOpenDeviceInterfaceA (SETUPAPI.@)
1417 BOOL WINAPI SetupDiOpenDeviceInterfaceA(
1418 HDEVINFO DeviceInfoSet,
1421 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
1423 FIXME("%p %s %08lx %p\n", DeviceInfoSet,
1424 debugstr_a(DevicePath), OpenFlags, DeviceInterfaceData);
1428 /***********************************************************************
1429 * SetupDiSetClassInstallParamsA (SETUPAPI.@)
1431 BOOL WINAPI SetupDiSetClassInstallParamsA(
1432 HDEVINFO DeviceInfoSet,
1433 PSP_DEVINFO_DATA DeviceInfoData,
1434 PSP_CLASSINSTALL_HEADER ClassInstallParams,
1435 DWORD ClassInstallParamsSize)
1437 FIXME("%p %p %x %lu\n",DeviceInfoSet, DeviceInfoData,
1438 ClassInstallParams->InstallFunction, ClassInstallParamsSize);
1442 /***********************************************************************
1443 * SetupDiCallClassInstaller (SETUPAPI.@)
1445 BOOL WINAPI SetupDiCallClassInstaller(
1446 DI_FUNCTION InstallFunction,
1447 HDEVINFO DeviceInfoSet,
1448 PSP_DEVINFO_DATA DeviceInfoData)
1450 FIXME("%d %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData);
1454 /***********************************************************************
1455 * SetupDiGetDeviceInstallParamsA (SETUPAPI.@)
1457 BOOL WINAPI SetupDiGetDeviceInstallParamsA(
1458 HDEVINFO DeviceInfoSet,
1459 PSP_DEVINFO_DATA DeviceInfoData,
1460 PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
1462 FIXME("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstallParams);
1466 /***********************************************************************
1467 * SetupDiOpenDevRegKey (SETUPAPI.@)
1469 HKEY WINAPI SetupDiOpenDevRegKey(
1470 HDEVINFO DeviceInfoSet,
1471 PSP_DEVINFO_DATA DeviceInfoData,
1477 FIXME("%p %p %ld %ld %ld %lx\n", DeviceInfoSet, DeviceInfoData,
1478 Scope, HwProfile, KeyType, samDesired);
1479 return INVALID_HANDLE_VALUE;