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"
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 /***********************************************************************
72 * SetupDiBuildClassInfoList (SETUPAPI.@)
74 BOOL WINAPI
SetupDiBuildClassInfoList(
77 DWORD ClassGuidListSize
,
81 return SetupDiBuildClassInfoListExW(Flags
, ClassGuidList
,
82 ClassGuidListSize
, RequiredSize
,
86 /***********************************************************************
87 * SetupDiBuildClassInfoListExA (SETUPAPI.@)
89 BOOL WINAPI
SetupDiBuildClassInfoListExA(
92 DWORD ClassGuidListSize
,
97 LPWSTR MachineNameW
= NULL
;
104 MachineNameW
= MultiByteToUnicode(MachineName
, CP_ACP
);
105 if (MachineNameW
== NULL
) return FALSE
;
108 bResult
= SetupDiBuildClassInfoListExW(Flags
, ClassGuidList
,
109 ClassGuidListSize
, RequiredSize
,
110 MachineNameW
, Reserved
);
113 MyFree(MachineNameW
);
118 /***********************************************************************
119 * SetupDiBuildClassInfoListExW (SETUPAPI.@)
121 BOOL WINAPI
SetupDiBuildClassInfoListExW(
123 LPGUID ClassGuidList
,
124 DWORD ClassGuidListSize
,
135 DWORD dwGuidListIndex
= 0;
139 if (RequiredSize
!= NULL
)
142 hClassesKey
= SetupDiOpenClassRegKeyExW(NULL
,
147 if (hClassesKey
== INVALID_HANDLE_VALUE
)
152 for (dwIndex
= 0; ; dwIndex
++)
155 lError
= RegEnumKeyExW(hClassesKey
,
163 TRACE("RegEnumKeyExW() returns %ld\n", lError
);
164 if (lError
== ERROR_SUCCESS
|| lError
== ERROR_MORE_DATA
)
166 TRACE("Key name: %p\n", szKeyName
);
168 if (RegOpenKeyExW(hClassesKey
,
174 RegCloseKey(hClassesKey
);
178 if (!RegQueryValueExW(hClassKey
,
185 TRACE("'NoUseClass' value found!\n");
186 RegCloseKey(hClassKey
);
190 if ((Flags
& DIBCI_NOINSTALLCLASS
) &&
191 (!RegQueryValueExW(hClassKey
,
198 TRACE("'NoInstallClass' value found!\n");
199 RegCloseKey(hClassKey
);
203 if ((Flags
& DIBCI_NODISPLAYCLASS
) &&
204 (!RegQueryValueExW(hClassKey
,
211 TRACE("'NoDisplayClass' value found!\n");
212 RegCloseKey(hClassKey
);
216 RegCloseKey(hClassKey
);
218 TRACE("Guid: %p\n", szKeyName
);
219 if (dwGuidListIndex
< ClassGuidListSize
)
221 if (szKeyName
[0] == L
'{' && szKeyName
[37] == L
'}')
225 TRACE("Guid: %p\n", &szKeyName
[1]);
227 UuidFromStringW(&szKeyName
[1],
228 &ClassGuidList
[dwGuidListIndex
]);
234 if (lError
!= ERROR_SUCCESS
)
238 RegCloseKey(hClassesKey
);
240 if (RequiredSize
!= NULL
)
241 *RequiredSize
= dwGuidListIndex
;
243 if (ClassGuidListSize
< dwGuidListIndex
)
245 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
252 /***********************************************************************
253 * SetupDiClassGuidsFromNameA (SETUPAPI.@)
255 BOOL WINAPI
SetupDiClassGuidsFromNameA(
257 LPGUID ClassGuidList
,
258 DWORD ClassGuidListSize
,
261 return SetupDiClassGuidsFromNameExA(ClassName
, ClassGuidList
,
262 ClassGuidListSize
, RequiredSize
,
266 /***********************************************************************
267 * SetupDiClassGuidsFromNameW (SETUPAPI.@)
269 BOOL WINAPI
SetupDiClassGuidsFromNameW(
271 LPGUID ClassGuidList
,
272 DWORD ClassGuidListSize
,
275 return SetupDiClassGuidsFromNameExW(ClassName
, ClassGuidList
,
276 ClassGuidListSize
, RequiredSize
,
280 /***********************************************************************
281 * SetupDiClassGuidsFromNameExA (SETUPAPI.@)
283 BOOL WINAPI
SetupDiClassGuidsFromNameExA(
285 LPGUID ClassGuidList
,
286 DWORD ClassGuidListSize
,
291 LPWSTR ClassNameW
= NULL
;
292 LPWSTR MachineNameW
= NULL
;
297 ClassNameW
= MultiByteToUnicode(ClassName
, CP_ACP
);
298 if (ClassNameW
== NULL
)
303 MachineNameW
= MultiByteToUnicode(MachineName
, CP_ACP
);
304 if (MachineNameW
== NULL
)
311 bResult
= SetupDiClassGuidsFromNameExW(ClassNameW
, ClassGuidList
,
312 ClassGuidListSize
, RequiredSize
,
313 MachineNameW
, Reserved
);
316 MyFree(MachineNameW
);
323 /***********************************************************************
324 * SetupDiClassGuidsFromNameExW (SETUPAPI.@)
326 BOOL WINAPI
SetupDiClassGuidsFromNameExW(
328 LPGUID ClassGuidList
,
329 DWORD ClassGuidListSize
,
335 WCHAR szClassName
[256];
341 DWORD dwGuidListIndex
= 0;
343 if (RequiredSize
!= NULL
)
346 hClassesKey
= SetupDiOpenClassRegKeyExW(NULL
,
351 if (hClassesKey
== INVALID_HANDLE_VALUE
)
356 for (dwIndex
= 0; ; dwIndex
++)
359 lError
= RegEnumKeyExW(hClassesKey
,
367 TRACE("RegEnumKeyExW() returns %ld\n", lError
);
368 if (lError
== ERROR_SUCCESS
|| lError
== ERROR_MORE_DATA
)
370 TRACE("Key name: %p\n", szKeyName
);
372 if (RegOpenKeyExW(hClassesKey
,
378 RegCloseKey(hClassesKey
);
382 dwLength
= 256 * sizeof(WCHAR
);
383 if (!RegQueryValueExW(hClassKey
,
390 TRACE("Class name: %p\n", szClassName
);
392 if (strcmpiW(szClassName
, ClassName
) == 0)
394 TRACE("Found matching class name\n");
396 TRACE("Guid: %p\n", szKeyName
);
397 if (dwGuidListIndex
< ClassGuidListSize
)
399 if (szKeyName
[0] == L
'{' && szKeyName
[37] == L
'}')
403 TRACE("Guid: %p\n", &szKeyName
[1]);
405 UuidFromStringW(&szKeyName
[1],
406 &ClassGuidList
[dwGuidListIndex
]);
413 RegCloseKey(hClassKey
);
416 if (lError
!= ERROR_SUCCESS
)
420 RegCloseKey(hClassesKey
);
422 if (RequiredSize
!= NULL
)
423 *RequiredSize
= dwGuidListIndex
;
425 if (ClassGuidListSize
< dwGuidListIndex
)
427 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
434 /***********************************************************************
435 * SetupDiClassNameFromGuidA (SETUPAPI.@)
437 BOOL WINAPI
SetupDiClassNameFromGuidA(
438 const GUID
* ClassGuid
,
443 return SetupDiClassNameFromGuidExA(ClassGuid
, ClassName
,
444 ClassNameSize
, RequiredSize
,
448 /***********************************************************************
449 * SetupDiClassNameFromGuidW (SETUPAPI.@)
451 BOOL WINAPI
SetupDiClassNameFromGuidW(
452 const GUID
* ClassGuid
,
457 return SetupDiClassNameFromGuidExW(ClassGuid
, ClassName
,
458 ClassNameSize
, RequiredSize
,
462 /***********************************************************************
463 * SetupDiClassNameFromGuidExA (SETUPAPI.@)
465 BOOL WINAPI
SetupDiClassNameFromGuidExA(
466 const GUID
* ClassGuid
,
473 WCHAR ClassNameW
[MAX_CLASS_NAME_LEN
];
474 LPWSTR MachineNameW
= NULL
;
478 MachineNameW
= MultiByteToUnicode(MachineName
, CP_ACP
);
479 ret
= SetupDiClassNameFromGuidExW(ClassGuid
, ClassNameW
, MAX_CLASS_NAME_LEN
,
480 NULL
, MachineNameW
, Reserved
);
483 int len
= WideCharToMultiByte(CP_ACP
, 0, ClassNameW
, -1, ClassName
,
484 ClassNameSize
, NULL
, NULL
);
486 if (!ClassNameSize
&& RequiredSize
)
489 MyFree(MachineNameW
);
493 /***********************************************************************
494 * SetupDiClassNameFromGuidExW (SETUPAPI.@)
496 BOOL WINAPI
SetupDiClassNameFromGuidExW(
497 const GUID
* ClassGuid
,
507 hKey
= SetupDiOpenClassRegKeyExW(ClassGuid
,
512 if (hKey
== INVALID_HANDLE_VALUE
)
517 if (RequiredSize
!= NULL
)
520 if (RegQueryValueExW(hKey
,
531 *RequiredSize
= dwLength
/ sizeof(WCHAR
);
534 dwLength
= ClassNameSize
* sizeof(WCHAR
);
535 if (RegQueryValueExW(hKey
,
551 /***********************************************************************
552 * SetupDiCreateDeviceInfoList (SETUPAPI.@)
555 SetupDiCreateDeviceInfoList(const GUID
*ClassGuid
,
558 return SetupDiCreateDeviceInfoListExW(ClassGuid
, hwndParent
, NULL
, NULL
);
561 /***********************************************************************
562 * SetupDiCreateDeviceInfoListExA (SETUPAPI.@)
565 SetupDiCreateDeviceInfoListExA(const GUID
*ClassGuid
,
570 LPWSTR MachineNameW
= NULL
;
577 MachineNameW
= MultiByteToUnicode(MachineName
, CP_ACP
);
578 if (MachineNameW
== NULL
)
579 return (HDEVINFO
)INVALID_HANDLE_VALUE
;
582 hDevInfo
= SetupDiCreateDeviceInfoListExW(ClassGuid
, hwndParent
,
583 MachineNameW
, Reserved
);
586 MyFree(MachineNameW
);
591 /***********************************************************************
592 * SetupDiCreateDeviceInfoListExW (SETUPAPI.@)
595 SetupDiCreateDeviceInfoListExW(const GUID
*ClassGuid
,
601 return (HDEVINFO
)INVALID_HANDLE_VALUE
;
604 /***********************************************************************
605 * SetupDiEnumDeviceInfo (SETUPAPI.@)
607 BOOL WINAPI
SetupDiEnumDeviceInfo(
610 PSP_DEVINFO_DATA info
)
612 FIXME("%p %ld %p\n", devinfo
, index
, info
);
616 if(info
->cbSize
< sizeof(*info
))
622 /***********************************************************************
623 * SetupDiGetActualSectionToInstallA (SETUPAPI.@)
625 BOOL WINAPI
SetupDiGetActualSectionToInstallA(
627 PCSTR InfSectionName
,
628 PSTR InfSectionWithExt
,
629 DWORD InfSectionWithExtSize
,
637 /***********************************************************************
638 * SetupDiGetActualSectionToInstallW (SETUPAPI.@)
640 BOOL WINAPI
SetupDiGetActualSectionToInstallW(
642 PCWSTR InfSectionName
,
643 PWSTR InfSectionWithExt
,
644 DWORD InfSectionWithExtSize
,
648 WCHAR szBuffer
[MAX_PATH
];
651 LONG lLineCount
= -1;
653 lstrcpyW(szBuffer
, InfSectionName
);
654 dwLength
= lstrlenW(szBuffer
);
656 if (OsVersionInfo
.dwPlatformId
== VER_PLATFORM_WIN32_NT
)
658 /* Test section name with '.NTx86' extension */
659 lstrcpyW(&szBuffer
[dwLength
], NtPlatformExtension
);
660 lLineCount
= SetupGetLineCountW(InfHandle
, szBuffer
);
662 if (lLineCount
== -1)
664 /* Test section name with '.NT' extension */
665 lstrcpyW(&szBuffer
[dwLength
], NtExtension
);
666 lLineCount
= SetupGetLineCountW(InfHandle
, szBuffer
);
671 /* Test section name with '.Win' extension */
672 lstrcpyW(&szBuffer
[dwLength
], WinExtension
);
673 lLineCount
= SetupGetLineCountW(InfHandle
, szBuffer
);
676 if (lLineCount
== -1)
678 /* Test section name without extension */
679 szBuffer
[dwLength
] = 0;
680 lLineCount
= SetupGetLineCountW(InfHandle
, szBuffer
);
683 if (lLineCount
== -1)
685 SetLastError(ERROR_INVALID_PARAMETER
);
689 dwFullLength
= lstrlenW(szBuffer
);
691 if (InfSectionWithExt
!= NULL
&& InfSectionWithExtSize
!= 0)
693 if (InfSectionWithExtSize
< (dwFullLength
+ 1))
695 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
699 lstrcpyW(InfSectionWithExt
, szBuffer
);
700 if (Extension
!= NULL
)
702 *Extension
= (dwLength
== dwFullLength
) ? NULL
: &InfSectionWithExt
[dwLength
];
706 if (RequiredSize
!= NULL
)
708 *RequiredSize
= dwFullLength
+ 1;
714 /***********************************************************************
715 * SetupDiGetClassDescriptionA (SETUPAPI.@)
717 BOOL WINAPI
SetupDiGetClassDescriptionA(
718 const GUID
* ClassGuid
,
719 PSTR ClassDescription
,
720 DWORD ClassDescriptionSize
,
723 return SetupDiGetClassDescriptionExA(ClassGuid
, ClassDescription
,
724 ClassDescriptionSize
,
725 RequiredSize
, NULL
, NULL
);
728 /***********************************************************************
729 * SetupDiGetClassDescriptionW (SETUPAPI.@)
731 BOOL WINAPI
SetupDiGetClassDescriptionW(
732 const GUID
* ClassGuid
,
733 PWSTR ClassDescription
,
734 DWORD ClassDescriptionSize
,
737 return SetupDiGetClassDescriptionExW(ClassGuid
, ClassDescription
,
738 ClassDescriptionSize
,
739 RequiredSize
, NULL
, NULL
);
742 /***********************************************************************
743 * SetupDiGetClassDescriptionExA (SETUPAPI.@)
745 BOOL WINAPI
SetupDiGetClassDescriptionExA(
746 const GUID
* ClassGuid
,
747 PSTR ClassDescription
,
748 DWORD ClassDescriptionSize
,
757 /***********************************************************************
758 * SetupDiGetClassDescriptionExW (SETUPAPI.@)
760 BOOL WINAPI
SetupDiGetClassDescriptionExW(
761 const GUID
* ClassGuid
,
762 PWSTR ClassDescription
,
763 DWORD ClassDescriptionSize
,
771 hKey
= SetupDiOpenClassRegKeyExW(ClassGuid
,
776 if (hKey
== INVALID_HANDLE_VALUE
)
778 WARN("SetupDiOpenClassRegKeyExW() failed (Error %lu)\n", GetLastError());
782 if (RequiredSize
!= NULL
)
785 if (RegQueryValueExW(hKey
,
796 *RequiredSize
= dwLength
/ sizeof(WCHAR
);
799 dwLength
= ClassDescriptionSize
* sizeof(WCHAR
);
800 if (RegQueryValueExW(hKey
,
804 (LPBYTE
)ClassDescription
,
816 /***********************************************************************
817 * SetupDiGetClassDevsA (SETUPAPI.@)
819 HDEVINFO WINAPI
SetupDiGetClassDevsA(
826 LPWSTR enumstrW
= NULL
;
830 int len
= MultiByteToWideChar(CP_ACP
, 0, enumstr
, -1, NULL
, 0);
831 enumstrW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
834 ret
= (HDEVINFO
)INVALID_HANDLE_VALUE
;
837 MultiByteToWideChar(CP_ACP
, 0, enumstr
, -1, enumstrW
, len
);
839 ret
= SetupDiGetClassDevsW(class, enumstrW
, parent
, flags
);
840 HeapFree(GetProcessHeap(), 0, enumstrW
);
846 #define SETUP_SERIAL_PORT_MAGIC 0xd00ff055
848 typedef struct _SerialPortName
853 typedef struct _SerialPortList
857 SerialPortName names
[1];
860 static HDEVINFO
SETUP_CreateSerialDeviceList(void)
862 static const size_t initialSize
= 100;
864 WCHAR buf
[initialSize
];
872 if (QueryDosDeviceW(NULL
, devices
, size
) == 0)
874 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
878 HeapFree(GetProcessHeap(), 0, devices
);
879 devices
= HeapAlloc(GetProcessHeap(), 0, size
* sizeof(WCHAR
));
888 } while (!*devices
&& !failed
);
891 static const WCHAR comW
[] = { 'C','O','M',0 };
893 UINT numSerialPorts
= 0;
894 SerialPortList
*list
;
896 for (ptr
= devices
; *ptr
; ptr
+= strlenW(ptr
) + 1)
898 if (!strncmpW(comW
, ptr
, sizeof(comW
) / sizeof(comW
[0]) - 1))
901 list
= HeapAlloc(GetProcessHeap(), 0, sizeof(SerialPortList
) +
902 numSerialPorts
? (numSerialPorts
- 1) * sizeof(SerialPortName
) : 0);
905 list
->magic
= SETUP_SERIAL_PORT_MAGIC
;
907 for (ptr
= devices
; *ptr
; ptr
+= strlenW(ptr
) + 1)
909 if (!strncmpW(comW
, ptr
, sizeof(comW
) / sizeof(comW
[0]) - 1))
911 lstrcpynW(list
->names
[list
->numPorts
].name
, ptr
,
912 sizeof(list
->names
[list
->numPorts
].name
) /
913 sizeof(list
->names
[list
->numPorts
].name
[0]));
914 TRACE("Adding %s to list\n",
915 debugstr_w(list
->names
[list
->numPorts
].name
));
919 TRACE("list->numPorts is %d\n", list
->numPorts
);
921 ret
= (HDEVINFO
)list
;
924 ret
= (HDEVINFO
)INVALID_HANDLE_VALUE
;
926 HeapFree(GetProcessHeap(), 0, devices
);
927 TRACE("returning %p\n", ret
);
931 /***********************************************************************
932 * SetupDiGetClassDevsW (SETUPAPI.@)
934 HDEVINFO WINAPI
SetupDiGetClassDevsW(
940 HDEVINFO ret
= (HDEVINFO
)INVALID_HANDLE_VALUE
;
942 TRACE("%s %s %p 0x%08lx\n", debugstr_guid(class), debugstr_w(enumstr
),
946 FIXME(": unimplemented for enumerator strings (%s)\n",
947 debugstr_w(enumstr
));
948 else if (flags
& DIGCF_ALLCLASSES
)
949 FIXME(": unimplemented for DIGCF_ALLCLASSES\n");
952 if (IsEqualIID(class, &GUID_DEVINTERFACE_COMPORT
))
953 ret
= SETUP_CreateSerialDeviceList();
954 else if (IsEqualIID(class, &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR
))
955 ret
= SETUP_CreateSerialDeviceList();
957 FIXME("(%s): stub\n", debugstr_guid(class));
962 /***********************************************************************
963 * SetupDiEnumDeviceInterfaces (SETUPAPI.@)
965 BOOL WINAPI
SetupDiEnumDeviceInterfaces(
966 HDEVINFO DeviceInfoSet
,
967 PSP_DEVINFO_DATA DeviceInfoData
,
968 CONST GUID
* InterfaceClassGuid
,
970 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
)
974 TRACE("%p, %p, %s, 0x%08lx, %p\n", DeviceInfoSet
, DeviceInfoData
,
975 debugstr_guid(InterfaceClassGuid
), MemberIndex
, DeviceInterfaceData
);
976 if (!DeviceInterfaceData
)
977 SetLastError(ERROR_INVALID_PARAMETER
);
978 else if (DeviceInfoData
)
979 FIXME(": unimplemented with PSP_DEVINFO_DATA set\n");
980 else if (DeviceInfoSet
&& DeviceInfoSet
!= (HDEVINFO
)INVALID_HANDLE_VALUE
)
982 /* FIXME: this assumes the only possible enumeration is of serial
985 SerialPortList
*list
= (SerialPortList
*)DeviceInfoSet
;
987 if (list
->magic
== SETUP_SERIAL_PORT_MAGIC
)
989 if (MemberIndex
>= list
->numPorts
)
990 SetLastError(ERROR_NO_MORE_ITEMS
);
993 DeviceInterfaceData
->cbSize
= sizeof(SP_DEVICE_INTERFACE_DATA
);
994 memcpy(&DeviceInterfaceData
->InterfaceClassGuid
,
995 &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR
,
996 sizeof(DeviceInterfaceData
->InterfaceClassGuid
));
997 DeviceInterfaceData
->Flags
= 0;
998 /* Note: this appears to be dangerous, passing a private
999 * pointer a heap-allocated datum to the caller. However, the
1000 * expected lifetime of the device data is the same as the
1001 * HDEVINFO; once that is closed, the data are no longer valid.
1003 DeviceInterfaceData
->Reserved
=
1004 (ULONG_PTR
)&list
->names
[MemberIndex
].name
;
1009 SetLastError(ERROR_INVALID_HANDLE
);
1012 SetLastError(ERROR_INVALID_HANDLE
);
1016 /***********************************************************************
1017 * SetupDiDestroyDeviceInfoList (SETUPAPI.@)
1019 BOOL WINAPI
SetupDiDestroyDeviceInfoList(HDEVINFO devinfo
)
1023 TRACE("%p\n", devinfo
);
1024 if (devinfo
&& devinfo
!= (HDEVINFO
)INVALID_HANDLE_VALUE
)
1026 /* FIXME: this assumes the only possible enumeration is of serial
1029 SerialPortList
*list
= (SerialPortList
*)devinfo
;
1031 if (list
->magic
== SETUP_SERIAL_PORT_MAGIC
)
1033 HeapFree(GetProcessHeap(), 0, list
);
1037 SetLastError(ERROR_INVALID_HANDLE
);
1040 SetLastError(ERROR_INVALID_HANDLE
);
1044 /***********************************************************************
1045 * SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@)
1047 BOOL WINAPI
SetupDiGetDeviceInterfaceDetailA(
1048 HDEVINFO DeviceInfoSet
,
1049 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
,
1050 PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData
,
1051 DWORD DeviceInterfaceDetailDataSize
,
1052 PDWORD RequiredSize
,
1053 PSP_DEVINFO_DATA DeviceInfoData
)
1057 TRACE("(%p, %p, %p, %ld, %p, %p)\n", DeviceInfoSet
,
1058 DeviceInterfaceData
, DeviceInterfaceDetailData
,
1059 DeviceInterfaceDetailDataSize
, RequiredSize
, DeviceInfoData
);
1060 if (!DeviceInterfaceData
)
1061 SetLastError(ERROR_INVALID_PARAMETER
);
1062 else if ((DeviceInterfaceDetailDataSize
&& !DeviceInterfaceDetailData
) ||
1063 (DeviceInterfaceDetailData
&& !DeviceInterfaceDetailDataSize
))
1064 SetLastError(ERROR_INVALID_PARAMETER
);
1065 else if (DeviceInfoSet
&& DeviceInfoSet
!= (HDEVINFO
)INVALID_HANDLE_VALUE
)
1067 /* FIXME: this assumes the only possible enumeration is of serial
1070 SerialPortList
*list
= (SerialPortList
*)DeviceInfoSet
;
1072 if (list
->magic
== SETUP_SERIAL_PORT_MAGIC
)
1074 LPCWSTR devName
= (LPCWSTR
)DeviceInterfaceData
->Reserved
;
1075 DWORD sizeRequired
= sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A
) +
1078 if (sizeRequired
> DeviceInterfaceDetailDataSize
)
1080 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1082 *RequiredSize
= sizeRequired
;
1086 LPSTR dst
= DeviceInterfaceDetailData
->DevicePath
;
1087 LPCWSTR src
= devName
;
1089 /* MSDN claims cbSize must be set by the caller, but it lies */
1090 DeviceInterfaceDetailData
->cbSize
=
1091 sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A
);
1092 for ( ; *src
; src
++, dst
++)
1095 TRACE("DevicePath is %s\n",
1096 debugstr_a(DeviceInterfaceDetailData
->DevicePath
));
1099 DeviceInfoData
->cbSize
= sizeof(SP_DEVINFO_DATA
);
1100 memcpy(&DeviceInfoData
->ClassGuid
,
1101 &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR
,
1102 sizeof(DeviceInfoData
->ClassGuid
));
1103 DeviceInfoData
->DevInst
= 0;
1104 DeviceInfoData
->Reserved
= (ULONG_PTR
)devName
;
1110 SetLastError(ERROR_INVALID_HANDLE
);
1113 SetLastError(ERROR_INVALID_HANDLE
);
1114 TRACE("Returning %d\n", ret
);
1118 /***********************************************************************
1119 * SetupDiGetDeviceInterfaceDetailW (SETUPAPI.@)
1121 BOOL WINAPI
SetupDiGetDeviceInterfaceDetailW(
1122 HDEVINFO DeviceInfoSet
,
1123 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
,
1124 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData
,
1125 DWORD DeviceInterfaceDetailDataSize
,
1126 PDWORD RequiredSize
,
1127 PSP_DEVINFO_DATA DeviceInfoData
)
1129 FIXME("(%p, %p, %p, %ld, %p, %p): stub\n", DeviceInfoSet
,
1130 DeviceInterfaceData
, DeviceInterfaceDetailData
,
1131 DeviceInterfaceDetailDataSize
, RequiredSize
, DeviceInfoData
);
1135 /***********************************************************************
1136 * SetupDiGetDeviceRegistryPropertyA (SETUPAPI.@)
1138 BOOL WINAPI
SetupDiGetDeviceRegistryPropertyA(
1140 PSP_DEVINFO_DATA DeviceInfoData
,
1142 PDWORD PropertyRegDataType
,
1143 PBYTE PropertyBuffer
,
1144 DWORD PropertyBufferSize
,
1145 PDWORD RequiredSize
)
1147 FIXME("%04lx %p %ld %p %p %ld %p\n", (DWORD
)devinfo
, DeviceInfoData
,
1148 Property
, PropertyRegDataType
, PropertyBuffer
, PropertyBufferSize
,
1153 /***********************************************************************
1154 * SetupDiInstallClassA (SETUPAPI.@)
1156 BOOL WINAPI
SetupDiInstallClassA(
1162 UNICODE_STRING FileNameW
;
1165 if (!RtlCreateUnicodeStringFromAsciiz(&FileNameW
, InfFileName
))
1167 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1171 Result
= SetupDiInstallClassW(hwndParent
, FileNameW
.Buffer
, Flags
, FileQueue
);
1173 RtlFreeUnicodeString(&FileNameW
);
1178 static HKEY
CreateClassKey(HINF hInf
)
1180 WCHAR FullBuffer
[MAX_PATH
];
1181 WCHAR Buffer
[MAX_PATH
];
1185 if (!SetupGetLineTextW(NULL
,
1193 return INVALID_HANDLE_VALUE
;
1196 lstrcpyW(FullBuffer
, ControlClass
);
1197 lstrcatW(FullBuffer
, Buffer
);
1199 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1205 if (!SetupGetLineTextW(NULL
,
1213 return INVALID_HANDLE_VALUE
;
1216 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
1220 REG_OPTION_NON_VOLATILE
,
1226 return INVALID_HANDLE_VALUE
;
1231 if (RegSetValueExW(hClassKey
,
1236 RequiredSize
* sizeof(WCHAR
)))
1238 RegCloseKey(hClassKey
);
1239 RegDeleteKeyW(HKEY_LOCAL_MACHINE
,
1241 return INVALID_HANDLE_VALUE
;
1247 /***********************************************************************
1248 * SetupDiInstallClassW (SETUPAPI.@)
1250 BOOL WINAPI
SetupDiInstallClassW(
1256 WCHAR SectionName
[MAX_PATH
];
1257 DWORD SectionNameLength
= 0;
1259 BOOL bFileQueueCreated
= FALSE
;
1265 if ((Flags
& DI_NOVCP
) && (FileQueue
== NULL
|| FileQueue
== INVALID_HANDLE_VALUE
))
1267 SetLastError(ERROR_INVALID_PARAMETER
);
1271 /* Open the .inf file */
1272 hInf
= SetupOpenInfFileW(InfFileName
,
1276 if (hInf
== INVALID_HANDLE_VALUE
)
1282 /* Create or open the class registry key 'HKLM\\CurrentControlSet\\Class\\{GUID}' */
1283 hClassKey
= CreateClassKey(hInf
);
1284 if (hClassKey
== INVALID_HANDLE_VALUE
)
1286 SetupCloseInfFile(hInf
);
1291 /* Try to append a layout file */
1293 SetupOpenAppendInfFileW(NULL
, hInf
, NULL
);
1296 /* Retrieve the actual section name */
1297 SetupDiGetActualSectionToInstallW(hInf
,
1305 if (!(Flags
& DI_NOVCP
))
1307 FileQueue
= SetupOpenFileQueue();
1308 if (FileQueue
== INVALID_HANDLE_VALUE
)
1310 SetupCloseInfFile(hInf
);
1314 bFileQueueCreated
= TRUE
;
1319 SetupInstallFromInfSectionW(NULL
,
1328 INVALID_HANDLE_VALUE
,
1331 /* FIXME: More code! */
1333 if (bFileQueueCreated
)
1334 SetupCloseFileQueue(FileQueue
);
1336 SetupCloseInfFile(hInf
);
1342 /***********************************************************************
1343 * SetupDiOpenClassRegKey (SETUPAPI.@)
1345 HKEY WINAPI
SetupDiOpenClassRegKey(
1346 const GUID
* ClassGuid
,
1349 return SetupDiOpenClassRegKeyExW(ClassGuid
, samDesired
,
1350 DIOCR_INSTALLER
, NULL
, NULL
);
1354 /***********************************************************************
1355 * SetupDiOpenClassRegKeyExA (SETUPAPI.@)
1357 HKEY WINAPI
SetupDiOpenClassRegKeyExA(
1358 const GUID
* ClassGuid
,
1364 PWSTR MachineNameW
= NULL
;
1371 MachineNameW
= MultiByteToUnicode(MachineName
, CP_ACP
);
1372 if (MachineNameW
== NULL
)
1373 return INVALID_HANDLE_VALUE
;
1376 hKey
= SetupDiOpenClassRegKeyExW(ClassGuid
, samDesired
,
1377 Flags
, MachineNameW
, Reserved
);
1380 MyFree(MachineNameW
);
1386 /***********************************************************************
1387 * SetupDiOpenClassRegKeyExW (SETUPAPI.@)
1389 HKEY WINAPI
SetupDiOpenClassRegKeyExW(
1390 const GUID
* ClassGuid
,
1396 LPWSTR lpGuidString
;
1401 if (MachineName
!= NULL
)
1403 FIXME("Remote access not supported yet!\n");
1404 return INVALID_HANDLE_VALUE
;
1407 if (Flags
== DIOCR_INSTALLER
)
1409 lpKeyName
= ControlClass
;
1411 else if (Flags
== DIOCR_INTERFACE
)
1413 lpKeyName
= DeviceClasses
;
1417 ERR("Invalid Flags parameter!\n");
1418 SetLastError(ERROR_INVALID_PARAMETER
);
1419 return INVALID_HANDLE_VALUE
;
1422 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1428 return INVALID_HANDLE_VALUE
;
1431 if (ClassGuid
== NULL
)
1434 if (UuidToStringW((UUID
*)ClassGuid
, &lpGuidString
) != RPC_S_OK
)
1436 RegCloseKey(hClassesKey
);
1440 if (RegOpenKeyExW(hClassesKey
,
1446 RpcStringFreeW(&lpGuidString
);
1447 RegCloseKey(hClassesKey
);
1451 RpcStringFreeW(&lpGuidString
);
1452 RegCloseKey(hClassesKey
);
1457 /***********************************************************************
1458 * SetupDiOpenDeviceInterfaceW (SETUPAPI.@)
1460 BOOL WINAPI
SetupDiOpenDeviceInterfaceW(
1461 HDEVINFO DeviceInfoSet
,
1464 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
)
1466 FIXME("%p %s %08lx %p\n",
1467 DeviceInfoSet
, debugstr_w(DevicePath
), OpenFlags
, DeviceInterfaceData
);
1471 /***********************************************************************
1472 * SetupDiOpenDeviceInterfaceA (SETUPAPI.@)
1474 BOOL WINAPI
SetupDiOpenDeviceInterfaceA(
1475 HDEVINFO DeviceInfoSet
,
1478 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
)
1480 FIXME("%p %s %08lx %p\n", DeviceInfoSet
,
1481 debugstr_a(DevicePath
), OpenFlags
, DeviceInterfaceData
);
1485 /***********************************************************************
1486 * SetupDiSetClassInstallParamsA (SETUPAPI.@)
1488 BOOL WINAPI
SetupDiSetClassInstallParamsA(
1489 HDEVINFO DeviceInfoSet
,
1490 PSP_DEVINFO_DATA DeviceInfoData
,
1491 PSP_CLASSINSTALL_HEADER ClassInstallParams
,
1492 DWORD ClassInstallParamsSize
)
1494 FIXME("%p %p %x %lu\n",DeviceInfoSet
, DeviceInfoData
,
1495 ClassInstallParams
->InstallFunction
, ClassInstallParamsSize
);
1499 /***********************************************************************
1500 * SetupDiCallClassInstaller (SETUPAPI.@)
1502 BOOL WINAPI
SetupDiCallClassInstaller(
1503 DWORD InstallFunction
,
1504 HDEVINFO DeviceInfoSet
,
1505 PSP_DEVINFO_DATA DeviceInfoData
)
1507 FIXME("%ld %p %p\n", InstallFunction
, DeviceInfoSet
, DeviceInfoData
);
1511 /***********************************************************************
1512 * SetupDiGetDeviceInstallParamsA (SETUPAPI.@)
1514 BOOL WINAPI
SetupDiGetDeviceInstallParamsA(
1515 HDEVINFO DeviceInfoSet
,
1516 PSP_DEVINFO_DATA DeviceInfoData
,
1517 PSP_DEVINSTALL_PARAMS_A DeviceInstallParams
)
1519 FIXME("%p %p %p\n", DeviceInfoSet
, DeviceInfoData
, DeviceInstallParams
);
1523 /***********************************************************************
1524 * SetupDiOpenDevRegKey (SETUPAPI.@)
1526 HKEY WINAPI
SetupDiOpenDevRegKey(
1527 HDEVINFO DeviceInfoSet
,
1528 PSP_DEVINFO_DATA DeviceInfoData
,
1534 FIXME("%p %p %ld %ld %ld %lx\n", DeviceInfoSet
, DeviceInfoData
,
1535 Scope
, HwProfile
, KeyType
, samDesired
);
1536 return INVALID_HANDLE_VALUE
;