mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 08:25:48 +00:00
SetupDiGetClassDevsExW: implement DIGCF_ALLCLASSES and DIGCF_DEVICEINTERFACE. use deviceset and enumstr parameters if provided
Set right last error (if needed) in SetupDiCreateDeviceInfoListExW, SetupDiEnumDeviceInfo, SetupDiEnumDeviceInterfaces, SetupDiGetDeviceRegistryPropertyW Replace some constants by constant names svn path=/trunk/; revision=16468
This commit is contained in:
parent
bb29508c33
commit
40c9cd2c5d
1 changed files with 358 additions and 76 deletions
|
@ -76,7 +76,21 @@ typedef struct _DeviceInfo
|
||||||
PWSTR InterfaceName; /* "COMx:" */
|
PWSTR InterfaceName; /* "COMx:" */
|
||||||
LPGUID InterfaceGuid; /* GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR */
|
LPGUID InterfaceGuid; /* GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR */
|
||||||
#else
|
#else
|
||||||
WCHAR DeviceInstance[0];
|
BOOL IsDevice; /* This entry is a device or an interface */
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
GUID ClassGuid;
|
||||||
|
WCHAR RegistryKey[0]; /* "0000", "0001"... */
|
||||||
|
} Device;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
GUID ClassGuid;
|
||||||
|
GUID InterfaceGuid;
|
||||||
|
WCHAR DeviceInstance[0]; /* "ACPI\PNP0501\4&2658d0a0&0"... */
|
||||||
|
} Interface;
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
} DeviceInfo;
|
} DeviceInfo;
|
||||||
|
|
||||||
|
@ -85,7 +99,7 @@ typedef struct _DeviceInfo
|
||||||
typedef struct _DeviceInfoList
|
typedef struct _DeviceInfoList
|
||||||
{
|
{
|
||||||
DWORD magic;
|
DWORD magic;
|
||||||
GUID ClassGuid;
|
GUID ClassGuid; /* Only devices related of this class are in the device list */
|
||||||
HWND hWnd;
|
HWND hWnd;
|
||||||
HKEY HKLM; /* Local or distant HKEY_LOCAL_MACHINE registry key */
|
HKEY HKLM; /* Local or distant HKEY_LOCAL_MACHINE registry key */
|
||||||
DWORD numberOfEntries;
|
DWORD numberOfEntries;
|
||||||
|
@ -154,7 +168,7 @@ BOOL WINAPI SetupDiBuildClassInfoListExW(
|
||||||
LPCWSTR MachineName,
|
LPCWSTR MachineName,
|
||||||
PVOID Reserved)
|
PVOID Reserved)
|
||||||
{
|
{
|
||||||
WCHAR szKeyName[40];
|
WCHAR szKeyName[MAX_GUID_STRING_LEN + 1];
|
||||||
HKEY hClassesKey;
|
HKEY hClassesKey;
|
||||||
HKEY hClassKey;
|
HKEY hClassKey;
|
||||||
DWORD dwLength;
|
DWORD dwLength;
|
||||||
|
@ -179,7 +193,7 @@ BOOL WINAPI SetupDiBuildClassInfoListExW(
|
||||||
|
|
||||||
for (dwIndex = 0; ; dwIndex++)
|
for (dwIndex = 0; ; dwIndex++)
|
||||||
{
|
{
|
||||||
dwLength = 40;
|
dwLength = MAX_GUID_STRING_LEN + 1;
|
||||||
lError = RegEnumKeyExW(hClassesKey,
|
lError = RegEnumKeyExW(hClassesKey,
|
||||||
dwIndex,
|
dwIndex,
|
||||||
szKeyName,
|
szKeyName,
|
||||||
|
@ -359,7 +373,7 @@ BOOL WINAPI SetupDiClassGuidsFromNameExW(
|
||||||
LPCWSTR MachineName,
|
LPCWSTR MachineName,
|
||||||
PVOID Reserved)
|
PVOID Reserved)
|
||||||
{
|
{
|
||||||
WCHAR szKeyName[40];
|
WCHAR szKeyName[MAX_GUID_STRING_LEN + 1];
|
||||||
WCHAR szClassName[256];
|
WCHAR szClassName[256];
|
||||||
HKEY hClassesKey;
|
HKEY hClassesKey;
|
||||||
HKEY hClassKey;
|
HKEY hClassKey;
|
||||||
|
@ -383,7 +397,7 @@ BOOL WINAPI SetupDiClassGuidsFromNameExW(
|
||||||
|
|
||||||
for (dwIndex = 0; ; dwIndex++)
|
for (dwIndex = 0; ; dwIndex++)
|
||||||
{
|
{
|
||||||
dwLength = 40;
|
dwLength = MAX_GUID_STRING_LEN + 1;
|
||||||
lError = RegEnumKeyExW(hClassesKey,
|
lError = RegEnumKeyExW(hClassesKey,
|
||||||
dwIndex,
|
dwIndex,
|
||||||
szKeyName,
|
szKeyName,
|
||||||
|
@ -636,7 +650,10 @@ SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid,
|
||||||
|
|
||||||
list = HeapAlloc(GetProcessHeap(), 0, sizeof(DeviceInfoList));
|
list = HeapAlloc(GetProcessHeap(), 0, sizeof(DeviceInfoList));
|
||||||
if (!list)
|
if (!list)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
return (HDEVINFO)INVALID_HANDLE_VALUE;
|
return (HDEVINFO)INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
list->magic = SETUP_DEV_INFO_LIST_MAGIC;
|
list->magic = SETUP_DEV_INFO_LIST_MAGIC;
|
||||||
list->hWnd = hwndParent;
|
list->hWnd = hwndParent;
|
||||||
|
@ -676,7 +693,7 @@ BOOL WINAPI SetupDiEnumDeviceInfo(
|
||||||
if (list->magic != SETUP_DEV_INFO_LIST_MAGIC)
|
if (list->magic != SETUP_DEV_INFO_LIST_MAGIC)
|
||||||
SetLastError(ERROR_INVALID_HANDLE);
|
SetLastError(ERROR_INVALID_HANDLE);
|
||||||
else if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
|
else if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
SetLastError(ERROR_INVALID_USER_BUFFER);
|
||||||
else if (MemberIndex >= list->numberOfEntries)
|
else if (MemberIndex >= list->numberOfEntries)
|
||||||
SetLastError(ERROR_NO_MORE_ITEMS);
|
SetLastError(ERROR_NO_MORE_ITEMS);
|
||||||
else
|
else
|
||||||
|
@ -686,6 +703,8 @@ BOOL WINAPI SetupDiEnumDeviceInfo(
|
||||||
while (MemberIndex-- > 0)
|
while (MemberIndex-- > 0)
|
||||||
ItemList = ItemList->Flink;
|
ItemList = ItemList->Flink;
|
||||||
DevInfo = (DeviceInfo *)ItemList;
|
DevInfo = (DeviceInfo *)ItemList;
|
||||||
|
if (DevInfo->IsDevice)
|
||||||
|
{
|
||||||
#ifdef __WINE__
|
#ifdef __WINE__
|
||||||
memcpy(&DeviceInfoData->ClassGuid,
|
memcpy(&DeviceInfoData->ClassGuid,
|
||||||
DevInfo->InterfaceGuid,
|
DevInfo->InterfaceGuid,
|
||||||
|
@ -694,13 +713,18 @@ BOOL WINAPI SetupDiEnumDeviceInfo(
|
||||||
DeviceInfoData->Reserved = 0;
|
DeviceInfoData->Reserved = 0;
|
||||||
#else
|
#else
|
||||||
memcpy(&DeviceInfoData->ClassGuid,
|
memcpy(&DeviceInfoData->ClassGuid,
|
||||||
&list->ClassGuid, /* FIXME */
|
&DevInfo->Device.ClassGuid,
|
||||||
sizeof(GUID));
|
sizeof(GUID));
|
||||||
DeviceInfoData->DevInst = 0; /* FIXME */
|
DeviceInfoData->DevInst = 0; /* FIXME */
|
||||||
DeviceInfoData->Reserved = 0;
|
DeviceInfoData->Reserved = 0;
|
||||||
#endif
|
#endif
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
SetLastError(ERROR_INVALID_HANDLE);
|
SetLastError(ERROR_INVALID_HANDLE);
|
||||||
|
@ -1125,27 +1149,24 @@ static HDEVINFO SETUP_CreateSerialDeviceList(void)
|
||||||
}
|
}
|
||||||
#endif /* __WINE__ */
|
#endif /* __WINE__ */
|
||||||
|
|
||||||
static HDEVINFO SETUP_CreateDevListFromClass(
|
static LONG SETUP_CreateDevListFromClass(
|
||||||
|
DeviceInfoList *list,
|
||||||
PCWSTR MachineName,
|
PCWSTR MachineName,
|
||||||
LPGUID class)
|
LPGUID class,
|
||||||
|
PCWSTR Enumerator)
|
||||||
{
|
{
|
||||||
HDEVINFO hDeviceInfo;
|
|
||||||
HKEY KeyClass;
|
HKEY KeyClass;
|
||||||
LONG rc;
|
LONG rc;
|
||||||
DWORD subKeys = 0, maxSubKey;
|
DWORD subKeys = 0, maxSubKey;
|
||||||
DeviceInfo* deviceInfo;
|
DeviceInfo* deviceInfo;
|
||||||
DWORD i;
|
DWORD i;
|
||||||
|
|
||||||
hDeviceInfo = SetupDiCreateDeviceInfoListExW(class, NULL, MachineName, NULL);
|
|
||||||
if (hDeviceInfo == INVALID_HANDLE_VALUE)
|
|
||||||
return INVALID_HANDLE_VALUE;
|
|
||||||
|
|
||||||
KeyClass = SetupDiOpenClassRegKeyExW(class, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, DIOCR_INSTALLER, MachineName, NULL);
|
KeyClass = SetupDiOpenClassRegKeyExW(class, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, DIOCR_INSTALLER, MachineName, NULL);
|
||||||
if (KeyClass == INVALID_HANDLE_VALUE)
|
if (KeyClass == INVALID_HANDLE_VALUE)
|
||||||
{
|
return GetLastError();
|
||||||
SetupDiDestroyDeviceInfoList(hDeviceInfo);
|
|
||||||
return INVALID_HANDLE_VALUE;
|
if (Enumerator)
|
||||||
}
|
FIXME("Enumerator parameter ignored\n");
|
||||||
|
|
||||||
rc = RegQueryInfoKeyW(
|
rc = RegQueryInfoKeyW(
|
||||||
KeyClass,
|
KeyClass,
|
||||||
|
@ -1157,35 +1178,185 @@ static HDEVINFO SETUP_CreateDevListFromClass(
|
||||||
if (rc != ERROR_SUCCESS)
|
if (rc != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
RegCloseKey(KeyClass);
|
RegCloseKey(KeyClass);
|
||||||
SetLastError(rc);
|
return rc;
|
||||||
return INVALID_HANDLE_VALUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < subKeys; i++)
|
for (i = 0; i < subKeys; i++)
|
||||||
{
|
{
|
||||||
deviceInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(DeviceInfo) + maxSubKey * sizeof(WCHAR));
|
deviceInfo = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(DeviceInfo, Device.RegistryKey) + maxSubKey * sizeof(WCHAR));
|
||||||
if (!deviceInfo)
|
if (!deviceInfo)
|
||||||
{
|
{
|
||||||
SetupDiDestroyDeviceInfoList(hDeviceInfo);
|
RegCloseKey(KeyClass);
|
||||||
SetLastError(ERROR_NO_SYSTEM_RESOURCES);
|
return ERROR_NO_SYSTEM_RESOURCES;
|
||||||
return INVALID_HANDLE_VALUE;
|
|
||||||
}
|
}
|
||||||
rc = RegEnumKeyW(KeyClass, i, &deviceInfo->DeviceInstance[0], maxSubKey);
|
rc = RegEnumKeyW(KeyClass, i, &deviceInfo->Device.RegistryKey[0], maxSubKey);
|
||||||
if (rc == ERROR_NO_MORE_ITEMS)
|
if (rc == ERROR_NO_MORE_ITEMS)
|
||||||
break;
|
break;
|
||||||
if (rc != ERROR_SUCCESS)
|
if (rc != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
SetupDiDestroyDeviceInfoList(hDeviceInfo);
|
RegCloseKey(KeyClass);
|
||||||
SetLastError(rc);
|
return rc;
|
||||||
return INVALID_HANDLE_VALUE;
|
|
||||||
}
|
}
|
||||||
InsertTailList(&((DeviceInfoList*)hDeviceInfo)->ListHead, &deviceInfo->ItemEntry);
|
deviceInfo->IsDevice = TRUE;
|
||||||
((DeviceInfoList*)hDeviceInfo)->numberOfEntries++;
|
memcpy(&deviceInfo->Device.ClassGuid, class, sizeof(GUID));
|
||||||
|
InsertTailList(&list->ListHead, &deviceInfo->ItemEntry);
|
||||||
|
list->numberOfEntries++;
|
||||||
}
|
}
|
||||||
|
|
||||||
RegCloseKey(KeyClass);
|
RegCloseKey(KeyClass);
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
return hDeviceInfo;
|
static LONG SETUP_CreateInterfaceList(
|
||||||
|
DeviceInfoList *list,
|
||||||
|
PCWSTR MachineName,
|
||||||
|
LPGUID InterfaceGuid,
|
||||||
|
PCWSTR DeviceInstance /* OPTIONAL */)
|
||||||
|
{
|
||||||
|
HKEY hInterfaceKey, hEnumKey, hKey;
|
||||||
|
LONG rc;
|
||||||
|
WCHAR KeyBuffer[max(MAX_PATH, MAX_GUID_STRING_LEN) + 1];
|
||||||
|
DWORD i;
|
||||||
|
DWORD dwLength, dwRegType;
|
||||||
|
DeviceInfo *deviceInfo;
|
||||||
|
|
||||||
|
/* Open registry key related to this interface */
|
||||||
|
hInterfaceKey = SetupDiOpenClassRegKeyExW(InterfaceGuid, KEY_ENUMERATE_SUB_KEYS, DIOCR_INTERFACE, MachineName, NULL);
|
||||||
|
if (hInterfaceKey == INVALID_HANDLE_VALUE)
|
||||||
|
return GetLastError();
|
||||||
|
|
||||||
|
/* Enumerate sub keys */
|
||||||
|
i = 0;
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
dwLength = sizeof(KeyBuffer) / sizeof(KeyBuffer[0]);
|
||||||
|
rc = RegEnumKeyExW(hInterfaceKey, i, KeyBuffer, &dwLength, NULL, NULL, NULL, NULL);
|
||||||
|
if (rc == ERROR_NO_MORE_ITEMS)
|
||||||
|
break;
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
RegCloseKey(hInterfaceKey);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
|
||||||
|
/* Open sub key */
|
||||||
|
rc = RegOpenKeyEx(hInterfaceKey, KeyBuffer, 0, KEY_QUERY_VALUE, &hKey);
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
RegCloseKey(hInterfaceKey);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read DeviceInstance value */
|
||||||
|
rc = RegQueryValueExW(hKey, L"DeviceInstance", NULL, &dwRegType, NULL, &dwLength);
|
||||||
|
if (rc != ERROR_SUCCESS )
|
||||||
|
{
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
RegCloseKey(hInterfaceKey);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
if (dwRegType != REG_SZ)
|
||||||
|
{
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
RegCloseKey(hInterfaceKey);
|
||||||
|
return ERROR_GEN_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate memory for list entry and read DeviceInstance */
|
||||||
|
deviceInfo = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(DeviceInfo, Interface.DeviceInstance) + dwLength + sizeof(UNICODE_NULL));
|
||||||
|
if (!deviceInfo)
|
||||||
|
{
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
RegCloseKey(hInterfaceKey);
|
||||||
|
return ERROR_NO_SYSTEM_RESOURCES;
|
||||||
|
}
|
||||||
|
rc = RegQueryValueExW(hKey, L"DeviceInstance", NULL, NULL, (LPBYTE)&deviceInfo->Interface.DeviceInstance[0], &dwLength);
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, deviceInfo);
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
RegCloseKey(hInterfaceKey);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
deviceInfo->Interface.DeviceInstance[dwLength / sizeof(WCHAR)] = UNICODE_NULL;
|
||||||
|
TRACE("DeviceInstance %S\n", deviceInfo->Interface.DeviceInstance);
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
|
||||||
|
if (DeviceInstance)
|
||||||
|
{
|
||||||
|
/* Check if device enumerator is not the right one */
|
||||||
|
if (wcscmp(DeviceInstance, deviceInfo->Interface.DeviceInstance) != 0)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, deviceInfo);;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find class GUID associated to the device instance */
|
||||||
|
rc = RegOpenKeyEx(
|
||||||
|
HKEY_LOCAL_MACHINE,
|
||||||
|
L"SYSTEM\\CurrentControlSet\\Enum",
|
||||||
|
0, /* Options */
|
||||||
|
KEY_ENUMERATE_SUB_KEYS,
|
||||||
|
&hEnumKey);
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, deviceInfo);
|
||||||
|
RegCloseKey(hInterfaceKey);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
rc = RegOpenKeyEx(
|
||||||
|
hEnumKey,
|
||||||
|
deviceInfo->Interface.DeviceInstance,
|
||||||
|
0, /* Options */
|
||||||
|
KEY_QUERY_VALUE,
|
||||||
|
&hKey);
|
||||||
|
RegCloseKey(hEnumKey);
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, deviceInfo);
|
||||||
|
RegCloseKey(hInterfaceKey);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
dwLength = sizeof(KeyBuffer) - sizeof(UNICODE_NULL);
|
||||||
|
rc = RegQueryValueExW(hKey, L"ClassGUID", NULL, NULL, (LPBYTE)KeyBuffer, &dwLength);
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, deviceInfo);
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
RegCloseKey(hInterfaceKey);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
KeyBuffer[dwLength / sizeof(WCHAR)] = UNICODE_NULL;
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
KeyBuffer[37] = UNICODE_NULL; /* Replace the } by a NULL character */
|
||||||
|
if (UuidFromStringW(&KeyBuffer[1], &deviceInfo->Interface.ClassGuid) != RPC_S_OK)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, deviceInfo);
|
||||||
|
return ERROR_GEN_FAILURE;
|
||||||
|
}
|
||||||
|
TRACE("ClassGUID %S\n", KeyBuffer);
|
||||||
|
|
||||||
|
/* If current device matches the list GUID (if any), append the entry to the list */
|
||||||
|
if (IsEqualIID(&list->ClassGuid, &GUID_NULL) || IsEqualIID(&list->ClassGuid, &deviceInfo->Interface.ClassGuid))
|
||||||
|
{
|
||||||
|
TRACE("Entry found\n");
|
||||||
|
deviceInfo->IsDevice = FALSE;
|
||||||
|
memcpy(
|
||||||
|
&deviceInfo->Interface.InterfaceGuid,
|
||||||
|
InterfaceGuid,
|
||||||
|
sizeof(deviceInfo->Interface.InterfaceGuid));
|
||||||
|
InsertTailList(&list->ListHead, &deviceInfo->ItemEntry);
|
||||||
|
list->numberOfEntries++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, deviceInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RegCloseKey(hInterfaceKey);
|
||||||
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -1200,38 +1371,141 @@ HDEVINFO WINAPI SetupDiGetClassDevsExW(
|
||||||
LPCWSTR machine,
|
LPCWSTR machine,
|
||||||
PVOID reserved)
|
PVOID reserved)
|
||||||
{
|
{
|
||||||
HDEVINFO ret = (HDEVINFO)INVALID_HANDLE_VALUE;
|
HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
|
||||||
|
DeviceInfoList *list;
|
||||||
|
LPGUID pClassGuid;
|
||||||
|
LPGUID ClassGuidList;
|
||||||
|
DWORD RequiredSize;
|
||||||
|
LONG i;
|
||||||
|
LONG rc;
|
||||||
|
|
||||||
TRACE("%s %s %p 0x%08lx %p %s %p\n", debugstr_guid(class), debugstr_w(enumstr),
|
TRACE("%s %s %p 0x%08lx %p %s %p\n", debugstr_guid(class), debugstr_w(enumstr),
|
||||||
parent, flags, deviceset, debugstr_w(machine), reserved);
|
parent, flags, deviceset, debugstr_w(machine), reserved);
|
||||||
|
|
||||||
|
/* Create the deviceset if not set */
|
||||||
|
if (deviceset)
|
||||||
|
{
|
||||||
|
list = (DeviceInfoList *)deviceset;
|
||||||
|
if (list->magic != SETUP_DEV_INFO_LIST_MAGIC)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_HANDLE);
|
||||||
|
return INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
hDeviceInfo = deviceset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hDeviceInfo = SetupDiCreateDeviceInfoListExW(
|
||||||
|
flags & DIGCF_DEVICEINTERFACE ? NULL : class,
|
||||||
|
NULL, machine, NULL);
|
||||||
|
if (hDeviceInfo == INVALID_HANDLE_VALUE)
|
||||||
|
return INVALID_HANDLE_VALUE;
|
||||||
|
list = (DeviceInfoList *)hDeviceInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsEqualIID(&list->ClassGuid, &GUID_NULL))
|
||||||
|
pClassGuid = NULL;
|
||||||
|
else
|
||||||
|
pClassGuid = &list->ClassGuid;
|
||||||
|
|
||||||
if (flags & DIGCF_PRESENT)
|
if (flags & DIGCF_PRESENT)
|
||||||
FIXME(": flag DIGCF_PRESENT ignored\n");
|
FIXME(": flag DIGCF_PRESENT ignored\n");
|
||||||
if (flags & DIGCF_PROFILE)
|
if (flags & DIGCF_PROFILE)
|
||||||
FIXME(": flag DIGCF_PROFILE ignored\n");
|
FIXME(": flag DIGCF_PROFILE ignored\n");
|
||||||
if (deviceset)
|
|
||||||
FIXME(": deviceset ignored\n");
|
|
||||||
|
|
||||||
if (enumstr)
|
if (flags & DIGCF_ALLCLASSES)
|
||||||
FIXME(": unimplemented for enumerator strings (%s)\n",
|
{
|
||||||
debugstr_w(enumstr));
|
/* Get list of device classes */
|
||||||
else if (flags & DIGCF_ALLCLASSES)
|
SetupDiBuildClassInfoList(0, NULL, 0, &RequiredSize);
|
||||||
FIXME(": unimplemented for DIGCF_ALLCLASSES\n");
|
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
||||||
|
{
|
||||||
|
if (!deviceset)
|
||||||
|
SetupDiDestroyDeviceInfoList(hDeviceInfo);
|
||||||
|
return INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
ClassGuidList = HeapAlloc(GetProcessHeap(), 0, RequiredSize * sizeof(GUID));
|
||||||
|
if (!ClassGuidList)
|
||||||
|
{
|
||||||
|
if (!deviceset)
|
||||||
|
SetupDiDestroyDeviceInfoList(hDeviceInfo);
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
if (!SetupDiBuildClassInfoListExW(0, ClassGuidList, RequiredSize, &RequiredSize, machine, NULL))
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, ClassGuidList);
|
||||||
|
if (!deviceset)
|
||||||
|
SetupDiDestroyDeviceInfoList(hDeviceInfo);
|
||||||
|
return INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enumerate devices in each device class */
|
||||||
|
for (i = 0; i < RequiredSize; i++)
|
||||||
|
{
|
||||||
|
if (pClassGuid == NULL || IsEqualIID(pClassGuid, &ClassGuidList[i]))
|
||||||
|
{
|
||||||
|
rc = SETUP_CreateDevListFromClass(list, machine, &ClassGuidList[i], enumstr);
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, ClassGuidList);
|
||||||
|
SetLastError(rc);
|
||||||
|
if (!deviceset)
|
||||||
|
SetupDiDestroyDeviceInfoList(hDeviceInfo);
|
||||||
|
return INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HeapFree(GetProcessHeap(), 0, ClassGuidList);
|
||||||
|
return hDeviceInfo;
|
||||||
|
}
|
||||||
else if (flags & DIGCF_DEVICEINTERFACE)
|
else if (flags & DIGCF_DEVICEINTERFACE)
|
||||||
FIXME(": unimplemented for DIGCF_DEVICEINTERFACE\n");
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
if (class == NULL)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
if (!deviceset)
|
||||||
|
SetupDiDestroyDeviceInfoList(hDeviceInfo);
|
||||||
|
return INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __WINE__
|
#ifdef __WINE__
|
||||||
if (IsEqualIID(class, &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR))
|
/* Special case: find serial ports by calling QueryDosDevice */
|
||||||
ret = SETUP_CreateSerialDeviceList();
|
if (IsEqualIID(class, &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR)
|
||||||
else
|
|
||||||
#else
|
|
||||||
{
|
{
|
||||||
ret = SETUP_CreateDevListFromClass(machine, (LPGUID)class);
|
rc = SETUP_CreateSerialDeviceList();
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
SetLastError(rc);
|
||||||
|
if (!deviceset)
|
||||||
|
SetupDiDestroyDeviceInfoList(hDeviceInfo);
|
||||||
|
return INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
return hDeviceInfo;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
rc = SETUP_CreateInterfaceList(list, machine, (LPGUID)class, enumstr);
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
SetLastError(rc);
|
||||||
|
if (!deviceset)
|
||||||
|
SetupDiDestroyDeviceInfoList(hDeviceInfo);
|
||||||
|
return INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
return hDeviceInfo;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = SETUP_CreateDevListFromClass(list, machine, (LPGUID)class, enumstr);
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
SetLastError(rc);
|
||||||
|
if (!deviceset)
|
||||||
|
SetupDiDestroyDeviceInfoList(hDeviceInfo);
|
||||||
|
return INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
return hDeviceInfo;
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -1268,7 +1542,9 @@ BOOL WINAPI SetupDiEnumDeviceInterfaces(
|
||||||
ItemList = ItemList->Flink;
|
ItemList = ItemList->Flink;
|
||||||
DevInfo = (DeviceInfo *)ItemList;
|
DevInfo = (DeviceInfo *)ItemList;
|
||||||
|
|
||||||
DeviceInterfaceData->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
|
if (!DevInfo->IsDevice)
|
||||||
|
{
|
||||||
|
DeviceInterfaceData->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); /* FIXME: verify instead of setting */
|
||||||
#ifdef __WINE__
|
#ifdef __WINE__
|
||||||
/* FIXME: this assumes the only possible enumeration is of serial
|
/* FIXME: this assumes the only possible enumeration is of serial
|
||||||
* ports.
|
* ports.
|
||||||
|
@ -1284,10 +1560,15 @@ BOOL WINAPI SetupDiEnumDeviceInterfaces(
|
||||||
*/
|
*/
|
||||||
DeviceInterfaceData->Reserved = (ULONG_PTR)DevInfo->InterfaceName;
|
DeviceInterfaceData->Reserved = (ULONG_PTR)DevInfo->InterfaceName;
|
||||||
#else
|
#else
|
||||||
FIXME("implemented\n");
|
FIXME("unimplemented\n");
|
||||||
#endif
|
#endif
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
SetLastError(ERROR_INVALID_HANDLE);
|
SetLastError(ERROR_INVALID_HANDLE);
|
||||||
|
@ -1513,6 +1794,7 @@ BOOL WINAPI SetupDiGetDeviceRegistryPropertyW(
|
||||||
FIXME("%04lx %p %ld %p %p %ld %p\n", (DWORD)devinfo, DeviceInfoData,
|
FIXME("%04lx %p %ld %p %p %ld %p\n", (DWORD)devinfo, DeviceInfoData,
|
||||||
Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize,
|
Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize,
|
||||||
RequiredSize);
|
RequiredSize);
|
||||||
|
SetLastError(ERROR_GEN_FAILURE);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue