From: Robert Gerigk <Robert-Gerigk@online.de> Verify that DEVPKEY_Device_Children is set on the bus PDO after child enumeration and contains the child's instance ID as a MULTI_SZ entry. Signed-off-by: Jan Robert Gerigk <Robert-Gerigk@online.de> --- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 49 ++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index 70c01543835..437e1caa778 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -2247,6 +2247,55 @@ static void test_pnp_devices(void) ok(size == sizeof(L"ROOT\\WINETEST\\0"), "got size %lu\n", size); ok(!wcscmp(buffer_w, L"ROOT\\WINETEST\\0"), "got parent ID %s\n", debugstr_w(buffer_w)); + /* DEVPKEY_Device_Children — must be set on the bus PDO after child + * enumeration. Open a DIGCF_DEVICEINTERFACE list scoped to the bus + * class, fetch the matching interface and resolve its owning device + * via SetupDiGetDeviceInterfaceDetail (the SP_DEVINFO_DATA out-param + * is filled even when the detail buffer is omitted), then verify + * that the current child appears in the MULTI_SZ children list. */ + { + SP_DEVICE_INTERFACE_DATA bus_iface = { sizeof(bus_iface) }; + SP_DEVINFO_DATA bus_dev = { sizeof(bus_dev) }; + HDEVINFO bus_set; + WCHAR *entry; + BOOL found_child; + + bus_set = SetupDiGetClassDevsA(&bus_class, NULL, NULL, + DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); + ok(bus_set != INVALID_HANDLE_VALUE, "failed to get bus device list, error %#lx\n", + GetLastError()); + ret = SetupDiEnumDeviceInterfaces(bus_set, NULL, &bus_class, 0, &bus_iface); + ok(ret, "failed to enumerate bus interface, error %#lx\n", GetLastError()); + + SetLastError(0); + ret = SetupDiGetDeviceInterfaceDetailA(bus_set, &bus_iface, NULL, 0, NULL, &bus_dev); + /* Detail buffer omitted on purpose — only the SP_DEVINFO_DATA out + * parameter is needed and that one is filled regardless of the + * ERROR_INSUFFICIENT_BUFFER returned by the detail-size probe. */ + ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "got ret %d, error %#lx\n", ret, GetLastError()); + + prop_type = DEVPROP_TYPE_EMPTY; + size = 0; + memset(buffer_w, 0, sizeof(buffer_w)); + ret = SetupDiGetDevicePropertyW(bus_set, &bus_dev, &DEVPKEY_Device_Children, + &prop_type, (BYTE *)buffer_w, sizeof(buffer_w), &size, 0); + ok(ret, "DEVPKEY_Device_Children missing, error %#lx\n", GetLastError()); + ok(prop_type == DEVPROP_TYPE_STRING_LIST, "got type %#lx\n", prop_type); + + found_child = FALSE; + for (entry = buffer_w; *entry; entry += wcslen(entry) + 1) + { + if (!wcscmp(entry, L"WINE\\TEST\\1")) + { + found_child = TRUE; + break; + } + } + ok(found_child, "expected WINE\\TEST\\1 in DEVPKEY_Device_Children\n"); + SetupDiDestroyDeviceInfoList(bus_set); + } + ret = SetupDiEnumDeviceInterfaces(set, NULL, &child_class, 0, &iface); ok(ret, "failed to get interface, error %#lx\n", GetLastError()); ok(IsEqualGUID(&iface.InterfaceClassGuid, &child_class), -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10604