Creating and using an IRP internally within a driver

I am writing a driver which currently handles IRPs send from userland.

My question is: is there any way to construct IRPs inside the driver and pass them internally to the functions currently handling userland IRPs?

I’ve seen information about creating IRPs and sending them to other drivers, but I need to pass them internally.

Greatly appreciate any help.

Regards,
Graham

Sure. Just build the IRP and IoCallDriver it to the desired device object. Windows doesn’t really care that it’s a device object you created.

Be, ah, “very careful” about deadlocks and such. But, what you’re asking about isn’t unheard of.

Peter
OSR

You can send it to yourself, but since it is not a threaded irp you can’t complete it back to the io manager, otherwise you will bug check. One way to work around this problem is to allocate the irp with an extra stack location, set a completion routine which returns SMPR, format the next stack location and send it to yourself

d

debt from my phone


From: xxxxx@osr.com
Sent: 10/15/2011 10:20 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Creating and using an IRP internally within a driver

Sure. Just build the IRP and IoCallDriver it to the desired device object. Windows doesn’t really care that it’s a device object you created.

Be, ah, “very careful” about deadlocks and such. But, what you’re asking about isn’t unheard of.

Peter
OSR


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Thanks for your replies! What I’m now doing is the following:

http://pastebin.com/xAKBYuTi

