From 38c825598f291f99407f3f215466e7c378aac7fd Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Wed, 6 Feb 2019 23:34:11 +0100 Subject: [PATCH] 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 Signed-off-by: Alexandre Julliard --- 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 c3276c9507a..448d50083af 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 bd1070c1134..da316b85f19 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);