Alexandre Julliard : ntoskrnl: Use the IRP allocation routines for standard ioctl processing.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Mar 4 09:22:17 CST 2015


Module: wine
Branch: master
Commit: 5fc369ff21ba4c66242ed7c26cf888bfc159fe9b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=5fc369ff21ba4c66242ed7c26cf888bfc159fe9b

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Mar  4 22:21:45 2015 +0900

ntoskrnl: Use the IRP allocation routines for standard ioctl processing.

---

 dlls/ntoskrnl.exe/ntoskrnl.c | 116 +++++++++++++++++++------------------------
 include/ddk/wdm.h            |   1 +
 2 files changed, 53 insertions(+), 64 deletions(-)

diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index cdc5305..9734296 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -140,45 +140,38 @@ static HANDLE get_device_manager(void)
 static NTSTATUS process_ioctl( DEVICE_OBJECT *device, ULONG code, void *in_buff, ULONG in_size,
                                void *out_buff, ULONG *out_size )
 {
-    IRP irp;
     MDL mdl;
-    IO_STACK_LOCATION irpsp;
+    IRP *irp;
+    void *sys_buff = NULL;
     FILE_OBJECT file;
-    PDRIVER_DISPATCH dispatch = device->DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL];
-    NTSTATUS status;
+    IO_STATUS_BLOCK iosb;
     LARGE_INTEGER count;
 
     TRACE( "ioctl %x device %p in_size %u out_size %u\n", code, device, in_size, *out_size );
 
     /* so we can spot things that we should initialize */
-    memset( &irp, 0x55, sizeof(irp) );
-    memset( &irpsp, 0x66, sizeof(irpsp) );
     memset( &mdl, 0x77, sizeof(mdl) );
     memset( &file, 0x88, sizeof(file) );
 
-    irp.RequestorMode = UserMode;
     if ((code & 3) == METHOD_BUFFERED)
     {
-        irp.AssociatedIrp.SystemBuffer = HeapAlloc( GetProcessHeap(), 0, max( in_size, *out_size ) );
-        if (!irp.AssociatedIrp.SystemBuffer)
+        if (!(sys_buff = HeapAlloc( GetProcessHeap(), 0, max( in_size, *out_size ) )))
             return STATUS_NO_MEMORY;
-        memcpy( irp.AssociatedIrp.SystemBuffer, in_buff, in_size );
+        memcpy( sys_buff, in_buff, in_size );
     }
-    else
-        irp.AssociatedIrp.SystemBuffer = in_buff;
-    irp.UserBuffer = out_buff;
-    irp.MdlAddress = &mdl;
-    irp.Tail.Overlay.s.u2.CurrentStackLocation = &irpsp;
-    irp.Tail.Overlay.OriginalFileObject = &file;
-    irp.UserIosb = NULL;
-
-    irpsp.MajorFunction = IRP_MJ_DEVICE_CONTROL;
-    irpsp.Parameters.DeviceIoControl.OutputBufferLength = *out_size;
-    irpsp.Parameters.DeviceIoControl.InputBufferLength = in_size;
-    irpsp.Parameters.DeviceIoControl.IoControlCode = code;
-    irpsp.Parameters.DeviceIoControl.Type3InputBuffer = in_buff;
-    irpsp.DeviceObject = device;
-    irpsp.CompletionRoutine = NULL;
+
+    irp = IoBuildDeviceIoControlRequest( code, device, in_buff, in_size, out_buff, *out_size,
+                                         FALSE, NULL, &iosb );
+    if (!irp)
+    {
+        HeapFree( GetProcessHeap(), 0, sys_buff );
+        return STATUS_NO_MEMORY;
+    }
+    irp->RequestorMode = UserMode;
+    irp->AssociatedIrp.SystemBuffer = ((code & 3) == METHOD_BUFFERED) ? sys_buff : in_buff;
+    irp->UserBuffer = out_buff;
+    irp->MdlAddress = &mdl;
+    irp->Tail.Overlay.OriginalFileObject = &file;
 
     mdl.Next = NULL;
     mdl.Size = 0;
