[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