[7/9] ntoskrnl.exe: Improve process_ioctl.

Alexander Morozov amorozov at etersoft.ru
Mon Oct 6 02:20:57 CDT 2008


-------------- next part --------------
From 8212dbfecb4c7e05d51a887fdb38e28674db089e Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov at etersoft.ru>
Date: Thu, 2 Oct 2008 13:03:48 +0400
Subject: [PATCH] ntoskrnl.exe: Improve process_ioctl.

---
 dlls/ntoskrnl.exe/ntoskrnl.c |   85 +++++++++++++++++++++++++++--------------
 1 files changed, 56 insertions(+), 29 deletions(-)

diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 9af2f16..47b9188 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -30,6 +30,7 @@
 #define WIN32_NO_STATUS
 #include "windef.h"
 #include "winternl.h"
+#include "winioctl.h"
 #include "excpt.h"
 #include "ddk/ntddk.h"
 #include "wine/unicode.h"
@@ -134,55 +135,81 @@ static LONG CALLBACK vectored_handler( EXCEPTION_POINTERS *ptrs )
 static NTSTATUS process_ioctl( DEVICE_OBJECT *device, ULONG code, void *in_buff, ULONG in_size,
                                void *out_buff, ULONG *out_size )
 {
-    IRP irp;
+    PIRP irp;
     MDL mdl;
-    IO_STACK_LOCATION irpsp;
+    PIO_STACK_LOCATION irpsp;
     PDRIVER_DISPATCH dispatch = device->DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL];
     NTSTATUS status;
     LARGE_INTEGER count;
+    CHAR *buf = NULL;
 
     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) );
-
-    irp.RequestorMode = UserMode;
-    irp.AssociatedIrp.SystemBuffer = in_buff;
-    irp.UserBuffer = out_buff;
-    irp.MdlAddress = &mdl;
-    irp.Tail.Overlay.s.u.CurrentStackLocation = &irpsp;
+    irp = IoAllocateIrp( device->StackSize, FALSE );
+    if (irp == NULL)
+        return STATUS_UNSUCCESSFUL;
 
-    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;
+    --irp->CurrentLocation;
+    irpsp = --irp->Tail.Overlay.s.u.CurrentStackLocation;
 
-    mdl.Next = NULL;
-    mdl.Size = 0;
-    mdl.StartVa = out_buff;
-    mdl.ByteCount = *out_size;
-    mdl.ByteOffset = 0;
+    switch (code & 3)
+    {
+    case METHOD_BUFFERED:
+        buf = ExAllocatePool( NonPagedPool, (*out_size > in_size) ? *out_size : in_size );
+        if (buf == NULL)
+        {
+            IoFreeIrp( irp );
+            return STATUS_UNSUCCESSFUL;
+        }
+        memcpy( buf, in_buff, in_size );
+        irp->AssociatedIrp.SystemBuffer = buf;
+        irp->UserBuffer = out_buff;
+        break;
+    case METHOD_NEITHER:
+        irpsp->Parameters.DeviceIoControl.Type3InputBuffer = in_buff;
+        irp->UserBuffer = out_buff;
+        break;
+    default:
+        irp->AssociatedIrp.SystemBuffer = in_buff;
+        irp->MdlAddress = &mdl;
+        mdl.Next = NULL;
+        mdl.Size = 0;
+        mdl.StartVa = out_buff;
+        mdl.ByteCount = *out_size;
+        mdl.ByteOffset = 0;
+    }
 
-    device->CurrentIrp = &irp;
+    irp->RequestorMode = UserMode;
+    irp->IoStatus.u.Status = STATUS_NOT_SUPPORTED;
+    irpsp->MajorFunction = IRP_MJ_DEVICE_CONTROL;
+    irpsp->Parameters.DeviceIoControl.OutputBufferLength = *out_size;
+    irpsp->Parameters.DeviceIoControl.InputBufferLength = in_size;
+    irpsp->Parameters.DeviceIoControl.IoControlCode = code;
+    irpsp->DeviceObject = device;
+    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 );
+                 GetCurrentThreadId(), dispatch, device, irp );
 
-    status = 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 );
+                 GetCurrentThreadId(), dispatch, device, irp, status );
 
-    *out_size = (irp.IoStatus.u.Status >= 0) ? irp.IoStatus.Information : 0;
-    return irp.IoStatus.u.Status;
+    status = irp->IoStatus.u.Status;
+    *out_size = (status >= 0) ? irp->IoStatus.Information : 0;
+    IoFreeIrp( irp );
+    if (buf != NULL)
+    {
+        memcpy( out_buff, buf, *out_size );
+        ExFreePool( buf );
+    }
+
+    return status;
 }
 
 
-- 
1.5.6.5.GIT



More information about the wine-patches mailing list