RE: [ntfsd] RE: using STATUS_MORE_PROCESSING_REQUIRED: am I using it
correctly??Yes. This is correct.
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Smith, Joel
Sent: Tuesday, August 01, 2000 12:30 PM
To: File Systems Developers
Subject: [ntfsd] RE: using STATUS_MORE_PROCESSING_REQUIRED: am I usin g it
correctly??
Ah yes, I see what you’re saying. I was thinking I shouldn’t need to
return pending (because I am forcing the irp to be synchronous, after all),
but I ran into a bug where NT4 NTFS actually did return pending, I didn’t,
and KABOOM! The reason, as I now see, was that I was marking the irp
pending in completion and returning a non -pending return code (not that I
wasn’t returning pending). Here is what I now think the code should look
like:
NTSTATUS Create(PDEVICE_OBJECT pDev, PIRP pIrp)
NTSTATUS ntRet;
PDEVICE_OBJECT pNextDevice;
KEVENT event;
//event used to make call synchronous even if the fsd pends the
operation
KeInitializeEvent(&event, NotificationEvent, FALSE);
//get the deviced we are attached to from the device extension
pNextDevice =
((PDEVICE_EXTENSION)(pDev->DeviceExtension))->NextDriverDeviceObject;
IoCopyCurrentIrpStackLocationToNext(pIrp);
//set a completion routine
IoSetCompletionRoutine(pIrp,
CreateComplete,
&event,
TRUE,
TRUE,
TRUE);
//pass the irp down
ntRet = IoCallDriver(pNextDevice, pIrp);
if (ntRet == STATUS_PENDING)
//wait for the event that is signalled in our completion
KeWaitForSingleObject(&event,
Executive,
KernelMode,
FALSE,
NULL);
//get the real success code - we will not need to return
STATUS_PENDING
//because we are forcing the thread to block, after all
ntRet = pIrp->IoStatus.Status;
}
//if the file was opened
if (NT_SUCCESS(ntRet))
//do some stuff that I didn’t want to do in the completion
routine
}
//we are done with the irp and ready to complete the request.
IoCompleteRequest(pIrp, IO_DISK_INCREMENT);
//don’t worry about returning STATUS_PENDING
return ntRet;
}
NTSTATUS CreateComplete(PDEVICE_OBJECT pDev, PIRP pIrp, PKEVENT pContext)
//alert the mainline thread that the io was completed
KeSetEvent((PKEVENT)pContext, IO_NO_INCREMENT, FALSE);
//we need to hold onto this irp for whatever reason
return (STATUS_MORE_PROCESSING_REQUIRED);
}
-----Original Message-----
From: Pavel Hrdina [mailto:xxxxx@sodatsw.cz]
Sent: Tuesday, August 01, 2000 3:04 PM
To: File Systems Developers
Subject: [ntfsd] RE: using STATUS_MORE_PROCESSING_REQUIRED: am I using it
correctly??
Dear Joel !
Also you do not need (and you can’t do that) to mark the IRP pending
in your completion routine. This is because you are blocking the
requesting
thread and the processing continues after the lover level driver calls
IoCompleteRequest. But this implies you’re always processing this
request synchronously - and thus you’re “eating” the IRP pending flag
below you.
In Create dispatch routine you have to always return value different
from STATUS_PENDING. Thus the last line should look like this:
return ntRet;
instead of your:
return pIrp->PendingReturned ? STATUS_PENDING : ntRet;
Paul
-----Pùvodní zpráva-----
> Od: Smith, Joel [SMTP:xxxxx@ntpsoftware.com]
> Odesláno: 31. èervence 2000 22:24
> Komu: File Systems Developers
> Pøedmìt: [ntfsd] using STATUS_MORE_PROCESSING_REQUIRED: am I using
> it correctly??
>
> Hello,
> I’ve just want to be sure I am using
> STATUS_MORE_PROCESSING_REQUIRED correctly. My code seems to work fine
> (code sample is pased below), but I’m nervous because of a footnote in
> ‘File System Internals’ (page 165). The footnote contains these
> sentences:
>
> “The problem, through, is that there is a lot of post processing
> required on that IRP that will have been abrubtly interrupted due to you
> returning such a status code from your completion routine. You driver
> will then have to device a method whereby such postprocessing can be
> resumed later; this is not a trivial task.”
>
> Well, just calling IoCompleteRequest on the irp certainly seems
> trivial, so I am wondering if I am handling this correctly or are there
> more steps I should be doing (note that everything seems to work just
> fine). Aside from Nagar’s book, there isn’t much documentation on how
to
> handle STATUS_MORE_PROCESSING_REQUIRED. Here is some code, with all of
> the irrelevant domain specific stuff stripped out. Am I doing this
right?
>
> Thanks,
> Joel
>
>
> NTSTATUS Create(PDEVICE_OBJECT pDev, PIRP pIrp)
>
NTSTATUS ntRet;
> PDEVICE_OBJECT pNextDevice;
> KEVENT event;
>
> //event used to make call synchronous even if the fsd pends the
> operation
> KeInitializeEvent(&event, NotificationEvent, FALSE);
>
> //get the deviced we are attached to from the device extension
> pNextDevice =
> ((PDEVICE_EXTENSION)(pDev->DeviceExtension))->NextDriverDeviceObject;
>
> IoCopyCurrentIrpStackLocationToNext(pIrp);
>
> //set a completion routine
> IoSetCompletionRoutine(pIrp,
> CreateComplete,
> &event,
> TRUE,
> TRUE,
> TRUE);
>
> //pass the irp down
> ntRet = IoCallDriver(pNextDevice, pIrp);
>
> if (ntRet == STATUS_PENDING)
>
//wait for the event that is signalled in our completion
> KeWaitForSingleObject(&event,
> Executive,
> KernelMode,
> FALSE,
> NULL);
>
> //get the real success code
> ntRet = pIrp->IoStatus.Status;
> }
>
> //if the file was opened
> if (NT_SUCCESS(ntRet))
>
//do some stuff that I didn’t want to do in the
completion
> routine
> }
>
> //we are done with the irp and ready to complete the request.
> IoCompleteRequest(pIrp, IO_DISK_INCREMENT);
>
> //done - should I always mark pending and return pending to
> prevent the inherently synchronous io
> //problem Nagar talks about?
> return pIrp->PendingReturned ? STATUS_PENDING : ntRet;
> }
>
> NTSTATUS CreateComplete(PDEVICE_OBJECT pDev, PIRP pIrp, PKEVENT
pContext)
>
//propogate the pending returned flag
> if (pIrp->PendingReturned)
>
IoMarkIrpPending(pIrp);
> }
>
> //alert the mainline thread that the io was completed
> KeSetEvent((PKEVENT)pContext, IO_NO_INCREMENT, FALSE);
>
> //we need to hold onto this irp for whatever reason
> return (STATUS_MORE_PROCESSING_REQUIRED);
> }
>
>
>
>
You are currently subscribed to ntfsd as: xxxxx@ntpsoftware.com
To unsubscribe send a blank email to $subst(‘Email.Unsub’)