Signed-off-by: Chip Davis cdavis@codeweavers.com ---
Notes: v2: Send just the tests. Attempt to fix a broken test. v3: Remove broken test. I have no idea what Windows is doing here.
dlls/ntoskrnl.exe/tests/driver.c | 30 ++++++++++++++++++++++++++++++ dlls/ntoskrnl.exe/tests/driver.h | 1 + dlls/ntoskrnl.exe/tests/ntoskrnl.c | 13 +++++++++++++ 3 files changed, 44 insertions(+)
diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c index a0f63ade791..6827b74a3c9 100644 --- a/dlls/ntoskrnl.exe/tests/driver.c +++ b/dlls/ntoskrnl.exe/tests/driver.c @@ -1855,6 +1855,34 @@ static NTSTATUS test_load_driver_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG return ZwUnloadDriver(&name); }
+static NTSTATUS test_mismatched_status_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info) +{ + ULONG length = stack->Parameters.DeviceIoControl.OutputBufferLength; + char *buffer = irp->UserBuffer; + + if (!buffer) + { + irp->IoStatus.Status = STATUS_ACCESS_VIOLATION; + IoCompleteRequest(irp, IO_NO_INCREMENT); + return STATUS_ACCESS_VIOLATION; + } + + if (length < sizeof(teststr)) + { + irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + IoCompleteRequest(irp, IO_NO_INCREMENT); + return STATUS_BUFFER_TOO_SMALL; + } + + memcpy(buffer, teststr, sizeof(teststr)); + + /* This is deliberate; some broken drivers do this */ + *info = 0; + irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + IoCompleteRequest(irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} + static NTSTATUS WINAPI driver_Create(DEVICE_OBJECT *device, IRP *irp) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); @@ -1916,6 +1944,8 @@ static NTSTATUS WINAPI driver_IoControl(DEVICE_OBJECT *device, IRP *irp) IoDetachDevice(lower_device); status = STATUS_SUCCESS; break; + case IOCTL_WINETEST_MISMATCHED_STATUS: + return test_mismatched_status_ioctl(irp, stack, &irp->IoStatus.Information); default: break; } diff --git a/dlls/ntoskrnl.exe/tests/driver.h b/dlls/ntoskrnl.exe/tests/driver.h index 313d554a37b..aa9de674e2f 100644 --- a/dlls/ntoskrnl.exe/tests/driver.h +++ b/dlls/ntoskrnl.exe/tests/driver.h @@ -33,6 +33,7 @@ #define IOCTL_WINETEST_GET_CLOSE_COUNT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x808, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_WINETEST_GET_FSCONTEXT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x809, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_WINETEST_RETURN_STATUS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80a, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_WINETEST_MISMATCHED_STATUS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80b, METHOD_NEITHER, FILE_ANY_ACCESS)
static const char teststr[] = "Wine is not an emulator";
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index 76bcf0d0ce6..2535ed903e7 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -208,6 +208,18 @@ static void test_basic_ioctl(void) ok(!strcmp(buf, "Wine is no"), "got '%s'\n", buf); }
+static void test_mismatched_status_ioctl(void) +{ + DWORD written; + char buf[32]; + BOOL res; + + res = DeviceIoControl(device, IOCTL_WINETEST_MISMATCHED_STATUS, NULL, 0, buf, + sizeof(buf), &written, NULL); + todo_wine ok(res, "DeviceIoControl failed: %u\n", GetLastError()); + todo_wine ok(!strcmp(buf, teststr), "got '%s'\n", buf); +} + static void test_overlapped(void) { OVERLAPPED overlapped, overlapped2, *o; @@ -514,6 +526,7 @@ START_TEST(ntoskrnl) ok(device != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
test_basic_ioctl(); + test_mismatched_status_ioctl(); main_test(); test_overlapped(); test_load_driver(service2);