Change structures used to keep information about devices/interfaces/drivers. This one is more logical and should be more extensible Sorry, i've disabled code to enumerate devices implementing some interface (not ported) Do related changes in the file Modified: trunk/reactos/lib/setupapi/devinst.c _____
Modified: trunk/reactos/lib/setupapi/devinst.c --- trunk/reactos/lib/setupapi/devinst.c 2005-08-08 15:56:27 UTC (rev 17209) +++ trunk/reactos/lib/setupapi/devinst.c 2005-08-08 16:06:52 UTC (rev 17210) @@ -76,50 +76,116 @@
'E','n','u','m',0};
-typedef struct _DeviceInfo +/* FIXME: header mess */ +DEFINE_GUID(GUID_NULL, + 0x00000000L, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + +#define SETUP_DEV_INFO_SET_MAGIC 0xd00ff057 + +struct DeviceInterface /* Element of DeviceInfoElement.InterfaceHead */ { - LIST_ENTRY ItemEntry; - BOOL IsDevice; /* This entry is a device or an interface */ - union - { - struct - { - GUID ClassGuid; - WCHAR InstancePath[0]; /* "ACPI\PNP0501\4&2658d0a0&0" */ - } Device; - struct - { - GUID InterfaceGuid; - GUID ClassGuid; -#ifndef __WINESRC__ - /* Pointer into Data field. Contains something like */ - /* "ACPI\PNP0501\4&2658d0a0&0" */ - PWSTR pInstancePath; -#endif - /* Pointer into Data field. Contains something like - * "\?\ACPI#PNP0501#4&2658d0a0&0#{GUID}", or "COMx" for WINE */ - PWSTR pSymbolicLink; - WCHAR Data[0]; - } Interface; - }; -} DeviceInfo; + LIST_ENTRY ListEntry;
-#define SETUP_DEV_INFO_LIST_MAGIC 0xd00ff056 + GUID InterfaceClassGuid; + + /* SPINT_ACTIVE : the interface is active/enabled + * SPINT_DEFAULT: the interface is the default interface for the device class FIXME??? + * SPINT_REMOVED: the interface is removed + */ + DWORD Flags;
-typedef struct _DeviceInfoList + WCHAR SymbolicLink[0]; /* \?\ACPI#PNP0501#4&2658d0a0&0#{GUID} */ +}; + +struct DriverInfoElement /* Element of DeviceInfoSet.DriverListHead and DeviceInfoElement.DriverListHead */ { - DWORD magic; - GUID ClassGuid; /* Only devices related of this class are in the device list */ - HWND hWnd; + LIST_ENTRY ListEntry; + + SP_DRVINFO_DATA_V2_W Info; +}; + +struct DeviceInfoElement /* Element of DeviceInfoSet.ListHead */ +{ + LIST_ENTRY ListEntry; + + /* Information about devnode: + * - DeviceName: + * "Root*PNP0501" for example. + * It doesn't contain the unique ID for the device + * (points into the Data field at the end of the structure) + * WARNING: no NULL char exist between DeviceName and UniqueId + * in Data field! + * - UniqueId + * "5&1be2108e&0" or "0000" + * If DICD_GENERATE_ID is specified in creation flags, + * this unique ID is autogenerated using 4 digits, base 10 + * (points into the Data field at the end of the structure) + * - DeviceDescription + * String which identifies the device. Can be NULL. If not NULL, + * points into the Data field at the end of the structure + * - ClassGuid + * Identifies the class of this device. FIXME: can it be GUID_NULL? + * - CreationFlags + * Is a combination of: + * - DICD_GENERATE_ID + * the unique ID needs to be generated + * - DICD_INHERIT_CLASSDRVS + * inherit driver of the device info set (== same pointer) + * - hwndParent + * Used when doing device-specific actions. Can be NULL + */ + PCWSTR DeviceName; + PCWSTR UniqueId; + PCWSTR DeviceDescription; + GUID ClassGuid; + DWORD CreationFlags; + HWND hwndParent; + + /* Flags is a combination of: + * - DI_DIDCOMPAT + * Set when the device driver list is created + * FlagsEx is a combination of: + */ + DWORD Flags; + DWORD FlagsEx; + + /* If CreationFlags contains DICD_INHERIT_CLASSDRVS, this list is invalid */ + /* If the driver is not searched/detected, this list is empty */ + LIST_ENTRY DriverListHead; /* List of struct DriverInfoElement */ + + /* List of interfaces implemented by this device */ + LIST_ENTRY InterfaceHead; /* List of struct DeviceInterface */ + + WCHAR Data[0]; +}; + +struct DeviceInfoSet /* HDEVINFO */ +{ + DWORD magic; /* SETUP_DEV_INFO_SET_MAGIC */ + GUID ClassGuid; /* If != GUID_NULL, only devices of this class can be in the device info set */ + HWND hwndParent; /* only used on non-device-specific actions, like as a select-device dialog using the global class driver list */ HKEY HKLM; /* Local or distant HKEY_LOCAL_MACHINE registry key */ - DWORD numberOfEntries; - LIST_ENTRY ListHead; -} DeviceInfoList;
-/* FIXME: header mess */ -DEFINE_GUID(GUID_NULL, - 0x00000000L, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + /* Flags is a combination of: + * - DI_FLAGSEX_DIDINFOLIST + * - DI_DIDCLASS + * - DI_MULTMFGS + * Set by SetupDiBuildDriverInfoList if drivers of + * multiple manufacturers found + * - DI_FLAGSEX_DIDCOMPATINFO + * - DI_COMPAT_FROM_CLASS + * Forces SetupDiBuildDriverInfoList to build a class drivers list + * FlagsEx is a combination of: + */ + DWORD Flags; + DWORD FlagsEx;
+ /* If the driver is not searched/detected, this list is empty */ + LIST_ENTRY DriverListHead; /* List of struct DriverInfoElement */ + + LIST_ENTRY ListHead; /* List of struct DeviceInfoElement */ +}; +
/*********************************************************************** * SetupDiBuildClassInfoList (SETUPAPI.@) */ @@ -627,7 +693,7 @@ LPWSTR MachineNameW = NULL; HDEVINFO hDevInfo;
- TRACE("\n"); + TRACE("%p %p %s %p\n", ClassGuid, hwndParent, MachineName, Reserved);
if (MachineName) { @@ -654,21 +720,24 @@ PCWSTR MachineName, PVOID Reserved) { - DeviceInfoList* list; + struct DeviceInfoSet *list; DWORD rc;
- TRACE("%p %p %p %p\n", ClassGuid, hwndParent, MachineName, Reserved); + TRACE("%p %p %S %p\n", ClassGuid, hwndParent, MachineName, Reserved);
- list = HeapAlloc(GetProcessHeap(), 0, sizeof(DeviceInfoList)); + list = HeapAlloc(GetProcessHeap(), 0, sizeof(struct DeviceInfoSet)); if (!list) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return (HDEVINFO)INVALID_HANDLE_VALUE; }
- list->magic = SETUP_DEV_INFO_LIST_MAGIC; - list->hWnd = hwndParent; - list->numberOfEntries = 0; + list->magic = SETUP_DEV_INFO_SET_MAGIC; + memcpy( + &list->ClassGuid, + ClassGuid ? ClassGuid : &GUID_NULL, + sizeof(list->ClassGuid)); + list->hwndParent = hwndParent; if (MachineName) { rc = RegConnectRegistryW(MachineName, HKEY_LOCAL_MACHINE, &list->HKLM); @@ -683,11 +752,9 @@ { list->HKLM = HKEY_LOCAL_MACHINE; } - - memcpy( - &list->ClassGuid, - ClassGuid ? ClassGuid : &GUID_NULL, - sizeof(list->ClassGuid)); + list->Flags = 0; /* FIXME */ + list->FlagsEx = 0; /* FIXME */ + InitializeListHead(&list->DriverListHead); InitializeListHead(&list->ListHead); return (HDEVINFO)list; } @@ -707,25 +774,24 @@ SetLastError(ERROR_INVALID_PARAMETER); else if (DeviceInfoSet && DeviceInfoSet != (HDEVINFO)INVALID_HANDLE_VALUE) { - DeviceInfoList *list = (DeviceInfoList *)DeviceInfoSet; + struct DeviceInfoSet *list = (struct DeviceInfoSet *)DeviceInfoSet;
- if (list->magic != SETUP_DEV_INFO_LIST_MAGIC) + if (list->magic != SETUP_DEV_INFO_SET_MAGIC) SetLastError(ERROR_INVALID_HANDLE); else if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)) SetLastError(ERROR_INVALID_USER_BUFFER); - else if (MemberIndex >= list->numberOfEntries) - SetLastError(ERROR_NO_MORE_ITEMS); else { PLIST_ENTRY ItemList = list->ListHead.Flink; - DeviceInfo* DevInfo; - while (MemberIndex-- > 0) + while (ItemList != &list->ListHead && MemberIndex-- > 0) ItemList = ItemList->Flink; - DevInfo = (DeviceInfo *)ItemList; - if (DevInfo->IsDevice) + if (ItemList == &list->ListHead) + SetLastError(ERROR_NO_MORE_ITEMS); + else { + struct DeviceInfoElement *DevInfo = (struct DeviceInfoElement *)ItemList; memcpy(&DeviceInfoData->ClassGuid, - &DevInfo->Device.ClassGuid, + &DevInfo->ClassGuid, sizeof(GUID)); DeviceInfoData->DevInst = 0; /* FIXME */ /* Note: this appears to be dangerous, passing a private @@ -736,10 +802,6 @@ DeviceInfoData->Reserved = (ULONG_PTR)DevInfo; ret = TRUE; } - else - { - SetLastError(ERROR_INVALID_PARAMETER); - } } } else @@ -1095,7 +1157,7 @@ }
static LONG SETUP_CreateDevListFromEnumerator( - DeviceInfoList* list, + struct DeviceInfoSet *list, LPCGUID pClassGuid OPTIONAL, LPCWSTR Enumerator, HKEY hEnumeratorKey) /* handle to Enumerator registry key */ @@ -1104,7 +1166,7 @@ WCHAR KeyBuffer[MAX_PATH]; WCHAR InstancePath[MAX_PATH]; LPWSTR pEndOfInstancePath; /* Pointer into InstancePath buffer */ - DeviceInfo* deviceInfo; + struct DeviceInfoElement *deviceInfo; DWORD i = 0, j; DWORD dwLength, dwRegType; DWORD rc; @@ -1178,6 +1240,7 @@ else if (pClassGuid) { GUID KeyGuid; + KeyBuffer[37] = '\0'; /* Replace the } by a NULL character */ if (UuidFromStringW(&KeyBuffer[1], &KeyGuid) != RPC_S_OK) { RegCloseKey(hDeviceIdKey); @@ -1189,17 +1252,25 @@ }
/* Add the entry to the list */ - deviceInfo = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(DeviceInfo, Device.InstancePath) + (wcslen(InstancePath) + 1) * sizeof(WCHAR)); + deviceInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(struct DeviceInfoElement) + (wcslen(InstancePath) + 1) * sizeof(WCHAR)); if (!deviceInfo) { RegCloseKey(hDeviceIdKey); return ERROR_NO_SYSTEM_RESOURCES; } - deviceInfo->IsDevice = TRUE; - memcpy(&deviceInfo->Device.ClassGuid, pClassGuid, sizeof(GUID)); - wcscpy(deviceInfo->Device.InstancePath, InstancePath); - InsertTailList(&list->ListHead, &deviceInfo->ItemEntry); - list->numberOfEntries++; + TRACE("Adding '%S' to device info set %p\n", InstancePath, list); + wcscpy(deviceInfo->Data, InstancePath); + deviceInfo->DeviceName = deviceInfo->Data; + deviceInfo->UniqueId = &deviceInfo->Data[pEndOfInstancePath - InstancePath + 1]; + deviceInfo->DeviceDescription = NULL; + memcpy(&deviceInfo->ClassGuid, pClassGuid, sizeof(GUID)); + deviceInfo->CreationFlags = 0; + deviceInfo->hwndParent = NULL; + deviceInfo->Flags = 0; /* FIXME */ + deviceInfo->FlagsEx = 0; /* FIXME */ + InitializeListHead(&deviceInfo->DriverListHead); + InitializeListHead(&deviceInfo->InterfaceHead); + InsertTailList(&list->ListHead, &deviceInfo->ListEntry); } RegCloseKey(hDeviceIdKey); } @@ -1208,7 +1279,7 @@ }
static LONG SETUP_CreateDevList( - DeviceInfoList* list, + struct DeviceInfoSet *list, PCWSTR MachineName OPTIONAL, LPGUID class OPTIONAL, PCWSTR Enumerator OPTIONAL) @@ -1301,7 +1372,7 @@
#ifdef __WINESRC__ static LONG SETUP_CreateSerialDeviceList( - DeviceInfoList *list, + struct DeviceInfoSet *list, PCWSTR MachineName, LPGUID InterfaceGuid, PCWSTR DeviceInstanceW) @@ -1312,7 +1383,7 @@ LPWSTR devices; static const WCHAR devicePrefixW[] = { 'C','O','M',0 }; LPWSTR ptr; - DeviceInfo *deviceInfo; + //DeviceInfo *deviceInfo;
if (MachineName) WARN("'MachineName' is ignored on Wine!\n"); @@ -1350,6 +1421,7 @@ { /* We have found a device */ TRACE("Adding %s to list\n", debugstr_w(ptr)); +#if 0 deviceInfo = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(DeviceInfo, Interface.Data) + (strlenW(ptr) + 1) * sizeof(WCHAR)); if (!deviceInfo) @@ -1363,7 +1435,9 @@ memcpy(&deviceInfo->Interface.InterfaceGuid, InterfaceGuid, sizeof(GUID)); wcscpy(deviceInfo->Interface.pSymbolicLink, ptr); InsertTailList(&list->ListHead, &deviceInfo->ItemEntry); - list->numberOfEntries++; +#else + FIXME("not implemented\n"); +#endif } } if (devices != buf) @@ -1374,7 +1448,7 @@ #else /* __WINESRC__ */
static LONG SETUP_CreateInterfaceList( - DeviceInfoList *list, + struct DeviceInfoSet *list, PCWSTR MachineName, LPGUID InterfaceGuid, PCWSTR DeviceInstanceW /* OPTIONAL */) @@ -1619,7 +1693,7 @@ PVOID reserved) { HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE; - DeviceInfoList *list; + struct DeviceInfoSet *list; LPGUID pClassGuid; LONG rc;
@@ -1629,8 +1703,8 @@ /* Create the deviceset if not set */ if (deviceset) { - list = (DeviceInfoList *)deviceset; - if (list->magic != SETUP_DEV_INFO_LIST_MAGIC) + list = (struct DeviceInfoSet *)deviceset; + if (list->magic != SETUP_DEV_INFO_SET_MAGIC) { SetLastError(ERROR_INVALID_HANDLE); return INVALID_HANDLE_VALUE; @@ -1644,7 +1718,7 @@ NULL, machine, NULL); if (hDeviceInfo == INVALID_HANDLE_VALUE) return INVALID_HANDLE_VALUE; - list = (DeviceInfoList *)hDeviceInfo; + list = (struct DeviceInfoSet *)hDeviceInfo; }
if (IsEqualIID(&list->ClassGuid, &GUID_NULL)) @@ -1730,8 +1804,6 @@
TRACE("%p, %p, %s, 0x%08lx, %p\n", DeviceInfoSet, DeviceInfoData, debugstr_guid(InterfaceClassGuid), MemberIndex, DeviceInterfaceData); - if (DeviceInfoData) - FIXME(": unimplemented with PSP_DEVINFO_DATA set\n");
if (!DeviceInterfaceData) SetLastError(ERROR_INVALID_PARAMETER); @@ -1739,39 +1811,54 @@ SetLastError(ERROR_INVALID_USER_BUFFER); else if (DeviceInfoSet && DeviceInfoSet != (HDEVINFO)INVALID_HANDLE_VALUE) { - DeviceInfoList *list = (DeviceInfoList *)DeviceInfoSet; + struct DeviceInfoSet *list = (struct DeviceInfoSet *)DeviceInfoSet;
- if (list->magic == SETUP_DEV_INFO_LIST_MAGIC) + if (list->magic == SETUP_DEV_INFO_SET_MAGIC) { - if (MemberIndex >= list->numberOfEntries) - SetLastError(ERROR_NO_MORE_ITEMS); - else + PLIST_ENTRY ItemList = list->ListHead.Flink; + BOOL Found = FALSE; + while (ItemList != &list->ListHead && !Found) { - PLIST_ENTRY ItemList = list->ListHead.Flink; - DeviceInfo* DevInfo; - while (MemberIndex-- > 0) + PLIST_ENTRY InterfaceListEntry; + struct DeviceInfoElement *DevInfo = (struct DeviceInfoElement *)ItemList; + if (DeviceInfoData && (struct DeviceInfoElement *)DeviceInfoData->Reserved != DevInfo) + { + /* We are not searching for this element */ ItemList = ItemList->Flink; - DevInfo = (DeviceInfo *)ItemList; - - if (DevInfo->IsDevice) - SetLastError(ERROR_INVALID_PARAMETER); - else if (!IsEqualIID(&DevInfo->Interface.InterfaceGuid, InterfaceClassGuid)) - SetLastError(ERROR_INVALID_PARAMETER); - else + continue; + } + InterfaceListEntry = DevInfo->InterfaceHead.Flink; + while (InterfaceListEntry != &DevInfo->InterfaceHead && !Found) { - memcpy(&DeviceInterfaceData->InterfaceClassGuid, - &DevInfo->Interface.InterfaceGuid, - sizeof(DeviceInterfaceData->InterfaceClassGuid)); - DeviceInterfaceData->Flags = 0; /* FIXME */ - /* Note: this appears to be dangerous, passing a private - * pointer a heap-allocated datum to the caller. However, the - * expected lifetime of the device data is the same as the - * HDEVINFO; once that is closed, the data are no longer valid. - */ - DeviceInterfaceData->Reserved = (ULONG_PTR)DevInfo; - ret = TRUE; + struct DeviceInterface *DevItf = (struct DeviceInterface *)InterfaceListEntry; + if (!IsEqualIID(&DevItf->InterfaceClassGuid, InterfaceClassGuid)) + { + InterfaceListEntry = InterfaceListEntry->Flink; + continue; + } + if (MemberIndex-- == 0) + { + /* return this item */ + memcpy(&DeviceInterfaceData->InterfaceClassGuid, + &DevItf->InterfaceClassGuid, + sizeof(GUID)); + DeviceInterfaceData->Flags = 0; /* FIXME */ + /* Note: this appears to be dangerous, passing a private + * pointer a heap-allocated datum to the caller. However, the + * expected lifetime of the device data is the same as the + * HDEVINFO; once that is closed, the data are no longer valid. + */ + DeviceInterfaceData->Reserved = (ULONG_PTR)DevItf; + Found = TRUE; + } + MemberIndex--; } + ItemList = ItemList->Flink; } + if (!Found) + SetLastError(ERROR_NO_MORE_ITEMS); + else + ret = TRUE; } else SetLastError(ERROR_INVALID_HANDLE); @@ -1791,14 +1878,21 @@ TRACE("%p\n", devinfo); if (devinfo && devinfo != (HDEVINFO)INVALID_HANDLE_VALUE) { - DeviceInfoList *list = (DeviceInfoList *)devinfo; + struct DeviceInfoSet *list = (struct DeviceInfoSet *)devinfo;
- if (list->magic == SETUP_DEV_INFO_LIST_MAGIC) + if (list->magic == SETUP_DEV_INFO_SET_MAGIC) { - PLIST_ENTRY ListEntry; + PLIST_ENTRY ListEntry, InterfaceEntry; + struct DeviceInfoElement *deviceInfo; while (!IsListEmpty(&list->ListHead)) { ListEntry = RemoveHeadList(&list->ListHead); + deviceInfo = (struct DeviceInfoElement *)ListEntry; + while (!IsListEmpty(&deviceInfo->InterfaceHead)) + { + InterfaceEntry = RemoveHeadList(&deviceInfo->InterfaceHead); + HeapFree(GetProcessHeap(), 0, InterfaceEntry); + } HeapFree(GetProcessHeap(), 0, ListEntry); } if (list->HKLM != HKEY_LOCAL_MACHINE) @@ -1905,7 +1999,7 @@ SetLastError(ERROR_INVALID_PARAMETER); else if (DeviceInfoSet == (HDEVINFO)INVALID_HANDLE_VALUE) SetLastError(ERROR_INVALID_HANDLE); - else if (((DeviceInfoList*)DeviceInfoSet)->magic != SETUP_DEV_INFO_LIST_MAGIC) + else if (((struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEV_INFO_SET_MAGIC) SetLastError(ERROR_INVALID_HANDLE); else if (DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA)) SetLastError(ERROR_INVALID_USER_BUFFER); @@ -1919,6 +2013,7 @@ SetLastError(ERROR_INVALID_PARAMETER); else { +#if 0 DeviceInfo *deviceInfo = (DeviceInfo *)DeviceInterfaceData->Reserved; LPCWSTR devName = deviceInfo->Interface.pSymbolicLink; DWORD sizeRequired = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + @@ -1949,6 +2044,11 @@ } ret = TRUE; } +#else + FIXME("not implemented\n"); + SetLastError(ERROR_GEN_FAILURE); + ret = FALSE; +#endif }
TRACE("Returning %d\n", ret); @@ -2052,7 +2152,7 @@
if (!DeviceInfoSet || DeviceInfoSet == (HDEVINFO)INVALID_HANDLE_VALUE) SetLastError(ERROR_INVALID_HANDLE); - else if (((DeviceInfoList *)DeviceInfoSet)->magic != SETUP_DEV_INFO_LIST_MAGIC) + else if (((struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEV_INFO_SET_MAGIC) SetLastError(ERROR_INVALID_HANDLE); else if (!DeviceInfoData) SetLastError(ERROR_INVALID_PARAMETER); @@ -2060,12 +2160,10 @@ SetLastError(ERROR_INVALID_USER_BUFFER); else if (Property >= SPDRP_MAXIMUM_PROPERTY) SetLastError(ERROR_INVALID_PARAMETER); - else if (!((DeviceInfo *)DeviceInfoData->Reserved)->IsDevice) - SetLastError(ERROR_INVALID_PARAMETER); else { - DeviceInfoList *list = (DeviceInfoList *)DeviceInfoSet; - DeviceInfo* DevInfo = (DeviceInfo *)DeviceInfoData->Reserved; + struct DeviceInfoSet *list = (struct DeviceInfoSet *)DeviceInfoSet; + struct DeviceInfoElement *DevInfo = (struct DeviceInfoElement *)DeviceInfoData->Reserved;
switch (Property) { @@ -2142,7 +2240,7 @@ } rc = RegOpenKeyExW( hEnumKey, - DevInfo->Device.InstancePath, + DevInfo->Data, 0, /* Options */ KEY_QUERY_VALUE, &hKey); @@ -2173,7 +2271,7 @@
case SPDRP_PHYSICAL_DEVICE_OBJECT_NAME: { - DWORD required = (wcslen(DevInfo->Device.InstancePath) + 1) * sizeof(WCHAR); + DWORD required = (wcslen(DevInfo->Data) + 1) * sizeof(WCHAR);
if (PropertyRegDataType) *PropertyRegDataType = REG_SZ; @@ -2181,7 +2279,7 @@ *RequiredSize = required; if (PropertyBufferSize >= required) { - wcscpy((LPWSTR)PropertyBuffer, DevInfo->Device.InstancePath); + wcscpy((LPWSTR)PropertyBuffer, DevInfo->Data); ret = TRUE; } else