@@ -189,27 +182,17 @@ static NTSTATUS process_ioctl( DEVICE_OBJECT *device, ULONG code, void *in_buff,
     file.FsContext = NULL;
     file.FsContext2 = NULL;
 
-    device->CurrentIrp = &irp;
+    device->CurrentIrp = irp;
 
     KeQueryTickCount( &count );  /* update the global KeTickCount */
 
-    if (TRACE_ON(relay))
-        DPRINTF( "%04x:Call driver dispatch %p (device=%p,irp=%p)\n",
-                 GetCurrentThreadId(), dispatch, device, &irp );
+    IoCallDriver( device, irp );
 
-    status = dispatch( device, &irp );
+    *out_size = (iosb.u.Status >= 0) ? iosb.Information : 0;
+    if (out_buff && (code & 3) == METHOD_BUFFERED) memcpy( out_buff, sys_buff, *out_size );
 
-    if (TRACE_ON(relay))
-        DPRINTF( "%04x:Ret  driver dispatch %p (device=%p,irp=%p) retval=%08x\n",
-                 GetCurrentThreadId(), dispatch, device, &irp, status );
-
-    *out_size = (irp.IoStatus.u.Status >= 0) ? irp.IoStatus.Information : 0;
-    if ((code & 3) == METHOD_BUFFERED)
-    {
-        if (out_buff) memcpy( out_buff, irp.AssociatedIrp.SystemBuffer, *out_size );
-        HeapFree( GetProcessHeap(), 0, irp.AssociatedIrp.SystemBuffer );
-    }
-    return irp.IoStatus.u.Status;
+    HeapFree( GetProcessHeap(), 0, sys_buff );
+    return iosb.u.Status;
 }
 
 
@@ -493,29 +476,23 @@ PDEVICE_OBJECT WINAPI IoAttachDeviceToDeviceStack( DEVICE_OBJECT *source,
 /***********************************************************************
  *           IoBuildDeviceIoControlRequest  (NTOSKRNL.EXE.@)
  */
-PIRP WINAPI IoBuildDeviceIoControlRequest( ULONG IoControlCode,
-                                           PDEVICE_OBJECT DeviceObject,
-                                           PVOID InputBuffer,
-                                           ULONG InputBufferLength,
-                                           PVOID OutputBuffer,
-                                           ULONG OutputBufferLength,
-                                           BOOLEAN InternalDeviceIoControl,
-                                           PKEVENT Event,
-                                           PIO_STATUS_BLOCK IoStatusBlock )
+PIRP WINAPI IoBuildDeviceIoControlRequest( ULONG code, PDEVICE_OBJECT device,
+                                           PVOID in_buff, ULONG in_len,
+                                           PVOID out_buff, ULONG out_len,
+                                           BOOLEAN internal, PKEVENT event,
+                                           PIO_STATUS_BLOCK iosb )
 {
     PIRP irp;
     PIO_STACK_LOCATION irpsp;
     struct IrpInstance *instance;
 
     TRACE( "%x, %p, %p, %u, %p, %u, %u, %p, %p\n",
-           IoControlCode, DeviceObject, InputBuffer, InputBufferLength,
-           OutputBuffer, OutputBufferLength, InternalDeviceIoControl,
-           Event, IoStatusBlock );
+           code, device, in_buff, in_len, out_buff, out_len, internal, event, iosb );
 
-    if (DeviceObject == NULL)
+    if (device == NULL)
         return NULL;
 
-    irp = IoAllocateIrp( DeviceObject->StackSize, FALSE );
+    irp = IoAllocateIrp( device->StackSize, FALSE );
     if (irp == NULL)
         return NULL;
 
@@ -529,12 +506,16 @@ PIRP WINAPI IoBuildDeviceIoControlRequest( ULONG IoControlCode,
     list_add_tail( &Irps, &instance->entry );
 
     irpsp = IoGetNextIrpStackLocation( irp );
-    irpsp->MajorFunction = InternalDeviceIoControl ?
-            IRP_MJ_INTERNAL_DEVICE_CONTROL : IRP_MJ_DEVICE_CONTROL;
-    irpsp->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
-    irp->UserIosb = IoStatusBlock;
-    irp->UserEvent = Event;
+    irpsp->MajorFunction = internal ? IRP_MJ_INTERNAL_DEVICE_CONTROL : IRP_MJ_DEVICE_CONTROL;
+    irpsp->Parameters.DeviceIoControl.IoControlCode = code;
+    irpsp->Parameters.DeviceIoControl.InputBufferLength = in_len;
+    irpsp->Parameters.DeviceIoControl.OutputBufferLength = out_len;
+    irpsp->Parameters.DeviceIoControl.Type3InputBuffer = in_buff;
+    irpsp->DeviceObject = device;
+    irpsp->CompletionRoutine = NULL;
 
+    irp->UserIosb = iosb;
+    irp->UserEvent = event;
     return irp;
 }
 
@@ -812,13 +793,20 @@ NTSTATUS WINAPI IoCallDriver( DEVICE_OBJECT *device, IRP *irp )
     IO_STACK_LOCATION *irpsp;
     NTSTATUS status;
 
-    TRACE( "%p %p\n", device, irp );
-
     --irp->CurrentLocation;
     irpsp = --irp->Tail.Overlay.s.u2.CurrentStackLocation;
     dispatch = device->DriverObject->MajorFunction[irpsp->MajorFunction];
+
+    if (TRACE_ON(relay))
+        DPRINTF( "%04x:Call driver dispatch %p (device=%p,irp=%p)\n",
+                 GetCurrentThreadId(), dispatch, device, irp );
+
     status = dispatch( device, irp );
 
+    if (TRACE_ON(relay))
+        DPRINTF( "%04x:Ret  driver dispatch %p (device=%p,irp=%p) retval=%08x\n",
+                 GetCurrentThreadId(), dispatch, device, irp, status );
+
     return status;
 }
 
