Module: wine Branch: master Commit: 54002103763188b5c5b1fd1210ad4cf09ef80bf9 URL: http://source.winehq.org/git/wine.git/?a=commit;h=54002103763188b5c5b1fd1210...
Author: Sebastian Lackner sebastian@fds-team.de Date: Mon Oct 10 17:15:39 2016 +0200
ntoskrnl.exe: Use completion routine to transfer result of IRP back to server.
Signed-off-by: Sebastian Lackner sebastian@fds-team.de Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntoskrnl.exe/ntoskrnl.c | 83 +++++++++++++++++++++----------------------- include/ddk/wdm.h | 12 +++++++ 2 files changed, 51 insertions(+), 44 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index cf87f7a..909bf6f 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -172,16 +172,40 @@ static HANDLE get_device_manager(void) return ret; }
-static void dispatch_irp( DEVICE_OBJECT *device, IRP *irp ) +/* transfer result of IRP back to wineserver */ +static NTSTATUS WINAPI dispatch_irp_completion( DEVICE_OBJECT *device, IRP *irp, void *context ) +{ + FILE_OBJECT *file = irp->Tail.Overlay.OriginalFileObject; + void *out_buff = irp->UserBuffer; + HANDLE handle = context; + + SERVER_START_REQ( set_irp_result ) + { + req->handle = wine_server_obj_handle( handle ); + req->status = irp->IoStatus.u.Status; + req->file_ptr = wine_server_client_ptr( file ); + if (irp->IoStatus.u.Status >= 0) + { + req->size = irp->IoStatus.Information; + if (out_buff) wine_server_add_data( req, out_buff, irp->IoStatus.Information ); + } + wine_server_call( req ); + } + SERVER_END_REQ; + + HeapFree( GetProcessHeap(), 0, out_buff ); + return STATUS_SUCCESS; +} + +static void dispatch_irp( DEVICE_OBJECT *device, IRP *irp, HANDLE irp_handle ) { LARGE_INTEGER count;
+ IoSetCompletionRoutine( irp, dispatch_irp_completion, irp_handle, TRUE, TRUE, TRUE ); KeQueryTickCount( &count ); /* update the global KeTickCount */
device->CurrentIrp = irp; - IoCallDriver( device, irp ); - device->CurrentIrp = NULL; }
@@ -211,7 +235,6 @@ 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->CompletionRoutine = NULL; irpsp->Parameters.Create.SecurityContext = NULL; /* FIXME */ irpsp->Parameters.Create.Options = params->create.options; irpsp->Parameters.Create.ShareAccess = params->create.sharing; @@ -222,10 +245,10 @@ static NTSTATUS dispatch_create( const irp_params_t *params, void *in_buff, ULON irp->RequestorMode = UserMode; irp->AssociatedIrp.SystemBuffer = NULL; irp->UserBuffer = NULL; - irp->UserIosb = irp_handle; /* note: we abuse UserIosb to store the server irp handle */ + irp->UserIosb = NULL; irp->UserEvent = NULL;
- dispatch_irp( device, irp ); + dispatch_irp( device, irp, irp_handle );
return STATUS_SUCCESS; } @@ -254,16 +277,15 @@ 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->CompletionRoutine = NULL;
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 */ + irp->UserIosb = NULL; irp->UserEvent = NULL;
- dispatch_irp( device, irp ); + dispatch_irp( device, irp, irp_handle );
HeapFree( GetProcessHeap(), 0, file ); /* FIXME: async close processing not supported */ return STATUS_SUCCESS; @@ -290,9 +312,8 @@ static NTSTATUS dispatch_read( const irp_params_t *params, void *in_buff, ULONG
offset.QuadPart = params->read.pos;
- /* note: we abuse UserIosb to store the server irp handle */ if (!(irp = IoBuildSynchronousFsdRequest( IRP_MJ_READ, device, out_buff, out_size, - &offset, NULL, irp_handle ))) + &offset, NULL, NULL ))) { HeapFree( GetProcessHeap(), 0, out_buff ); return STATUS_NO_MEMORY; @@ -304,7 +325,7 @@ static NTSTATUS dispatch_read( const irp_params_t *params, void *in_buff, ULONG irpsp = IoGetNextIrpStackLocation( irp ); irpsp->Parameters.Read.Key = params->read.key;
- dispatch_irp( device, irp ); + dispatch_irp( device, irp, irp_handle );
return STATUS_SUCCESS; } @@ -327,9 +348,8 @@ static NTSTATUS dispatch_write( const irp_params_t *params, void *in_buff, ULONG
offset.QuadPart = params->write.pos;
- /* note: we abuse UserIosb to store the server irp handle */ if (!(irp = IoBuildSynchronousFsdRequest( IRP_MJ_WRITE, device, in_buff, in_size, - &offset, NULL, irp_handle ))) + &offset, NULL, NULL ))) return STATUS_NO_MEMORY;
irp->Tail.Overlay.OriginalFileObject = file; @@ -338,7 +358,7 @@ static NTSTATUS dispatch_write( const irp_params_t *params, void *in_buff, ULONG irpsp = IoGetNextIrpStackLocation( irp ); irpsp->Parameters.Write.Key = params->write.key;
- dispatch_irp( device, irp ); + dispatch_irp( device, irp, irp_handle );
return STATUS_SUCCESS; } @@ -357,15 +377,14 @@ static NTSTATUS dispatch_flush( const irp_params_t *params, void *in_buff, ULONG
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, NULL, 0, - NULL, NULL, irp_handle ))) + NULL, NULL, NULL ))) return STATUS_NO_MEMORY;
irp->Tail.Overlay.OriginalFileObject = file; irp->RequestorMode = UserMode;
- dispatch_irp( device, irp ); + dispatch_irp( device, irp, irp_handle );
return STATUS_SUCCESS; } @@ -398,9 +417,8 @@ static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG } }
- /* note: we abuse UserIosb to store the server handle to the ioctl */ irp = IoBuildDeviceIoControlRequest( params->ioctl.code, device, in_buff, in_size, out_buff, out_size, - FALSE, NULL, irp_handle ); + FALSE, NULL, NULL ); if (!irp) { HeapFree( GetProcessHeap(), 0, out_buff ); @@ -410,7 +428,7 @@ static NTSTATUS dispatch_ioctl( const irp_params_t *params, void *in_buff, ULONG irp->Tail.Overlay.OriginalFileObject = file; irp->RequestorMode = UserMode;
- dispatch_irp( device, irp ); + dispatch_irp( device, irp, irp_handle );
return STATUS_SUCCESS; } @@ -1390,7 +1408,6 @@ VOID WINAPI IoCompleteRequest( IRP *irp, UCHAR priority_boost ) IO_STACK_LOCATION *irpsp; PIO_COMPLETION_ROUTINE routine; NTSTATUS status, stat; - HANDLE handle; int call_flag = 0;
TRACE( "%p %u\n", irp, priority_boost ); @@ -1422,28 +1439,6 @@ VOID WINAPI IoCompleteRequest( IRP *irp, UCHAR priority_boost ) } }
- handle = (HANDLE)irp->UserIosb; - if (handle) - { - void *out_buff = irp->UserBuffer; - FILE_OBJECT *file = irp->Tail.Overlay.OriginalFileObject; - - SERVER_START_REQ( set_irp_result ) - { - req->handle = wine_server_obj_handle( handle ); - req->status = irp->IoStatus.u.Status; - req->file_ptr = wine_server_client_ptr( file ); - if (irp->IoStatus.u.Status >= 0) - { - req->size = irp->IoStatus.Information; - if (out_buff) wine_server_add_data( req, out_buff, irp->IoStatus.Information ); - } - wine_server_call( req ); - } - SERVER_END_REQ; - HeapFree( GetProcessHeap(), 0, out_buff ); - } - IoFreeIrp( irp ); }
diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index 918797e..5602f7d 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -1189,6 +1189,18 @@ NTSTATUS WINAPI ObCloseHandle(IN HANDLE handle); # endif #endif
+static inline void IoSetCompletionRoutine(IRP *irp, PIO_COMPLETION_ROUTINE routine, void *context, + BOOLEAN on_success, BOOLEAN on_error, BOOLEAN on_cancel) +{ + IO_STACK_LOCATION *irpsp = IoGetNextIrpStackLocation(irp); + irpsp->CompletionRoutine = routine; + irpsp->Context = context; + irpsp->Control = 0; + if (on_success) irpsp->Control |= SL_INVOKE_ON_SUCCESS; + if (on_error) irpsp->Control |= SL_INVOKE_ON_ERROR; + if (on_cancel) irpsp->Control |= SL_INVOKE_ON_CANCEL; +} + #define KernelMode 0 #define UserMode 1