[Wine-patches] [4/8] ntoskrnl.exe: Improve IoBuildDeviceIoControlRequest and wine_complete_request.

Alexander Morozov =?iso-8859-1?q?amorozov_=CE=C1_etersoft=2Eru?=
Чт Дек 11 11:47:11 MSK 2008


----------- следующая часть -----------
From 5928b0afecc39713a538cdd408472ab98d12d238 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Fri, 5 Dec 2008 16:29:28 +0300
Subject: [PATCH] ntoskrnl.exe: Improve IoBuildDeviceIoControlRequest and wine_complete_request.

---
 dlls/ntoskrnl.exe/ntoskrnl.c |   63 ++++++++++++++++++++++++++++++++++++------
 1 files changed, 54 insertions(+), 9 deletions(-)

diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index ce1e199..02a4992 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -594,6 +594,8 @@ PIRP WINAPI IoBuildDeviceIoControlRequest( ULONG IoControlCode,
     PIRP irp;
     PIO_STACK_LOCATION irpsp;
     struct IrpInstance *instance;
+    CHAR *buf = NULL;
+    MDL *mdl = NULL;
 
     TRACE( "%x, %p, %p, %u, %p, %u, %u, %p, %p\n",
            IoControlCode, DeviceObject, InputBuffer, InputBufferLength,
@@ -607,23 +609,56 @@ PIRP WINAPI IoBuildDeviceIoControlRequest( ULONG IoControlCode,
     if (irp == NULL)
         return NULL;
 
-    instance = HeapAlloc( GetProcessHeap(), 0, sizeof(struct IrpInstance) );
-    if (instance == NULL)
-    {
-        IoFreeIrp( irp );
-        return NULL;
-    }
-    instance->irp = irp;
-    list_add_tail( &Irps, &instance->entry );
-
     irpsp = irp->Tail.Overlay.s.u.CurrentStackLocation - 1;
     irpsp->MajorFunction = InternalDeviceIoControl ?
             IRP_MJ_INTERNAL_DEVICE_CONTROL : IRP_MJ_DEVICE_CONTROL;
     irpsp->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
+    irpsp->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
+    irpsp->Parameters.DeviceIoControl.OutputBufferLength = OutputBufferLength;
     irp->UserIosb = IoStatusBlock;
     irp->UserEvent = Event;
 
+    switch (IoControlCode & 3)
+    {
+    case METHOD_BUFFERED:
+        buf = ExAllocatePool( NonPagedPool, max( OutputBufferLength, InputBufferLength ) );
+        if (buf == NULL)
+            goto err;
+        memcpy( buf, InputBuffer, InputBufferLength );
+        irp->AssociatedIrp.SystemBuffer = buf;
+        irp->UserBuffer = OutputBuffer;
+        break;
+    case METHOD_NEITHER:
+        irpsp->Parameters.DeviceIoControl.Type3InputBuffer = InputBuffer;
+        irp->UserBuffer = OutputBuffer;
+        break;
+    default:
+        irp->AssociatedIrp.SystemBuffer = InputBuffer;
+        mdl = ExAllocatePool( NonPagedPool, sizeof(*mdl) );
+        if (mdl == NULL)
+            goto err;
+        mdl->Next = NULL;
+        mdl->Size = 0;
+        mdl->StartVa = OutputBuffer;
+        mdl->ByteCount = OutputBufferLength;
+        mdl->ByteOffset = 0;
+        irp->MdlAddress = mdl;
+    }
+
+    instance = HeapAlloc( GetProcessHeap(), 0, sizeof(struct IrpInstance) );
+    if (instance == NULL)
+        goto err;
+    instance->irp = irp;
+    list_add_tail( &Irps, &instance->entry );
+
     return irp;
+err:
+    if (buf)
+        ExFreePool( buf );
+    if (mdl)
+        ExFreePool( mdl );
+    IoFreeIrp( irp );
+    return NULL;
 }
 
 
@@ -1148,8 +1183,18 @@ void wine_complete_request( IRP *irp, UCHAR priority_boost )
     {
         if (instance->irp == irp)
         {
+            void *buf = irp->AssociatedIrp.SystemBuffer;
+            MDL *mdl = irp->MdlAddress;
+
             list_remove( &instance->entry );
             HeapFree( GetProcessHeap(), 0, instance );
+            if (buf)
+            {
+                memcpy( irp->UserBuffer, buf, irp->IoStatus.Information );
+                ExFreePool( buf );
+            }
+            if (mdl)
+                ExFreePool( mdl );
             IoFreeIrp( irp );
             break;
         }
-- 
1.6.0.2.GIT



Подробная информация о списке рассылки Wine-patches