Zebediah Figura : ntoskrnl.exe/tests: Add some tests for file objects.

Alexandre Julliard julliard at winehq.org
Wed Aug 7 15:36:22 CDT 2019


Module: wine
Branch: master
Commit: 7845c0117a6a26f78fcc870b8fbae4ff74816ff4
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=7845c0117a6a26f78fcc870b8fbae4ff74816ff4

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Tue Aug  6 22:48:41 2019 -0500

ntoskrnl.exe/tests: Add some tests for file objects.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntoskrnl.exe/tests/driver.c   | 42 ++++++++++++++++++++--
 dlls/ntoskrnl.exe/tests/driver.h   |  3 ++
 dlls/ntoskrnl.exe/tests/ntoskrnl.c | 71 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 113 insertions(+), 3 deletions(-)

diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c
index 41b1420..f43e48f 100644
--- a/dlls/ntoskrnl.exe/tests/driver.c
+++ b/dlls/ntoskrnl.exe/tests/driver.c
@@ -209,6 +209,7 @@ static void *get_proc_address(const char *name)
 }
 
 static FILE_OBJECT *last_created_file;
+static unsigned int create_count, close_count;
 
 static void test_irp_struct(IRP *irp, DEVICE_OBJECT *device)
 {
@@ -1631,7 +1632,7 @@ static NTSTATUS test_basic_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *
     return STATUS_SUCCESS;
 }
 
