Problem manually creating IRP to submit from one driver to another

Hi,

I’m trying to send a simple IOCTL to a driver from another driver, by manually creating an IRP and submitting it (Is there another way to do this from within a driver?). Unfortunately I am getting a BugCheck 7E, (exception c0000005, indicating a memory access violation), when the driver that is being called calls the IoComplete request function.

When I test sending the IOCTL with a user mode application, using the DeviceIoControl function, it executes without any problems.

This is the code I am using, is there any obvious problems/ommisions? Am I forgetting to initialise some part of the IRP or something? I’ve been stuck on this for ages, please help!

ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

status = IoGetDeviceObjectPointer(
&usDeviceName,
FILE_READ_DATA,
&m_pMyFileObject,
&m_pMyDeviceObject
);

if(!NT_SUCCESS(status)){
return STATUS_ERROR;
}

pIrp = IoAllocateIrp(m_pMyDeviceObject->StackSize, FALSE);

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

{
PIO_STACK_LOCATION _IRPSP;
pIrp->AssociatedIrp.SystemBuffer = pBuffer;
IoSetCompletionRoutine(pIrp, NULL, NULL, FALSE, FALSE, FALSE);
_IRPSP = IoGetNextIrpStackLocation(pIrp);
_IRPSP->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
_IRPSP->MinorFunction = 0;
_IRPSP->DeviceObject = m_pMyDeviceObject;
_IRPSP->FileObject = m_pMyFileObject;
_IRPSP->Parameters.DeviceIoControl.IoControlCode = IOCTL_DO_SOMETHING;
_IRPSP->Parameters.DeviceIoControl.InputBufferLength = sizeof(BUFFER_TYPE);
_IRPSP->Parameters.DeviceIoControl.OutputBufferLength = 0;
_IRPSP->Parameters.DeviceIoControl.Type3InputBuffer = 0;
}

//Go ahead and submit the request
status = IoCallDriver(m_pMyDeviceObject, pIrp);

Thanks,
David

Oh, and one other weird thing I observe about this problem.

After the calling driver calls IoGetDeviceObjectPointer, the driver being called receives an IRP_MJ_CREATE, followed immediately by an IRP_MJ_CLEANUP. Only later does it receive the IRP_MJ_INTERNAL_DEVICE_CONTROL after the calling driver calls IoCallDriver. During processing of this IRP, the called driver crashes while calling the IoCompleteRequest function.

In the user mode application, I notice the called driver receives the IRPs in the different order IRP_MJ_CREATE, IRP_MJ_INTERNAL_DEVICE_CONTROL, IRP_MJ_CLEANUP, IRP_MJ_CLOSE.

Thanks
----- Original Message -----
From: David West
To: Windows System Software Devs Interest List
Sent: Thursday, October 09, 2003 4:40 PM
Subject: [ntdev] Problem manually creating IRP to submit from one driver to another

Hi,

I’m trying to send a simple IOCTL to a driver from another driver, by manually creating an IRP and submitting it (Is there another way to do this from within a driver?). Unfortunately I am getting a BugCheck 7E, (exception c0000005, indicating a memory access violation), when the driver that is being called calls the IoComplete request function.

When I test sending the IOCTL with a user mode application, using the DeviceIoControl function, it executes without any problems.

This is the code I am using, is there any obvious problems/ommisions? Am I forgetting to initialise some part of the IRP or something? I’ve been stuck on this for ages, please help!

ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

status = IoGetDeviceObjectPointer(
&usDeviceName,
FILE_READ_DATA,
&m_pMyFileObject,
&m_pMyDeviceObject
);

if(!NT_SUCCESS(status)){
return STATUS_ERROR;
}

pIrp = IoAllocateIrp(m_pMyDeviceObject->StackSize, FALSE);

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

{
PIO_STACK_LOCATION _IRPSP;
pIrp->AssociatedIrp.SystemBuffer = pBuffer;
IoSetCompletionRoutine(pIrp, NULL, NULL, FALSE, FALSE, FALSE);
_IRPSP = IoGetNextIrpStackLocation(pIrp);
_IRPSP->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
_IRPSP->MinorFunction = 0;
_IRPSP->DeviceObject = m_pMyDeviceObject;
_IRPSP->FileObject = m_pMyFileObject;
_IRPSP->Parameters.DeviceIoControl.IoControlCode = IOCTL_DO_SOMETHING;
_IRPSP->Parameters.DeviceIoControl.InputBufferLength = sizeof(BUFFER_TYPE);
_IRPSP->Parameters.DeviceIoControl.OutputBufferLength = 0;
_IRPSP->Parameters.DeviceIoControl.Type3InputBuffer = 0;
}

//Go ahead and submit the request
status = IoCallDriver(m_pMyDeviceObject, pIrp);

Thanks,
David

Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@tcd.ie
To unsubscribe send a blank email to xxxxx@lists.osr.com

Without having tried this sort of thing myself, I would guess the
“weird” thing is due to IoGetDeviceObjectPointer() doing, in effect,
open on the called device object.

As for your real problem, I suggest looking at the DDK, where there are
lots of examples of IoGetDeviceObjectPointer. Then I would look at an
IOCTL Irp produced by a user-space call and an Irp that you build.

David West wrote:

Oh, and one other weird thing I observe about this problem. After the
calling driver calls IoGetDeviceObjectPointer, the driver being called
receives an IRP_MJ_CREATE, followed immediately by an IRP_MJ_CLEANUP.
Only later does it receive the IRP_MJ_INTERNAL_DEVICE_CONTROL after
the calling driver calls IoCallDriver. During processing of this IRP,
the called driver crashes while calling the IoCompleteRequest
function. In the user mode application, I notice the called driver
receives the IRPs in the different order IRP_MJ_CREATE,
IRP_MJ_INTERNAL_DEVICE_CONTROL, IRP_MJ_CLEANUP, IRP_MJ_CLOSE.


If replying by e-mail, please remove “nospam.” from the address.

James Antognini
Windows DDK MVP

  1. Allocate 1 more stack location in IoAllocateIrp.
  2. Just after IoAllocateIrp, call IoSetNextIrpStackLocation.
  3. Then set IoGetCurrentIrpStackLocation(Irp)->DeviceObject to your device object.

This will lead to your completion routine called with non-NULL device object.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

----- Original Message -----
From: David West
To: Windows System Software Devs Interest List
Sent: Thursday, October 09, 2003 7:40 PM
Subject: [ntdev] Problem manually creating IRP to submit from one driver to another

Hi,

I’m trying to send a simple IOCTL to a driver from another driver, by manually creating an IRP and submitting it (Is there another way to do this from within a driver?). Unfortunately I am getting a BugCheck 7E, (exception c0000005, indicating a memory access violation), when the driver that is being called calls the IoComplete request function.

When I test sending the IOCTL with a user mode application, using the DeviceIoControl function, it executes without any problems.

This is the code I am using, is there any obvious problems/ommisions? Am I forgetting to initialise some part of the IRP or something? I’ve been stuck on this for ages, please help!

ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

status = IoGetDeviceObjectPointer(
&usDeviceName,
FILE_READ_DATA,
&m_pMyFileObject,
&m_pMyDeviceObject
);

if(!NT_SUCCESS(status)){
return STATUS_ERROR;
}

pIrp = IoAllocateIrp(m_pMyDeviceObject->StackSize, FALSE);

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

{
PIO_STACK_LOCATION _IRPSP;
pIrp->AssociatedIrp.SystemBuffer = pBuffer;
IoSetCompletionRoutine(pIrp, NULL, NULL, FALSE, FALSE, FALSE);
_IRPSP = IoGetNextIrpStackLocation(pIrp);
_IRPSP->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
_IRPSP->MinorFunction = 0;
_IRPSP->DeviceObject = m_pMyDeviceObject;
_IRPSP->FileObject = m_pMyFileObject;
_IRPSP->Parameters.DeviceIoControl.IoControlCode = IOCTL_DO_SOMETHING;
_IRPSP->Parameters.DeviceIoControl.InputBufferLength = sizeof(BUFFER_TYPE);
_IRPSP->Parameters.DeviceIoControl.OutputBufferLength = 0;
_IRPSP->Parameters.DeviceIoControl.Type3InputBuffer = 0;
}

//Go ahead and submit the request
status = IoCallDriver(m_pMyDeviceObject, pIrp);

Thanks,
David

Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@storagecraft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

If you build an IRP using IoAllocateIrp you MUST set a completion routine that returns STATUS_MORE_PROCESSING_REQUIRED to avoid processing the IRP completion by IoManager. It is the respnsobility of the driver that allocated the IRP to free it if you don’t want to reuse the IRP. Usually IoFreeIrp is called from the completion routine.

Alexei.
“David West” <david.west> wrote in message news:xxxxx@ntdev…
Hi,

I’m trying to send a simple IOCTL to a driver from another driver, by manually creating an IRP and submitting it (Is there another way to do this from within a driver?). Unfortunately I am getting a BugCheck 7E, (exception c0000005, indicating a memory access violation), when the driver that is being called calls the IoComplete request function.

When I test sending the IOCTL with a user mode application, using the DeviceIoControl function, it executes without any problems.

This is the code I am using, is there any obvious problems/ommisions? Am I forgetting to initialise some part of the IRP or something? I’ve been stuck on this for ages, please help!

ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

status = IoGetDeviceObjectPointer(
&usDeviceName,
FILE_READ_DATA,
&m_pMyFileObject,
&m_pMyDeviceObject
);

if(!NT_SUCCESS(status)){
return STATUS_ERROR;
}

pIrp = IoAllocateIrp(m_pMyDeviceObject->StackSize, FALSE);

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

{
PIO_STACK_LOCATION _IRPSP;
pIrp->AssociatedIrp.SystemBuffer = pBuffer;
IoSetCompletionRoutine(pIrp, NULL, NULL, FALSE, FALSE, FALSE);
_IRPSP = IoGetNextIrpStackLocation(pIrp);
_IRPSP->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
_IRPSP->MinorFunction = 0;
_IRPSP->DeviceObject = m_pMyDeviceObject;
_IRPSP->FileObject = m_pMyFileObject;
_IRPSP->Parameters.DeviceIoControl.IoControlCode = IOCTL_DO_SOMETHING;
_IRPSP->Parameters.DeviceIoControl.InputBufferLength = sizeof(BUFFER_TYPE);
_IRPSP->Parameters.DeviceIoControl.OutputBufferLength = 0;
_IRPSP->Parameters.DeviceIoControl.Type3InputBuffer = 0;
}

//Go ahead and submit the request
status = IoCallDriver(m_pMyDeviceObject, pIrp);

Thanks,
David</david.west>