Sadly I get a BSOD (http://i.imgur.com/Uo0iu.png) when I try to create the IRP. Commenting it out makes it run fine. Am I missing something?

Have I got the right idea with sending the IRP and deviceobject to my IRP_MJ_DEVICE_CONTROL (NPF_IoCOntrol) function?

Very grateful,
Graham

Post the code

d

debt from my phone


From: xxxxx@greyboxconcepts.com.au
Sent: 10/15/2011 4:55 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Creating and using an IRP internally within a driver

Thanks for your replies! What I’m now doing is the following:

http://pastebin.com/xAKBYuTi

Sadly I get a BSOD (http://i.imgur.com/Uo0iu.png) when I try to create the IRP. Commenting it out makes it run fine. Am I missing something?

Have I got the right idea with sending the IRP and deviceobject to my IRP_MJ_DEVICE_CONTROL (NPF_IoCOntrol) function?

Very grateful,
Graham


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

I’m modifying winpcap so there’s quite a lot of code… But here’s the current file: http://pastebin.com/M4fvQEJ0

Post the snippet where you are creating the irp

d

debt from my phone


From: xxxxx@greyboxconcepts.com.au
Sent: 10/15/2011 5:44 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Creating and using an IRP internally within a driver

I’m modifying winpcap so there’s quite a lot of code… But here’s the current file: http://pastebin.com/M4fvQEJ0


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Here: http://pastebin.com/xAKBYuTi
Or below:

UINT i = 0;  
PIRP Irp = NULL;  
ULONG Offset = 0;  
PIO_STACK_LOCATION IrpSp = NULL;  
LARGE_INTEGER StartingOffset;  
PKEVENT Event = NULL;  
CHAR packetBuffer[100];  
BOOLEAN BytesTransfered = FALSE;  
PDEVICE_OBJECT CurrentDeviceObject;  
ULONG IoControlCode = BIOCSENDPACKETSNOSYNC; // #define BIOCSENDPACKETSNOSYNC 9032  
  
...  
  
DriverObject-\>MajorFunction[IRP_MJ_DEVICE_CONTROL] = NPF_IoControl;  
  
...  
  
// CurrentDeviceObject gets set here  
  
...  
  
StartingOffset.QuadPart = (LONGLONG) Offset;  
  
/\* Supposing to be on ethernet, set mac destination to 1:1:1:1:1:1 \*/  
packetBuffer[0]=1;  
packetBuffer[1]=1;  
packetBuffer[2]=1;  
packetBuffer[3]=1;  
packetBuffer[4]=1;  
packetBuffer[5]=1;  
  
/\* set mac source to 2:2:2:2:2:2 \*/  
packetBuffer[6]=2;  
packetBuffer[7]=2;  
packetBuffer[8]=2;  
packetBuffer[9]=2;  
packetBuffer[10]=2;  
packetBuffer[11]=2;  
  
packetBuffer[12] = 'H';  
packetBuffer[13] = 'E';  
packetBuffer[14] = 'L';  
packetBuffer[15] = 'L';  
packetBuffer[16] = 'O';  
  
/\* Fill the rest of the packet \*/  
for(i=17;i\<100;i++) {  
  
packetBuffer[i]= (u_char)i;  
}  
  
/\*  
 PIRP IoBuildDeviceIoControlRequest(  
 __in ULONG IoControlCode,  
 __in PDEVICE_OBJECT DeviceObject,  
 __in_opt PVOID InputBuffer,  
 __in ULONG InputBufferLength,  
 __out_opt PVOID OutputBuffer,  
 __in ULONG OutputBufferLength,  
 __in BOOLEAN InternalDeviceIoControl,  
 __in PKEVENT Event,  
 __out PIO_STATUS_BLOCK IoStatusBlock  
 );  
\*/  
  
Irp = IoBuildDeviceIoControlRequest (  
IoControlCode,  
CurrentDeviceObject,  
packetBuffer,  
100,  
NULL,  
0,  
BytesTransfered,  
Event,  
NULL  
);  
  
if (!Irp) {  
  
TRACE_MESSAGE(PACKET_DEBUG_INIT,"Failed to create IRP!");  
  
} else {  
  
IrpSp = IoGetCurrentIrpStackLocation(Irp);  
  
TRACE_MESSAGE3(PACKET_DEBUG_LOUD,  
 "Function code is %08lx Input size=%08lx Output size %08lx",  
 IrpSp-\>Parameters.DeviceIoControl.IoControlCode,  
 IrpSp-\>Parameters.DeviceIoControl.InputBufferLength,  
 IrpSp-\>Parameters.DeviceIoControl.OutputBufferLength);  
  
// Send the IRP and deviceobject to our IRP_MJ_DEVICE_CONTROL function  
 // NPF_IoControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);  
}  

Thanks

wrote in message news:xxxxx@ntdev…
> I am writing a driver which currently handles IRPs send from userland.
>
> My question is: is there any way to construct IRPs inside the driver and
> pass them internally to the functions currently handling userland IRPs?
>
> I’ve seen information about creating IRPs and sending them to other
> drivers, but I need to pass them internally.
>
> Greatly appreciate any help.
>
> Regards,
> Graham

[Replied in the MSDN WDK forum]

– pa

The irp returned by IoBuildDeviceIoControlRequest does not have a valid current irp stack location, you nerd to either

A) call IoSetNextIrpStackLocation and then your current code

Or

B) get next the stack location when formatting and then call IoCallDriver instead of calling NPF_IoControl directly

d

debt from my phone


From: xxxxx@greyboxconcepts.com.au
Sent: 10/15/2011 7:20 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Creating and using an IRP internally within a driver

IoBuildDeviceIoControlRequest function builds a threaded IRP.

BOOLEAN InternalDeviceIoControl specifies whether the IRP is IRP_MJ_INTERNAL_DEVICE_CONTROL, in which case the control code is driver-specific, or IRP_MJ_DEVICE_CONTROL, in which case you MUST use an appropriate macro to define the IOCTL code. The actual method by which the contents of the InputBuffer and OutputBuffer parameters are stored in the IRP depends on the TransferType value for the IOCTL.

Also, you can’t call this function from an arbitrary thread context.

Also, IoStatusBlock pointer is NOT optional.

Am I on the right track here? I’m now getting IRQL_NOT_LESS_OR_EQUAL: http://i.imgur.com/AHPOx.png

Code: http://pastebin.com/Ryc4yDnt or below:

NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{

UINT i = 0;
CHAR packetBuffer[100];
ULONG IoctlControlCode = BIOCSENDPACKETSNOSYNC;
PDEVICE_OBJECT TopOfDeviceStack = NULL;
PVOID OutputBuffer = NULL;
ULONG OutputBufferLength = 0;

for(i=0;i<100;i++) {

packetBuffer[i]= (u_char)i;
}

TopOfDeviceStack = IoGetAttachedDeviceReference(DriverObject->DeviceObject);

/*
NTSTATUS
MakeSynchronousIoctl (
IN PDEVICE_OBJECT TopOfDeviceStack,
IN ULONG IoctlControlCode,
PVOID InputBuffer,
ULONG InputBufferLength,
PVOID OutputBuffer,
ULONG OutputBufferLength
);
*/
MakeSynchronousIoctl (
TopOfDeviceStack,
IoctlControlCode,
&packetBuffer,
100,
OutputBuffer,
OutputBufferLength
);

ObDereferenceObject(TopOfDeviceStack);

}

NTSTATUS
MakeSynchronousIoctl (
IN PDEVICE_OBJECT TopOfDeviceStack,
IN ULONG IoctlControlCode,
PVOID InputBuffer,
ULONG InputBufferLength,
PVOID OutputBuffer,
ULONG OutputBufferLength
)
/*++

Arguments:

TopOfDeviceStack - ??

IoctlControlCode - Value of the IOCTL request

InputBuffer - Buffer to be sent to the TopOfDeviceStack

InputBufferLength - Size of buffer to be sent to the TopOfDeviceStack

OutputBuffer - Buffer for received data from the TopOfDeviceStack

OutputBufferLength - Size of receive buffer from the TopOfDeviceStack

Return Value:

NT status code

–*/
{
KEVENT event;
PIRP irp;
IO_STATUS_BLOCK ioStatus;
NTSTATUS status;

//
// Creating Device control IRP and send it to the another
// driver without setting a completion routine.
//

KeInitializeEvent(&event, NotificationEvent, FALSE);

irp = IoBuildDeviceIoControlRequest (
IoctlControlCode,
TopOfDeviceStack,
InputBuffer,
InputBufferLength,
OutputBuffer,
OutputBufferLength,
FALSE, // External
&event,
&ioStatus);

if (NULL == irp) {
return STATUS_INSUFFICIENT_RESOURCES;
}

status = IoCallDriver(TopOfDeviceStack, irp);

if (status == STATUS_PENDING) {
//
// You must wait here for the IRP to be completed because:
// 1) The IoBuildDeviceIoControlRequest associates the IRP with the
// thread and if the thread exits for any reason, it would cause the IRP
// to be canceled.
// 2) The Event and IoStatus block memory is from the stack and we
// cannot go out of scope.
// This event will be signaled by the I/O manager when the
// IRP is completed.
//
status = KeWaitForSingleObject(
&event,
Executive, // wait reason
KernelMode, // To prevent stack from being paged out.
FALSE, // You are not alertable
NULL); // No time out !!!

status = ioStatus.Status;
}

return status;
}

Very much appreciated.

How do you define the IOCTL?

Like this:
#define BIOCSENDPACKETSNOSYNC 9032

Use CTL_CODE to define your ioctl, not a pure constant, http://msdn.microsoft.com/en-us/library/ms902086.aspx

d

debt from my phone


From: xxxxx@greyboxconcepts.com.au
Sent: 10/16/2011 10:14 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Creating and using an IRP internally within a driver

Like this:
#define BIOCSENDPACKETSNOSYNC 9032


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Defining with

#define BIOCSENDPACKETSNOSYNC CTL_CODE(FILE_DEVICE_UNKNOWN, 9032, METHOD_BUFFERED, FILE_ANY_ACCESS)

still gives me a (different) BSOD: http://i.imgur.com/EoFHx.png

!analyze -v

d

debt from my phone


From: xxxxx@greyboxconcepts.com.au
Sent: 10/17/2011 2:47 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Creating and using an IRP internally within a driver

Defining with

#define BIOCSENDPACKETSNOSYNC CTL_CODE(FILE_DEVICE_UNKNOWN, 9032, METHOD_BUFFERED, FILE_ANY_ACCESS)

still gives me a (different) BSOD: http://i.imgur.com/EoFHx.png


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer