2 * SetupAPI device installer
4 * Copyright 2000 Andreas Mohr for CodeWeavers
5 * Copyright 2004 Aric Stewart for CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/port.h"
36 #include "wine/debug.h"
37 #include "wine/unicode.h"
44 #include "setupapi_private.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(setupapi
);
49 /* Unicode constants */
50 static const WCHAR ClassGUID
[] = {'C','l','a','s','s','G','U','I','D',0};
51 static const WCHAR Class
[] = {'C','l','a','s','s',0};
52 static const WCHAR ClassInstall32
[] = {'C','l','a','s','s','I','n','s','t','a','l','l','3','2',0};
53 static const WCHAR NoDisplayClass
[] = {'N','o','D','i','s','p','l','a','y','C','l','a','s','s',0};
54 static const WCHAR NoInstallClass
[] = {'N','o','I','s','t','a','l','l','C','l','a','s','s',0};
55 static const WCHAR NoUseClass
[] = {'N','o','U','s','e','C','l','a','s','s',0};
56 static const WCHAR NtExtension
[] = {'.','N','T',0};
57 static const WCHAR NtPlatformExtension
[] = {'.','N','T','x','8','6',0};
58 static const WCHAR Version
[] = {'V','e','r','s','i','o','n',0};
59 static const WCHAR WinExtension
[] = {'.','W','i','n',0};
61 /* Registry key and value names */
62 static const WCHAR ControlClass
[] = {'S','y','s','t','e','m','\\',
63 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
64 'C','o','n','t','r','o','l','\\',
65 'C','l','a','s','s',0};
67 static const WCHAR DeviceClasses
[] = {'S','y','s','t','e','m','\\',
68 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
69 'C','o','n','t','r','o','l','\\',
70 'D','e','v','i','c','e','C','l','a','s','s','e','s',0};
72 /* is used to identify if a DeviceInfoSet pointer is
74 #define SETUP_DEVICE_INFO_SET_MAGIC 0xd00ff056
78 DWORD magic
; /* if is equal to SETUP_DEVICE_INFO_SET_MAGIC struct is okay */
83 /***********************************************************************
84 * SetupDiBuildClassInfoList (SETUPAPI.@)
86 * Returns a list of setup class GUIDs that identify the classes
87 * that are installed on a local machine.
90 * Flags [I] control exclusion of classes from the list.
91 * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
92 * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
93 * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
99 BOOL WINAPI
SetupDiBuildClassInfoList(
101 LPGUID ClassGuidList
,
102 DWORD ClassGuidListSize
,
106 return SetupDiBuildClassInfoListExW(Flags
, ClassGuidList
,
107 ClassGuidListSize
, RequiredSize
,
111 /***********************************************************************
112 * SetupDiBuildClassInfoListExA (SETUPAPI.@)
114 * Returns a list of setup class GUIDs that identify the classes
115 * that are installed on a local or remote macine.
118 * Flags [I] control exclusion of classes from the list.
119 * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
120 * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
121 * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
122 * MachineName [I] name of a remote machine.
123 * Reserved [I] must be NULL.
129 BOOL WINAPI
SetupDiBuildClassInfoListExA(
131 LPGUID ClassGuidList
,
132 DWORD ClassGuidListSize
,
137 LPWSTR MachineNameW
= NULL
;
144 MachineNameW
= MultiByteToUnicode(MachineName
, CP_ACP
);
145 if (MachineNameW
== NULL
) return FALSE
;
148 bResult
= SetupDiBuildClassInfoListExW(Flags
, ClassGuidList
,
149 ClassGuidListSize
, RequiredSize
,
150 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 %d\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
);
369 MyFree(MachineNameW
);
375 /***********************************************************************
376 * SetupDiClassGuidsFromNameExW (SETUPAPI.@)
378 BOOL WINAPI
SetupDiClassGuidsFromNameExW(
380 LPGUID ClassGuidList
,
381 DWORD ClassGuidListSize
,
387 WCHAR szClassName
[256];
393 DWORD dwGuidListIndex
= 0;
395 if (RequiredSize
!= NULL
)
398 hClassesKey
= SetupDiOpenClassRegKeyExW(NULL
,
403 if (hClassesKey
== INVALID_HANDLE_VALUE
)
408 for (dwIndex
= 0; ; dwIndex
++)
411 lError
= RegEnumKeyExW(hClassesKey
,
419 TRACE("RegEnumKeyExW() returns %d\n", lError
);
420 if (lError
== ERROR_SUCCESS
|| lError
== ERROR_MORE_DATA
)
422 TRACE("Key name: %p\n", szKeyName
);
424 if (RegOpenKeyExW(hClassesKey
,
430 RegCloseKey(hClassesKey
);
434 dwLength
= 256 * sizeof(WCHAR
);
435 if (!RegQueryValueExW(hClassKey
,
442 TRACE("Class name: %p\n", szClassName
);
444 if (strcmpiW(szClassName
, ClassName
) == 0)
446 TRACE("Found matching class name\n");
448 TRACE("Guid: %p\n", szKeyName
);
449 if (dwGuidListIndex
< ClassGuidListSize
)
451 if (szKeyName
[0] == L
'{' && szKeyName
[37] == L
'}')
455 TRACE("Guid: %p\n", &szKeyName
[1]);
457 UuidFromStringW(&szKeyName
[1],
458 &ClassGuidList
[dwGuidListIndex
]);
465 RegCloseKey(hClassKey
);
468 if (lError
!= ERROR_SUCCESS
)
472 RegCloseKey(hClassesKey
);
474 if (RequiredSize
!= NULL
)
475 *RequiredSize
= dwGuidListIndex
;
477 if (ClassGuidListSize
< dwGuidListIndex
)
479 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
486 /***********************************************************************
487 * SetupDiClassNameFromGuidA (SETUPAPI.@)
489 BOOL WINAPI
SetupDiClassNameFromGuidA(
490 const GUID
* ClassGuid
,
495 return SetupDiClassNameFromGuidExA(ClassGuid
, ClassName
,
496 ClassNameSize
, RequiredSize
,
500 /***********************************************************************
501 * SetupDiClassNameFromGuidW (SETUPAPI.@)
503 BOOL WINAPI
SetupDiClassNameFromGuidW(
504 const GUID
* ClassGuid
,
509 return SetupDiClassNameFromGuidExW(ClassGuid
, ClassName
,
510 ClassNameSize
, RequiredSize
,
514 /***********************************************************************
515 * SetupDiClassNameFromGuidExA (SETUPAPI.@)
517 BOOL WINAPI
SetupDiClassNameFromGuidExA(
518 const GUID
* ClassGuid
,
525 WCHAR ClassNameW
[MAX_CLASS_NAME_LEN
];
526 LPWSTR MachineNameW
= NULL
;
530 MachineNameW
= MultiByteToUnicode(MachineName
, CP_ACP
);
531 ret
= SetupDiClassNameFromGuidExW(ClassGuid
, ClassNameW
, MAX_CLASS_NAME_LEN
,
532 NULL
, MachineNameW
, Reserved
);
535 int len
= WideCharToMultiByte(CP_ACP
, 0, ClassNameW
, -1, ClassName
,
536 ClassNameSize
, NULL
, NULL
);
538 if (!ClassNameSize
&& RequiredSize
)
541 MyFree(MachineNameW
);
545 /***********************************************************************
546 * SetupDiClassNameFromGuidExW (SETUPAPI.@)
548 BOOL WINAPI
SetupDiClassNameFromGuidExW(
549 const GUID
* ClassGuid
,
559 hKey
= SetupDiOpenClassRegKeyExW(ClassGuid
,
564 if (hKey
== INVALID_HANDLE_VALUE
)
569 if (RequiredSize
!= NULL
)
572 if (RegQueryValueExW(hKey
,
583 *RequiredSize
= dwLength
/ sizeof(WCHAR
);
586 dwLength
= ClassNameSize
* sizeof(WCHAR
);
587 if (RegQueryValueExW(hKey
,
603 /***********************************************************************
604 * SetupDiCreateDeviceInfoList (SETUPAPI.@)
607 SetupDiCreateDeviceInfoList(const GUID
*ClassGuid
,
610 return SetupDiCreateDeviceInfoListExW(ClassGuid
, hwndParent
, NULL
, NULL
);
613 /***********************************************************************
614 * SetupDiCreateDeviceInfoListExA (SETUPAPI.@)
617 SetupDiCreateDeviceInfoListExA(const GUID
*ClassGuid
,
622 LPWSTR MachineNameW
= NULL
;
629 MachineNameW
= MultiByteToUnicode(MachineName
, CP_ACP
);
630 if (MachineNameW
== NULL
)
631 return (HDEVINFO
)INVALID_HANDLE_VALUE
;
634 hDevInfo
= SetupDiCreateDeviceInfoListExW(ClassGuid
, hwndParent
,
635 MachineNameW
, Reserved
);
637 MyFree(MachineNameW
);
642 /***********************************************************************
643 * SetupDiCreateDeviceInfoListExW (SETUPAPI.@)
645 * Create an empty DeviceInfoSet list.
648 * ClassGuid [I] if not NULL only devices with GUID ClcassGuid are associated
650 * hwndParent [I] hwnd needed for interface related actions.
651 * MachineName [I] name of machine to create emtpy DeviceInfoSet list, if NULL
652 * local registry will be used.
653 * Reserved [I] must be NULL
656 * Success: empty list.
657 * Failure: INVALID_HANDLE_VALUE.
660 SetupDiCreateDeviceInfoListExW(const GUID
*ClassGuid
,
665 devinfo_struct
*list
= NULL
;
666 DWORD size
= sizeof(devinfo_struct
);
668 TRACE("%s %p %s %p\n", debugstr_guid(ClassGuid
), hwndParent
,
669 debugstr_w(MachineName
), Reserved
);
671 if (MachineName
!= NULL
)
673 FIXME("remote support is not implemented\n");
674 SetLastError(ERROR_INVALID_MACHINENAME
);
675 return (HDEVINFO
)INVALID_HANDLE_VALUE
;
678 if (Reserved
!= NULL
)
680 SetLastError(ERROR_INVALID_PARAMETER
);
681 return (HDEVINFO
)INVALID_HANDLE_VALUE
;
684 list
= HeapAlloc(GetProcessHeap(), 0, size
);
687 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
688 return (HDEVINFO
)INVALID_HANDLE_VALUE
;
691 memset(list
,0,sizeof(devinfo_struct
));
692 list
->magic
= SETUP_DEVICE_INFO_SET_MAGIC
;
693 list
->hwndParent
= hwndParent
;
694 memcpy(&list
->ClassGuid
,
695 ClassGuid
? ClassGuid
: &GUID_NULL
,
696 sizeof(list
->ClassGuid
));
698 return (HDEVINFO
)list
;
701 /***********************************************************************
702 * SetupDiDestroyDeviceInfoList (SETUPAPI.@)
704 BOOL WINAPI
SetupDiDestroyDeviceInfoList(HDEVINFO devinfo
)
706 devinfo_struct
*info
= (devinfo_struct
*)devinfo
;
708 TRACE("%p\n", devinfo
);
716 for (i
= 0; i
< info
->count
; i
++)
718 if (info
->devices
[i
].hardwareid
)
719 HeapFree(GetProcessHeap(),0,info
->devices
[i
].hardwareid
);
721 HeapFree(GetProcessHeap(),0,info
->devices
);
724 HeapFree(GetProcessHeap(),0,info
);
729 /***********************************************************************
730 * SetupDiCreateDeviceInfoA (SETUPAPI.@)
732 BOOL WINAPI
SetupDiCreateDeviceInfoA(
733 HDEVINFO DeviceInfoSet
,
735 CONST GUID
*ClassGuid
,
736 PCSTR DeviceDescription
,
739 PSP_DEVINFO_DATA DeviceInfoData
)
742 LPWSTR DeviceNameW
= NULL
;
743 LPWSTR DeviceDescriptionW
= NULL
;
747 DeviceNameW
= MultiByteToUnicode(DeviceName
, CP_ACP
);
748 if (DeviceNameW
== NULL
) return FALSE
;
750 if (DeviceDescription
)
752 DeviceDescriptionW
= MultiByteToUnicode(DeviceDescription
, CP_ACP
);
753 if (DeviceDescriptionW
== NULL
)
760 ret
= SetupDiCreateDeviceInfoW(DeviceInfoSet
, DeviceNameW
, ClassGuid
, DeviceDescriptionW
,
761 hwndParent
, CreationFlags
, DeviceInfoData
);
764 MyFree(DeviceDescriptionW
);
769 /***********************************************************************
770 * SetupDiCreateDeviceInfoW (SETUPAPI.@)
772 BOOL WINAPI
SetupDiCreateDeviceInfoW(
773 HDEVINFO DeviceInfoSet
,
775 CONST GUID
*ClassGuid
,
776 PCWSTR DeviceDescription
,
779 PSP_DEVINFO_DATA DeviceInfoData
)
781 TRACE("%p %s %s %s %p %x %p\n", DeviceInfoSet
, debugstr_w(DeviceName
),
782 debugstr_guid(ClassGuid
), debugstr_w(DeviceDescription
),
783 hwndParent
, CreationFlags
, DeviceInfoData
);
790 /***********************************************************************
791 * SetupDiEnumDeviceInfo (SETUPAPI.@)
793 BOOL WINAPI
SetupDiEnumDeviceInfo(
796 PSP_DEVINFO_DATA info
)
799 devinfo_struct
*tree
= (devinfo_struct
*)devinfo
;
801 TRACE("%p %d %p\n", devinfo
, index
, info
);
805 if(info
->cbSize
< sizeof(*info
))
810 if (index
>= tree
->count
)
812 SetLastError(ERROR_NO_MORE_ITEMS
);
816 memcpy(&(info
->ClassGuid
),&(tree
->devices
[index
].guid
),sizeof(GUID
));
817 info
->Reserved
= (ULONG_PTR
)&(tree
->devices
[index
]);
820 * Used by cfgmgr32... this is BAD BAD not threadsafe
821 * also it should be a handle that can be used to retrieve data like this
822 * not the straight up data.... but this hack works for the ipod
824 tree
->devices
[index
].registry_fn(&(tree
->devices
[index
]), SPDRP_DEVICE_ID
,
825 NULL
, NULL
, 0, &rc
, FALSE
);
826 info
->DevInst
= (DWORD
)(tree
->devices
[index
].deviceId
);
831 /***********************************************************************
832 * SetupDiEnumDeviceInterfaces (SETUPAPI.@)
834 BOOL WINAPI
SetupDiEnumDeviceInterfaces(
835 HDEVINFO DeviceInfoSet
,
836 PSP_DEVINFO_DATA DeviceInfoData
,
837 CONST GUID
* InterfaceClassGuid
,
839 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
)
841 devinfo_struct
*tree
= (devinfo_struct
*)DeviceInfoSet
;
843 TRACE("(%p, %p, %s, %i %p\n",DeviceInfoSet
, DeviceInfoData
,
844 debugstr_guid(InterfaceClassGuid
), MemberIndex
, DeviceInterfaceData
);
849 if (MemberIndex
>= tree
->count
)
851 SetLastError(ERROR_NO_MORE_ITEMS
);
855 memcpy(&(DeviceInterfaceData
->InterfaceClassGuid
),
856 &(tree
->devices
[MemberIndex
].guid
),sizeof(GUID
));
857 DeviceInterfaceData
->Flags
= tree
->devices
[MemberIndex
].flags
;
858 DeviceInterfaceData
->Reserved
= (ULONG_PTR
)&(tree
->devices
[MemberIndex
]);
863 /***********************************************************************
864 * SetupDiGetActualSectionToInstallA (SETUPAPI.@)
866 BOOL WINAPI
SetupDiGetActualSectionToInstallA(
868 PCSTR InfSectionName
,
869 PSTR InfSectionWithExt
,
870 DWORD InfSectionWithExtSize
,
878 /***********************************************************************
879 * SetupDiGetActualSectionToInstallW (SETUPAPI.@)
881 BOOL WINAPI
SetupDiGetActualSectionToInstallW(
883 PCWSTR InfSectionName
,
884 PWSTR InfSectionWithExt
,
885 DWORD InfSectionWithExtSize
,
889 WCHAR szBuffer
[MAX_PATH
];
892 LONG lLineCount
= -1;
894 lstrcpyW(szBuffer
, InfSectionName
);
895 dwLength
= lstrlenW(szBuffer
);
897 if (OsVersionInfo
.dwPlatformId
== VER_PLATFORM_WIN32_NT
)
899 /* Test section name with '.NTx86' extension */
900 lstrcpyW(&szBuffer
[dwLength
], NtPlatformExtension
);
901 lLineCount
= SetupGetLineCountW(InfHandle
, szBuffer
);
903 if (lLineCount
== -1)
905 /* Test section name with '.NT' extension */
906 lstrcpyW(&szBuffer
[dwLength
], NtExtension
);
907 lLineCount
= SetupGetLineCountW(InfHandle
, szBuffer
);
912 /* Test section name with '.Win' extension */
913 lstrcpyW(&szBuffer
[dwLength
], WinExtension
);
914 lLineCount
= SetupGetLineCountW(InfHandle
, szBuffer
);
917 if (lLineCount
== -1)
919 /* Test section name without extension */
920 szBuffer
[dwLength
] = 0;
921 lLineCount
= SetupGetLineCountW(InfHandle
, szBuffer
);
924 if (lLineCount
== -1)
926 SetLastError(ERROR_INVALID_PARAMETER
);
930 dwFullLength
= lstrlenW(szBuffer
);
932 if (InfSectionWithExt
!= NULL
&& InfSectionWithExtSize
!= 0)
934 if (InfSectionWithExtSize
< (dwFullLength
+ 1))
936 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
940 lstrcpyW(InfSectionWithExt
, szBuffer
);
941 if (Extension
!= NULL
)
943 *Extension
= (dwLength
== dwFullLength
) ? NULL
: &InfSectionWithExt
[dwLength
];
947 if (RequiredSize
!= NULL
)
949 *RequiredSize
= dwFullLength
+ 1;
955 /***********************************************************************
956 * SetupDiGetClassDescriptionA (SETUPAPI.@)
958 BOOL WINAPI
SetupDiGetClassDescriptionA(
959 const GUID
* ClassGuid
,
960 PSTR ClassDescription
,
961 DWORD ClassDescriptionSize
,
964 return SetupDiGetClassDescriptionExA(ClassGuid
, ClassDescription
,
965 ClassDescriptionSize
,
966 RequiredSize
, NULL
, NULL
);
969 /***********************************************************************
970 * SetupDiGetClassDescriptionW (SETUPAPI.@)
972 BOOL WINAPI
SetupDiGetClassDescriptionW(
973 const GUID
* ClassGuid
,
974 PWSTR ClassDescription
,
975 DWORD ClassDescriptionSize
,
978 return SetupDiGetClassDescriptionExW(ClassGuid
, ClassDescription
,
979 ClassDescriptionSize
,
980 RequiredSize
, NULL
, NULL
);
983 /***********************************************************************
984 * SetupDiGetClassDescriptionExA (SETUPAPI.@)
986 BOOL WINAPI
SetupDiGetClassDescriptionExA(
987 const GUID
* ClassGuid
,
988 PSTR ClassDescription
,
989 DWORD ClassDescriptionSize
,
998 /***********************************************************************
999 * SetupDiGetClassDescriptionExW (SETUPAPI.@)
1001 BOOL WINAPI
SetupDiGetClassDescriptionExW(
1002 const GUID
* ClassGuid
,
1003 PWSTR ClassDescription
,
1004 DWORD ClassDescriptionSize
,
1005 PDWORD RequiredSize
,
1012 hKey
= SetupDiOpenClassRegKeyExW(ClassGuid
,
1017 if (hKey
== INVALID_HANDLE_VALUE
)
1019 WARN("SetupDiOpenClassRegKeyExW() failed (Error %u)\n", GetLastError());
1023 if (RequiredSize
!= NULL
)
1026 if (RegQueryValueExW(hKey
,
1037 *RequiredSize
= dwLength
/ sizeof(WCHAR
);
1040 dwLength
= ClassDescriptionSize
* sizeof(WCHAR
);
1041 if (RegQueryValueExW(hKey
,
1045 (LPBYTE
)ClassDescription
,
1057 /***********************************************************************
1058 * SetupDiGetClassDevsA (SETUPAPI.@)
1060 HDEVINFO WINAPI
SetupDiGetClassDevsA(
1066 devinfo_struct
*info
;
1068 TRACE("%s %s %p %08x\n",debugstr_guid(class),enumstr
,parent
,flags
);
1070 /* TODO: make this thread safe*/
1071 info
= HeapAlloc(GetProcessHeap(),0,sizeof(devinfo_struct
));
1072 memset(info
,0,sizeof(devinfo_struct
));
1073 info
->flags
= flags
;
1074 info
->unicode
= FALSE
;
1075 /* setting the winehq structure members */
1076 info
->magic
= SETUP_DEVICE_INFO_SET_MAGIC
;
1077 info
->hwndParent
= parent
;
1078 memcpy(&info
->ClassGuid
,
1079 class ? class: &GUID_NULL
,
1080 sizeof(info
->ClassGuid
));
1082 USB_GetDeviceDevs(info
,class,enumstr
);
1084 return (HDEVINFO
)info
;
1087 /***********************************************************************
1088 * SetupDiGetClassDevsW (SETUPAPI.@)
1090 HDEVINFO WINAPI
SetupDiGetClassDevsW(
1096 TRACE("%s %s %p 0x%08x\n", debugstr_guid(class), debugstr_w(enumstr
), parent
, flags
);
1098 /* WinXP always succeeds, returns empty list for unknown classes */
1099 FIXME("returning empty list\n");
1100 return SetupDiCreateDeviceInfoList(class, parent
);
1103 /***********************************************************************
1104 * SetupDiGetClassDevsExW (SETUPAPI.@)
1106 HDEVINFO WINAPI
SetupDiGetClassDevsExW(
1119 /***********************************************************************
1120 * SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@)
1122 BOOL WINAPI
SetupDiGetDeviceInterfaceDetailA(
1123 HDEVINFO DeviceInfoSet
,
1124 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
,
1125 PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData
,
1126 DWORD DeviceInterfaceDetailDataSize
,
1127 PDWORD RequiredSize
,
1128 PSP_DEVINFO_DATA DeviceInfoData
)
1130 devnode
*node
= (devnode
*)DeviceInterfaceData
->Reserved
;
1132 FIXME("%p %p %p %i %p %p\n",DeviceInfoSet
, DeviceInterfaceData
,
1133 DeviceInterfaceDetailData
, DeviceInterfaceDetailDataSize
,
1134 RequiredSize
, DeviceInfoData
);
1136 node
->registry_fn(node
, SPDRP_DEVICE_PATH
, NULL
,
1137 (LPBYTE
)DeviceInterfaceDetailData
->DevicePath
,
1138 DeviceInterfaceDetailDataSize
, RequiredSize
, FALSE
);
1144 /***********************************************************************
1145 * SetupDiGetDeviceInterfaceDetailW (SETUPAPI.@)
1147 BOOL WINAPI
SetupDiGetDeviceInterfaceDetailW(
1148 HDEVINFO DeviceInfoSet
,
1149 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
,
1150 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData
,
1151 DWORD DeviceInterfaceDetailDataSize
,
1152 PDWORD RequiredSize
,
1153 PSP_DEVINFO_DATA DeviceInfoData
)
1159 /***********************************************************************
1160 * SetupDiGetDeviceRegistryPropertyA (SETUPAPI.@)
1162 BOOL WINAPI
SetupDiGetDeviceRegistryPropertyA(
1164 PSP_DEVINFO_DATA DeviceInfoData
,
1166 PDWORD PropertyRegDataType
,
1167 PBYTE PropertyBuffer
,
1168 DWORD PropertyBufferSize
,
1169 PDWORD RequiredSize
)
1171 devnode
*node
= (devnode
*)DeviceInfoData
->Reserved
;
1173 TRACE("%p %p %d %p %p %d %p\n", devinfo
, DeviceInfoData
,
1174 Property
, PropertyRegDataType
, PropertyBuffer
, PropertyBufferSize
,
1180 return (BOOL
)node
->registry_fn(node
, Property
, PropertyRegDataType
,
1181 PropertyBuffer
, PropertyBufferSize
, RequiredSize
, FALSE
);
1184 /***********************************************************************
1185 * SetupDiInstallClassA (SETUPAPI.@)
1187 BOOL WINAPI
SetupDiInstallClassA(
1193 UNICODE_STRING FileNameW
;
1196 if (!RtlCreateUnicodeStringFromAsciiz(&FileNameW
, InfFileName
))
1198 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1202 Result
= SetupDiInstallClassW(hwndParent
, FileNameW
.Buffer
, Flags
, FileQueue
);
1204 RtlFreeUnicodeString(&FileNameW
);
1209 static HKEY
CreateClassKey(HINF hInf
)
1211 WCHAR FullBuffer
[MAX_PATH
];
1212 WCHAR Buffer
[MAX_PATH
];
1216 if (!SetupGetLineTextW(NULL
,
1224 return INVALID_HANDLE_VALUE
;
1227 lstrcpyW(FullBuffer
, ControlClass
);
1228 lstrcatW(FullBuffer
, Buffer
);
1230 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1236 if (!SetupGetLineTextW(NULL
,
1244 return INVALID_HANDLE_VALUE
;
1247 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
1251 REG_OPTION_NON_VOLATILE
,
1257 return INVALID_HANDLE_VALUE
;
1262 if (RegSetValueExW(hClassKey
,
1267 RequiredSize
* sizeof(WCHAR
)))
1269 RegCloseKey(hClassKey
);
1270 RegDeleteKeyW(HKEY_LOCAL_MACHINE
,
1272 return INVALID_HANDLE_VALUE
;
1278 /***********************************************************************
1279 * SetupDiInstallClassW (SETUPAPI.@)
1281 BOOL WINAPI
SetupDiInstallClassW(
1287 WCHAR SectionName
[MAX_PATH
];
1288 DWORD SectionNameLength
= 0;
1290 BOOL bFileQueueCreated
= FALSE
;
1296 if ((Flags
& DI_NOVCP
) && (FileQueue
== NULL
|| FileQueue
== INVALID_HANDLE_VALUE
))
1298 SetLastError(ERROR_INVALID_PARAMETER
);
1302 /* Open the .inf file */
1303 hInf
= SetupOpenInfFileW(InfFileName
,
1307 if (hInf
== INVALID_HANDLE_VALUE
)
1313 /* Create or open the class registry key 'HKLM\\CurrentControlSet\\Class\\{GUID}' */
1314 hClassKey
= CreateClassKey(hInf
);
1315 if (hClassKey
== INVALID_HANDLE_VALUE
)
1317 SetupCloseInfFile(hInf
);
1322 /* Try to append a layout file */
1324 SetupOpenAppendInfFileW(NULL
, hInf
, NULL
);
1327 /* Retrieve the actual section name */
1328 SetupDiGetActualSectionToInstallW(hInf
,
1336 if (!(Flags
& DI_NOVCP
))
1338 FileQueue
= SetupOpenFileQueue();
1339 if (FileQueue
== INVALID_HANDLE_VALUE
)
1341 SetupCloseInfFile(hInf
);
1345 bFileQueueCreated
= TRUE
;
1350 SetupInstallFromInfSectionW(NULL
,
1359 INVALID_HANDLE_VALUE
,
1362 /* FIXME: More code! */
1364 if (bFileQueueCreated
)
1365 SetupCloseFileQueue(FileQueue
);
1367 SetupCloseInfFile(hInf
);
1373 /***********************************************************************
1374 * SetupDiOpenClassRegKey (SETUPAPI.@)
1376 HKEY WINAPI
SetupDiOpenClassRegKey(
1377 const GUID
* ClassGuid
,
1380 return SetupDiOpenClassRegKeyExW(ClassGuid
, samDesired
,
1381 DIOCR_INSTALLER
, NULL
, NULL
);
1385 /***********************************************************************
1386 * SetupDiOpenClassRegKeyExA (SETUPAPI.@)
1388 HKEY WINAPI
SetupDiOpenClassRegKeyExA(
1389 const GUID
* ClassGuid
,
1395 PWSTR MachineNameW
= NULL
;
1402 MachineNameW
= MultiByteToUnicode(MachineName
, CP_ACP
);
1403 if (MachineNameW
== NULL
)
1404 return INVALID_HANDLE_VALUE
;
1407 hKey
= SetupDiOpenClassRegKeyExW(ClassGuid
, samDesired
,
1408 Flags
, MachineNameW
, Reserved
);
1410 MyFree(MachineNameW
);
1416 /***********************************************************************
1417 * SetupDiOpenClassRegKeyExW (SETUPAPI.@)
1419 HKEY WINAPI
SetupDiOpenClassRegKeyExW(
1420 const GUID
* ClassGuid
,
1426 LPWSTR lpGuidString
;
1427 WCHAR bracedGuidString
[39];
1432 if (MachineName
!= NULL
)
1434 FIXME("Remote access not supported yet!\n");
1435 return INVALID_HANDLE_VALUE
;
1438 if (Flags
== DIOCR_INSTALLER
)
1440 lpKeyName
= ControlClass
;
1442 else if (Flags
== DIOCR_INTERFACE
)
1444 lpKeyName
= DeviceClasses
;
1448 ERR("Invalid Flags parameter!\n");
1449 SetLastError(ERROR_INVALID_PARAMETER
);
1450 return INVALID_HANDLE_VALUE
;
1453 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1459 return INVALID_HANDLE_VALUE
;
1462 if (ClassGuid
== NULL
)
1465 if (UuidToStringW((UUID
*)ClassGuid
, &lpGuidString
) != RPC_S_OK
)
1467 RegCloseKey(hClassesKey
);
1468 return INVALID_HANDLE_VALUE
;
1470 bracedGuidString
[0] = '{';
1471 memcpy(&bracedGuidString
[1], lpGuidString
, 36*sizeof(WCHAR
));
1472 bracedGuidString
[37] = '}';
1473 bracedGuidString
[38] = 0;
1474 RpcStringFreeW(&lpGuidString
);
1476 if (RegOpenKeyExW(hClassesKey
,
1482 RegCloseKey(hClassesKey
);
1483 return INVALID_HANDLE_VALUE
;
1486 RegCloseKey(hClassesKey
);
1491 /***********************************************************************
1492 * SetupDiOpenDeviceInterfaceW (SETUPAPI.@)
1494 BOOL WINAPI
SetupDiOpenDeviceInterfaceW(
1495 HDEVINFO DeviceInfoSet
,
1498 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
)
1500 FIXME("%p %s %08x %p\n",
1501 DeviceInfoSet
, debugstr_w(DevicePath
), OpenFlags
, DeviceInterfaceData
);
1505 /***********************************************************************
1506 * SetupDiOpenDeviceInterfaceA (SETUPAPI.@)
1508 BOOL WINAPI
SetupDiOpenDeviceInterfaceA(
1509 HDEVINFO DeviceInfoSet
,
1512 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
)
1514 FIXME("%p %s %08x %p\n", DeviceInfoSet
,
1515 debugstr_a(DevicePath
), OpenFlags
, DeviceInterfaceData
);
1519 /***********************************************************************
1520 * SetupDiSetClassInstallParamsA (SETUPAPI.@)
1522 BOOL WINAPI
SetupDiSetClassInstallParamsA(
1523 HDEVINFO DeviceInfoSet
,
1524 PSP_DEVINFO_DATA DeviceInfoData
,
1525 PSP_CLASSINSTALL_HEADER ClassInstallParams
,
1526 DWORD ClassInstallParamsSize
)
1528 FIXME("%p %p %x %u\n",DeviceInfoSet
, DeviceInfoData
,
1529 ClassInstallParams
->InstallFunction
, ClassInstallParamsSize
);
1533 /***********************************************************************
1534 * SetupDiCallClassInstaller (SETUPAPI.@)
1536 BOOL WINAPI
SetupDiCallClassInstaller(
1537 DI_FUNCTION InstallFunction
,
1538 HDEVINFO DeviceInfoSet
,
1539 PSP_DEVINFO_DATA DeviceInfoData
)
1541 FIXME("%d %p %p\n", InstallFunction
, DeviceInfoSet
, DeviceInfoData
);
1545 /***********************************************************************
1546 * SetupDiGetDeviceInstallParamsA (SETUPAPI.@)
1548 BOOL WINAPI
SetupDiGetDeviceInstallParamsA(
1549 HDEVINFO DeviceInfoSet
,
1550 PSP_DEVINFO_DATA DeviceInfoData
,
1551 PSP_DEVINSTALL_PARAMS_A DeviceInstallParams
)
1553 FIXME("%p %p %p\n", DeviceInfoSet
, DeviceInfoData
, DeviceInstallParams
);
1557 /***********************************************************************
1558 * SetupDiOpenDevRegKey (SETUPAPI.@)
1560 HKEY WINAPI
SetupDiOpenDevRegKey(
1561 HDEVINFO DeviceInfoSet
,
1562 PSP_DEVINFO_DATA DeviceInfoData
,
1568 FIXME("%p %p %d %d %d %x\n", DeviceInfoSet
, DeviceInfoData
,
1569 Scope
, HwProfile
, KeyType
, samDesired
);
1570 return INVALID_HANDLE_VALUE
;