From bf2695019450deda848c450087cc4853809f9199 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 8 Jul 2015 19:04:32 +0900 Subject: [PATCH] server: Pass the file instead of the device pointer in all IRP requests. --- dlls/ntoskrnl.exe/ntoskrnl.c | 56 ++++++++++++++++++++++++---------- include/wine/server_protocol.h | 10 +++--- server/device.c | 30 ++++++++++-------- server/protocol.def | 8 ++--- server/trace.c | 8 ++--- 5 files changed, 70 insertions(+), 42 deletions(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index ccd2d3ad0e..bff3ca14fc 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -131,14 +131,6 @@ static HANDLE get_device_manager(void) static NTSTATUS dispatch_irp( DEVICE_OBJECT *device, IRP *irp ) { LARGE_INTEGER count; - FILE_OBJECT file; - - irp->RequestorMode = UserMode; - irp->Tail.Overlay.OriginalFileObject = &file; - - memset( &file, 0x88, sizeof(file) ); - file.FsContext = NULL; - file.FsContext2 = NULL; KeQueryTickCount( &count ); /* update the global KeTickCount */ @@ -185,6 +177,7 @@ static NTSTATUS dispatch_create( const irp_params_t *params, void *in_buff, ULON irpsp->Parameters.Create.EaLength = 0; irp->Tail.Overlay.OriginalFileObject = file; + irp->RequestorMode = UserMode; irp->AssociatedIrp.SystemBuffer = NULL; irp->UserBuffer = NULL; irp->UserIosb = irp_handle; /* note: we abuse UserIosb to store the server irp handle */ @@ -227,6 +220,7 @@ static NTSTATUS dispatch_close( const irp_params_t *params, void *in_buff, ULONG irpsp->Parameters.Create.EaLength = 0; irp->Tail.Overlay.OriginalFileObject = file; + irp->RequestorMode = UserMode; irp->AssociatedIrp.SystemBuffer = NULL; irp->UserBuffer = NULL; irp->UserIosb = irp_handle; /* note: we abuse UserIosb to store the server irp handle */ @@ -247,11 +241,15 @@ static NTSTATUS dispatch_read( const irp_params_t *params, void *in_buff, ULONG void *out_buff; LARGE_INTEGER offset; IO_STACK_LOCATION *irpsp; - DEVICE_OBJECT *device = wine_server_get_ptr( params->read.device ); + DEVICE_OBJECT *device; + FILE_OBJECT *file = wine_server_get_ptr( params->read.file ); + if (!file) return STATUS_INVALID_HANDLE; + + device = file->DeviceObject; if (!device->DriverObject->MajorFunction[IRP_MJ_READ]) return STATUS_NOT_SUPPORTED; - TRACE( "device %p size %u\n", device, out_size ); + TRACE( "device %p file %p size %u\n", device, file, out_size ); if (!(out_buff = HeapAlloc( GetProcessHeap(), 0, out_size ))) return STATUS_NO_MEMORY; @@ -265,6 +263,9 @@ static NTSTATUS dispatch_read( const irp_params_t *params, void *in_buff, ULONG return STATUS_NO_MEMORY; } + irp->Tail.Overlay.OriginalFileObject = file; + irp->RequestorMode = UserMode; + irpsp = IoGetNextIrpStackLocation( irp ); irpsp->Parameters.Read.Key = params->read.key; @@ -278,11 +279,15 @@ static NTSTATUS dispatch_write( const irp_params_t *params, void *in_buff, ULONG IRP *irp; LARGE_INTEGER offset; IO_STACK_LOCATION *irpsp; - DEVICE_OBJECT *device = wine_server_get_ptr( params->write.device ); + DEVICE_OBJECT *device; + FILE_OBJECT *file = wine_server_get_ptr( params->write.file ); + if (!file) return STATUS_INVALID_HANDLE; + + device = file->DeviceObject; if (!device->DriverObject->MajorFunction[IRP_MJ_WRITE]) return STATUS_NOT_SUPPORTED; - TRACE( "device %p size %u\n", device, in_size ); + TRACE( "device %p file %p size %u\n", device, file, in_size ); offset.QuadPart = params->write.pos; @@ -291,6 +296,9 @@ static NTSTATUS dispatch_write( const irp_params_t *params, void *in_buff, ULONG &offset, NULL, irp_handle ))) return STATUS_NO_MEMORY; + irp->Tail.Overlay.OriginalFileObject = file; + irp->RequestorMode = UserMode; + irpsp = IoGetNextIrpStackLocation( irp ); irpsp->Parameters.Write.Key = params->write.key; @@ -302,17 +310,24 @@ static NTSTATUS dispatch_flush( const irp_params_t *params, void *in_buff, ULONG ULONG out_size, HANDLE irp_handle ) { IRP *irp; - DEVICE_OBJECT *device = wine_server_get_ptr( params->flush.device ); + DEVICE_OBJECT *device; + FILE_OBJECT *file = wine_server_get_ptr( params->flush.file ); + if (!file) return STATUS_INVALID_HANDLE; + + device = file->DeviceObject; if (!device->DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS]) return STATUS_NOT_SUPPORTED; - TRACE( "device %p\n", device ); + TRACE( "device %p file %p\n", device, file ); /* note: we abuse UserIosb to store the server irp handle */ if (!(irp = IoBuildSynchronousFsdRequest( IRP_MJ_FLUSH_BUFFERS, device, in_buff, in_size, NULL, NULL, irp_handle ))) return STATUS_NO_MEMORY; + irp->Tail.Overlay.OriginalFileObject = file; + irp->RequestorMode = UserMode; + return dispatch_irp( device, irp ); } @@ -322,11 +337,16 @@ static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG { IRP *irp; void *out_buff = NULL; - DEVICE_OBJECT *device = wine_server_get_ptr( params->ioctl.device ); + DEVICE_OBJECT *device; + FILE_OBJECT *file = wine_server_get_ptr( params->ioctl.file ); + if (!file) return STATUS_INVALID_HANDLE; + + device = file->DeviceObject; if (!device->DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]) return STATUS_NOT_SUPPORTED; - TRACE( "ioctl %x device %p in_size %u out_size %u\n", params->ioctl.code, device, in_size, out_size ); + TRACE( "ioctl %x device %p file %p in_size %u out_size %u\n", + params->ioctl.code, device, file, in_size, out_size ); if ((params->ioctl.code & 3) == METHOD_BUFFERED) out_size = max( in_size, out_size ); @@ -348,6 +368,10 @@ static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG HeapFree( GetProcessHeap(), 0, out_buff ); return STATUS_NO_MEMORY; } + + irp->Tail.Overlay.OriginalFileObject = file; + irp->RequestorMode = UserMode; + return dispatch_irp( device, irp ); } diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index eefeea56c0..8b186fa319 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -652,27 +652,27 @@ typedef union { unsigned int major; unsigned int key; - client_ptr_t device; + client_ptr_t file; file_pos_t pos; } read; struct { unsigned int major; unsigned int key; - client_ptr_t device; + client_ptr_t file; file_pos_t pos; } write; struct { unsigned int major; int __pad; - client_ptr_t device; + client_ptr_t file; } flush; struct { unsigned int major; ioctl_code_t code; - client_ptr_t device; + client_ptr_t file; } ioctl; } irp_params_t; @@ -6096,6 +6096,6 @@ union generic_reply struct terminate_job_reply terminate_job_reply; }; -#define SERVER_PROTOCOL_VERSION 480 +#define SERVER_PROTOCOL_VERSION 481 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/device.c b/server/device.c index 50c6d3b64b..e8ef8325b8 100644 --- a/server/device.c +++ b/server/device.c @@ -475,6 +475,10 @@ static void set_file_user_ptr( struct device_file *file, client_ptr_t ptr ) switch (irp->params.major) { case IRP_MJ_CLOSE: irp->params.close.file = ptr; break; + case IRP_MJ_READ: irp->params.read.file = ptr; break; + case IRP_MJ_WRITE: irp->params.write.file = ptr; break; + case IRP_MJ_FLUSH_BUFFERS: irp->params.flush.file = ptr; break; + case IRP_MJ_DEVICE_CONTROL: irp->params.ioctl.file = ptr; break; } } } @@ -511,10 +515,10 @@ static obj_handle_t device_file_read( struct fd *fd, const async_data_t *async_d obj_handle_t handle; irp_params_t params; - params.read.major = IRP_MJ_READ; - params.read.key = 0; - params.read.pos = pos; - params.read.device = file->device->user_ptr; + params.read.major = IRP_MJ_READ; + params.read.key = 0; + params.read.pos = pos; + params.read.file = file->user_ptr; irp = create_irp( file, ¶ms, NULL, 0, get_reply_max_size() ); if (!irp) return 0; @@ -532,10 +536,10 @@ static obj_handle_t device_file_write( struct fd *fd, const async_data_t *async_ obj_handle_t handle; irp_params_t params; - params.write.major = IRP_MJ_WRITE; - params.write.key = 0; - params.write.pos = pos; - params.write.device = file->device->user_ptr; + params.write.major = IRP_MJ_WRITE; + params.write.key = 0; + params.write.pos = pos; + params.write.file = file->user_ptr; irp = create_irp( file, ¶ms, get_req_data(), get_req_data_size(), 0 ); if (!irp) return 0; @@ -552,8 +556,8 @@ static obj_handle_t device_file_flush( struct fd *fd, const async_data_t *async_ obj_handle_t handle; irp_params_t params; - params.flush.major = IRP_MJ_FLUSH_BUFFERS; - params.flush.device = file->device->user_ptr; + params.flush.major = IRP_MJ_FLUSH_BUFFERS; + params.flush.file = file->user_ptr; irp = create_irp( file, ¶ms, NULL, 0, 0 ); if (!irp) return 0; @@ -571,9 +575,9 @@ static obj_handle_t device_file_ioctl( struct fd *fd, ioctl_code_t code, const a obj_handle_t handle; irp_params_t params; - params.ioctl.major = IRP_MJ_DEVICE_CONTROL; - params.ioctl.code = code; - params.ioctl.device = file->device->user_ptr; + params.ioctl.major = IRP_MJ_DEVICE_CONTROL; + params.ioctl.code = code; + params.ioctl.file = file->user_ptr; irp = create_irp( file, ¶ms, get_req_data(), get_req_data_size(), get_reply_max_size() ); diff --git a/server/protocol.def b/server/protocol.def index 2d06344245..0ff1a6bd37 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -668,27 +668,27 @@ typedef union { unsigned int major; /* IRP_MJ_READ */ unsigned int key; /* driver key */ - client_ptr_t device; /* opaque ptr for the device */ + client_ptr_t file; /* opaque ptr for the file object */ file_pos_t pos; /* file position */ } read; struct { unsigned int major; /* IRP_MJ_WRITE */ unsigned int key; /* driver key */ - client_ptr_t device; /* opaque ptr for the device */ + client_ptr_t file; /* opaque ptr for the file object */ file_pos_t pos; /* file position */ } write; struct { unsigned int major; /* IRP_MJ_FLUSH_BUFFERS */ int __pad; - client_ptr_t device; /* opaque ptr for the device */ + client_ptr_t file; /* opaque ptr for the file object */ } flush; struct { unsigned int major; /* IRP_MJ_DEVICE_CONTROL */ ioctl_code_t code; /* ioctl code */ - client_ptr_t device; /* opaque ptr for the device */ + client_ptr_t file; /* opaque ptr for the file object */ } ioctl; } irp_params_t; diff --git a/server/trace.c b/server/trace.c index e43c0c7d8d..42cff99c8b 100644 --- a/server/trace.c +++ b/server/trace.c @@ -330,24 +330,24 @@ static void dump_irp_params( const char *prefix, const irp_params_t *data ) case IRP_MJ_READ: fprintf( stderr, "%s{major=READ,key=%08x", prefix, data->read.key ); dump_uint64( ",pos=", &data->read.pos ); - dump_uint64( ",device=", &data->read.device ); + dump_uint64( ",file=", &data->read.file ); fputc( '}', stderr ); break; case IRP_MJ_WRITE: fprintf( stderr, "%s{major=WRITE,key=%08x", prefix, data->write.key ); dump_uint64( ",pos=", &data->write.pos ); - dump_uint64( ",device=", &data->write.device ); + dump_uint64( ",file=", &data->write.file ); fputc( '}', stderr ); break; case IRP_MJ_FLUSH_BUFFERS: fprintf( stderr, "%s{major=FLUSH_BUFFERS", prefix ); - dump_uint64( ",device=", &data->flush.device ); + dump_uint64( ",file=", &data->flush.file ); fputc( '}', stderr ); break; case IRP_MJ_DEVICE_CONTROL: fprintf( stderr, "%s{major=DEVICE_CONTROL", prefix ); dump_ioctl_code( ",code=", &data->ioctl.code ); - dump_uint64( ",device=", &data->ioctl.device ); + dump_uint64( ",file=", &data->ioctl.file ); fputc( '}', stderr ); break; case IRP_MJ_MAXIMUM_FUNCTION + 1: /* invalid */