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