Signed-off-by: Zebediah Figura z.figura12@gmail.com --- programs/winedevice/device.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/programs/winedevice/device.c b/programs/winedevice/device.c index 509cab96308..07a76b911e9 100644 --- a/programs/winedevice/device.c +++ b/programs/winedevice/device.c @@ -83,6 +83,7 @@ static DWORD device_handler( DWORD ctrl, const WCHAR *driver_name )
case SERVICE_CONTROL_REENUMERATE_ROOT_DEVICES: wine_enumerate_root_devices( driver_name ); + break;
default: FIXME( "got driver ctrl %x for %s\n", ctrl, wine_dbgstr_w(driver_name) );
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntoskrnl.exe/tests/driver.h | 2 + dlls/ntoskrnl.exe/tests/driver_pnp.c | 82 ++++++++++++++++++++++++++++ dlls/ntoskrnl.exe/tests/ntoskrnl.c | 6 ++ 3 files changed, 90 insertions(+)
diff --git a/dlls/ntoskrnl.exe/tests/driver.h b/dlls/ntoskrnl.exe/tests/driver.h index 397dd528e84..c95de67be3a 100644 --- a/dlls/ntoskrnl.exe/tests/driver.h +++ b/dlls/ntoskrnl.exe/tests/driver.h @@ -36,6 +36,8 @@ #define IOCTL_WINETEST_MISMATCHED_STATUS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80b, METHOD_NEITHER, FILE_ANY_ACCESS) #define IOCTL_WINETEST_COMPLETION CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80c, METHOD_NEITHER, FILE_ANY_ACCESS)
+#define IOCTL_WINETEST_BUS_MAIN CTL_CODE(FILE_DEVICE_BUS_EXTENDER, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) + static const char teststr[] = "Wine is not an emulator";
struct test_data diff --git a/dlls/ntoskrnl.exe/tests/driver_pnp.c b/dlls/ntoskrnl.exe/tests/driver_pnp.c index 53403d2fa7b..ae33c7b8f01 100644 --- a/dlls/ntoskrnl.exe/tests/driver_pnp.c +++ b/dlls/ntoskrnl.exe/tests/driver_pnp.c @@ -19,6 +19,7 @@ */
#include <stdarg.h> +#include <stdio.h>
#include "ntstatus.h" #define WIN32_NO_STATUS @@ -29,6 +30,7 @@ #include "ddk/wdm.h"
#include "driver.h" +#include "utils.h"
static const GUID control_class = {0xdeadbeef, 0x29ef, 0x4538, {0xa5, 0xfd, 0xb6, 0x95, 0x73, 0xa3, 0x62, 0xc0}}; static UNICODE_STRING control_symlink; @@ -94,6 +96,79 @@ static NTSTATUS WINAPI driver_pnp(DEVICE_OBJECT *device, IRP *irp) return pdo_pnp(device, irp); }
+static void test_bus_query_id(DEVICE_OBJECT *top_device) +{ + IO_STACK_LOCATION *stack; + IO_STATUS_BLOCK io; + NTSTATUS ret; + KEVENT event; + IRP *irp; + + KeInitializeEvent(&event, NotificationEvent, FALSE); + + irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, top_device, NULL, 0, NULL, &event, &io); + irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + stack = IoGetNextIrpStackLocation(irp); + stack->MinorFunction = IRP_MN_QUERY_ID; + stack->Parameters.QueryId.IdType = BusQueryDeviceID; + ret = IoCallDriver(top_device, irp); + ok(ret == STATUS_SUCCESS, "got %#x\n", ret); + ok(io.Status == STATUS_SUCCESS, "got %#x\n", ret); + ok(!wcscmp((WCHAR *)io.Information, L"ROOT\WINETEST"), "got id '%ls'\n", (WCHAR *)io.Information); + ExFreePool((WCHAR *)io.Information); + + irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, top_device, NULL, 0, NULL, &event, &io); + irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + stack = IoGetNextIrpStackLocation(irp); + stack->MinorFunction = IRP_MN_QUERY_ID; + stack->Parameters.QueryId.IdType = BusQueryInstanceID; + ret = IoCallDriver(top_device, irp); + ok(ret == STATUS_SUCCESS, "got %#x\n", ret); + ok(io.Status == STATUS_SUCCESS, "got %#x\n", ret); + ok(!wcscmp((WCHAR *)io.Information, L"0"), "got id '%ls'\n", (WCHAR *)io.Information); + ExFreePool((WCHAR *)io.Information); +} + +static void test_bus_query(void) +{ + DEVICE_OBJECT *top_device; + + top_device = IoGetAttachedDeviceReference(bus_pdo); + ok(top_device == bus_fdo, "wrong top device\n"); + + test_bus_query_id(top_device); + + ObDereferenceObject(top_device); +} + +static NTSTATUS fdo_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG code) +{ + switch (code) + { + case IOCTL_WINETEST_BUS_MAIN: + test_bus_query(); + return STATUS_SUCCESS; + + default: + ok(0, "Unexpected ioctl %#x.\n", code); + return STATUS_NOT_IMPLEMENTED; + } +} + +static NTSTATUS WINAPI driver_ioctl(DEVICE_OBJECT *device, IRP *irp) +{ + IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp); + ULONG code = stack->Parameters.DeviceIoControl.IoControlCode; + NTSTATUS status = STATUS_NOT_IMPLEMENTED; + + if (device == bus_fdo) + status = fdo_ioctl(irp, stack, code); + + irp->IoStatus.Status = status; + IoCompleteRequest(irp, IO_NO_INCREMENT); + return status; +} + static NTSTATUS WINAPI driver_add_device(DRIVER_OBJECT *driver, DEVICE_OBJECT *pdo) { NTSTATUS ret; @@ -129,13 +204,20 @@ static NTSTATUS WINAPI driver_close(DEVICE_OBJECT *device, IRP *irp)
static void WINAPI driver_unload(DRIVER_OBJECT *driver) { + winetest_cleanup(); }
NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, UNICODE_STRING *registry) { + NTSTATUS ret; + + if ((ret = winetest_init())) + return ret; + driver->DriverExtension->AddDevice = driver_add_device; driver->DriverUnload = driver_unload; driver->MajorFunction[IRP_MJ_PNP] = driver_pnp; + driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = driver_ioctl; driver->MajorFunction[IRP_MJ_CREATE] = driver_create; driver->MajorFunction[IRP_MJ_CLOSE] = driver_close;
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index 4981709034c..7faa49dc049 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -994,6 +994,7 @@ static void test_pnp_devices(void) SP_DEVINFO_DATA device = {sizeof(device)}; HDEVINFO set; HANDLE bus; + DWORD size; BOOL ret;
set = SetupDiGetClassDevsA(&control_class, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); @@ -1024,6 +1025,9 @@ static void test_pnp_devices(void) bus = CreateFileA(iface_detail->DevicePath, 0, 0, NULL, OPEN_EXISTING, 0, NULL); ok(bus != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
+ ret = DeviceIoControl(bus, IOCTL_WINETEST_BUS_MAIN, NULL, 0, NULL, 0, &size, NULL); + ok(ret, "got error %u\n", GetLastError()); + CloseHandle(bus); }
@@ -1175,6 +1179,8 @@ static void test_pnp_driver(struct testsign_context *ctx) unload_driver(service); CloseServiceHandle(manager);
+ cat_okfile(); + GetFullPathNameA("winetest.inf", sizeof(path), path, NULL); ret = SetupCopyOEMInfA(path, NULL, 0, 0, dest, sizeof(dest), NULL, &filepart); ok(ret, "Failed to copy INF, error %#x\n", GetLastError());
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntoskrnl.exe/tests/driver_pnp.c | 110 +++++++++++++++++++++++++++ 1 file changed, 110 insertions(+)
diff --git a/dlls/ntoskrnl.exe/tests/driver_pnp.c b/dlls/ntoskrnl.exe/tests/driver_pnp.c index ae33c7b8f01..f9d331f1716 100644 --- a/dlls/ntoskrnl.exe/tests/driver_pnp.c +++ b/dlls/ntoskrnl.exe/tests/driver_pnp.c @@ -96,6 +96,115 @@ static NTSTATUS WINAPI driver_pnp(DEVICE_OBJECT *device, IRP *irp) return pdo_pnp(device, irp); }
+static void test_bus_query_caps(DEVICE_OBJECT *top_device) +{ + DEVICE_CAPABILITIES caps; + IO_STACK_LOCATION *stack; + IO_STATUS_BLOCK io; + unsigned int i; + NTSTATUS ret; + KEVENT event; + IRP *irp; + + memset(&caps, 0, sizeof(caps)); + caps.Size = sizeof(caps); + caps.Version = 1; + + KeInitializeEvent(&event, NotificationEvent, FALSE); + + irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, top_device, NULL, 0, NULL, &event, &io); + irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + stack = IoGetNextIrpStackLocation(irp); + stack->MinorFunction = IRP_MN_QUERY_CAPABILITIES; + stack->Parameters.DeviceCapabilities.Capabilities = ∩︀ + ret = IoCallDriver(top_device, irp); + ok(ret == STATUS_SUCCESS, "got %#x\n", ret); + ok(io.Status == STATUS_SUCCESS, "got %#x\n", ret); + + ok(caps.Size == sizeof(caps), "wrong size %u\n", caps.Size); + ok(caps.Version == 1, "wrong version %u\n", caps.Version); + ok(!caps.DeviceD1, "got DeviceD1 %u\n", caps.DeviceD1); + ok(!caps.DeviceD2, "got DeviceD2 %u\n", caps.DeviceD2); + ok(!caps.LockSupported, "got LockSupported %u\n", caps.LockSupported); + ok(!caps.EjectSupported, "got EjectSupported %u\n", caps.EjectSupported); + ok(!caps.Removable, "got Removable %u\n", caps.Removable); + ok(!caps.DockDevice, "got DockDevice %u\n", caps.DockDevice); + ok(!caps.UniqueID, "got UniqueID %u\n", caps.UniqueID); + ok(!caps.SilentInstall, "got SilentInstall %u\n", caps.SilentInstall); + ok(!caps.RawDeviceOK, "got RawDeviceOK %u\n", caps.RawDeviceOK); + ok(!caps.SurpriseRemovalOK, "got SurpriseRemovalOK %u\n", caps.SurpriseRemovalOK); + ok(!caps.WakeFromD0, "got WakeFromD0 %u\n", caps.WakeFromD0); + ok(!caps.WakeFromD1, "got WakeFromD1 %u\n", caps.WakeFromD1); + ok(!caps.WakeFromD2, "got WakeFromD2 %u\n", caps.WakeFromD2); + ok(!caps.WakeFromD3, "got WakeFromD3 %u\n", caps.WakeFromD3); + ok(!caps.HardwareDisabled, "got HardwareDisabled %u\n", caps.HardwareDisabled); + ok(!caps.NonDynamic, "got NonDynamic %u\n", caps.NonDynamic); + ok(!caps.WarmEjectSupported, "got WarmEjectSupported %u\n", caps.WarmEjectSupported); + ok(!caps.NoDisplayInUI, "got NoDisplayInUI %u\n", caps.NoDisplayInUI); + ok(!caps.Address, "got Address %#x\n", caps.Address); + ok(!caps.UINumber, "got UINumber %#x\n", caps.UINumber); + ok(caps.DeviceState[PowerSystemUnspecified] == PowerDeviceUnspecified, + "got DeviceState[PowerSystemUnspecified] %u\n", caps.DeviceState[PowerSystemUnspecified]); + todo_wine ok(caps.DeviceState[PowerSystemWorking] == PowerDeviceD0, + "got DeviceState[PowerSystemWorking] %u\n", caps.DeviceState[PowerSystemWorking]); + for (i = PowerSystemSleeping1; i < PowerSystemMaximum; ++i) + todo_wine ok(caps.DeviceState[i] == PowerDeviceD3, "got DeviceState[%u] %u\n", i, caps.DeviceState[i]); + ok(caps.SystemWake == PowerSystemUnspecified, "got SystemWake %u\n", caps.SystemWake); + ok(caps.DeviceWake == PowerDeviceUnspecified, "got DeviceWake %u\n", caps.DeviceWake); + ok(!caps.D1Latency, "got D1Latency %u\n", caps.D1Latency); + ok(!caps.D2Latency, "got D2Latency %u\n", caps.D2Latency); + ok(!caps.D3Latency, "got D3Latency %u\n", caps.D3Latency); + + memset(&caps, 0xff, sizeof(caps)); + caps.Size = sizeof(caps); + caps.Version = 1; + + KeClearEvent(&event); + + irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, top_device, NULL, 0, NULL, &event, &io); + irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + stack = IoGetNextIrpStackLocation(irp); + stack->MinorFunction = IRP_MN_QUERY_CAPABILITIES; + stack->Parameters.DeviceCapabilities.Capabilities = ∩︀ + ret = IoCallDriver(top_device, irp); + ok(ret == STATUS_SUCCESS, "got %#x\n", ret); + ok(io.Status == STATUS_SUCCESS, "got %#x\n", ret); + + ok(caps.Size == sizeof(caps), "wrong size %u\n", caps.Size); + ok(caps.Version == 1, "wrong version %u\n", caps.Version); + ok(caps.DeviceD1, "got DeviceD1 %u\n", caps.DeviceD1); + ok(caps.DeviceD2, "got DeviceD2 %u\n", caps.DeviceD2); + ok(caps.LockSupported, "got LockSupported %u\n", caps.LockSupported); + ok(caps.EjectSupported, "got EjectSupported %u\n", caps.EjectSupported); + ok(caps.Removable, "got Removable %u\n", caps.Removable); + ok(caps.DockDevice, "got DockDevice %u\n", caps.DockDevice); + ok(caps.UniqueID, "got UniqueID %u\n", caps.UniqueID); + ok(caps.SilentInstall, "got SilentInstall %u\n", caps.SilentInstall); + ok(caps.RawDeviceOK, "got RawDeviceOK %u\n", caps.RawDeviceOK); + ok(caps.SurpriseRemovalOK, "got SurpriseRemovalOK %u\n", caps.SurpriseRemovalOK); + ok(caps.WakeFromD0, "got WakeFromD0 %u\n", caps.WakeFromD0); + ok(caps.WakeFromD1, "got WakeFromD1 %u\n", caps.WakeFromD1); + ok(caps.WakeFromD2, "got WakeFromD2 %u\n", caps.WakeFromD2); + ok(caps.WakeFromD3, "got WakeFromD3 %u\n", caps.WakeFromD3); + ok(caps.HardwareDisabled, "got HardwareDisabled %u\n", caps.HardwareDisabled); + ok(caps.NonDynamic, "got NonDynamic %u\n", caps.NonDynamic); + ok(caps.WarmEjectSupported, "got WarmEjectSupported %u\n", caps.WarmEjectSupported); + ok(caps.NoDisplayInUI, "got NoDisplayInUI %u\n", caps.NoDisplayInUI); + ok(caps.Address == 0xffffffff, "got Address %#x\n", caps.Address); + ok(caps.UINumber == 0xffffffff, "got UINumber %#x\n", caps.UINumber); + todo_wine ok(caps.DeviceState[PowerSystemUnspecified] == PowerDeviceUnspecified, + "got DeviceState[PowerSystemUnspecified] %u\n", caps.DeviceState[PowerSystemUnspecified]); + todo_wine ok(caps.DeviceState[PowerSystemWorking] == PowerDeviceD0, + "got DeviceState[PowerSystemWorking] %u\n", caps.DeviceState[PowerSystemWorking]); + for (i = PowerSystemSleeping1; i < PowerSystemMaximum; ++i) + todo_wine ok(caps.DeviceState[i] == PowerDeviceD3, "got DeviceState[%u] %u\n", i, caps.DeviceState[i]); + ok(caps.SystemWake == 0xffffffff, "got SystemWake %u\n", caps.SystemWake); + ok(caps.DeviceWake == 0xffffffff, "got DeviceWake %u\n", caps.DeviceWake); + ok(caps.D1Latency == 0xffffffff, "got D1Latency %u\n", caps.D1Latency); + ok(caps.D2Latency == 0xffffffff, "got D2Latency %u\n", caps.D2Latency); + ok(caps.D3Latency == 0xffffffff, "got D3Latency %u\n", caps.D3Latency); +} + static void test_bus_query_id(DEVICE_OBJECT *top_device) { IO_STACK_LOCATION *stack; @@ -136,6 +245,7 @@ static void test_bus_query(void) top_device = IoGetAttachedDeviceReference(bus_pdo); ok(top_device == bus_fdo, "wrong top device\n");
+ test_bus_query_caps(top_device); test_bus_query_id(top_device);
ObDereferenceObject(top_device);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=88448
Your paranoid android.
=== debiant2 (32 bit report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl contains a misplaced todo line for driver_pnp
=== debiant2 (32 bit French report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl contains a misplaced todo line for driver_pnp
=== debiant2 (32 bit Japanese:Japan report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl contains a misplaced todo line for driver_pnp
=== debiant2 (32 bit Chinese:China report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl contains a misplaced todo line for driver_pnp
=== debiant2 (64 bit WoW report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl contains a misplaced todo line for driver_pnp
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/setupapi/devinst.c | 80 +++++++++++++++++++++++++++++++++++ dlls/setupapi/tests/devinst.c | 30 +++++++++++++ 2 files changed, 110 insertions(+)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 8f826c30250..7ff3cb01eb6 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -690,6 +690,81 @@ static void delete_device_iface(struct device_iface *iface) heap_free(iface); }
+/* remove all interfaces associated with the device, including those not + * enumerated in the set */ +static void remove_all_device_ifaces(struct device *device) +{ + HKEY classes_key; + DWORD i, len; + LONG ret; + + if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, DeviceClasses, 0, KEY_READ, &classes_key))) + { + ERR("Failed to open classes key, error %u.\n", ret); + return; + } + + for (i = 0; ; ++i) + { + WCHAR class_name[40]; + HKEY class_key; + DWORD j; + + len = ARRAY_SIZE(class_name); + if ((ret = RegEnumKeyExW(classes_key, i, class_name, &len, NULL, NULL, NULL, NULL))) + { + if (ret != ERROR_NO_MORE_ITEMS) ERR("Failed to enumerate classes, error %u.\n", ret); + break; + } + + if ((ret = RegOpenKeyExW(classes_key, class_name, 0, KEY_READ, &class_key))) + { + ERR("Failed to open class %s, error %u.\n", debugstr_w(class_name), ret); + continue; + } + + for (j = 0; ; ++j) + { + WCHAR iface_name[MAX_DEVICE_ID_LEN + 39], device_name[MAX_DEVICE_ID_LEN]; + HKEY iface_key; + + len = ARRAY_SIZE(iface_name); + if ((ret = RegEnumKeyExW(class_key, j, iface_name, &len, NULL, NULL, NULL, NULL))) + { + if (ret != ERROR_NO_MORE_ITEMS) ERR("Failed to enumerate interfaces, error %u.\n", ret); + break; + } + + if ((ret = RegOpenKeyExW(class_key, iface_name, 0, KEY_ALL_ACCESS, &iface_key))) + { + ERR("Failed to open interface %s, error %u.\n", debugstr_w(iface_name), ret); + continue; + } + + len = sizeof(device_name); + if ((ret = RegQueryValueExW(iface_key, L"DeviceInstance", NULL, NULL, (BYTE *)device_name, &len))) + { + ERR("Failed to query device instance, error %u.\n", ret); + RegCloseKey(iface_key); + continue; + } + + if (!wcsicmp(device_name, device->instanceId)) + { + if ((ret = RegDeleteTreeW(iface_key, NULL))) + ERR("Failed to delete interface %s subkeys, error %u.\n", debugstr_w(iface_name), ret); + if ((ret = RegDeleteKeyW(iface_key, L""))) + ERR("Failed to delete interface %s, error %u.\n", debugstr_w(iface_name), ret); + } + + RegCloseKey(iface_key); + } + RegCloseKey(class_key); + } + + RegCloseKey(classes_key); +} + static void remove_device(struct device *device) { WCHAR id[MAX_DEVICE_ID_LEN], *p; @@ -735,7 +810,10 @@ static void delete_device(struct device *device) SetupDiCallClassInstaller(DIF_DESTROYPRIVATEDATA, device->set, &device_data);
if (device->phantom) + { remove_device(device); + remove_all_device_ifaces(device); + }
RegCloseKey(device->key); heap_free(device->instanceId); @@ -1725,6 +1803,8 @@ BOOL WINAPI SetupDiRemoveDevice(HDEVINFO devinfo, SP_DEVINFO_DATA *device_data) } CloseServiceHandle(manager);
+ remove_all_device_ifaces(device); + return TRUE; }
diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c index 48b84c21e84..de302d21660 100644 --- a/dlls/setupapi/tests/devinst.c +++ b/dlls/setupapi/tests/devinst.c @@ -1448,6 +1448,7 @@ static void test_register_device_iface(void) 'E','n','u','m','\','R','o','o','t','\', 'L','E','G','A','C','Y','_','B','O','G','U','S',0}; SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)}; + SP_DEVINFO_DATA device2 = {sizeof(device2)}; SP_DEVINFO_DATA device = {sizeof(device)}; HDEVINFO set, set2; BOOL ret; @@ -1487,11 +1488,40 @@ static void test_register_device_iface(void) check_device_iface(set2, NULL, &guid, 1, 0, "\\?\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}\deleted"); check_device_iface(set2, NULL, &guid, 2, 0, NULL);
+ ret = SetupDiEnumDeviceInfo(set2, 0, &device2); + ok(ret, "Failed to enumerate devices, error %#x.\n", GetLastError()); + ret = SetupDiCreateDeviceInterfaceA(set2, &device2, &guid, "second", 0, NULL); + ok(ret, "Failed to create interface, error %#x.\n", GetLastError()); + ret = SetupDiRemoveDevice(set, &device); ok(ret, "Failed to remove device, error %#x.\n", GetLastError());
+ check_device_iface(set, NULL, &guid, 0, SPINT_REMOVED, "\\?\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}"); + check_device_iface(set, NULL, &guid, 1, SPINT_REMOVED, "\\?\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}\removed"); + check_device_iface(set, NULL, &guid, 2, 0, NULL); + + check_device_iface(set2, NULL, &guid, 0, 0, "\\?\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}"); + check_device_iface(set2, NULL, &guid, 1, 0, "\\?\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}\deleted"); + check_device_iface(set2, NULL, &guid, 2, 0, "\\?\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}\second"); + check_device_iface(set2, NULL, &guid, 3, 0, NULL); + SetupDiDestroyDeviceInfoList(set); SetupDiDestroyDeviceInfoList(set2); + + /* make sure all interface keys are deleted when a device is removed */ + + set = SetupDiGetClassDevsA(&guid, NULL, 0, DIGCF_DEVICEINTERFACE); + ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError()); + + ret = SetupDiCreateDeviceInfoA(set, "Root\LEGACY_BOGUS\0000", &guid, NULL, NULL, 0, &device); + ok(ret, "Failed to create device, error %#x.\n", GetLastError()); + + set2 = SetupDiGetClassDevsA(&guid, NULL, 0, DIGCF_DEVICEINTERFACE); + ok(set2 != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError()); + check_device_iface(set2, NULL, &guid, 0, 0, NULL); + SetupDiDestroyDeviceInfoList(set2); + + SetupDiDestroyDeviceInfoList(set); }
static void test_registry_property_a(void)
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntoskrnl.exe/tests/driver.h | 5 ++- dlls/ntoskrnl.exe/tests/driver_pnp.c | 15 ++++++- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 60 ++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 2 deletions(-)
diff --git a/dlls/ntoskrnl.exe/tests/driver.h b/dlls/ntoskrnl.exe/tests/driver.h index c95de67be3a..10e2f13ed7b 100644 --- a/dlls/ntoskrnl.exe/tests/driver.h +++ b/dlls/ntoskrnl.exe/tests/driver.h @@ -36,7 +36,10 @@ #define IOCTL_WINETEST_MISMATCHED_STATUS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80b, METHOD_NEITHER, FILE_ANY_ACCESS) #define IOCTL_WINETEST_COMPLETION CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80c, METHOD_NEITHER, FILE_ANY_ACCESS)
-#define IOCTL_WINETEST_BUS_MAIN CTL_CODE(FILE_DEVICE_BUS_EXTENDER, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_WINETEST_BUS_MAIN CTL_CODE(FILE_DEVICE_BUS_EXTENDER, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_WINETEST_BUS_REGISTER_IFACE CTL_CODE(FILE_DEVICE_BUS_EXTENDER, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_WINETEST_BUS_ENABLE_IFACE CTL_CODE(FILE_DEVICE_BUS_EXTENDER, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_WINETEST_BUS_DISABLE_IFACE CTL_CODE(FILE_DEVICE_BUS_EXTENDER, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
static const char teststr[] = "Wine is not an emulator";
diff --git a/dlls/ntoskrnl.exe/tests/driver_pnp.c b/dlls/ntoskrnl.exe/tests/driver_pnp.c index f9d331f1716..b8d97f9cfb5 100644 --- a/dlls/ntoskrnl.exe/tests/driver_pnp.c +++ b/dlls/ntoskrnl.exe/tests/driver_pnp.c @@ -33,7 +33,8 @@ #include "utils.h"
static const GUID control_class = {0xdeadbeef, 0x29ef, 0x4538, {0xa5, 0xfd, 0xb6, 0x95, 0x73, 0xa3, 0x62, 0xc0}}; -static UNICODE_STRING control_symlink; +static const GUID bus_class = {0xdeadbeef, 0x29ef, 0x4538, {0xa5, 0xfd, 0xb6, 0x95, 0x73, 0xa3, 0x62, 0xc1}}; +static UNICODE_STRING control_symlink, bus_symlink;
static DEVICE_OBJECT *bus_fdo, *bus_pdo;
@@ -60,6 +61,7 @@ static NTSTATUS fdo_pnp(IRP *irp) IoDetachDevice(bus_pdo); IoDeleteDevice(bus_fdo); RtlFreeUnicodeString(&control_symlink); + RtlFreeUnicodeString(&bus_symlink); return ret; }
@@ -259,6 +261,17 @@ static NTSTATUS fdo_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG code) test_bus_query(); return STATUS_SUCCESS;
+ case IOCTL_WINETEST_BUS_REGISTER_IFACE: + return IoRegisterDeviceInterface(bus_pdo, &bus_class, NULL, &bus_symlink); + + case IOCTL_WINETEST_BUS_ENABLE_IFACE: + IoSetDeviceInterfaceState(&bus_symlink, TRUE); + return STATUS_SUCCESS; + + case IOCTL_WINETEST_BUS_DISABLE_IFACE: + IoSetDeviceInterfaceState(&bus_symlink, FALSE); + return STATUS_SUCCESS; + default: ok(0, "Unexpected ioctl %#x.\n", code); return STATUS_NOT_IMPLEMENTED; diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index 7faa49dc049..ff679d6ee4a 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -987,6 +987,7 @@ static void add_file_to_catalog(HANDLE catalog, const WCHAR *file) static void test_pnp_devices(void) { static const GUID control_class = {0xdeadbeef, 0x29ef, 0x4538, {0xa5, 0xfd, 0xb6, 0x95, 0x73, 0xa3, 0x62, 0xc0}}; + static const GUID bus_class = {0xdeadbeef, 0x29ef, 0x4538, {0xa5, 0xfd, 0xb6, 0x95, 0x73, 0xa3, 0x62, 0xc1}};
char buffer[200]; SP_DEVICE_INTERFACE_DETAIL_DATA_A *iface_detail = (void *)buffer; @@ -1028,6 +1029,65 @@ static void test_pnp_devices(void) ret = DeviceIoControl(bus, IOCTL_WINETEST_BUS_MAIN, NULL, 0, NULL, 0, &size, NULL); ok(ret, "got error %u\n", GetLastError());
+ /* Test IoRegisterDeviceInterface() and IoSetDeviceInterfaceState(). */ + + set = SetupDiGetClassDevsA(&bus_class, NULL, NULL, DIGCF_DEVICEINTERFACE); + ok(set != INVALID_HANDLE_VALUE, "failed to get device list, error %#x\n", GetLastError()); + ret = SetupDiEnumDeviceInterfaces(set, NULL, &bus_class, 0, &iface); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_NO_MORE_ITEMS, "got error %#x\n", GetLastError()); + SetupDiDestroyDeviceInfoList(set); + + ret = DeviceIoControl(bus, IOCTL_WINETEST_BUS_REGISTER_IFACE, NULL, 0, NULL, 0, &size, NULL); + ok(ret, "got error %u\n", GetLastError()); + + set = SetupDiGetClassDevsA(&bus_class, NULL, NULL, DIGCF_DEVICEINTERFACE); + ok(set != INVALID_HANDLE_VALUE, "failed to get device list, error %#x\n", GetLastError()); + ret = SetupDiEnumDeviceInterfaces(set, NULL, &bus_class, 0, &iface); + ok(ret, "failed to get interface, error %#x\n", GetLastError()); + ok(IsEqualGUID(&iface.InterfaceClassGuid, &bus_class), + "wrong class %s\n", debugstr_guid(&iface.InterfaceClassGuid)); + ok(!iface.Flags, "got flags %#x\n", iface.Flags); + SetupDiDestroyDeviceInfoList(set); + + set = SetupDiGetClassDevsA(&bus_class, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); + ok(set != INVALID_HANDLE_VALUE, "failed to get device list, error %#x\n", GetLastError()); + ret = SetupDiEnumDeviceInterfaces(set, NULL, &bus_class, 0, &iface); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_NO_MORE_ITEMS, "got error %#x\n", GetLastError()); + SetupDiDestroyDeviceInfoList(set); + + ret = DeviceIoControl(bus, IOCTL_WINETEST_BUS_ENABLE_IFACE, NULL, 0, NULL, 0, &size, NULL); + ok(ret, "got error %u\n", GetLastError()); + + set = SetupDiGetClassDevsA(&bus_class, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); + ok(set != INVALID_HANDLE_VALUE, "failed to get device list, error %#x\n", GetLastError()); + ret = SetupDiEnumDeviceInterfaces(set, NULL, &bus_class, 0, &iface); + ok(ret, "failed to get interface, error %#x\n", GetLastError()); + ok(IsEqualGUID(&iface.InterfaceClassGuid, &bus_class), + "wrong class %s\n", debugstr_guid(&iface.InterfaceClassGuid)); + ok(iface.Flags == SPINT_ACTIVE, "got flags %#x\n", iface.Flags); + SetupDiDestroyDeviceInfoList(set); + + ret = DeviceIoControl(bus, IOCTL_WINETEST_BUS_DISABLE_IFACE, NULL, 0, NULL, 0, &size, NULL); + ok(ret, "got error %u\n", GetLastError()); + + set = SetupDiGetClassDevsA(&bus_class, NULL, NULL, DIGCF_DEVICEINTERFACE); + ok(set != INVALID_HANDLE_VALUE, "failed to get device list, error %#x\n", GetLastError()); + ret = SetupDiEnumDeviceInterfaces(set, NULL, &bus_class, 0, &iface); + ok(ret, "failed to get interface, error %#x\n", GetLastError()); + ok(IsEqualGUID(&iface.InterfaceClassGuid, &bus_class), + "wrong class %s\n", debugstr_guid(&iface.InterfaceClassGuid)); + ok(!iface.Flags, "got flags %#x\n", iface.Flags); + SetupDiDestroyDeviceInfoList(set); + + set = SetupDiGetClassDevsA(&bus_class, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); + ok(set != INVALID_HANDLE_VALUE, "failed to get device list, error %#x\n", GetLastError()); + ret = SetupDiEnumDeviceInterfaces(set, NULL, &bus_class, 0, &iface); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_NO_MORE_ITEMS, "got error %#x\n", GetLastError()); + SetupDiDestroyDeviceInfoList(set); + CloseHandle(bus); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=88450
Your paranoid android.
=== debiant2 (32 bit report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl contains a misplaced todo line for driver_pnp
=== debiant2 (32 bit French report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl contains a misplaced todo line for driver_pnp
=== debiant2 (32 bit Japanese:Japan report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl contains a misplaced todo line for driver_pnp
=== debiant2 (32 bit Chinese:China report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl contains a misplaced todo line for driver_pnp
=== debiant2 (64 bit WoW report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl contains a misplaced todo line for driver_pnp