ntoskrnl: Use the IRP allocation routines for standard ioctl processing.

This commit is contained in:
Alexandre Julliard 2015-03-04 22:21:45 +09:00
parent 41eb2fd714
commit 5fc369ff21
2 changed files with 52 additions and 63 deletions

View File

@ -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 )
{

View File

@ -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**);