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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "wine/port.h"
35 #include "wine/debug.h"
36 #include "wine/unicode.h"
42 #include "setupapi_private.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
47 /* Unicode constants */
48 static const WCHAR ClassGUID[] = {'C','l','a','s','s','G','U','I','D',0};
49 static const WCHAR Class[] = {'C','l','a','s','s',0};
50 static const WCHAR ClassInstall32[] = {'C','l','a','s','s','I','n','s','t','a','l','l','3','2',0};
51 static const WCHAR NoDisplayClass[] = {'N','o','D','i','s','p','l','a','y','C','l','a','s','s',0};
52 static const WCHAR NoInstallClass[] = {'N','o','I','s','t','a','l','l','C','l','a','s','s',0};
53 static const WCHAR NoUseClass[] = {'N','o','U','s','e','C','l','a','s','s',0};
54 static const WCHAR NtExtension[] = {'.','N','T',0};
55 static const WCHAR NtPlatformExtension[] = {'.','N','T','x','8','6',0};
56 static const WCHAR Version[] = {'V','e','r','s','i','o','n',0};
57 static const WCHAR WinExtension[] = {'.','W','i','n',0};
59 /* Registry key and value names */
60 static const WCHAR ControlClass[] = {'S','y','s','t','e','m','\\',
61 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
62 'C','o','n','t','r','o','l','\\',
63 'C','l','a','s','s',0};
65 static const WCHAR DeviceClasses[] = {'S','y','s','t','e','m','\\',
66 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
67 'C','o','n','t','r','o','l','\\',
68 'D','e','v','i','c','e','C','l','a','s','s','e','s',0};
70 /***********************************************************************
71 * SetupDiBuildClassInfoList (SETUPAPI.@)
73 BOOL WINAPI SetupDiBuildClassInfoList(
76 DWORD ClassGuidListSize,
80 return SetupDiBuildClassInfoListExW(Flags, ClassGuidList,
81 ClassGuidListSize, RequiredSize,
85 /***********************************************************************
86 * SetupDiBuildClassInfoListExA (SETUPAPI.@)
88 BOOL WINAPI SetupDiBuildClassInfoListExA(
91 DWORD ClassGuidListSize,
96 LPWSTR MachineNameW = NULL;
103 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
104 if (MachineNameW == NULL) return FALSE;
107 bResult = SetupDiBuildClassInfoListExW(Flags, ClassGuidList,
108 ClassGuidListSize, RequiredSize,
109 MachineNameW, Reserved);
112 MyFree(MachineNameW);
117 /***********************************************************************
118 * SetupDiBuildClassInfoListExW (SETUPAPI.@)
120 BOOL WINAPI SetupDiBuildClassInfoListExW(
122 LPGUID ClassGuidList,
123 DWORD ClassGuidListSize,
134 DWORD dwGuidListIndex = 0;
138 if (RequiredSize != NULL)
141 hClassesKey = SetupDiOpenClassRegKeyExW(NULL,
146 if (hClassesKey == INVALID_HANDLE_VALUE)
151 for (dwIndex = 0; ; dwIndex++)
154 lError = RegEnumKeyExW(hClassesKey,
162 TRACE("RegEnumKeyExW() returns %ld\n", lError);
163 if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
165 TRACE("Key name: %p\n", szKeyName);
167 if (RegOpenKeyExW(hClassesKey,
173 RegCloseKey(hClassesKey);
177 if (!RegQueryValueExW(hClassKey,
184 TRACE("'NoUseClass' value found!\n");
185 RegCloseKey(hClassKey);
189 if ((Flags & DIBCI_NOINSTALLCLASS) &&
190 (!RegQueryValueExW(hClassKey,
197 TRACE("'NoInstallClass' value found!\n");
198 RegCloseKey(hClassKey);
202 if ((Flags & DIBCI_NODISPLAYCLASS) &&
203 (!RegQueryValueExW(hClassKey,
210 TRACE("'NoDisplayClass' value found!\n");
211 RegCloseKey(hClassKey);
215 RegCloseKey(hClassKey);
217 TRACE("Guid: %p\n", szKeyName);
218 if (dwGuidListIndex < ClassGuidListSize)
220 if (szKeyName[0] == L'{' && szKeyName[37] == L'}')
224 TRACE("Guid: %p\n", &szKeyName[1]);
226 UuidFromStringW(&szKeyName[1],
227 &ClassGuidList[dwGuidListIndex]);
233 if (lError != ERROR_SUCCESS)
237 RegCloseKey(hClassesKey);
239 if (RequiredSize != NULL)
240 *RequiredSize = dwGuidListIndex;
242 if (ClassGuidListSize < dwGuidListIndex)
244 SetLastError(ERROR_INSUFFICIENT_BUFFER);
251 /***********************************************************************
252 * SetupDiClassGuidsFromNameA (SETUPAPI.@)
254 BOOL WINAPI SetupDiClassGuidsFromNameA(
256 LPGUID ClassGuidList,
257 DWORD ClassGuidListSize,
260 return SetupDiClassGuidsFromNameExA(ClassName, ClassGuidList,
261 ClassGuidListSize, RequiredSize,
265 /***********************************************************************
266 * SetupDiClassGuidsFromNameW (SETUPAPI.@)
268 BOOL WINAPI SetupDiClassGuidsFromNameW(
270 LPGUID ClassGuidList,
271 DWORD ClassGuidListSize,
274 return SetupDiClassGuidsFromNameExW(ClassName, ClassGuidList,
275 ClassGuidListSize, RequiredSize,
279 /***********************************************************************
280 * SetupDiClassGuidsFromNameExA (SETUPAPI.@)
282 BOOL WINAPI SetupDiClassGuidsFromNameExA(
284 LPGUID ClassGuidList,
285 DWORD ClassGuidListSize,
290 LPWSTR ClassNameW = NULL;
291 LPWSTR MachineNameW = NULL;
296 ClassNameW = MultiByteToUnicode(ClassName, CP_ACP);
297 if (ClassNameW == NULL)
302 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
303 if (MachineNameW == NULL)
310 bResult = SetupDiClassGuidsFromNameExW(ClassNameW, ClassGuidList,
311 ClassGuidListSize, RequiredSize,
312 MachineNameW, Reserved);
315 MyFree(MachineNameW);
322 /***********************************************************************
323 * SetupDiClassGuidsFromNameExW (SETUPAPI.@)
325 BOOL WINAPI SetupDiClassGuidsFromNameExW(
327 LPGUID ClassGuidList,
328 DWORD ClassGuidListSize,
334 WCHAR szClassName[256];
340 DWORD dwGuidListIndex = 0;
342 if (RequiredSize != NULL)
345 hClassesKey = SetupDiOpenClassRegKeyExW(NULL,
350 if (hClassesKey == INVALID_HANDLE_VALUE)
355 for (dwIndex = 0; ; dwIndex++)
358 lError = RegEnumKeyExW(hClassesKey,
366 TRACE("RegEnumKeyExW() returns %ld\n", lError);
367 if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
369 TRACE("Key name: %p\n", szKeyName);
371 if (RegOpenKeyExW(hClassesKey,
377 RegCloseKey(hClassesKey);
381 dwLength = 256 * sizeof(WCHAR);
382 if (!RegQueryValueExW(hClassKey,
389 TRACE("Class name: %p\n", szClassName);
391 if (strcmpiW(szClassName, ClassName) == 0)
393 TRACE("Found matching class name\n");
395 TRACE("Guid: %p\n", szKeyName);
396 if (dwGuidListIndex < ClassGuidListSize)
398 if (szKeyName[0] == L'{' && szKeyName[37] == L'}')
402 TRACE("Guid: %p\n", &szKeyName[1]);
404 UuidFromStringW(&szKeyName[1],
405 &ClassGuidList[dwGuidListIndex]);
412 RegCloseKey(hClassKey);
415 if (lError != ERROR_SUCCESS)
419 RegCloseKey(hClassesKey);
421 if (RequiredSize != NULL)
422 *RequiredSize = dwGuidListIndex;
424 if (ClassGuidListSize < dwGuidListIndex)
426 SetLastError(ERROR_INSUFFICIENT_BUFFER);
433 /***********************************************************************
434 * SetupDiClassNameFromGuidA (SETUPAPI.@)
436 BOOL WINAPI SetupDiClassNameFromGuidA(
437 const GUID* ClassGuid,
442 return SetupDiClassNameFromGuidExA(ClassGuid, ClassName,
443 ClassNameSize, RequiredSize,
447 /***********************************************************************
448 * SetupDiClassNameFromGuidW (SETUPAPI.@)
450 BOOL WINAPI SetupDiClassNameFromGuidW(
451 const GUID* ClassGuid,
456 return SetupDiClassNameFromGuidExW(ClassGuid, ClassName,
457 ClassNameSize, RequiredSize,
461 /***********************************************************************
462 * SetupDiClassNameFromGuidExA (SETUPAPI.@)
464 BOOL WINAPI SetupDiClassNameFromGuidExA(
465 const GUID* ClassGuid,
476 /***********************************************************************
477 * SetupDiClassNameFromGuidExW (SETUPAPI.@)
479 BOOL WINAPI SetupDiClassNameFromGuidExW(
480 const GUID* ClassGuid,
490 hKey = SetupDiOpenClassRegKeyExW(ClassGuid,
495 if (hKey == INVALID_HANDLE_VALUE)
500 if (RequiredSize != NULL)
503 if (RegQueryValueExW(hKey,
514 *RequiredSize = dwLength / sizeof(WCHAR);
517 dwLength = ClassNameSize * sizeof(WCHAR);
518 if (RegQueryValueExW(hKey,
534 /***********************************************************************
535 * SetupDiCreateDeviceInfoList (SETUPAPI.@)
538 SetupDiCreateDeviceInfoList(const GUID *ClassGuid,
541 return SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent, NULL, NULL);
544 /***********************************************************************
545 * SetupDiCreateDeviceInfoListExA (SETUPAPI.@)
548 SetupDiCreateDeviceInfoListExA(const GUID *ClassGuid,
553 LPWSTR MachineNameW = NULL;
560 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
561 if (MachineNameW == NULL)
562 return (HDEVINFO)INVALID_HANDLE_VALUE;
565 hDevInfo = SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent,
566 MachineNameW, Reserved);
569 MyFree(MachineNameW);
574 /***********************************************************************
575 * SetupDiCreateDeviceInfoListExW (SETUPAPI.@)
578 SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid,
584 return (HDEVINFO)INVALID_HANDLE_VALUE;
587 /***********************************************************************
588 * SetupDiEnumDeviceInfo (SETUPAPI.@)
590 BOOL WINAPI SetupDiEnumDeviceInfo(
593 PSP_DEVINFO_DATA info)
595 FIXME("%p %ld %p\n", devinfo, index, info);
599 if(info->cbSize < sizeof(*info))
605 /***********************************************************************
606 * SetupDiGetActualSectionToInstallA (SETUPAPI.@)
608 BOOL WINAPI SetupDiGetActualSectionToInstallA(
610 PCSTR InfSectionName,
611 PSTR InfSectionWithExt,
612 DWORD InfSectionWithExtSize,
620 /***********************************************************************
621 * SetupDiGetActualSectionToInstallW (SETUPAPI.@)
623 BOOL WINAPI SetupDiGetActualSectionToInstallW(
625 PCWSTR InfSectionName,
626 PWSTR InfSectionWithExt,
627 DWORD InfSectionWithExtSize,
631 WCHAR szBuffer[MAX_PATH];
634 LONG lLineCount = -1;
636 lstrcpyW(szBuffer, InfSectionName);
637 dwLength = lstrlenW(szBuffer);
639 if (OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
641 /* Test section name with '.NTx86' extension */
642 lstrcpyW(&szBuffer[dwLength], NtPlatformExtension);
643 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
645 if (lLineCount == -1)
647 /* Test section name with '.NT' extension */
648 lstrcpyW(&szBuffer[dwLength], NtExtension);
649 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
654 /* Test section name with '.Win' extension */
655 lstrcpyW(&szBuffer[dwLength], WinExtension);
656 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
659 if (lLineCount == -1)
661 /* Test section name without extension */
662 szBuffer[dwLength] = 0;
663 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
666 if (lLineCount == -1)
668 SetLastError(ERROR_INVALID_PARAMETER);
672 dwFullLength = lstrlenW(szBuffer);
674 if (InfSectionWithExt != NULL && InfSectionWithExtSize != 0)
676 if (InfSectionWithExtSize < (dwFullLength + 1))
678 SetLastError(ERROR_INSUFFICIENT_BUFFER);
682 lstrcpyW(InfSectionWithExt, szBuffer);
683 if (Extension != NULL)
685 *Extension = (dwLength == dwFullLength) ? NULL : &InfSectionWithExt[dwLength];
689 if (RequiredSize != NULL)
691 *RequiredSize = dwFullLength + 1;
697 /***********************************************************************
698 * SetupDiGetClassDescriptionA (SETUPAPI.@)
700 BOOL WINAPI SetupDiGetClassDescriptionA(
701 const GUID* ClassGuid,
702 PSTR ClassDescription,
703 DWORD ClassDescriptionSize,
706 return SetupDiGetClassDescriptionExA(ClassGuid, ClassDescription,
707 ClassDescriptionSize,
708 RequiredSize, NULL, NULL);
711 /***********************************************************************
712 * SetupDiGetClassDescriptionW (SETUPAPI.@)
714 BOOL WINAPI SetupDiGetClassDescriptionW(
715 const GUID* ClassGuid,
716 PWSTR ClassDescription,
717 DWORD ClassDescriptionSize,
720 return SetupDiGetClassDescriptionExW(ClassGuid, ClassDescription,
721 ClassDescriptionSize,
722 RequiredSize, NULL, NULL);
725 /***********************************************************************
726 * SetupDiGetClassDescriptionExA (SETUPAPI.@)
728 BOOL WINAPI SetupDiGetClassDescriptionExA(
729 const GUID* ClassGuid,
730 PSTR ClassDescription,
731 DWORD ClassDescriptionSize,
740 /***********************************************************************
741 * SetupDiGetClassDescriptionExW (SETUPAPI.@)
743 BOOL WINAPI SetupDiGetClassDescriptionExW(
744 const GUID* ClassGuid,
745 PWSTR ClassDescription,
746 DWORD ClassDescriptionSize,
754 hKey = SetupDiOpenClassRegKeyExW(ClassGuid,
759 if (hKey == INVALID_HANDLE_VALUE)
761 WARN("SetupDiOpenClassRegKeyExW() failed (Error %lu)\n", GetLastError());
765 if (RequiredSize != NULL)
768 if (RegQueryValueExW(hKey,
779 *RequiredSize = dwLength / sizeof(WCHAR);
782 dwLength = ClassDescriptionSize * sizeof(WCHAR);
783 if (RegQueryValueExW(hKey,
787 (LPBYTE)ClassDescription,
799 /***********************************************************************
800 * SetupDiGetClassDevsA (SETUPAPI.@)
802 HDEVINFO WINAPI SetupDiGetClassDevsA(
809 LPWSTR enumstrW = NULL;
813 int len = MultiByteToWideChar(CP_ACP, 0, enumstr, -1, NULL, 0);
814 enumstrW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
817 ret = (HDEVINFO)INVALID_HANDLE_VALUE;
820 MultiByteToWideChar(CP_ACP, 0, enumstr, -1, enumstrW, len);
822 ret = SetupDiGetClassDevsW(class, enumstrW, parent, flags);
823 HeapFree(GetProcessHeap(), 0, enumstrW);
829 #define SETUP_SERIAL_PORT_MAGIC 0xd00ff055
831 typedef struct _SerialPortName
836 typedef struct _SerialPortList
840 SerialPortName names[1];
843 static HDEVINFO SETUP_CreateSerialDeviceList(void)
845 static const size_t initialSize = 100;
847 WCHAR buf[initialSize];
855 if (QueryDosDeviceW(NULL, devices, size) == 0)
857 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
861 HeapFree(GetProcessHeap(), 0, devices);
862 devices = (LPWSTR)HeapAlloc(GetProcessHeap(), 0,
863 size * sizeof(WCHAR));
872 } while (!*devices && !failed);
875 static const WCHAR comW[] = { 'C','O','M',0 };
877 UINT numSerialPorts = 0;
878 SerialPortList *list;
880 for (ptr = devices; *ptr; ptr += strlenW(ptr) + 1)
882 if (!strncmpW(comW, ptr, sizeof(comW) / sizeof(comW[0]) - 1))
885 list = HeapAlloc(GetProcessHeap(), 0, sizeof(SerialPortList) +
886 numSerialPorts ? (numSerialPorts - 1) * sizeof(SerialPortName) : 0);
889 list->magic = SETUP_SERIAL_PORT_MAGIC;
891 for (ptr = devices; *ptr; ptr += strlenW(ptr) + 1)
893 if (!strncmpW(comW, ptr, sizeof(comW) / sizeof(comW[0]) - 1))
895 strncpyW(list->names[list->numPorts].name, ptr,
896 sizeof(list->names[list->numPorts].name) /
897 sizeof(list->names[list->numPorts].name[0]));
898 TRACE("Adding %s to list\n",
899 debugstr_w(list->names[list->numPorts].name));
903 TRACE("list->numPorts is %d\n", list->numPorts);
905 ret = (HDEVINFO)list;
908 ret = (HDEVINFO)INVALID_HANDLE_VALUE;
910 HeapFree(GetProcessHeap(), 0, devices);
911 TRACE("returning %p\n", ret);
915 /***********************************************************************
916 * SetupDiGetClassDevsW (SETUPAPI.@)
918 HDEVINFO WINAPI SetupDiGetClassDevsW(
924 HDEVINFO ret = (HDEVINFO)INVALID_HANDLE_VALUE;
926 TRACE("%s %s %p 0x%08lx\n", debugstr_guid(class), debugstr_w(enumstr),
930 FIXME(": unimplemented for enumerator strings (%s)\n",
931 debugstr_w(enumstr));
932 else if (flags & DIGCF_ALLCLASSES)
933 FIXME(": unimplemented for DIGCF_ALLCLASSES\n");
936 if (IsEqualIID(class, &GUID_DEVINTERFACE_COMPORT))
937 ret = SETUP_CreateSerialDeviceList();
938 else if (IsEqualIID(class, &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR))
939 ret = SETUP_CreateSerialDeviceList();
941 FIXME("(%s): stub\n", debugstr_guid(class));
946 /***********************************************************************
947 * SetupDiEnumDeviceInterfaces (SETUPAPI.@)
949 BOOL WINAPI SetupDiEnumDeviceInterfaces(
950 HDEVINFO DeviceInfoSet,
951 PSP_DEVINFO_DATA DeviceInfoData,
952 CONST GUID * InterfaceClassGuid,
954 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
958 TRACE("%p, %p, %s, 0x%08lx, %p\n", DeviceInfoSet, DeviceInfoData,
959 debugstr_guid(InterfaceClassGuid), MemberIndex, DeviceInterfaceData);
960 if (!DeviceInterfaceData)
961 SetLastError(ERROR_INVALID_PARAMETER);
962 else if (DeviceInfoData)
963 FIXME(": unimplemented with PSP_DEVINFO_DATA set\n");
964 else if (DeviceInfoSet && DeviceInfoSet != (HDEVINFO)INVALID_HANDLE_VALUE)
966 /* FIXME: this assumes the only possible enumeration is of serial
969 SerialPortList *list = (SerialPortList *)DeviceInfoSet;
971 if (list->magic == SETUP_SERIAL_PORT_MAGIC)
973 if (MemberIndex >= list->numPorts)
974 SetLastError(ERROR_NO_MORE_ITEMS);
977 DeviceInterfaceData->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
978 memcpy(&DeviceInterfaceData->InterfaceClassGuid,
979 &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR,
980 sizeof(DeviceInterfaceData->InterfaceClassGuid));
981 DeviceInterfaceData->Flags = 0;
982 /* Note: this appears to be dangerous, passing a private
983 * pointer a heap-allocated datum to the caller. However, the
984 * expected lifetime of the device data is the same as the
985 * HDEVINFO; once that is closed, the data are no longer valid.
987 DeviceInterfaceData->Reserved =
988 (ULONG_PTR)&list->names[MemberIndex].name;
993 SetLastError(ERROR_INVALID_HANDLE);
996 SetLastError(ERROR_INVALID_HANDLE);
1000 /***********************************************************************
1001 * SetupDiDestroyDeviceInfoList (SETUPAPI.@)
1003 BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
1007 TRACE("%p\n", devinfo);
1008 if (devinfo && devinfo != (HDEVINFO)INVALID_HANDLE_VALUE)
1010 /* FIXME: this assumes the only possible enumeration is of serial
1013 SerialPortList *list = (SerialPortList *)devinfo;
1015 if (list->magic == SETUP_SERIAL_PORT_MAGIC)
1017 HeapFree(GetProcessHeap(), 0, list);
1021 SetLastError(ERROR_INVALID_HANDLE);
1024 SetLastError(ERROR_INVALID_HANDLE);
1028 /***********************************************************************
1029 * SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@)
1031 BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(
1032 HDEVINFO DeviceInfoSet,
1033 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
1034 PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData,
1035 DWORD DeviceInterfaceDetailDataSize,
1036 PDWORD RequiredSize,
1037 PSP_DEVINFO_DATA DeviceInfoData)
1041 TRACE("(%p, %p, %p, %ld, %p, %p)\n", DeviceInfoSet,
1042 DeviceInterfaceData, DeviceInterfaceDetailData,
1043 DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
1044 if (!DeviceInterfaceData)
1045 SetLastError(ERROR_INVALID_PARAMETER);
1046 else if ((DeviceInterfaceDetailDataSize && !DeviceInterfaceDetailData) ||
1047 (DeviceInterfaceDetailData && !DeviceInterfaceDetailDataSize))
1048 SetLastError(ERROR_INVALID_PARAMETER);
1049 else if (DeviceInfoSet && DeviceInfoSet != (HDEVINFO)INVALID_HANDLE_VALUE)
1051 /* FIXME: this assumes the only possible enumeration is of serial
1054 SerialPortList *list = (SerialPortList *)DeviceInfoSet;
1056 if (list->magic == SETUP_SERIAL_PORT_MAGIC)
1058 LPCWSTR devName = (LPCWSTR)DeviceInterfaceData->Reserved;
1059 DWORD sizeRequired = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A) +
1062 if (sizeRequired > DeviceInterfaceDetailDataSize)
1064 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1066 *RequiredSize = sizeRequired;
1070 LPSTR dst = DeviceInterfaceDetailData->DevicePath;
1071 LPCWSTR src = devName;
1073 /* MSDN claims cbSize must be set by the caller, but it lies */
1074 DeviceInterfaceDetailData->cbSize =
1075 sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
1076 for ( ; *src; src++, dst++)
1079 TRACE("DevicePath is %s\n",
1080 debugstr_a(DeviceInterfaceDetailData->DevicePath));
1083 DeviceInfoData->cbSize = sizeof(SP_DEVINFO_DATA);
1084 memcpy(&DeviceInfoData->ClassGuid,
1085 &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR,
1086 sizeof(DeviceInfoData->ClassGuid));
1087 DeviceInfoData->DevInst = 0;
1088 DeviceInfoData->Reserved = (ULONG_PTR)devName;
1094 SetLastError(ERROR_INVALID_HANDLE);
1097 SetLastError(ERROR_INVALID_HANDLE);
1098 TRACE("Returning %d\n", ret);
1102 /***********************************************************************
1103 * SetupDiGetDeviceInterfaceDetailW (SETUPAPI.@)
1105 BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(
1106 HDEVINFO DeviceInfoSet,
1107 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
1108 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData,
1109 DWORD DeviceInterfaceDetailDataSize,
1110 PDWORD RequiredSize,
1111 PSP_DEVINFO_DATA DeviceInfoData)
1113 FIXME("(%p, %p, %p, %ld, %p, %p): stub\n", DeviceInfoSet,
1114 DeviceInterfaceData, DeviceInterfaceDetailData,
1115 DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
1119 /***********************************************************************
1120 * SetupDiGetDeviceRegistryPropertyA (SETUPAPI.@)
1122 BOOL WINAPI SetupDiGetDeviceRegistryPropertyA(
1124 PSP_DEVINFO_DATA DeviceInfoData,
1126 PDWORD PropertyRegDataType,
1127 PBYTE PropertyBuffer,
1128 DWORD PropertyBufferSize,
1129 PDWORD RequiredSize)
1131 FIXME("%04lx %p %ld %p %p %ld %p\n", (DWORD)devinfo, DeviceInfoData,
1132 Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize,
1137 /***********************************************************************
1138 * SetupDiInstallClassA (SETUPAPI.@)
1140 BOOL WINAPI SetupDiInstallClassA(
1146 UNICODE_STRING FileNameW;
1149 if (!RtlCreateUnicodeStringFromAsciiz(&FileNameW, InfFileName))
1151 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1155 Result = SetupDiInstallClassW(hwndParent, FileNameW.Buffer, Flags, FileQueue);
1157 RtlFreeUnicodeString(&FileNameW);
1162 static HKEY CreateClassKey(HINF hInf)
1164 WCHAR FullBuffer[MAX_PATH];
1165 WCHAR Buffer[MAX_PATH];
1169 if (!SetupGetLineTextW(NULL,
1177 return INVALID_HANDLE_VALUE;
1180 lstrcpyW(FullBuffer, ControlClass);
1181 lstrcatW(FullBuffer, Buffer);
1183 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1189 if (!SetupGetLineTextW(NULL,
1197 return INVALID_HANDLE_VALUE;
1200 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,
1204 REG_OPTION_NON_VOLATILE,
1210 return INVALID_HANDLE_VALUE;
1215 if (RegSetValueExW(hClassKey,
1220 RequiredSize * sizeof(WCHAR)))
1222 RegCloseKey(hClassKey);
1223 RegDeleteKeyW(HKEY_LOCAL_MACHINE,
1225 return INVALID_HANDLE_VALUE;
1231 /***********************************************************************
1232 * SetupDiInstallClassW (SETUPAPI.@)
1234 BOOL WINAPI SetupDiInstallClassW(
1240 WCHAR SectionName[MAX_PATH];
1241 DWORD SectionNameLength = 0;
1243 BOOL bFileQueueCreated = FALSE;
1249 if ((Flags & DI_NOVCP) && (FileQueue == NULL || FileQueue == INVALID_HANDLE_VALUE))
1251 SetLastError(ERROR_INVALID_PARAMETER);
1255 /* Open the .inf file */
1256 hInf = SetupOpenInfFileW(InfFileName,
1260 if (hInf == INVALID_HANDLE_VALUE)
1266 /* Create or open the class registry key 'HKLM\\CurrentControlSet\\Class\\{GUID}' */
1267 hClassKey = CreateClassKey(hInf);
1268 if (hClassKey == INVALID_HANDLE_VALUE)
1270 SetupCloseInfFile(hInf);
1275 /* Try to append a layout file */
1277 SetupOpenAppendInfFileW(NULL, hInf, NULL);
1280 /* Retrieve the actual section name */
1281 SetupDiGetActualSectionToInstallW(hInf,
1289 if (!(Flags & DI_NOVCP))
1291 FileQueue = SetupOpenFileQueue();
1292 if (FileQueue == INVALID_HANDLE_VALUE)
1294 SetupCloseInfFile(hInf);
1298 bFileQueueCreated = TRUE;
1303 SetupInstallFromInfSectionW(NULL,
1312 INVALID_HANDLE_VALUE,
1315 /* FIXME: More code! */
1317 if (bFileQueueCreated)
1318 SetupCloseFileQueue(FileQueue);
1320 SetupCloseInfFile(hInf);
1326 /***********************************************************************
1327 * SetupDiOpenClassRegKey (SETUPAPI.@)
1329 HKEY WINAPI SetupDiOpenClassRegKey(
1330 const GUID* ClassGuid,
1333 return SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
1334 DIOCR_INSTALLER, NULL, NULL);
1338 /***********************************************************************
1339 * SetupDiOpenClassRegKeyExA (SETUPAPI.@)
1341 HKEY WINAPI SetupDiOpenClassRegKeyExA(
1342 const GUID* ClassGuid,
1348 PWSTR MachineNameW = NULL;
1355 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
1356 if (MachineNameW == NULL)
1357 return INVALID_HANDLE_VALUE;
1360 hKey = SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
1361 Flags, MachineNameW, Reserved);
1364 MyFree(MachineNameW);
1370 /***********************************************************************
1371 * SetupDiOpenClassRegKeyExW (SETUPAPI.@)
1373 HKEY WINAPI SetupDiOpenClassRegKeyExW(
1374 const GUID* ClassGuid,
1380 LPWSTR lpGuidString;
1385 if (MachineName != NULL)
1387 FIXME("Remote access not supported yet!\n");
1388 return INVALID_HANDLE_VALUE;
1391 if (Flags == DIOCR_INSTALLER)
1393 lpKeyName = ControlClass;
1395 else if (Flags == DIOCR_INTERFACE)
1397 lpKeyName = DeviceClasses;
1401 ERR("Invalid Flags parameter!\n");
1402 SetLastError(ERROR_INVALID_PARAMETER);
1403 return INVALID_HANDLE_VALUE;
1406 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1412 return INVALID_HANDLE_VALUE;
1415 if (ClassGuid == NULL)
1418 if (UuidToStringW((UUID*)ClassGuid, &lpGuidString) != RPC_S_OK)
1420 RegCloseKey(hClassesKey);
1424 if (RegOpenKeyExW(hClassesKey,
1430 RpcStringFreeW(&lpGuidString);
1431 RegCloseKey(hClassesKey);
1435 RpcStringFreeW(&lpGuidString);
1436 RegCloseKey(hClassesKey);
1441 /***********************************************************************
1442 * SetupDiOpenDeviceInterfaceW (SETUPAPI.@)
1444 BOOL WINAPI SetupDiOpenDeviceInterfaceW(
1445 HDEVINFO DeviceInfoSet,
1448 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
1450 FIXME("%p %s %08lx %p\n",
1451 DeviceInfoSet, debugstr_w(DevicePath), OpenFlags, DeviceInterfaceData);
1455 /***********************************************************************
1456 * SetupDiOpenDeviceInterfaceA (SETUPAPI.@)
1458 BOOL WINAPI SetupDiOpenDeviceInterfaceA(
1459 HDEVINFO DeviceInfoSet,
1462 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
1464 FIXME("%p %s %08lx %p\n", DeviceInfoSet,
1465 debugstr_a(DevicePath), OpenFlags, DeviceInterfaceData);
1469 /***********************************************************************
1470 * SetupDiSetClassInstallParamsA (SETUPAPI.@)
1472 BOOL WINAPI SetupDiSetClassInstallParamsA(
1473 HDEVINFO DeviceInfoSet,
1474 PSP_DEVINFO_DATA DeviceInfoData,
1475 PSP_CLASSINSTALL_HEADER ClassInstallParams,
1476 DWORD ClassInstallParamsSize)
1478 FIXME("%p %p %x %lu\n",DeviceInfoSet, DeviceInfoData,
1479 ClassInstallParams->InstallFunction, ClassInstallParamsSize);
1483 /***********************************************************************
1484 * SetupDiCallClassInstaller (SETUPAPI.@)
1486 BOOL WINAPI SetupDiCallClassInstaller(
1487 DWORD InstallFunction,
1488 HDEVINFO DeviceInfoSet,
1489 PSP_DEVINFO_DATA DeviceInfoData)
1491 FIXME("%ld %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData);
1495 /***********************************************************************
1496 * SetupDiGetDeviceInstallParamsA (SETUPAPI.@)
1498 BOOL WINAPI SetupDiGetDeviceInstallParamsA(
1499 HDEVINFO DeviceInfoSet,
1500 PSP_DEVINFO_DATA DeviceInfoData,
1501 PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
1503 FIXME("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstallParams);
1507 /***********************************************************************
1508 * SetupDiOpenDevRegKey (SETUPAPI.@)
1510 HKEY WINAPI SetupDiOpenDevRegKey(
1511 HDEVINFO DeviceInfoSet,
1512 PSP_DEVINFO_DATA DeviceInfoData,
1518 FIXME("%p %p %ld %ld %ld %lx\n", DeviceInfoSet, DeviceInfoData,
1519 Scope, HwProfile, KeyType, samDesired);
1520 return INVALID_HANDLE_VALUE;