This is a set of tests to prove the correctness of a fix for bug 57588 which i am going to send in a separate PR. Also a small fix for getting DevicePropertyEnumeratorName is included.
From: Alexander Morozov amorozov@etersoft.ru
--- dlls/ntoskrnl.exe/tests/driver_pnp.c | 61 ++++++++++++++++++++++++++++ dlls/ntoskrnl.exe/tests/ntoskrnl.c | 11 +++++ include/ddk/wdm.h | 4 ++ 3 files changed, 76 insertions(+)
diff --git a/dlls/ntoskrnl.exe/tests/driver_pnp.c b/dlls/ntoskrnl.exe/tests/driver_pnp.c index 714271da63a..ebcb6c76981 100644 --- a/dlls/ntoskrnl.exe/tests/driver_pnp.c +++ b/dlls/ntoskrnl.exe/tests/driver_pnp.c @@ -690,6 +690,65 @@ static void test_device_properties( DEVICE_OBJECT *device ) } }
+static void test_enumerator_name(void) +{ + static const WCHAR root[] = L"ROOT"; + WCHAR buffer[10]; + ULONG req_size; + NTSTATUS status; + + status = IoGetDeviceProperty(bus_fdo, DevicePropertyEnumeratorName, sizeof(buffer), buffer, &req_size); + todo_wine ok(status == STATUS_INVALID_DEVICE_REQUEST, "got unexpected status %#lx\n", status); + + req_size = 0; + memset(buffer, 0, sizeof(buffer)); + status = IoGetDeviceProperty(bus_pdo, DevicePropertyEnumeratorName, sizeof(buffer), buffer, &req_size); + ok(status == STATUS_SUCCESS, "IoGetDeviceProperty failed: %#lx\n", status); + todo_wine ok(req_size == sizeof(root), "unexpected size %lu\n", req_size); + if (status == STATUS_SUCCESS) + todo_wine ok(!wcscmp(root, buffer), "unexpected property value '%ls'\n", buffer); +} + +static void test_device_registry_key(void) +{ + static const WCHAR foobar[] = L"foobar"; + static const WCHAR foo[] = L"foo"; + + KEY_VALUE_PARTIAL_INFORMATION *info; + UNICODE_STRING name_str; + NTSTATUS status; + HANDLE hkey; + DWORD size; + + status = IoOpenDeviceRegistryKey(bus_fdo, PLUGPLAY_REGKEY_DEVICE, KEY_ALL_ACCESS, &hkey); + todo_wine ok(status == STATUS_INVALID_PARAMETER, "got unexpected status %#lx\n", status); + + status = IoOpenDeviceRegistryKey(bus_pdo, PLUGPLAY_REGKEY_DEVICE, KEY_ALL_ACCESS, &hkey); + ok(status == STATUS_SUCCESS, "IoOpenDeviceRegistryKey failed: %#lx\n", status); + if (status == STATUS_SUCCESS) + { + RtlInitUnicodeString(&name_str, foobar); + status = ZwQueryValueKey(hkey, &name_str, KeyValuePartialInformation, NULL, 0, &size); + ok(status == STATUS_BUFFER_TOO_SMALL, "got unexpected status %#lx\n", status); + + info = ExAllocatePool(PagedPool, size); + ok(!!info, "failed to allocate memory\n"); + if (info) + { + memset(info, 0, size); + status = ZwQueryValueKey(hkey, &name_str, KeyValuePartialInformation, info, size, &size); + ok(status == STATUS_SUCCESS, "ZwQueryValueKey failed: %#lx\n", status); + ok(info->Type == REG_SZ, "expected type REG_SZ, got %lu\n", info->Type); + ok(info->DataLength == sizeof(foo), "unexpected DataLength %lu\n", info->DataLength); + ok(!wcscmp((WCHAR *)info->Data, foo), "got unexpected key value\n"); + ExFreePool(info); + } + + status = ZwClose(hkey); + ok(status == STATUS_SUCCESS, "ZwClose failed: %#lx\n", status); + } +} + static NTSTATUS fdo_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG code) { switch (code) @@ -697,6 +756,8 @@ static NTSTATUS fdo_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG code) case IOCTL_WINETEST_BUS_MAIN: test_bus_query(); test_device_properties( bus_pdo ); + test_enumerator_name(); + test_device_registry_key(); return STATUS_SUCCESS;
case IOCTL_WINETEST_BUS_REGISTER_IFACE: diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index fc2a205e6d2..aa258b95328 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -1447,6 +1447,8 @@ static void test_pnp_devices(void) static const char expect_hardware_id[] = "winetest_hardware\0winetest_hardware_1\0"; static const char expect_compat_id[] = "winetest_compat\0winetest_compat_1\0"; static const WCHAR expect_container_id_w[] = L"{12345678-1234-1234-1234-123456789123}"; + static const char foobar[] = "foobar"; + static const char foo[] = "foo";
char buffer[200]; WCHAR buffer_w[200]; @@ -1472,6 +1474,8 @@ static void test_pnp_devices(void) IO_STATUS_BLOCK io; HDEVINFO set; HWND window; + LSTATUS status; + HKEY key; BOOL ret; int id;
@@ -1505,6 +1509,13 @@ static void test_pnp_devices(void) ok(!strcmp(iface_detail->DevicePath, "\\?\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}"), "wrong path %s\n", debugstr_a(iface_detail->DevicePath));
+ /* Create a device parameter for testing IoOpenDeviceRegistryKey */ + key = SetupDiCreateDevRegKeyA(set, &device, DICS_FLAG_GLOBAL, 0, DIREG_DEV, NULL, NULL); + ok(key != INVALID_HANDLE_VALUE, "failed to create a hardware parameters key, got error %#lx\n", GetLastError()); + status = RegSetValueExA(key, foobar, 0, REG_SZ, (const BYTE *)foo, sizeof(foo)); + ok(status == ERROR_SUCCESS, "failed to save a device parameter, got error %lu\n", status); + RegCloseKey(key); + SetupDiDestroyDeviceInfoList(set);
bus = CreateFileA(iface_detail->DevicePath, 0, 0, NULL, OPEN_EXISTING, 0, NULL); diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index 61b54f2ddb1..a4566c7d54c 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -1749,6 +1749,10 @@ void WINAPI ExReleaseResourceForThreadLite(ERESOURCE*,ERESOURCE_THREAD); ULONG WINAPI ExSetTimerResolution(ULONG,BOOLEAN); void WINAPI ExUnregisterCallback(void*);
+#define PLUGPLAY_REGKEY_DEVICE 1 +#define PLUGPLAY_REGKEY_DRIVER 2 +#define PLUGPLAY_REGKEY_CURRENT_HWPROFILE 4 + #define PLUGPLAY_PROPERTY_PERSISTENT 0x0001
void WINAPI IoFreeErrorLogEntry(void*);
From: Alexander Morozov amorozov@etersoft.ru
--- dlls/ntoskrnl.exe/tests/driver.h | 1 + dlls/ntoskrnl.exe/tests/driver_pnp.c | 100 ++++++++++++++++++++++++++- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 11 +++ 3 files changed, 111 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/tests/driver.h b/dlls/ntoskrnl.exe/tests/driver.h index 9c51af0a4c6..e22d756e69e 100644 --- a/dlls/ntoskrnl.exe/tests/driver.h +++ b/dlls/ntoskrnl.exe/tests/driver.h @@ -47,6 +47,7 @@ #define IOCTL_WINETEST_CHILD_GET_ID CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_WINETEST_CHILD_MARK_PENDING CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_NEITHER, FILE_ANY_ACCESS) #define IOCTL_WINETEST_CHILD_CHECK_REMOVED CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_NEITHER, FILE_ANY_ACCESS) +#define IOCTL_WINETEST_CHILD_MAIN CTL_CODE(FILE_DEVICE_UNKNOWN, 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 ebcb6c76981..7e94c643ae9 100644 --- a/dlls/ntoskrnl.exe/tests/driver_pnp.c +++ b/dlls/ntoskrnl.exe/tests/driver_pnp.c @@ -60,7 +60,11 @@ static UNICODE_STRING control_symlink, bus_symlink; static DRIVER_OBJECT *driver_obj; static DEVICE_OBJECT *bus_fdo, *bus_pdo;
-static unsigned int remove_device_count, surprise_removal_count, query_remove_device_count, cancel_remove_device_count; +static unsigned int remove_device_count; +static unsigned int surprise_removal_count; +static unsigned int query_remove_device_count; +static unsigned int cancel_remove_device_count; +static unsigned int query_id_count;
struct irp_queue { @@ -270,6 +274,7 @@ static NTSTATUS pdo_pnp(DEVICE_OBJECT *device_obj, IRP *irp) switch (stack->MinorFunction) { case IRP_MN_QUERY_ID: + query_id_count++; ret = query_id(device, irp, stack->Parameters.QueryId.IdType); break;
@@ -285,7 +290,9 @@ static NTSTATUS pdo_pnp(DEVICE_OBJECT *device_obj, IRP *irp) ok(!stack->Parameters.StartDevice.AllocatedResources, "expected no resources\n"); ok(!stack->Parameters.StartDevice.AllocatedResourcesTranslated, "expected no translated resources\n");
+ query_id_count = 0; status = IoRegisterDeviceInterface(device_obj, &child_class, NULL, &device->child_symlink); + todo_wine ok(query_id_count == 0, "expected no IRP_MN_QUERY_ID\n"); ok(!status, "Failed to register interface, status %#lx.\n", status); ok(device->child_symlink.Length == sizeof(expect_symlink) - sizeof(WCHAR), "Got length %u.\n", device->child_symlink.Length); @@ -690,6 +697,36 @@ static void test_device_properties( DEVICE_OBJECT *device ) } }
+static void test_child_device_properties(DEVICE_OBJECT *device) +{ + NTSTATUS status; + const DEVPROPKEY *key = &DEVPKEY_Winetest_1; + DEVPROPTYPE type = DEVPROP_TYPE_BYTE; + DEVPROPTYPE stored_type = DEVPROP_TYPE_EMPTY; + ULONG size = sizeof(BYTE); + ULONG req_size = 0; + BYTE value = 0xe2; + BYTE stored_value = 0; + + query_id_count = 0; + status = IoSetDevicePropertyData(device, key, LOCALE_NEUTRAL, 0, type, size, &value); + todo_wine ok(query_id_count == 0, "expected no IRP_MN_QUERY_ID\n"); + ok(status == STATUS_SUCCESS, "failed to set device property, status %#lx\n", status); + + query_id_count = 0; + status = IoGetDevicePropertyData(device, key, LOCALE_NEUTRAL, 0, size, &stored_value, &req_size, &stored_type); + todo_wine ok(query_id_count == 0, "expected no IRP_MN_QUERY_ID\n"); + ok(status == STATUS_SUCCESS, "failed to get device property, status %#lx\n", status); + ok(req_size == size, "expected required size %lu, got %lu\n", req_size, size); + ok(stored_type == type, "expected DEVPROPTYPE value %#lx, got %#lx\n", type, stored_type); + ok(stored_value == value, "got unexpected device property value: %#x\n", stored_value); + + query_id_count = 0; + status = IoSetDevicePropertyData(device, key, LOCALE_NEUTRAL, 0, type, 0, NULL); + todo_wine ok(query_id_count == 0, "expected no IRP_MN_QUERY_ID\n"); + ok(status == STATUS_SUCCESS, "failed to delete device property, status %#lx\n", status); +} + static void test_enumerator_name(void) { static const WCHAR root[] = L"ROOT"; @@ -709,6 +746,22 @@ static void test_enumerator_name(void) todo_wine ok(!wcscmp(root, buffer), "unexpected property value '%ls'\n", buffer); }
+static void test_child_enumerator_name(DEVICE_OBJECT *device) +{ + static const WCHAR wine[] = L"Wine"; + WCHAR buffer[10] = {0}; + ULONG req_size = 0; + NTSTATUS status; + + query_id_count = 0; + status = IoGetDeviceProperty(device, DevicePropertyEnumeratorName, sizeof(buffer), buffer, &req_size); + todo_wine ok(query_id_count == 0, "expected no IRP_MN_QUERY_ID\n"); + ok(status == STATUS_SUCCESS, "IoGetDeviceProperty failed: %#lx\n", status); + todo_wine ok(req_size == sizeof(wine), "unexpected size %lu\n", req_size); + if (status == STATUS_SUCCESS) + todo_wine ok(!wcscmp(wine, buffer), "unexpected property value '%ls'\n", buffer); +} + static void test_device_registry_key(void) { static const WCHAR foobar[] = L"foobar"; @@ -749,6 +802,45 @@ static void test_device_registry_key(void) } }
+static void test_child_device_registry_key(DEVICE_OBJECT *device) +{ + static const WCHAR foobar[] = L"foobar"; + static const WCHAR bar[] = L"bar"; + + KEY_VALUE_PARTIAL_INFORMATION *info; + UNICODE_STRING name_str; + NTSTATUS status; + HANDLE hkey; + DWORD size; + + query_id_count = 0; + status = IoOpenDeviceRegistryKey(device, PLUGPLAY_REGKEY_DEVICE, KEY_ALL_ACCESS, &hkey); + todo_wine ok(query_id_count == 0, "expected no IRP_MN_QUERY_ID\n"); + ok(status == STATUS_SUCCESS, "IoOpenDeviceRegistryKey failed: %#lx\n", status); + if (status == STATUS_SUCCESS) + { + RtlInitUnicodeString(&name_str, foobar); + status = ZwQueryValueKey(hkey, &name_str, KeyValuePartialInformation, NULL, 0, &size); + ok(status == STATUS_BUFFER_TOO_SMALL, "got unexpected status %#lx\n", status); + + info = ExAllocatePool(PagedPool, size); + ok(!!info, "failed to allocate memory\n"); + if (info) + { + memset(info, 0, size); + status = ZwQueryValueKey(hkey, &name_str, KeyValuePartialInformation, info, size, &size); + ok(status == STATUS_SUCCESS, "ZwQueryValueKey failed: %#lx\n", status); + ok(info->Type == REG_SZ, "expected type REG_SZ, got %lu\n", info->Type); + ok(info->DataLength == sizeof(bar), "unexpected DataLength %lu\n", info->DataLength); + ok(!wcscmp((WCHAR *)info->Data, bar), "got unexpected key value\n"); + ExFreePool(info); + } + + status = ZwClose(hkey); + ok(status == STATUS_SUCCESS, "ZwClose failed: %#lx\n", status); + } +} + static NTSTATUS fdo_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG code) { switch (code) @@ -910,6 +1002,12 @@ static NTSTATUS pdo_ioctl(DEVICE_OBJECT *device_obj, IRP *irp, IO_STACK_LOCATION cancel_remove_device_count = 0; return STATUS_SUCCESS;
+ case IOCTL_WINETEST_CHILD_MAIN: + test_child_device_properties(device_obj); + test_child_enumerator_name(device_obj); + test_child_device_registry_key(device_obj); + return STATUS_SUCCESS; + default: ok(0, "Unexpected ioctl %#lx.\n", code); return STATUS_NOT_IMPLEMENTED; diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index aa258b95328..517b3cf4791 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -1449,6 +1449,7 @@ static void test_pnp_devices(void) static const WCHAR expect_container_id_w[] = L"{12345678-1234-1234-1234-123456789123}"; static const char foobar[] = "foobar"; static const char foo[] = "foo"; + static const char bar[] = "bar";
char buffer[200]; WCHAR buffer_w[200]; @@ -1688,6 +1689,13 @@ static void test_pnp_devices(void) ok(!strcmp(iface_detail->DevicePath, "\\?\wine#test#1#{deadbeef-29ef-4538-a5fd-b69573a362c2}"), "wrong path %s\n", debugstr_a(iface_detail->DevicePath));
+ /* Create a device parameter for testing IoOpenDeviceRegistryKey */ + key = SetupDiCreateDevRegKeyA(set, &device, DICS_FLAG_GLOBAL, 0, DIREG_DEV, NULL, NULL); + ok(key != INVALID_HANDLE_VALUE, "failed to create a hardware parameters key, got error %#lx\n", GetLastError()); + status = RegSetValueExA(key, foobar, 0, REG_SZ, (const BYTE *)bar, sizeof(bar)); + ok(status == ERROR_SUCCESS, "failed to save a device parameter, got error %lu\n", status); + RegCloseKey(key); + SetupDiDestroyDeviceInfoList(set);
RtlInitUnicodeString(&string, L"\Device\winetest_pnp_1"); @@ -1701,6 +1709,9 @@ static void test_pnp_devices(void) ok(id == 1, "got id %d\n", id); ok(size == sizeof(id), "got size %lu\n", size);
+ ret = DeviceIoControl(child, IOCTL_WINETEST_CHILD_MAIN, NULL, 0, NULL, 0, &size, NULL); + ok(ret, "got error %lu\n", GetLastError()); + CloseHandle(child);
ret = NtOpenFile(&child, SYNCHRONIZE, &attr, &io, 0, 0);
From: Alexander Morozov amorozov@etersoft.ru
--- dlls/ntoskrnl.exe/pnp.c | 3 +-- dlls/ntoskrnl.exe/tests/driver_pnp.c | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c index f887bfc619d..49af547d4fa 100644 --- a/dlls/ntoskrnl.exe/pnp.c +++ b/dlls/ntoskrnl.exe/pnp.c @@ -573,14 +573,13 @@ NTSTATUS WINAPI IoGetDeviceProperty( DEVICE_OBJECT *device, DEVICE_REGISTRY_PROP { WCHAR *id, *ptr;
- status = get_device_id( device, BusQueryInstanceID, &id ); + status = get_device_id( device, BusQueryDeviceID, &id ); if (status != STATUS_SUCCESS) { ERR("Failed to get instance ID, status %#lx.\n", status); break; }
- wcsupr( id ); ptr = wcschr( id, '\' ); if (ptr) *ptr = 0;
diff --git a/dlls/ntoskrnl.exe/tests/driver_pnp.c b/dlls/ntoskrnl.exe/tests/driver_pnp.c index 7e94c643ae9..a5fb145c387 100644 --- a/dlls/ntoskrnl.exe/tests/driver_pnp.c +++ b/dlls/ntoskrnl.exe/tests/driver_pnp.c @@ -741,9 +741,9 @@ static void test_enumerator_name(void) memset(buffer, 0, sizeof(buffer)); status = IoGetDeviceProperty(bus_pdo, DevicePropertyEnumeratorName, sizeof(buffer), buffer, &req_size); ok(status == STATUS_SUCCESS, "IoGetDeviceProperty failed: %#lx\n", status); - todo_wine ok(req_size == sizeof(root), "unexpected size %lu\n", req_size); + ok(req_size == sizeof(root), "unexpected size %lu\n", req_size); if (status == STATUS_SUCCESS) - todo_wine ok(!wcscmp(root, buffer), "unexpected property value '%ls'\n", buffer); + ok(!wcscmp(root, buffer), "unexpected property value '%ls'\n", buffer); }
static void test_child_enumerator_name(DEVICE_OBJECT *device) @@ -757,9 +757,9 @@ static void test_child_enumerator_name(DEVICE_OBJECT *device) status = IoGetDeviceProperty(device, DevicePropertyEnumeratorName, sizeof(buffer), buffer, &req_size); todo_wine ok(query_id_count == 0, "expected no IRP_MN_QUERY_ID\n"); ok(status == STATUS_SUCCESS, "IoGetDeviceProperty failed: %#lx\n", status); - todo_wine ok(req_size == sizeof(wine), "unexpected size %lu\n", req_size); + ok(req_size == sizeof(wine), "unexpected size %lu\n", req_size); if (status == STATUS_SUCCESS) - todo_wine ok(!wcscmp(wine, buffer), "unexpected property value '%ls'\n", buffer); + ok(!wcscmp(wine, buffer), "unexpected property value '%ls'\n", buffer); }
static void test_device_registry_key(void)
This merge request was approved by Elizabeth Figura.