-static NTSTATUS get_cancel_count(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)
+static NTSTATUS get_dword(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info, DWORD value)
 {
     ULONG length = stack->Parameters.DeviceIoControl.OutputBufferLength;
     char *buffer = irp->AssociatedIrp.SystemBuffer;
@@ -1642,7 +1643,24 @@ static NTSTATUS get_cancel_count(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *
     if (length < sizeof(DWORD))
         return STATUS_BUFFER_TOO_SMALL;
 
-    *(DWORD*)buffer = cancel_cnt;
+    *(DWORD*)buffer = value;
+    *info = sizeof(DWORD);
+    return STATUS_SUCCESS;
+}
+
+static NTSTATUS get_fscontext(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)
+{
+    ULONG length = stack->Parameters.DeviceIoControl.OutputBufferLength;
+    char *buffer = irp->AssociatedIrp.SystemBuffer;
+    DWORD *context = stack->FileObject->FsContext;
+
+    if (!buffer || !context)
+        return STATUS_ACCESS_VIOLATION;
+
+    if (length < sizeof(DWORD))
+        return STATUS_BUFFER_TOO_SMALL;
+
+    *(DWORD*)buffer = *context;
     *info = sizeof(DWORD);
     return STATUS_SUCCESS;
 }
@@ -1667,8 +1685,13 @@ static NTSTATUS test_load_driver_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG
 static NTSTATUS WINAPI driver_Create(DEVICE_OBJECT *device, IRP *irp)
 {
     IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
+    DWORD *context = ExAllocatePool(PagedPool, sizeof(*context));
 
     last_created_file = irpsp->FileObject;
+    ++create_count;
+    if (context)
+        *context = create_count;
+    irpsp->FileObject->FsContext = context;
     create_caller_thread = KeGetCurrentThread();
 
     irp->IoStatus.Status = STATUS_SUCCESS;
@@ -1701,7 +1724,16 @@ static NTSTATUS WINAPI driver_IoControl(DEVICE_OBJECT *device, IRP *irp)
             IoMarkIrpPending(irp);
             return STATUS_PENDING;
         case IOCTL_WINETEST_GET_CANCEL_COUNT:
-            status = get_cancel_count(irp, stack, &irp->IoStatus.Information);
+            status = get_dword(irp, stack, &irp->IoStatus.Information, cancel_cnt);
+            break;
+        case IOCTL_WINETEST_GET_CREATE_COUNT:
+            status = get_dword(irp, stack, &irp->IoStatus.Information, create_count);
+            break;
+        case IOCTL_WINETEST_GET_CLOSE_COUNT:
+            status = get_dword(irp, stack, &irp->IoStatus.Information, close_count);
+            break;
+        case IOCTL_WINETEST_GET_FSCONTEXT:
+            status = get_fscontext(irp, stack, &irp->IoStatus.Information);
             break;
         case IOCTL_WINETEST_DETACH:
             IoDetachDevice(lower_device);
@@ -1733,6 +1765,10 @@ static NTSTATUS WINAPI driver_FlushBuffers(DEVICE_OBJECT *device, IRP *irp)
 
 static NTSTATUS WINAPI driver_Close(DEVICE_OBJECT *device, IRP *irp)
 {
+    IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp);
+    ++close_count;
+    if (stack->FileObject->FsContext)
+        ExFreePool(stack->FileObject->FsContext);
     irp->IoStatus.Status = STATUS_SUCCESS;
     IoCompleteRequest(irp, IO_NO_INCREMENT);
     return STATUS_SUCCESS;
diff --git a/dlls/ntoskrnl.exe/tests/driver.h b/dlls/ntoskrnl.exe/tests/driver.h
index d5ff09a..a468cbd 100644
--- a/dlls/ntoskrnl.exe/tests/driver.h
+++ b/dlls/ntoskrnl.exe/tests/driver.h
@@ -29,6 +29,9 @@
 #define IOCTL_WINETEST_TEST_CANCEL      CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)
 #define IOCTL_WINETEST_GET_CANCEL_COUNT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS)
 #define IOCTL_WINETEST_DETACH           CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#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)
 
 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 48ddb29..dfd0cb3 100644
--- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
@@ -318,6 +318,76 @@ static void test_load_driver(SC_HANDLE service)
     ok(status.dwCurrentState == SERVICE_STOPPED, "got state %#x\n", status.dwCurrentState);
 }
 
+static void test_file_handles(void)
+{
+    DWORD count, ret_size;
+    HANDLE file, dup, file2;
+    BOOL ret;
+
+    ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CREATE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
+    ok(ret, "ioctl failed: %u\n", GetLastError());
+    ok(count == 2, "got %u\n", count);
+
+    ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CLOSE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
+    ok(ret, "ioctl failed: %u\n", GetLastError());
+    ok(count == 1, "got %u\n", count);
+
+    file = CreateFileA("\\\\.\\WineTestDriver", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
+    ok(file != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
+
+    ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CREATE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
+    ok(ret, "ioctl failed: %u\n", GetLastError());
+    ok(count == 3, "got %u\n", count);
+
+    file2 = CreateFileA("\\\\.\\WineTestDriver", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
+    ok(file2 != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
+
+    ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CREATE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
+    ok(ret, "ioctl failed: %u\n", GetLastError());
+    ok(count == 4, "got %u\n", count);
+
+    ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup, 0, FALSE, DUPLICATE_SAME_ACCESS);
+    ok(ret, "failed to duplicate handle: %u\n", GetLastError());
+
+    ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CREATE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
+    ok(ret, "ioctl failed: %u\n", GetLastError());
+    ok(count == 4, "got %u\n", count);
+
+    ret = DeviceIoControl(device, IOCTL_WINETEST_GET_FSCONTEXT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
+    ok(ret, "ioctl failed: %u\n", GetLastError());
+    ok(count == 1, "got %u\n", count);
+
+    ret = DeviceIoControl(file, IOCTL_WINETEST_GET_FSCONTEXT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
+    ok(ret, "ioctl failed: %u\n", GetLastError());
+    ok(count == 3, "got %u\n", count);
+
+    ret = DeviceIoControl(file2, IOCTL_WINETEST_GET_FSCONTEXT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
+    ok(ret, "ioctl failed: %u\n", GetLastError());
+    ok(count == 4, "got %u\n", count);
+
+    ret = DeviceIoControl(dup, IOCTL_WINETEST_GET_FSCONTEXT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
+    ok(ret, "ioctl failed: %u\n", GetLastError());
+    ok(count == 3, "got %u\n", count);
+
+    CloseHandle(dup);
+
+    ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CLOSE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
+    ok(ret, "ioctl failed: %u\n", GetLastError());
+    ok(count == 1, "got %u\n", count);
+
+    CloseHandle(file2);
+
+    ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CLOSE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
+    ok(ret, "ioctl failed: %u\n", GetLastError());
+    ok(count == 2, "got %u\n", count);
+
+    CloseHandle(file);
+
+    ret = DeviceIoControl(device, IOCTL_WINETEST_GET_CLOSE_COUNT, NULL, 0, &count, sizeof(count), &ret_size, NULL);
+    ok(ret, "ioctl failed: %u\n", GetLastError());
+    ok(count == 3, "got %u\n", count);
+}
+
 static void test_driver3(void)
 {
     char filename[MAX_PATH];
@@ -369,6 +439,7 @@ START_TEST(ntoskrnl)
     main_test();
     test_overlapped();
     test_load_driver(service2);
+    test_file_handles();
 
     /* We need a separate ioctl to call IoDetachDevice(); calling it in the
      * driver unload routine causes a live-lock. */




More information about the wine-cvs mailing list