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};
72 /***********************************************************************
73 * SetupDiBuildClassInfoList (SETUPAPI.@)
75 * Returns a list of setup class GUIDs that identify the classes
76 * that are installed on a local machine.
79 * Flags [I] control exclusion of classes from the list.
80 * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
81 * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
82 * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
88 BOOL WINAPI SetupDiBuildClassInfoList(
91 DWORD ClassGuidListSize,
95 return SetupDiBuildClassInfoListExW(Flags, ClassGuidList,
96 ClassGuidListSize, RequiredSize,
100 /***********************************************************************
101 * SetupDiBuildClassInfoListExA (SETUPAPI.@)
103 * Returns a list of setup class GUIDs that identify the classes
104 * that are installed on a local or remote macine.
107 * Flags [I] control exclusion of classes from the list.
108 * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
109 * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
110 * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
111 * MachineName [I] name of a remote machine.
112 * Reserved [I] must be NULL.
118 BOOL WINAPI SetupDiBuildClassInfoListExA(
120 LPGUID ClassGuidList,
121 DWORD ClassGuidListSize,
126 LPWSTR MachineNameW = NULL;
133 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
134 if (MachineNameW == NULL) return FALSE;
137 bResult = SetupDiBuildClassInfoListExW(Flags, ClassGuidList,
138 ClassGuidListSize, RequiredSize,
139 MachineNameW, Reserved);
142 MyFree(MachineNameW);
147 /***********************************************************************
148 * SetupDiBuildClassInfoListExW (SETUPAPI.@)
150 * Returns a list of setup class GUIDs that identify the classes
151 * that are installed on a local or remote macine.
154 * Flags [I] control exclusion of classes from the list.
155 * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
156 * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
157 * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
158 * MachineName [I] name of a remote machine.
159 * Reserved [I] must be NULL.
165 BOOL WINAPI SetupDiBuildClassInfoListExW(
167 LPGUID ClassGuidList,
168 DWORD ClassGuidListSize,
179 DWORD dwGuidListIndex = 0;
183 if (RequiredSize != NULL)
186 hClassesKey = SetupDiOpenClassRegKeyExW(NULL,
191 if (hClassesKey == INVALID_HANDLE_VALUE)
196 for (dwIndex = 0; ; dwIndex++)
199 lError = RegEnumKeyExW(hClassesKey,
207 TRACE("RegEnumKeyExW() returns %ld\n", lError);
208 if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
210 TRACE("Key name: %p\n", szKeyName);
212 if (RegOpenKeyExW(hClassesKey,
218 RegCloseKey(hClassesKey);
222 if (!RegQueryValueExW(hClassKey,
229 TRACE("'NoUseClass' value found!\n");
230 RegCloseKey(hClassKey);
234 if ((Flags & DIBCI_NOINSTALLCLASS) &&
235 (!RegQueryValueExW(hClassKey,
242 TRACE("'NoInstallClass' value found!\n");
243 RegCloseKey(hClassKey);
247 if ((Flags & DIBCI_NODISPLAYCLASS) &&
248 (!RegQueryValueExW(hClassKey,
255 TRACE("'NoDisplayClass' value found!\n");
256 RegCloseKey(hClassKey);
260 RegCloseKey(hClassKey);
262 TRACE("Guid: %p\n", szKeyName);
263 if (dwGuidListIndex < ClassGuidListSize)
265 if (szKeyName[0] == L'{' && szKeyName[37] == L'}')
269 TRACE("Guid: %p\n", &szKeyName[1]);
271 UuidFromStringW(&szKeyName[1],
272 &ClassGuidList[dwGuidListIndex]);
278 if (lError != ERROR_SUCCESS)
282 RegCloseKey(hClassesKey);
284 if (RequiredSize != NULL)
285 *RequiredSize = dwGuidListIndex;
287 if (ClassGuidListSize < dwGuidListIndex)
289 SetLastError(ERROR_INSUFFICIENT_BUFFER);
296 /***********************************************************************
297 * SetupDiClassGuidsFromNameA (SETUPAPI.@)
299 BOOL WINAPI SetupDiClassGuidsFromNameA(
301 LPGUID ClassGuidList,
302 DWORD ClassGuidListSize,
305 return SetupDiClassGuidsFromNameExA(ClassName, ClassGuidList,
306 ClassGuidListSize, RequiredSize,
310 /***********************************************************************
311 * SetupDiClassGuidsFromNameW (SETUPAPI.@)
313 BOOL WINAPI SetupDiClassGuidsFromNameW(
315 LPGUID ClassGuidList,
316 DWORD ClassGuidListSize,
319 return SetupDiClassGuidsFromNameExW(ClassName, ClassGuidList,
320 ClassGuidListSize, RequiredSize,
324 /***********************************************************************
325 * SetupDiClassGuidsFromNameExA (SETUPAPI.@)
327 BOOL WINAPI SetupDiClassGuidsFromNameExA(
329 LPGUID ClassGuidList,
330 DWORD ClassGuidListSize,
335 LPWSTR ClassNameW = NULL;
336 LPWSTR MachineNameW = NULL;
341 ClassNameW = MultiByteToUnicode(ClassName, CP_ACP);
342 if (ClassNameW == NULL)
347 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
348 if (MachineNameW == NULL)
355 bResult = SetupDiClassGuidsFromNameExW(ClassNameW, ClassGuidList,
356 ClassGuidListSize, RequiredSize,
357 MachineNameW, Reserved);
360 MyFree(MachineNameW);
367 /***********************************************************************
368 * SetupDiClassGuidsFromNameExW (SETUPAPI.@)
370 BOOL WINAPI SetupDiClassGuidsFromNameExW(
372 LPGUID ClassGuidList,
373 DWORD ClassGuidListSize,
379 WCHAR szClassName[256];
385 DWORD dwGuidListIndex = 0;
387 if (RequiredSize != NULL)
390 hClassesKey = SetupDiOpenClassRegKeyExW(NULL,
395 if (hClassesKey == INVALID_HANDLE_VALUE)
400 for (dwIndex = 0; ; dwIndex++)
403 lError = RegEnumKeyExW(hClassesKey,
411 TRACE("RegEnumKeyExW() returns %ld\n", lError);
412 if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
414 TRACE("Key name: %p\n", szKeyName);
416 if (RegOpenKeyExW(hClassesKey,
422 RegCloseKey(hClassesKey);
426 dwLength = 256 * sizeof(WCHAR);
427 if (!RegQueryValueExW(hClassKey,
434 TRACE("Class name: %p\n", szClassName);
436 if (strcmpiW(szClassName, ClassName) == 0)
438 TRACE("Found matching class name\n");
440 TRACE("Guid: %p\n", szKeyName);
441 if (dwGuidListIndex < ClassGuidListSize)
443 if (szKeyName[0] == L'{' && szKeyName[37] == L'}')
447 TRACE("Guid: %p\n", &szKeyName[1]);
449 UuidFromStringW(&szKeyName[1],
450 &ClassGuidList[dwGuidListIndex]);
457 RegCloseKey(hClassKey);
460 if (lError != ERROR_SUCCESS)
464 RegCloseKey(hClassesKey);
466 if (RequiredSize != NULL)
467 *RequiredSize = dwGuidListIndex;
469 if (ClassGuidListSize < dwGuidListIndex)
471 SetLastError(ERROR_INSUFFICIENT_BUFFER);
478 /***********************************************************************
479 * SetupDiClassNameFromGuidA (SETUPAPI.@)
481 BOOL WINAPI SetupDiClassNameFromGuidA(
482 const GUID* ClassGuid,
487 return SetupDiClassNameFromGuidExA(ClassGuid, ClassName,
488 ClassNameSize, RequiredSize,
492 /***********************************************************************
493 * SetupDiClassNameFromGuidW (SETUPAPI.@)
495 BOOL WINAPI SetupDiClassNameFromGuidW(
496 const GUID* ClassGuid,
501 return SetupDiClassNameFromGuidExW(ClassGuid, ClassName,
502 ClassNameSize, RequiredSize,
506 /***********************************************************************
507 * SetupDiClassNameFromGuidExA (SETUPAPI.@)
509 BOOL WINAPI SetupDiClassNameFromGuidExA(
510 const GUID* ClassGuid,
517 WCHAR ClassNameW[MAX_CLASS_NAME_LEN];
518 LPWSTR MachineNameW = NULL;
522 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
523 ret = SetupDiClassNameFromGuidExW(ClassGuid, ClassNameW, MAX_CLASS_NAME_LEN,
524 NULL, MachineNameW, Reserved);
527 int len = WideCharToMultiByte(CP_ACP, 0, ClassNameW, -1, ClassName,
528 ClassNameSize, NULL, NULL);
530 if (!ClassNameSize && RequiredSize)
533 MyFree(MachineNameW);
537 /***********************************************************************
538 * SetupDiClassNameFromGuidExW (SETUPAPI.@)
540 BOOL WINAPI SetupDiClassNameFromGuidExW(
541 const GUID* ClassGuid,
551 hKey = SetupDiOpenClassRegKeyExW(ClassGuid,
556 if (hKey == INVALID_HANDLE_VALUE)
561 if (RequiredSize != NULL)
564 if (RegQueryValueExW(hKey,
575 *RequiredSize = dwLength / sizeof(WCHAR);
578 dwLength = ClassNameSize * sizeof(WCHAR);
579 if (RegQueryValueExW(hKey,
595 /***********************************************************************
596 * SetupDiCreateDeviceInfoList (SETUPAPI.@)
599 SetupDiCreateDeviceInfoList(const GUID *ClassGuid,
602 return SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent, NULL, NULL);
605 /***********************************************************************
606 * SetupDiCreateDeviceInfoListExA (SETUPAPI.@)
609 SetupDiCreateDeviceInfoListExA(const GUID *ClassGuid,
614 LPWSTR MachineNameW = NULL;
621 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
622 if (MachineNameW == NULL)
623 return (HDEVINFO)INVALID_HANDLE_VALUE;
626 hDevInfo = SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent,
627 MachineNameW, Reserved);
630 MyFree(MachineNameW);
635 /***********************************************************************
636 * SetupDiCreateDeviceInfoListExW (SETUPAPI.@)
639 SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid,
645 return (HDEVINFO)INVALID_HANDLE_VALUE;
648 /***********************************************************************
649 * SetupDiEnumDeviceInfo (SETUPAPI.@)
651 BOOL WINAPI SetupDiEnumDeviceInfo(
654 PSP_DEVINFO_DATA info)
656 FIXME("%p %ld %p\n", devinfo, index, info);
660 if(info->cbSize < sizeof(*info))
666 /***********************************************************************
667 * SetupDiGetActualSectionToInstallA (SETUPAPI.@)
669 BOOL WINAPI SetupDiGetActualSectionToInstallA(
671 PCSTR InfSectionName,
672 PSTR InfSectionWithExt,
673 DWORD InfSectionWithExtSize,
681 /***********************************************************************
682 * SetupDiGetActualSectionToInstallW (SETUPAPI.@)
684 BOOL WINAPI SetupDiGetActualSectionToInstallW(
686 PCWSTR InfSectionName,
687 PWSTR InfSectionWithExt,
688 DWORD InfSectionWithExtSize,
692 WCHAR szBuffer[MAX_PATH];
695 LONG lLineCount = -1;
697 lstrcpyW(szBuffer, InfSectionName);
698 dwLength = lstrlenW(szBuffer);
700 if (OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
702 /* Test section name with '.NTx86' extension */
703 lstrcpyW(&szBuffer[dwLength], NtPlatformExtension);
704 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
706 if (lLineCount == -1)
708 /* Test section name with '.NT' extension */
709 lstrcpyW(&szBuffer[dwLength], NtExtension);
710 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
715 /* Test section name with '.Win' extension */
716 lstrcpyW(&szBuffer[dwLength], WinExtension);
717 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
720 if (lLineCount == -1)
722 /* Test section name without extension */
723 szBuffer[dwLength] = 0;
724 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
727 if (lLineCount == -1)
729 SetLastError(ERROR_INVALID_PARAMETER);
733 dwFullLength = lstrlenW(szBuffer);
735 if (InfSectionWithExt != NULL && InfSectionWithExtSize != 0)
737 if (InfSectionWithExtSize < (dwFullLength + 1))
739 SetLastError(ERROR_INSUFFICIENT_BUFFER);
743 lstrcpyW(InfSectionWithExt, szBuffer);
744 if (Extension != NULL)
746 *Extension = (dwLength == dwFullLength) ? NULL : &InfSectionWithExt[dwLength];
750 if (RequiredSize != NULL)
752 *RequiredSize = dwFullLength + 1;
758 /***********************************************************************
759 * SetupDiGetClassDescriptionA (SETUPAPI.@)
761 BOOL WINAPI SetupDiGetClassDescriptionA(
762 const GUID* ClassGuid,
763 PSTR ClassDescription,
764 DWORD ClassDescriptionSize,
767 return SetupDiGetClassDescriptionExA(ClassGuid, ClassDescription,
768 ClassDescriptionSize,
769 RequiredSize, NULL, NULL);
772 /***********************************************************************
773 * SetupDiGetClassDescriptionW (SETUPAPI.@)
775 BOOL WINAPI SetupDiGetClassDescriptionW(
776 const GUID* ClassGuid,
777 PWSTR ClassDescription,
778 DWORD ClassDescriptionSize,
781 return SetupDiGetClassDescriptionExW(ClassGuid, ClassDescription,
782 ClassDescriptionSize,
783 RequiredSize, NULL, NULL);
786 /***********************************************************************
787 * SetupDiGetClassDescriptionExA (SETUPAPI.@)
789 BOOL WINAPI SetupDiGetClassDescriptionExA(
790 const GUID* ClassGuid,
791 PSTR ClassDescription,
792 DWORD ClassDescriptionSize,
801 /***********************************************************************
802 * SetupDiGetClassDescriptionExW (SETUPAPI.@)
804 BOOL WINAPI SetupDiGetClassDescriptionExW(
805 const GUID* ClassGuid,
806 PWSTR ClassDescription,
807 DWORD ClassDescriptionSize,
815 hKey = SetupDiOpenClassRegKeyExW(ClassGuid,
820 if (hKey == INVALID_HANDLE_VALUE)
822 WARN("SetupDiOpenClassRegKeyExW() failed (Error %lu)\n", GetLastError());
826 if (RequiredSize != NULL)
829 if (RegQueryValueExW(hKey,
840 *RequiredSize = dwLength / sizeof(WCHAR);
843 dwLength = ClassDescriptionSize * sizeof(WCHAR);
844 if (RegQueryValueExW(hKey,
848 (LPBYTE)ClassDescription,
860 /***********************************************************************
861 * SetupDiGetClassDevsA (SETUPAPI.@)
863 HDEVINFO WINAPI SetupDiGetClassDevsA(
870 LPWSTR enumstrW = NULL;
874 int len = MultiByteToWideChar(CP_ACP, 0, enumstr, -1, NULL, 0);
875 enumstrW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
878 ret = (HDEVINFO)INVALID_HANDLE_VALUE;
881 MultiByteToWideChar(CP_ACP, 0, enumstr, -1, enumstrW, len);
883 ret = SetupDiGetClassDevsW(class, enumstrW, parent, flags);
884 HeapFree(GetProcessHeap(), 0, enumstrW);
890 #define SETUP_SERIAL_PORT_MAGIC 0xd00ff055
892 typedef struct _SerialPortName
897 typedef struct _SerialPortList
901 SerialPortName names[1];
904 static HDEVINFO SETUP_CreateSerialDeviceList(void)
906 static const size_t initialSize = 100;
908 WCHAR buf[initialSize];
916 if (QueryDosDeviceW(NULL, devices, size) == 0)
918 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
922 HeapFree(GetProcessHeap(), 0, devices);
923 devices = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
932 } while (!*devices && !failed);
935 static const WCHAR comW[] = { 'C','O','M',0 };
937 UINT numSerialPorts = 0;
938 SerialPortList *list;
940 for (ptr = devices; *ptr; ptr += strlenW(ptr) + 1)
942 if (!strncmpW(comW, ptr, sizeof(comW) / sizeof(comW[0]) - 1))
945 list = HeapAlloc(GetProcessHeap(), 0, sizeof(SerialPortList) +
946 numSerialPorts ? (numSerialPorts - 1) * sizeof(SerialPortName) : 0);
949 list->magic = SETUP_SERIAL_PORT_MAGIC;
951 for (ptr = devices; *ptr; ptr += strlenW(ptr) + 1)
953 if (!strncmpW(comW, ptr, sizeof(comW) / sizeof(comW[0]) - 1))
955 lstrcpynW(list->names[list->numPorts].name, ptr,
956 sizeof(list->names[list->numPorts].name) /
957 sizeof(list->names[list->numPorts].name[0]));
958 TRACE("Adding %s to list\n",
959 debugstr_w(list->names[list->numPorts].name));
963 TRACE("list->numPorts is %d\n", list->numPorts);
965 ret = (HDEVINFO)list;
968 ret = (HDEVINFO)INVALID_HANDLE_VALUE;
970 HeapFree(GetProcessHeap(), 0, devices);
971 TRACE("returning %p\n", ret);
975 /***********************************************************************
976 * SetupDiGetClassDevsW (SETUPAPI.@)
978 HDEVINFO WINAPI SetupDiGetClassDevsW(
984 HDEVINFO ret = (HDEVINFO)INVALID_HANDLE_VALUE;
986 TRACE("%s %s %p 0x%08lx\n", debugstr_guid(class), debugstr_w(enumstr),
990 FIXME(": unimplemented for enumerator strings (%s)\n",
991 debugstr_w(enumstr));
992 else if (flags & DIGCF_ALLCLASSES)
993 FIXME(": unimplemented for DIGCF_ALLCLASSES\n");
996 if (IsEqualIID(class, &GUID_DEVINTERFACE_COMPORT))
997 ret = SETUP_CreateSerialDeviceList();
998 else if (IsEqualIID(class, &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR))
999 ret = SETUP_CreateSerialDeviceList();
1001 FIXME("(%s): stub\n", debugstr_guid(class));
1006 /***********************************************************************
1007 * SetupDiEnumDeviceInterfaces (SETUPAPI.@)
1009 BOOL WINAPI SetupDiEnumDeviceInterfaces(
1010 HDEVINFO DeviceInfoSet,
1011 PSP_DEVINFO_DATA DeviceInfoData,
1012 CONST GUID * InterfaceClassGuid,
1014 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
1018 TRACE("%p, %p, %s, 0x%08lx, %p\n", DeviceInfoSet, DeviceInfoData,
1019 debugstr_guid(InterfaceClassGuid), MemberIndex, DeviceInterfaceData);
1020 if (!DeviceInterfaceData)
1021 SetLastError(ERROR_INVALID_PARAMETER);
1022 else if (DeviceInfoData)
1023 FIXME(": unimplemented with PSP_DEVINFO_DATA set\n");
1024 else if (DeviceInfoSet && DeviceInfoSet != (HDEVINFO)INVALID_HANDLE_VALUE)
1026 /* FIXME: this assumes the only possible enumeration is of serial
1029 SerialPortList *list = (SerialPortList *)DeviceInfoSet;
1031 if (list->magic == SETUP_SERIAL_PORT_MAGIC)
1033 if (MemberIndex >= list->numPorts)
1034 SetLastError(ERROR_NO_MORE_ITEMS);
1037 DeviceInterfaceData->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
1038 memcpy(&DeviceInterfaceData->InterfaceClassGuid,
1039 &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR,
1040 sizeof(DeviceInterfaceData->InterfaceClassGuid));
1041 DeviceInterfaceData->Flags = 0;
1042 /* Note: this appears to be dangerous, passing a private
1043 * pointer a heap-allocated datum to the caller. However, the
1044 * expected lifetime of the device data is the same as the
1045 * HDEVINFO; once that is closed, the data are no longer valid.
1047 DeviceInterfaceData->Reserved =
1048 (ULONG_PTR)&list->names[MemberIndex].name;
1053 SetLastError(ERROR_INVALID_HANDLE);
1056 SetLastError(ERROR_INVALID_HANDLE);
1060 /***********************************************************************
1061 * SetupDiDestroyDeviceInfoList (SETUPAPI.@)
1063 BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
1067 TRACE("%p\n", devinfo);
1068 if (devinfo && devinfo != (HDEVINFO)INVALID_HANDLE_VALUE)
1070 /* FIXME: this assumes the only possible enumeration is of serial
1073 SerialPortList *list = (SerialPortList *)devinfo;
1075 if (list->magic == SETUP_SERIAL_PORT_MAGIC)
1077 HeapFree(GetProcessHeap(), 0, list);
1081 SetLastError(ERROR_INVALID_HANDLE);
1084 SetLastError(ERROR_INVALID_HANDLE);
1088 /***********************************************************************
1089 * SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@)
1091 BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(
1092 HDEVINFO DeviceInfoSet,
1093 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
1094 PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData,
1095 DWORD DeviceInterfaceDetailDataSize,
1096 PDWORD RequiredSize,
1097 PSP_DEVINFO_DATA DeviceInfoData)
1101 TRACE("(%p, %p, %p, %ld, %p, %p)\n", DeviceInfoSet,
1102 DeviceInterfaceData, DeviceInterfaceDetailData,
1103 DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
1104 if (!DeviceInterfaceData)
1105 SetLastError(ERROR_INVALID_PARAMETER);
1106 else if ((DeviceInterfaceDetailDataSize && !DeviceInterfaceDetailData) ||
1107 (DeviceInterfaceDetailData && !DeviceInterfaceDetailDataSize))
1108 SetLastError(ERROR_INVALID_PARAMETER);
1109 else if (DeviceInfoSet && DeviceInfoSet != (HDEVINFO)INVALID_HANDLE_VALUE)
1111 /* FIXME: this assumes the only possible enumeration is of serial
1114 SerialPortList *list = (SerialPortList *)DeviceInfoSet;
1116 if (list->magic == SETUP_SERIAL_PORT_MAGIC)
1118 LPCWSTR devName = (LPCWSTR)DeviceInterfaceData->Reserved;
1119 DWORD sizeRequired = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A) +
1122 if (sizeRequired > DeviceInterfaceDetailDataSize)
1124 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1126 *RequiredSize = sizeRequired;
1130 LPSTR dst = DeviceInterfaceDetailData->DevicePath;
1131 LPCWSTR src = devName;
1133 /* MSDN claims cbSize must be set by the caller, but it lies */
1134 DeviceInterfaceDetailData->cbSize =
1135 sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
1136 for ( ; *src; src++, dst++)
1139 TRACE("DevicePath is %s\n",
1140 debugstr_a(DeviceInterfaceDetailData->DevicePath));
1143 DeviceInfoData->cbSize = sizeof(SP_DEVINFO_DATA);
1144 memcpy(&DeviceInfoData->ClassGuid,
1145 &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR,
1146 sizeof(DeviceInfoData->ClassGuid));
1147 DeviceInfoData->DevInst = 0;
1148 DeviceInfoData->Reserved = (ULONG_PTR)devName;
1154 SetLastError(ERROR_INVALID_HANDLE);
1157 SetLastError(ERROR_INVALID_HANDLE);
1158 TRACE("Returning %d\n", ret);
1162 /***********************************************************************
1163 * SetupDiGetDeviceInterfaceDetailW (SETUPAPI.@)
1165 BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(
1166 HDEVINFO DeviceInfoSet,
1167 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
1168 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData,
1169 DWORD DeviceInterfaceDetailDataSize,
1170 PDWORD RequiredSize,
1171 PSP_DEVINFO_DATA DeviceInfoData)
1173 FIXME("(%p, %p, %p, %ld, %p, %p): stub\n", DeviceInfoSet,
1174 DeviceInterfaceData, DeviceInterfaceDetailData,
1175 DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
1179 /***********************************************************************
1180 * SetupDiGetDeviceRegistryPropertyA (SETUPAPI.@)
1182 BOOL WINAPI SetupDiGetDeviceRegistryPropertyA(
1184 PSP_DEVINFO_DATA DeviceInfoData,
1186 PDWORD PropertyRegDataType,
1187 PBYTE PropertyBuffer,
1188 DWORD PropertyBufferSize,
1189 PDWORD RequiredSize)
1191 FIXME("%04lx %p %ld %p %p %ld %p\n", (DWORD)devinfo, DeviceInfoData,
1192 Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize,
1197 /***********************************************************************
1198 * SetupDiInstallClassA (SETUPAPI.@)
1200 BOOL WINAPI SetupDiInstallClassA(
1206 UNICODE_STRING FileNameW;
1209 if (!RtlCreateUnicodeStringFromAsciiz(&FileNameW, InfFileName))
1211 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1215 Result = SetupDiInstallClassW(hwndParent, FileNameW.Buffer, Flags, FileQueue);
1217 RtlFreeUnicodeString(&FileNameW);
1222 static HKEY CreateClassKey(HINF hInf)
1224 WCHAR FullBuffer[MAX_PATH];
1225 WCHAR Buffer[MAX_PATH];
1229 if (!SetupGetLineTextW(NULL,
1237 return INVALID_HANDLE_VALUE;
1240 lstrcpyW(FullBuffer, ControlClass);
1241 lstrcatW(FullBuffer, Buffer);
1243 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1249 if (!SetupGetLineTextW(NULL,
1257 return INVALID_HANDLE_VALUE;
1260 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,
1264 REG_OPTION_NON_VOLATILE,
1270 return INVALID_HANDLE_VALUE;
1275 if (RegSetValueExW(hClassKey,
1280 RequiredSize * sizeof(WCHAR)))
1282 RegCloseKey(hClassKey);
1283 RegDeleteKeyW(HKEY_LOCAL_MACHINE,
1285 return INVALID_HANDLE_VALUE;
1291 /***********************************************************************
1292 * SetupDiInstallClassW (SETUPAPI.@)
1294 BOOL WINAPI SetupDiInstallClassW(
1300 WCHAR SectionName[MAX_PATH];
1301 DWORD SectionNameLength = 0;
1303 BOOL bFileQueueCreated = FALSE;
1309 if ((Flags & DI_NOVCP) && (FileQueue == NULL || FileQueue == INVALID_HANDLE_VALUE))
1311 SetLastError(ERROR_INVALID_PARAMETER);
1315 /* Open the .inf file */
1316 hInf = SetupOpenInfFileW(InfFileName,
1320 if (hInf == INVALID_HANDLE_VALUE)
1326 /* Create or open the class registry key 'HKLM\\CurrentControlSet\\Class\\{GUID}' */
1327 hClassKey = CreateClassKey(hInf);
1328 if (hClassKey == INVALID_HANDLE_VALUE)
1330 SetupCloseInfFile(hInf);
1335 /* Try to append a layout file */
1337 SetupOpenAppendInfFileW(NULL, hInf, NULL);
1340 /* Retrieve the actual section name */
1341 SetupDiGetActualSectionToInstallW(hInf,
1349 if (!(Flags & DI_NOVCP))
1351 FileQueue = SetupOpenFileQueue();
1352 if (FileQueue == INVALID_HANDLE_VALUE)
1354 SetupCloseInfFile(hInf);
1358 bFileQueueCreated = TRUE;
1363 SetupInstallFromInfSectionW(NULL,
1372 INVALID_HANDLE_VALUE,
1375 /* FIXME: More code! */
1377 if (bFileQueueCreated)
1378 SetupCloseFileQueue(FileQueue);
1380 SetupCloseInfFile(hInf);
1386 /***********************************************************************
1387 * SetupDiOpenClassRegKey (SETUPAPI.@)
1389 HKEY WINAPI SetupDiOpenClassRegKey(
1390 const GUID* ClassGuid,
1393 return SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
1394 DIOCR_INSTALLER, NULL, NULL);
1398 /***********************************************************************
1399 * SetupDiOpenClassRegKeyExA (SETUPAPI.@)
1401 HKEY WINAPI SetupDiOpenClassRegKeyExA(
1402 const GUID* ClassGuid,
1408 PWSTR MachineNameW = NULL;
1415 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
1416 if (MachineNameW == NULL)
1417 return INVALID_HANDLE_VALUE;
1420 hKey = SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
1421 Flags, MachineNameW, Reserved);
1424 MyFree(MachineNameW);
1430 /***********************************************************************
1431 * SetupDiOpenClassRegKeyExW (SETUPAPI.@)
1433 HKEY WINAPI SetupDiOpenClassRegKeyExW(
1434 const GUID* ClassGuid,
1440 LPWSTR lpGuidString;
1445 if (MachineName != NULL)
1447 FIXME("Remote access not supported yet!\n");
1448 return INVALID_HANDLE_VALUE;
1451 if (Flags == DIOCR_INSTALLER)
1453 lpKeyName = ControlClass;
1455 else if (Flags == DIOCR_INTERFACE)
1457 lpKeyName = DeviceClasses;
1461 ERR("Invalid Flags parameter!\n");
1462 SetLastError(ERROR_INVALID_PARAMETER);
1463 return INVALID_HANDLE_VALUE;
1466 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1472 return INVALID_HANDLE_VALUE;
1475 if (ClassGuid == NULL)
1478 if (UuidToStringW((UUID*)ClassGuid, &lpGuidString) != RPC_S_OK)
1480 RegCloseKey(hClassesKey);
1484 if (RegOpenKeyExW(hClassesKey,
1490 RpcStringFreeW(&lpGuidString);
1491 RegCloseKey(hClassesKey);
1495 RpcStringFreeW(&lpGuidString);
1496 RegCloseKey(hClassesKey);
1501 /***********************************************************************
1502 * SetupDiOpenDeviceInterfaceW (SETUPAPI.@)
1504 BOOL WINAPI SetupDiOpenDeviceInterfaceW(
1505 HDEVINFO DeviceInfoSet,
1508 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
1510 FIXME("%p %s %08lx %p\n",
1511 DeviceInfoSet, debugstr_w(DevicePath), OpenFlags, DeviceInterfaceData);
1515 /***********************************************************************
1516 * SetupDiOpenDeviceInterfaceA (SETUPAPI.@)
1518 BOOL WINAPI SetupDiOpenDeviceInterfaceA(
1519 HDEVINFO DeviceInfoSet,
1522 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
1524 FIXME("%p %s %08lx %p\n", DeviceInfoSet,
1525 debugstr_a(DevicePath), OpenFlags, DeviceInterfaceData);
1529 /***********************************************************************
1530 * SetupDiSetClassInstallParamsA (SETUPAPI.@)
1532 BOOL WINAPI SetupDiSetClassInstallParamsA(
1533 HDEVINFO DeviceInfoSet,
1534 PSP_DEVINFO_DATA DeviceInfoData,
1535 PSP_CLASSINSTALL_HEADER ClassInstallParams,
1536 DWORD ClassInstallParamsSize)
1538 FIXME("%p %p %x %lu\n",DeviceInfoSet, DeviceInfoData,
1539 ClassInstallParams->InstallFunction, ClassInstallParamsSize);
1543 /***********************************************************************
1544 * SetupDiCallClassInstaller (SETUPAPI.@)
1546 BOOL WINAPI SetupDiCallClassInstaller(
1547 DI_FUNCTION InstallFunction,
1548 HDEVINFO DeviceInfoSet,
1549 PSP_DEVINFO_DATA DeviceInfoData)
1551 FIXME("%d %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData);
1555 /***********************************************************************
1556 * SetupDiGetDeviceInstallParamsA (SETUPAPI.@)
1558 BOOL WINAPI SetupDiGetDeviceInstallParamsA(
1559 HDEVINFO DeviceInfoSet,
1560 PSP_DEVINFO_DATA DeviceInfoData,
1561 PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
1563 FIXME("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstallParams);
1567 /***********************************************************************
1568 * SetupDiOpenDevRegKey (SETUPAPI.@)
1570 HKEY WINAPI SetupDiOpenDevRegKey(
1571 HDEVINFO DeviceInfoSet,
1572 PSP_DEVINFO_DATA DeviceInfoData,
1578 FIXME("%p %p %ld %ld %ld %lx\n", DeviceInfoSet, DeviceInfoData,
1579 Scope, HwProfile, KeyType, samDesired);
1580 return INVALID_HANDLE_VALUE;