IoCallDriver is returning status_pending

Hi
I’m writing an encryption /decryption filter driver .
In my IRP_MJ_READ function, In order to write the decrypted data into file, I roll my own Irp and call IoCallDriver(). But IoCallDriver() returns STATUS_PENDING . Can you please tell me where I went wrong?

My Code is
NTSTATUS WriteFile(IN PDEVICE_OBJECT Deviceobject, IN PFILE_OBJECT FileObject,IN ULONG length,IN LARGE_INTEGER ByteOffset,IN PUCHAR Buffer)
{
PIRP WriteIrp = NULL;
PIO_STACK_LOCATION WriteIrpsp = NULL;
IO_STATUS_BLOCK istatusblock;
KEVENT Syncevent;
NTSTATUS status;

istatusblock.Status = STATUS_SUCCESS;
istatusblock.Information = 0;

KeInitializeEvent(&Syncevent,SynchronizationEvent,FALSE);
WriteIrp = IoAllocateIrp(((PFSFILTER_DEVICE_EXTENSION)Deviceobject->DeviceExtension)->AttachedToDeviceObject->StackSize,FALSE);
if(WriteIrp == NULL)
{
DbgPrint(“Irp not created”);
return STATUS_INSUFFICIENT_RESOURCES;
}

WriteIrp ->UserBuffer = Buffer;
WriteIrp ->Tail.Overlay.Thread = PsGetCurrentThread();
WriteIrp->RequestorMode = KernelMode;
WriteIrp ->UserIosb = &istatusblock;
WriteIrp ->UserEvent = &Syncevent;
WriteIrp ->Flags = IRP_WRITE_OPERATION;
WriteIrpsp =IoGetNextIrpStackLocation(WriteIrp);
WriteIrpsp ->MajorFunction = IRP_MJ_WRITE;
WriteIrpsp ->MinorFunction = 0;
WriteIrpsp ->FileObject = FileObject;
IoSetCompletionRoutine(WriteIrp ,WriteCompletionRoutine,&Syncevent,TRUE,TRUE,TRUE);
WriteIrpsp ->Parameters.Write.Length = length;
WriteIrpsp ->Parameters.Write.ByteOffset = ByteOffset;

status= IoCallDriver(((PFSFILTER_DEVICE_EXTENSION)Deviceobject->DeviceExtension)->AttachedToDeviceObject,WriteIrp);
DbgPrint(“ntstatus 0x%x”,status);
if(STATUS_PENDING == status)
{
DbgPrint(“write file pending”);
IoMarkIrpPending(WriteIrp);
KeWaitForSingleObject(&Syncevent,Executive,KernelMode,FALSE,NULL);
}

return istatusblock.Status;

}

NTSTATUS WriteCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp, IN PVOID Context)
{
*Irp->UserIosb = Irp->IoStatus;
KeSetEvent(Irp->UserEvent,0,FALSE);
IoFreeIrp(Irp);

return STATUS_MORE_PROCESSING_REQUIRED;

}

Hi Praneetha,

It’s usual to receive STATUS_PENDING from IoCallDriver. It’s not a sign of error. That means the underlying driver chose to attend your request asynchronously. All that you need to do is waiting the event to be signed as you did.

Additionally, you don’t need to mark the IRP as pending as you did. The underlying driver did so before returning STATUS_PENDING from its dispatch routine. Also, don’t forget checking MDL address before releasing the IRP and release any MDL the underlying driver might set.

Regards,

Fernando Roberto da Silva
DriverEntry Kernel Development
http://www.driverentry.com.br

> Hi

I’m writing an encryption /decryption filter driver .
In my IRP_MJ_READ function, In order to write the decrypted data into
file, I roll my own Irp and call IoCallDriver(). But IoCallDriver()
returns STATUS_PENDING . Can you please tell me where I went wrong?

