Jacek Caban : ntoskrnl.exe: Set FileObject of IRP passed to driver callbacks.

Alexandre Julliard julliard at winehq.org
Thu Feb 7 16:20:55 CST 2019


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Feb  6 23:34:11 2019 +0100

ntoskrnl.exe: Set FileObject of IRP passed to driver callbacks.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=20083
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntoskrnl.exe/ntoskrnl.c     | 12 ++++++++++++
 dlls/ntoskrnl.exe/tests/driver.c | 21 +++++++++++++++++++--
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index c3276c9..448d500 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -326,6 +326,7 @@ static NTSTATUS dispatch_create( const irp_params_t *params, void *in_buff, ULON
     irpsp = IoGetNextIrpStackLocation( irp );
     irpsp->MajorFunction = IRP_MJ_CREATE;
     irpsp->DeviceObject = device;
+    irpsp->FileObject = file;
     irpsp->Parameters.Create.SecurityContext = NULL;  /* FIXME */
     irpsp->Parameters.Create.Options = params->create.options;
     irpsp->Parameters.Create.ShareAccess = params->create.sharing;
@@ -370,6 +371,7 @@ static NTSTATUS dispatch_close( const irp_params_t *params, void *in_buff, ULONG
     irpsp = IoGetNextIrpStackLocation( irp );
     irpsp->MajorFunction = IRP_MJ_CLOSE;
     irpsp->DeviceObject = device;
+    irpsp->FileObject = file;
 
     irp->Tail.Overlay.OriginalFileObject = file;
     irp->RequestorMode = UserMode;
@@ -417,6 +419,7 @@ static NTSTATUS dispatch_read( const irp_params_t *params, void *in_buff, ULONG
     irp->RequestorMode = UserMode;
 
     irpsp = IoGetNextIrpStackLocation( irp );
+    irpsp->FileObject = file;
     irpsp->Parameters.Read.Key = params->read.key;
 
     irp->Flags |= IRP_READ_OPERATION;
@@ -453,6 +456,7 @@ static NTSTATUS dispatch_write( const irp_params_t *params, void *in_buff, ULONG
     irp->RequestorMode = UserMode;
 
     irpsp = IoGetNextIrpStackLocation( irp );
+    irpsp->FileObject = file;
     irpsp->Parameters.Write.Key = params->write.key;
 
     irp->Flags |= IRP_WRITE_OPERATION;
@@ -467,6 +471,7 @@ static NTSTATUS dispatch_flush( const irp_params_t *params, void *in_buff, ULONG
                                 ULONG out_size, HANDLE irp_handle )
 {
     IRP *irp;
+    IO_STACK_LOCATION *irpsp;
     DEVICE_OBJECT *device;
     FILE_OBJECT *file = wine_server_get_ptr( params->flush.file );
 
@@ -483,6 +488,9 @@ static NTSTATUS dispatch_flush( const irp_params_t *params, void *in_buff, ULONG
     irp->Tail.Overlay.OriginalFileObject = file;
     irp->RequestorMode = UserMode;
 
+    irpsp = IoGetNextIrpStackLocation( irp );
+    irpsp->FileObject = file;
+
     dispatch_irp( device, irp, irp_handle );
 
     HeapFree( GetProcessHeap(), 0, in_buff );
@@ -493,6 +501,7 @@ static NTSTATUS dispatch_flush( const irp_params_t *params, void *in_buff, ULONG
 static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG in_size,
                                 ULONG out_size, HANDLE irp_handle )
 {
+    IO_STACK_LOCATION *irpsp;
     IRP *irp;
     void *out_buff = NULL;
     void *to_free = NULL;
@@ -540,6 +549,9 @@ static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG
     if (out_size && (params->ioctl.code & 3) != METHOD_BUFFERED)
         HeapReAlloc( GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, in_buff, in_size );
 
+    irpsp = IoGetNextIrpStackLocation( irp );
+    irpsp->FileObject = file;
+
     irp->Tail.Overlay.OriginalFileObject = file;
     irp->RequestorMode = UserMode;
     irp->AssociatedIrp.SystemBuffer = in_buff;
diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c
index bd1070c..da316b8 100644
--- a/dlls/ntoskrnl.exe/tests/driver.c
+++ b/dlls/ntoskrnl.exe/tests/driver.c
@@ -183,6 +183,18 @@ todo_wine
     ok(current != NULL, "Expected current process to be non-NULL\n");
 }
 
+static FILE_OBJECT *last_created_file;
+
+static void test_irp_struct(IRP *irp, DEVICE_OBJECT *device)
+{
+    IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
+
+    ok(last_created_file != NULL, "last_created_file = NULL\n");
+    ok(irpsp->FileObject == last_created_file, "FileObject != last_created_file\n");
+    ok(irpsp->DeviceObject == device, "unexpected DeviceObject\n");
+    ok(irpsp->FileObject->DeviceObject == device, "unexpected FileObject->DeviceObject\n");
+}
+
 static void test_mdl_map(void)
 {
     char buffer[20] = "test buffer";
@@ -604,7 +616,7 @@ static void test_lookaside_list(void)
     ExDeleteNPagedLookasideList(&list);
 }
 
-static NTSTATUS main_test(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)
+static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)
 {
     ULONG length = stack->Parameters.DeviceIoControl.OutputBufferLength;
     void *buffer = irp->AssociatedIrp.SystemBuffer;
@@ -628,6 +640,7 @@ static NTSTATUS main_test(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)
     attr.Attributes = OBJ_KERNEL_HANDLE; /* needed to be accessible from system threads */
     ZwOpenFile(&okfile, FILE_APPEND_DATA | SYNCHRONIZE, &attr, &io, 0, FILE_SYNCHRONOUS_IO_NONALERT);
 
+    test_irp_struct(irp, device);
     test_currentprocess();
     test_mdl_map();
     test_init_funcs();
@@ -686,6 +699,10 @@ 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 );
+
+    last_created_file = irpsp->FileObject;
+
     irp->IoStatus.Status = STATUS_SUCCESS;
     IoCompleteRequest(irp, IO_NO_INCREMENT);
     return STATUS_SUCCESS;
@@ -702,7 +719,7 @@ static NTSTATUS WINAPI driver_IoControl(DEVICE_OBJECT *device, IRP *irp)
             status = test_basic_ioctl(irp, stack, &irp->IoStatus.Information);
             break;
         case IOCTL_WINETEST_MAIN_TEST:
-            status = main_test(irp, stack, &irp->IoStatus.Information);
+            status = main_test(device, irp, stack, &irp->IoStatus.Information);
             break;
         case IOCTL_WINETEST_LOAD_DRIVER:
             status = test_load_driver_ioctl(irp, stack, &irp->IoStatus.Information);




More information about the wine-cvs mailing list