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);
152 MyFree(MachineNameW);
157 /***********************************************************************
158 * SetupDiBuildClassInfoListExW (SETUPAPI.@)
160 * Returns a list of setup class GUIDs that identify the classes
161 * that are installed on a local or remote macine.
164 * Flags [I] control exclusion of classes from the list.
165 * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
166 * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
167 * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
168 * MachineName [I] name of a remote machine.
169 * Reserved [I] must be NULL.
175 BOOL WINAPI SetupDiBuildClassInfoListExW(
177 LPGUID ClassGuidList,
178 DWORD ClassGuidListSize,
189 DWORD dwGuidListIndex = 0;
193 if (RequiredSize != NULL)
196 hClassesKey = SetupDiOpenClassRegKeyExW(NULL,
201 if (hClassesKey == INVALID_HANDLE_VALUE)
206 for (dwIndex = 0; ; dwIndex++)
209 lError = RegEnumKeyExW(hClassesKey,
217 TRACE("RegEnumKeyExW() returns %ld\n", lError);
218 if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
220 TRACE("Key name: %p\n", szKeyName);
222 if (RegOpenKeyExW(hClassesKey,
228 RegCloseKey(hClassesKey);
232 if (!RegQueryValueExW(hClassKey,
239 TRACE("'NoUseClass' value found!\n");
240 RegCloseKey(hClassKey);
244 if ((Flags & DIBCI_NOINSTALLCLASS) &&
245 (!RegQueryValueExW(hClassKey,
252 TRACE("'NoInstallClass' value found!\n");
253 RegCloseKey(hClassKey);
257 if ((Flags & DIBCI_NODISPLAYCLASS) &&
258 (!RegQueryValueExW(hClassKey,
265 TRACE("'NoDisplayClass' value found!\n");
266 RegCloseKey(hClassKey);
270 RegCloseKey(hClassKey);
272 TRACE("Guid: %p\n", szKeyName);
273 if (dwGuidListIndex < ClassGuidListSize)
275 if (szKeyName[0] == L'{' && szKeyName[37] == L'}')
279 TRACE("Guid: %p\n", &szKeyName[1]);
281 UuidFromStringW(&szKeyName[1],
282 &ClassGuidList[dwGuidListIndex]);
288 if (lError != ERROR_SUCCESS)
292 RegCloseKey(hClassesKey);
294 if (RequiredSize != NULL)
295 *RequiredSize = dwGuidListIndex;
297 if (ClassGuidListSize < dwGuidListIndex)
299 SetLastError(ERROR_INSUFFICIENT_BUFFER);
306 /***********************************************************************
307 * SetupDiClassGuidsFromNameA (SETUPAPI.@)
309 BOOL WINAPI SetupDiClassGuidsFromNameA(
311 LPGUID ClassGuidList,
312 DWORD ClassGuidListSize,
315 return SetupDiClassGuidsFromNameExA(ClassName, ClassGuidList,
316 ClassGuidListSize, RequiredSize,
320 /***********************************************************************
321 * SetupDiClassGuidsFromNameW (SETUPAPI.@)
323 BOOL WINAPI SetupDiClassGuidsFromNameW(
325 LPGUID ClassGuidList,
326 DWORD ClassGuidListSize,
329 return SetupDiClassGuidsFromNameExW(ClassName, ClassGuidList,
330 ClassGuidListSize, RequiredSize,
334 /***********************************************************************
335 * SetupDiClassGuidsFromNameExA (SETUPAPI.@)
337 BOOL WINAPI SetupDiClassGuidsFromNameExA(
339 LPGUID ClassGuidList,
340 DWORD ClassGuidListSize,
345 LPWSTR ClassNameW = NULL;
346 LPWSTR MachineNameW = NULL;
351 ClassNameW = MultiByteToUnicode(ClassName, CP_ACP);
352 if (ClassNameW == NULL)
357 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
358 if (MachineNameW == NULL)
365 bResult = SetupDiClassGuidsFromNameExW(ClassNameW, ClassGuidList,
366 ClassGuidListSize, RequiredSize,
367 MachineNameW, Reserved);
370 MyFree(MachineNameW);
377 /***********************************************************************
378 * SetupDiClassGuidsFromNameExW (SETUPAPI.@)
380 BOOL WINAPI SetupDiClassGuidsFromNameExW(
382 LPGUID ClassGuidList,
383 DWORD ClassGuidListSize,
389 WCHAR szClassName[256];
395 DWORD dwGuidListIndex = 0;
397 if (RequiredSize != NULL)
400 hClassesKey = SetupDiOpenClassRegKeyExW(NULL,
405 if (hClassesKey == INVALID_HANDLE_VALUE)
410 for (dwIndex = 0; ; dwIndex++)
413 lError = RegEnumKeyExW(hClassesKey,
421 TRACE("RegEnumKeyExW() returns %ld\n", lError);
422 if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
424 TRACE("Key name: %p\n", szKeyName);
426 if (RegOpenKeyExW(hClassesKey,
432 RegCloseKey(hClassesKey);
436 dwLength = 256 * sizeof(WCHAR);
437 if (!RegQueryValueExW(hClassKey,
444 TRACE("Class name: %p\n", szClassName);
446 if (strcmpiW(szClassName, ClassName) == 0)
448 TRACE("Found matching class name\n");
450 TRACE("Guid: %p\n", szKeyName);
451 if (dwGuidListIndex < ClassGuidListSize)
453 if (szKeyName[0] == L'{' && szKeyName[37] == L'}')
457 TRACE("Guid: %p\n", &szKeyName[1]);
459 UuidFromStringW(&szKeyName[1],
460 &ClassGuidList[dwGuidListIndex]);
467 RegCloseKey(hClassKey);
470 if (lError != ERROR_SUCCESS)
474 RegCloseKey(hClassesKey);
476 if (RequiredSize != NULL)
477 *RequiredSize = dwGuidListIndex;
479 if (ClassGuidListSize < dwGuidListIndex)
481 SetLastError(ERROR_INSUFFICIENT_BUFFER);
488 /***********************************************************************
489 * SetupDiClassNameFromGuidA (SETUPAPI.@)
491 BOOL WINAPI SetupDiClassNameFromGuidA(
492 const GUID* ClassGuid,
497 return SetupDiClassNameFromGuidExA(ClassGuid, ClassName,
498 ClassNameSize, RequiredSize,
502 /***********************************************************************
503 * SetupDiClassNameFromGuidW (SETUPAPI.@)
505 BOOL WINAPI SetupDiClassNameFromGuidW(
506 const GUID* ClassGuid,
511 return SetupDiClassNameFromGuidExW(ClassGuid, ClassName,
512 ClassNameSize, RequiredSize,
516 /***********************************************************************
517 * SetupDiClassNameFromGuidExA (SETUPAPI.@)
519 BOOL WINAPI SetupDiClassNameFromGuidExA(
520 const GUID* ClassGuid,
527 WCHAR ClassNameW[MAX_CLASS_NAME_LEN];
528 LPWSTR MachineNameW = NULL;
532 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
533 ret = SetupDiClassNameFromGuidExW(ClassGuid, ClassNameW, MAX_CLASS_NAME_LEN,
534 NULL, MachineNameW, Reserved);
537 int len = WideCharToMultiByte(CP_ACP, 0, ClassNameW, -1, ClassName,
538 ClassNameSize, NULL, NULL);
540 if (!ClassNameSize && RequiredSize)
543 MyFree(MachineNameW);
547 /***********************************************************************
548 * SetupDiClassNameFromGuidExW (SETUPAPI.@)
550 BOOL WINAPI SetupDiClassNameFromGuidExW(
551 const GUID* ClassGuid,
561 hKey = SetupDiOpenClassRegKeyExW(ClassGuid,
566 if (hKey == INVALID_HANDLE_VALUE)
571 if (RequiredSize != NULL)
574 if (RegQueryValueExW(hKey,
585 *RequiredSize = dwLength / sizeof(WCHAR);
588 dwLength = ClassNameSize * sizeof(WCHAR);
589 if (RegQueryValueExW(hKey,
605 /***********************************************************************
606 * SetupDiCreateDeviceInfoList (SETUPAPI.@)
609 SetupDiCreateDeviceInfoList(const GUID *ClassGuid,
612 return SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent, NULL, NULL);
615 /***********************************************************************
616 * SetupDiCreateDeviceInfoListExA (SETUPAPI.@)
619 SetupDiCreateDeviceInfoListExA(const GUID *ClassGuid,
624 LPWSTR MachineNameW = NULL;
631 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
632 if (MachineNameW == NULL)
633 return (HDEVINFO)INVALID_HANDLE_VALUE;
636 hDevInfo = SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent,
637 MachineNameW, Reserved);
640 MyFree(MachineNameW);
645 /***********************************************************************
646 * SetupDiCreateDeviceInfoListExW (SETUPAPI.@)
648 * Create an empty DeviceInfoSet list.
651 * ClassGuid [I] if not NULL only devices with GUID ClcassGuid are associated
653 * hwndParent [I] hwnd needed for interface related actions.
654 * MachineName [I] name of machine to create emtpy DeviceInfoSet list, if NULL
655 * local regestry will be used.
656 * Reserved [I] must be NULL
659 * Success: empty list.
660 * Failure: INVALID_HANDLE_VALUE.
663 SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid,
668 struct DeviceInfoSet *list = NULL;
669 DWORD size = sizeof(struct DeviceInfoSet);
671 TRACE("%s %p %s %p\n", debugstr_guid(ClassGuid), hwndParent,
672 debugstr_w(MachineName), Reserved);
674 if (MachineName != NULL)
676 FIXME("remote support is not implemented");
677 SetLastError(ERROR_INVALID_MACHINENAME);
678 return (HDEVINFO)INVALID_HANDLE_VALUE;
681 if (Reserved != NULL)
683 SetLastError(ERROR_INVALID_PARAMETER);
684 return (HDEVINFO)INVALID_HANDLE_VALUE;
687 list = HeapAlloc(GetProcessHeap(), 0, size);
690 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
691 return (HDEVINFO)INVALID_HANDLE_VALUE;
694 list->magic = SETUP_DEVICE_INFO_SET_MAGIC;
695 list->hwndParent = hwndParent;
696 memcpy(&list->ClassGuid,
697 ClassGuid ? ClassGuid : &GUID_NULL,
698 sizeof(list->ClassGuid));
700 return (HDEVINFO)list;
703 /***********************************************************************
704 * SetupDiEnumDeviceInfo (SETUPAPI.@)
706 BOOL WINAPI SetupDiEnumDeviceInfo(
709 PSP_DEVINFO_DATA info)
711 FIXME("%p %ld %p\n", devinfo, index, info);
715 if(info->cbSize < sizeof(*info))
721 /***********************************************************************
722 * SetupDiGetActualSectionToInstallA (SETUPAPI.@)
724 BOOL WINAPI SetupDiGetActualSectionToInstallA(
726 PCSTR InfSectionName,
727 PSTR InfSectionWithExt,
728 DWORD InfSectionWithExtSize,
736 /***********************************************************************
737 * SetupDiGetActualSectionToInstallW (SETUPAPI.@)
739 BOOL WINAPI SetupDiGetActualSectionToInstallW(
741 PCWSTR InfSectionName,
742 PWSTR InfSectionWithExt,
743 DWORD InfSectionWithExtSize,
747 WCHAR szBuffer[MAX_PATH];
750 LONG lLineCount = -1;
752 lstrcpyW(szBuffer, InfSectionName);
753 dwLength = lstrlenW(szBuffer);
755 if (OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
757 /* Test section name with '.NTx86' extension */
758 lstrcpyW(&szBuffer[dwLength], NtPlatformExtension);
759 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
761 if (lLineCount == -1)
763 /* Test section name with '.NT' extension */
764 lstrcpyW(&szBuffer[dwLength], NtExtension);
765 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
770 /* Test section name with '.Win' extension */
771 lstrcpyW(&szBuffer[dwLength], WinExtension);
772 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
775 if (lLineCount == -1)
777 /* Test section name without extension */
778 szBuffer[dwLength] = 0;
779 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
782 if (lLineCount == -1)
784 SetLastError(ERROR_INVALID_PARAMETER);
788 dwFullLength = lstrlenW(szBuffer);
790 if (InfSectionWithExt != NULL && InfSectionWithExtSize != 0)
792 if (InfSectionWithExtSize < (dwFullLength + 1))
794 SetLastError(ERROR_INSUFFICIENT_BUFFER);
798 lstrcpyW(InfSectionWithExt, szBuffer);
799 if (Extension != NULL)
801 *Extension = (dwLength == dwFullLength) ? NULL : &InfSectionWithExt[dwLength];
805 if (RequiredSize != NULL)
807 *RequiredSize = dwFullLength + 1;
813 /***********************************************************************
814 * SetupDiGetClassDescriptionA (SETUPAPI.@)
816 BOOL WINAPI SetupDiGetClassDescriptionA(
817 const GUID* ClassGuid,
818 PSTR ClassDescription,
819 DWORD ClassDescriptionSize,
822 return SetupDiGetClassDescriptionExA(ClassGuid, ClassDescription,
823 ClassDescriptionSize,
824 RequiredSize, NULL, NULL);
827 /***********************************************************************
828 * SetupDiGetClassDescriptionW (SETUPAPI.@)
830 BOOL WINAPI SetupDiGetClassDescriptionW(
831 const GUID* ClassGuid,
832 PWSTR ClassDescription,
833 DWORD ClassDescriptionSize,
836 return SetupDiGetClassDescriptionExW(ClassGuid, ClassDescription,
837 ClassDescriptionSize,
838 RequiredSize, NULL, NULL);
841 /***********************************************************************
842 * SetupDiGetClassDescriptionExA (SETUPAPI.@)
844 BOOL WINAPI SetupDiGetClassDescriptionExA(
845 const GUID* ClassGuid,
846 PSTR ClassDescription,
847 DWORD ClassDescriptionSize,
856 /***********************************************************************
857 * SetupDiGetClassDescriptionExW (SETUPAPI.@)
859 BOOL WINAPI SetupDiGetClassDescriptionExW(
860 const GUID* ClassGuid,
861 PWSTR ClassDescription,
862 DWORD ClassDescriptionSize,
870 hKey = SetupDiOpenClassRegKeyExW(ClassGuid,
875 if (hKey == INVALID_HANDLE_VALUE)
877 WARN("SetupDiOpenClassRegKeyExW() failed (Error %lu)\n", GetLastError());
881 if (RequiredSize != NULL)
884 if (RegQueryValueExW(hKey,
895 *RequiredSize = dwLength / sizeof(WCHAR);
898 dwLength = ClassDescriptionSize * sizeof(WCHAR);
899 if (RegQueryValueExW(hKey,
903 (LPBYTE)ClassDescription,
915 /***********************************************************************
916 * SetupDiGetClassDevsA (SETUPAPI.@)
918 HDEVINFO WINAPI SetupDiGetClassDevsA(
925 LPWSTR enumstrW = NULL;
929 int len = MultiByteToWideChar(CP_ACP, 0, enumstr, -1, NULL, 0);
930 enumstrW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
933 ret = (HDEVINFO)INVALID_HANDLE_VALUE;
936 MultiByteToWideChar(CP_ACP, 0, enumstr, -1, enumstrW, len);
938 ret = SetupDiGetClassDevsW(class, enumstrW, parent, flags);
939 HeapFree(GetProcessHeap(), 0, enumstrW);
945 /***********************************************************************
946 * SetupDiGetClassDevsW (SETUPAPI.@)
948 HDEVINFO WINAPI SetupDiGetClassDevsW(
954 HDEVINFO ret = (HDEVINFO)INVALID_HANDLE_VALUE;
956 TRACE("%s %s %p 0x%08lx\n", debugstr_guid(class), debugstr_w(enumstr),
960 FIXME(": unimplemented for enumerator strings (%s)\n",
961 debugstr_w(enumstr));
962 else if (flags & DIGCF_ALLCLASSES)
963 FIXME(": unimplemented for DIGCF_ALLCLASSES\n");
966 FIXME("(%s): stub\n", debugstr_guid(class));
971 /***********************************************************************
972 * SetupDiEnumDeviceInterfaces (SETUPAPI.@)
974 BOOL WINAPI SetupDiEnumDeviceInterfaces(
975 HDEVINFO DeviceInfoSet,
976 PSP_DEVINFO_DATA DeviceInfoData,
977 CONST GUID * InterfaceClassGuid,
979 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
983 FIXME("%p, %p, %s, 0x%08lx, %p\n", DeviceInfoSet, DeviceInfoData,
984 debugstr_guid(InterfaceClassGuid), MemberIndex, DeviceInterfaceData);
986 SetLastError(ERROR_INVALID_HANDLE);
990 /***********************************************************************
991 * SetupDiDestroyDeviceInfoList (SETUPAPI.@)
993 * Destroy a DeviceInfoList and free all used memory of the list.
996 * devinfo [I] DeviceInfoList pointer to list to destroy
999 * Success: non zero value.
1000 * Failure: zero value.
1002 BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
1006 TRACE("%p\n", devinfo);
1007 if (devinfo && devinfo != (HDEVINFO)INVALID_HANDLE_VALUE)
1009 struct DeviceInfoSet *list = (struct DeviceInfoSet *)devinfo;
1011 if (list->magic == SETUP_DEVICE_INFO_SET_MAGIC)
1013 HeapFree(GetProcessHeap(), 0, list);
1019 SetLastError(ERROR_INVALID_HANDLE);
1024 /***********************************************************************
1025 * SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@)
1027 BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(
1028 HDEVINFO DeviceInfoSet,
1029 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
1030 PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData,
1031 DWORD DeviceInterfaceDetailDataSize,
1032 PDWORD RequiredSize,
1033 PSP_DEVINFO_DATA DeviceInfoData)
1037 FIXME("(%p, %p, %p, %ld, %p, %p)\n", DeviceInfoSet,
1038 DeviceInterfaceData, DeviceInterfaceDetailData,
1039 DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
1041 SetLastError(ERROR_INVALID_HANDLE);
1045 /***********************************************************************
1046 * SetupDiGetDeviceInterfaceDetailW (SETUPAPI.@)
1048 BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(
1049 HDEVINFO DeviceInfoSet,
1050 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
1051 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData,
1052 DWORD DeviceInterfaceDetailDataSize,
1053 PDWORD RequiredSize,
1054 PSP_DEVINFO_DATA DeviceInfoData)
1056 FIXME("(%p, %p, %p, %ld, %p, %p): stub\n", DeviceInfoSet,
1057 DeviceInterfaceData, DeviceInterfaceDetailData,
1058 DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
1062 /***********************************************************************
1063 * SetupDiGetDeviceRegistryPropertyA (SETUPAPI.@)
1065 BOOL WINAPI SetupDiGetDeviceRegistryPropertyA(
1067 PSP_DEVINFO_DATA DeviceInfoData,
1069 PDWORD PropertyRegDataType,
1070 PBYTE PropertyBuffer,
1071 DWORD PropertyBufferSize,
1072 PDWORD RequiredSize)
1074 FIXME("%04lx %p %ld %p %p %ld %p\n", (DWORD)devinfo, DeviceInfoData,
1075 Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize,
1080 /***********************************************************************
1081 * SetupDiInstallClassA (SETUPAPI.@)
1083 BOOL WINAPI SetupDiInstallClassA(
1089 UNICODE_STRING FileNameW;
1092 if (!RtlCreateUnicodeStringFromAsciiz(&FileNameW, InfFileName))
1094 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1098 Result = SetupDiInstallClassW(hwndParent, FileNameW.Buffer, Flags, FileQueue);
1100 RtlFreeUnicodeString(&FileNameW);
1105 static HKEY CreateClassKey(HINF hInf)
1107 WCHAR FullBuffer[MAX_PATH];
1108 WCHAR Buffer[MAX_PATH];
1112 if (!SetupGetLineTextW(NULL,
1120 return INVALID_HANDLE_VALUE;
1123 lstrcpyW(FullBuffer, ControlClass);
1124 lstrcatW(FullBuffer, Buffer);
1126 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1132 if (!SetupGetLineTextW(NULL,
1140 return INVALID_HANDLE_VALUE;
1143 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,
1147 REG_OPTION_NON_VOLATILE,
1153 return INVALID_HANDLE_VALUE;
1158 if (RegSetValueExW(hClassKey,
1163 RequiredSize * sizeof(WCHAR)))
1165 RegCloseKey(hClassKey);
1166 RegDeleteKeyW(HKEY_LOCAL_MACHINE,
1168 return INVALID_HANDLE_VALUE;
1174 /***********************************************************************
1175 * SetupDiInstallClassW (SETUPAPI.@)
1177 BOOL WINAPI SetupDiInstallClassW(
1183 WCHAR SectionName[MAX_PATH];
1184 DWORD SectionNameLength = 0;
1186 BOOL bFileQueueCreated = FALSE;
1192 if ((Flags & DI_NOVCP) && (FileQueue == NULL || FileQueue == INVALID_HANDLE_VALUE))
1194 SetLastError(ERROR_INVALID_PARAMETER);
1198 /* Open the .inf file */
1199 hInf = SetupOpenInfFileW(InfFileName,
1203 if (hInf == INVALID_HANDLE_VALUE)
1209 /* Create or open the class registry key 'HKLM\\CurrentControlSet\\Class\\{GUID}' */
1210 hClassKey = CreateClassKey(hInf);
1211 if (hClassKey == INVALID_HANDLE_VALUE)
1213 SetupCloseInfFile(hInf);
1218 /* Try to append a layout file */
1220 SetupOpenAppendInfFileW(NULL, hInf, NULL);
1223 /* Retrieve the actual section name */
1224 SetupDiGetActualSectionToInstallW(hInf,
1232 if (!(Flags & DI_NOVCP))
1234 FileQueue = SetupOpenFileQueue();
1235 if (FileQueue == INVALID_HANDLE_VALUE)
1237 SetupCloseInfFile(hInf);
1241 bFileQueueCreated = TRUE;
1246 SetupInstallFromInfSectionW(NULL,
1255 INVALID_HANDLE_VALUE,
1258 /* FIXME: More code! */
1260 if (bFileQueueCreated)
1261 SetupCloseFileQueue(FileQueue);
1263 SetupCloseInfFile(hInf);
1269 /***********************************************************************
1270 * SetupDiOpenClassRegKey (SETUPAPI.@)
1272 HKEY WINAPI SetupDiOpenClassRegKey(
1273 const GUID* ClassGuid,
1276 return SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
1277 DIOCR_INSTALLER, NULL, NULL);
1281 /***********************************************************************
1282 * SetupDiOpenClassRegKeyExA (SETUPAPI.@)
1284 HKEY WINAPI SetupDiOpenClassRegKeyExA(
1285 const GUID* ClassGuid,
1291 PWSTR MachineNameW = NULL;
1298 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
1299 if (MachineNameW == NULL)
1300 return INVALID_HANDLE_VALUE;
1303 hKey = SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
1304 Flags, MachineNameW, Reserved);
1307 MyFree(MachineNameW);
1313 /***********************************************************************
1314 * SetupDiOpenClassRegKeyExW (SETUPAPI.@)
1316 HKEY WINAPI SetupDiOpenClassRegKeyExW(
1317 const GUID* ClassGuid,
1323 LPWSTR lpGuidString;
1328 if (MachineName != NULL)
1330 FIXME("Remote access not supported yet!\n");
1331 return INVALID_HANDLE_VALUE;
1334 if (Flags == DIOCR_INSTALLER)
1336 lpKeyName = ControlClass;
1338 else if (Flags == DIOCR_INTERFACE)
1340 lpKeyName = DeviceClasses;
1344 ERR("Invalid Flags parameter!\n");
1345 SetLastError(ERROR_INVALID_PARAMETER);
1346 return INVALID_HANDLE_VALUE;
1349 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1355 return INVALID_HANDLE_VALUE;
1358 if (ClassGuid == NULL)
1361 if (UuidToStringW((UUID*)ClassGuid, &lpGuidString) != RPC_S_OK)
1363 RegCloseKey(hClassesKey);
1367 if (RegOpenKeyExW(hClassesKey,
1373 RpcStringFreeW(&lpGuidString);
1374 RegCloseKey(hClassesKey);
1378 RpcStringFreeW(&lpGuidString);
1379 RegCloseKey(hClassesKey);
1384 /***********************************************************************
1385 * SetupDiOpenDeviceInterfaceW (SETUPAPI.@)
1387 BOOL WINAPI SetupDiOpenDeviceInterfaceW(
1388 HDEVINFO DeviceInfoSet,
1391 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
1393 FIXME("%p %s %08lx %p\n",
1394 DeviceInfoSet, debugstr_w(DevicePath), OpenFlags, DeviceInterfaceData);
1398 /***********************************************************************
1399 * SetupDiOpenDeviceInterfaceA (SETUPAPI.@)
1401 BOOL WINAPI SetupDiOpenDeviceInterfaceA(
1402 HDEVINFO DeviceInfoSet,
1405 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
1407 FIXME("%p %s %08lx %p\n", DeviceInfoSet,
1408 debugstr_a(DevicePath), OpenFlags, DeviceInterfaceData);
1412 /***********************************************************************
1413 * SetupDiSetClassInstallParamsA (SETUPAPI.@)
1415 BOOL WINAPI SetupDiSetClassInstallParamsA(
1416 HDEVINFO DeviceInfoSet,
1417 PSP_DEVINFO_DATA DeviceInfoData,
1418 PSP_CLASSINSTALL_HEADER ClassInstallParams,
1419 DWORD ClassInstallParamsSize)
1421 FIXME("%p %p %x %lu\n",DeviceInfoSet, DeviceInfoData,
1422 ClassInstallParams->InstallFunction, ClassInstallParamsSize);
1426 /***********************************************************************
1427 * SetupDiCallClassInstaller (SETUPAPI.@)
1429 BOOL WINAPI SetupDiCallClassInstaller(
1430 DI_FUNCTION InstallFunction,
1431 HDEVINFO DeviceInfoSet,
1432 PSP_DEVINFO_DATA DeviceInfoData)
1434 FIXME("%d %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData);
1438 /***********************************************************************
1439 * SetupDiGetDeviceInstallParamsA (SETUPAPI.@)
1441 BOOL WINAPI SetupDiGetDeviceInstallParamsA(
1442 HDEVINFO DeviceInfoSet,
1443 PSP_DEVINFO_DATA DeviceInfoData,
1444 PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
1446 FIXME("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstallParams);
1450 /***********************************************************************
1451 * SetupDiOpenDevRegKey (SETUPAPI.@)
1453 HKEY WINAPI SetupDiOpenDevRegKey(
1454 HDEVINFO DeviceInfoSet,
1455 PSP_DEVINFO_DATA DeviceInfoData,
1461 FIXME("%p %p %ld %ld %ld %lx\n", DeviceInfoSet, DeviceInfoData,
1462 Scope, HwProfile, KeyType, samDesired);
1463 return INVALID_HANDLE_VALUE;