My Code is
NTSTATUS WriteFile(IN PDEVICE_OBJECT Deviceobject, IN PFILE_OBJECT
FileObject,IN ULONG length,IN LARGE_INTEGER ByteOffset,IN PUCHAR Buffer)
{
PIRP WriteIrp = NULL;
PIO_STACK_LOCATION WriteIrpsp = NULL;
IO_STATUS_BLOCK istatusblock;
KEVENT Syncevent;
NTSTATUS status;

istatusblock.Status = STATUS_SUCCESS;
istatusblock.Information = 0;

KeInitializeEvent(&Syncevent,SynchronizationEvent,FALSE);
WriteIrp =
IoAllocateIrp(((PFSFILTER_DEVICE_EXTENSION)Deviceobject->DeviceExtension)->AttachedToDeviceObject->StackSize,FALSE);
if(WriteIrp == NULL)
{
DbgPrint(“Irp not created”);
return STATUS_INSUFFICIENT_RESOURCES;
}

WriteIrp ->UserBuffer = Buffer;
WriteIrp ->Tail.Overlay.Thread = PsGetCurrentThread();
WriteIrp->RequestorMode = KernelMode;
WriteIrp ->UserIosb = &istatusblock;
WriteIrp ->UserEvent = &Syncevent;
WriteIrp ->Flags = IRP_WRITE_OPERATION;
WriteIrpsp =IoGetNextIrpStackLocation(WriteIrp);
WriteIrpsp ->MajorFunction = IRP_MJ_WRITE;
WriteIrpsp ->MinorFunction = 0;
WriteIrpsp ->FileObject = FileObject;
IoSetCompletionRoutine(WriteIrp
,WriteCompletionRoutine,&Syncevent,TRUE,TRUE,TRUE);
WriteIrpsp ->Parameters.Write.Length = length;
WriteIrpsp ->Parameters.Write.ByteOffset = ByteOffset;

status=
IoCallDriver(((PFSFILTER_DEVICE_EXTENSION)Deviceobject->DeviceExtension)->AttachedToDeviceObject,WriteIrp);
DbgPrint(“ntstatus 0x%x”,status);
if(STATUS_PENDING == status)
{
DbgPrint(“write file pending”);
IoMarkIrpPending(WriteIrp);
KeWaitForSingleObject(&Syncevent,Executive,KernelMode,FALSE,NULL);
}

return istatusblock.Status;

}

NTSTATUS WriteCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp, IN PVOID Context)
{
*Irp->UserIosb = Irp->IoStatus;
KeSetEvent(Irp->UserEvent,0,FALSE);
IoFreeIrp(Irp);

return STATUS_MORE_PROCESSING_REQUIRED;

}

Actually, I would expect it to return STATUS_PENDING. That would mean
that you have to wait for it.

However, I think I spotted a couple serious errors here.

First, you call IoMarkIrpPending after you call IoCallDriver. At the
point where you call IoCallDriver, you have to assume that the Irp no
longer exists. Any assumption that the Irp still exists are unfounded,
and you are flirting with total disaster here. Note that it is te
responsibility of the called driver to call IoMarkIrpPending if it is the
one that pended it (note that in a deep driver stack, whichever driver
pends the request is the one that marks it). By the time you call
IoMarkIrpPending, the IRP may be gone, deleted by the competion routine.

Note the lower levels cannot know that you intend to wait for the
completion; their responsibily ends when the mark the IRP as pending.

But why are you sending it down synchronously? It may look like a simple
solution, but it hangs the calling thread. If the device does not have a
response time measured in (and bounded by) single-digit milliseconds,
this would be a bad design; the caller may be using async I/O and you have
forced synchronous I/O. I see this all the time in people new to
multithreading; they want serialness of execution to be embodied in the
syntax of their code and go to excessive lengths to convert asynchronous
event-driven code into synchronous code. I’d suggest moving whatever
follows the WaiFor to the completion routine. For me, it takes a lot of
justification to defeat the asynchronous I/O model with code like this.
Unless you have a serious reason for converting asynchronous to
sychronous, I’d say you should ditch this code.
joe

NTFSD is sponsored by OSR

For our schedule of debugging and file system 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

It’s peculiar that you call your IRP_MJ_READ handler “WriteFile”. Is this a technique for ensuring job security by obscuring the true function of the driver components? :wink:

My question is why you are writing a legacy filter at all? At this point you should be writing a mini-filter, so you shouldn’t be sending IRPs, for example.

Tony
OSR

HI
I checked by not marking IRP as pending.
But the IOcallDriver is returning STATUS_PENDING…

Read the thread. It’s /supposed/ to return STATUS_PENDING. It means that
some lower driver (perhaps the one you called) has pended the IRP. This
should not be a surprise, you should expect it.
joe

HI
I checked by not marking IRP as pending.
But the IOcallDriver is returning STATUS_PENDING…


NTFSD is sponsored by OSR

For our schedule of debugging and file system 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

yes i know it returns STATUS_PENDING if the low level driver is pending IRP. In my case it is always STATUS_PENDING and after that it is not processing any statements. It is not coming out from stataus_pending

Are you waiting for it to finish?

Tony
OSR

Well, as already mentioned by many others, the first wrong thing here is
calling IoMarkIrpPending() after calling IoCallDriver().

Second, I don’t think you need to or should be touching the irp’s user
event field.

You have a SyncEvent that you defined and you are passing it as the context
to you completion routine.

Use that to wait on after IoCallDriver() and set it in your completion
routine.

On Thu, Jan 10, 2013 at 12:38 PM, Tony Mason wrote:

> Are you waiting for it to finish?
>
> Tony
> OSR
>
>
> —
> NTFSD is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
> For our schedule of debugging and file system 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
>