@@ -1020,10 +1008,10 @@ VOID WINAPI IoCompleteRequest( IRP *irp, UCHAR priority_boost )
                 return;
         }
     }
-    if (iosb && STATUS_SUCCESS == status)
+    if (iosb)
     {
         iosb->u.Status = irp->IoStatus.u.Status;
-        iosb->Information = irp->IoStatus.Information;
+        if (iosb->u.Status >= 0) iosb->Information = irp->IoStatus.Information;
     }
     LIST_FOR_EACH_ENTRY( instance, &Irps, struct IrpInstance, entry )
     {
diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h
index e4f693a..661b75e 100644
--- a/include/ddk/wdm.h
+++ b/include/ddk/wdm.h
@@ -1199,6 +1199,7 @@ void      WINAPI ExFreePoolWithTag(PVOID,ULONG);
 NTSTATUS  WINAPI IoAllocateDriverObjectExtension(PDRIVER_OBJECT,PVOID,ULONG,PVOID*);
 PVOID     WINAPI IoAllocateErrorLogEntry(PVOID,UCHAR);
 PIRP      WINAPI IoAllocateIrp(CCHAR,BOOLEAN);
+PIRP      WINAPI IoBuildDeviceIoControlRequest(ULONG,DEVICE_OBJECT*,PVOID,ULONG,PVOID,ULONG,BOOLEAN,PKEVENT,IO_STATUS_BLOCK*);
 NTSTATUS  WINAPI IoCallDriver(DEVICE_OBJECT*,IRP*);
 VOID      WINAPI IoCompleteRequest(IRP*,UCHAR);
 NTSTATUS  WINAPI IoCreateDevice(DRIVER_OBJECT*,ULONG,UNICODE_STRING*,DEVICE_TYPE,ULONG,BOOLEAN,DEVICE_OBJECT**);




More information about the wine-cvs mailing list