Sebastian Lackner : ntoskrnl.exe: Use completion routine to transfer result of IRP back to server.
Alexandre Julliard
julliard at winehq.org
Tue Oct 11 15:21:09 CDT 2016
Module: wine
Branch: master
Commit: 54002103763188b5c5b1fd1210ad4cf09ef80bf9
URL: http://source.winehq.org/git/wine.git/?a=commit;h=54002103763188b5c5b1fd1210ad4cf09ef80bf9
Author: Sebastian Lackner <sebastian at 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 at fds-team.de>
Signed-off-by: Alexandre Julliard <julliard at 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
More information about the wine-cvs
mailing list