Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntoskrnl.exe/tests/driver.c | 21 +++++++++ dlls/ntoskrnl.exe/tests/driver.h | 1 + dlls/ntoskrnl.exe/tests/ntoskrnl.c | 71 ++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+)
diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c index 125cf9b67b..3c5c1ace5c 100644 --- a/dlls/ntoskrnl.exe/tests/driver.c +++ b/dlls/ntoskrnl.exe/tests/driver.c @@ -1688,6 +1688,24 @@ static NTSTATUS get_fscontext(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *inf return STATUS_SUCCESS; }
+static NTSTATUS return_status(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info) +{ + char *buffer = irp->AssociatedIrp.SystemBuffer; + NTSTATUS ret; + + if (!buffer) + return STATUS_ACCESS_VIOLATION; + + if (stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(DWORD) + || stack->Parameters.DeviceIoControl.OutputBufferLength < 3) + return STATUS_BUFFER_TOO_SMALL; + + ret = *(DWORD *)irp->AssociatedIrp.SystemBuffer; + memcpy(buffer, "ghi", 3); + *info = 3; + return ret; +} + static NTSTATUS test_load_driver_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info) { BOOL *load = irp->AssociatedIrp.SystemBuffer; @@ -1758,6 +1776,9 @@ static NTSTATUS WINAPI driver_IoControl(DEVICE_OBJECT *device, IRP *irp) case IOCTL_WINETEST_GET_FSCONTEXT: status = get_fscontext(irp, stack, &irp->IoStatus.Information); break; + case IOCTL_WINETEST_RETURN_STATUS: + status = return_status(irp, stack, &irp->IoStatus.Information); + break; case IOCTL_WINETEST_DETACH: IoDetachDevice(lower_device); status = STATUS_SUCCESS; diff --git a/dlls/ntoskrnl.exe/tests/driver.h b/dlls/ntoskrnl.exe/tests/driver.h index a468cbda9e..313d554a37 100644 --- a/dlls/ntoskrnl.exe/tests/driver.h +++ b/dlls/ntoskrnl.exe/tests/driver.h @@ -32,6 +32,7 @@ #define IOCTL_WINETEST_GET_CREATE_COUNT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807, METHOD_BUFFERED, FILE_ANY_ACCESS) #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)
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 dfd0cb3ba6..c701cf21d8 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -21,6 +21,8 @@ */
#include <stdio.h> +#include "ntstatus.h" +#define WIN32_NO_STATUS #include "windows.h" #include "winsvc.h" #include "winioctl.h" @@ -388,6 +390,74 @@ static void test_file_handles(void) ok(count == 3, "got %u\n", count); }
+static void test_return_status(void) +{ + NTSTATUS status; + char buffer[7]; + DWORD ret_size; + BOOL ret; + + strcpy(buffer, "abcdef"); + status = STATUS_SUCCESS; + SetLastError(0xdeadbeef); + ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status, + sizeof(status), buffer, sizeof(buffer), &ret_size, NULL); + ok(ret, "ioctl failed\n"); + ok(GetLastError() == 0xdeadbeef, "got error %u\n", GetLastError()); + ok(!strcmp(buffer, "ghidef"), "got buffer %s\n", buffer); + ok(ret_size == 3, "got size %u\n", ret_size); + + strcpy(buffer, "abcdef"); + status = STATUS_TIMEOUT; + SetLastError(0xdeadbeef); + ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status, + sizeof(status), buffer, sizeof(buffer), &ret_size, NULL); + todo_wine ok(ret, "ioctl failed\n"); + todo_wine ok(GetLastError() == 0xdeadbeef, "got error %u\n", GetLastError()); + ok(!strcmp(buffer, "ghidef"), "got buffer %s\n", buffer); + ok(ret_size == 3, "got size %u\n", ret_size); + + strcpy(buffer, "abcdef"); + status = 0x0eadbeef; + SetLastError(0xdeadbeef); + ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status, + sizeof(status), buffer, sizeof(buffer), &ret_size, NULL); + todo_wine ok(ret, "ioctl failed\n"); + todo_wine ok(GetLastError() == 0xdeadbeef, "got error %u\n", GetLastError()); + ok(!strcmp(buffer, "ghidef"), "got buffer %s\n", buffer); + ok(ret_size == 3, "got size %u\n", ret_size); + + strcpy(buffer, "abcdef"); + status = 0x4eadbeef; + SetLastError(0xdeadbeef); + ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status, + sizeof(status), buffer, sizeof(buffer), &ret_size, NULL); + todo_wine ok(ret, "ioctl failed\n"); + todo_wine ok(GetLastError() == 0xdeadbeef, "got error %u\n", GetLastError()); + ok(!strcmp(buffer, "ghidef"), "got buffer %s\n", buffer); + ok(ret_size == 3, "got size %u\n", ret_size); + + strcpy(buffer, "abcdef"); + status = 0x8eadbeef; + SetLastError(0xdeadbeef); + ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status, + sizeof(status), buffer, sizeof(buffer), &ret_size, NULL); + ok(!ret, "ioctl succeeded\n"); + ok(GetLastError() == ERROR_MR_MID_NOT_FOUND, "got error %u\n", GetLastError()); + todo_wine ok(!strcmp(buffer, "ghidef"), "got buffer %s\n", buffer); + todo_wine ok(ret_size == 3, "got size %u\n", ret_size); + + strcpy(buffer, "abcdef"); + status = 0xceadbeef; + SetLastError(0xdeadbeef); + ret = DeviceIoControl(device, IOCTL_WINETEST_RETURN_STATUS, &status, + sizeof(status), buffer, sizeof(buffer), &ret_size, NULL); + ok(!ret, "ioctl succeeded\n"); + ok(GetLastError() == ERROR_MR_MID_NOT_FOUND, "got error %u\n", GetLastError()); + ok(!strcmp(buffer, "abcdef"), "got buffer %s\n", buffer); + todo_wine ok(ret_size == 3, "got size %u\n", ret_size); +} + static void test_driver3(void) { char filename[MAX_PATH]; @@ -440,6 +510,7 @@ START_TEST(ntoskrnl) test_overlapped(); test_load_driver(service2); test_file_handles(); + test_return_status();
/* We need a separate ioctl to call IoDetachDevice(); calling it in the * driver unload routine causes a live-lock. */