[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