return code after calling FltDoCompletionProcessingWhenSafe

I’m writing a mini-filter that needs to grab the name of a file during a
rename operation. Since the PostOp could be called at IPC_DISPATCH I’m
using FltDoCompletionProcessingWhenSafe to get to a safe IRQL so I can get
the filename.

My question is, do I just return FLT_POSTOP_FINISHED_PROCESSING after having
called FltDoCompletionProcessingWhenSafe?

Please see the example code below:

FLT_POSTOP_CALLBACK_STATUS
AppPostOperationCallback (
IN OUT PFLT_CALLBACK_DATA Data,
IN PCFLT_RELATED_OBJECTS FltObjects,
IN PVOID CompletionContext,
IN FLT_POST_OPERATION_FLAGS Flags
)
{
switch(Data->Iopb->MajorFunction)
{
case IRP_MJ_SET_INFORMATION:
{
if(FileRenameInformation ==
Data->Iopb->Parameters.SetFileInformation.FileInformationClass)
{
//we need to make some calls that aren’t safe at
IRQL DISPATCH_LEVEL, and we might be at that level right now, so defer if
needed
if(KeGetCurrentIrql() >= DISPATCH_LEVEL)
{
FLT_POSTOP_CALLBACK_STATUS stat = 0;
FltDoCompletionProcessingWhenSafe(Data,
FltObjects, CompletionContext, Flags, AppPostOperationCallback, &stat);
//it either worked or it didn’t – can’t do
much about it either way, so ignoring return codes
}
else
{
//OK to proceed because now at APC_LEVEL or
lower
Call FltGetDestinationFileNameInformation,
etc …
}
}
}
break;
}

return FLT_POSTOP_FINISHED_PROCESSING; //is this correct even after
having called FltDoCompletionProcessingWhenSafe?
}

Thanks for any help.

Doug

You’ll want to return the RetPostOperationStatus that
FltDoCompletionProcessingWhenSafe returns to you. If your callback runs
immediately, it’s the value returned by your callback. If the callback
is run later at a safe level it’s MORE_PROCESSING_REQUIRED. If the op
can’t be posted, it’s FINISHED_PROCESSING and FltDCPWS returns FALSE.

I’ll agree that the use of this function is a bit confusing.

Your code should probably look something like this:

if (!FltDCPWS (Data, FltObjects, CompletionContext, Flags, callback,
&post_op_status)) {
Data->IoStatus.Status = STATUS_OH_SHIT;
}
return post_op_status;

The beauty of it is that the same callback handles both cases (and you
don’t have to check IRQL yourself).

~Eric

Hi!

Why not simply returning “FLT_PREOP_SYNCHRONIZE” in PreOp? This guarantees
your PostOp to be called at passive level.

“Doug” wrote news:xxxxx@ntfsd…
> I’m writing a mini-filter that needs to grab the name of a file during a
> rename operation. Since the PostOp could be called at IPC_DISPATCH I’m
> using FltDoCompletionProcessingWhenSafe to get to a safe IRQL so I can get
> the filename.
>
> My question is, do I just return FLT_POSTOP_FINISHED_PROCESSING after
> having
> called FltDoCompletionProcessingWhenSafe?
>
> Please see the example code below:
>
> FLT_POSTOP_CALLBACK_STATUS
> AppPostOperationCallback (
> IN OUT PFLT_CALLBACK_DATA Data,
> IN PCFLT_RELATED_OBJECTS FltObjects,
> IN PVOID CompletionContext,
> IN FLT_POST_OPERATION_FLAGS Flags
> )
> {
> switch(Data->Iopb->MajorFunction)
> {
> case IRP_MJ_SET_INFORMATION:
> {
> if(FileRenameInformation ==
> Data->Iopb->Parameters.SetFileInformation.FileInformationClass)
> {
> //we need to make some calls that aren’t safe at
> IRQL DISPATCH_LEVEL, and we might be at that level right now, so defer if
> needed
> if(KeGetCurrentIrql() >= DISPATCH_LEVEL)
> {
> FLT_POSTOP_CALLBACK_STATUS stat = 0;
> FltDoCompletionProcessingWhenSafe(Data,
> FltObjects, CompletionContext, Flags, AppPostOperationCallback, &stat);
> //it either worked or it didn’t – can’t do
> much about it either way, so ignoring return codes
> }
> else
> {
> //OK to proceed because now at APC_LEVEL or
> lower
> Call FltGetDestinationFileNameInformation,
> etc …
> }
> }
> }
> break;
> }
>
> return FLT_POSTOP_FINISHED_PROCESSING; //is this correct even after
> having called FltDoCompletionProcessingWhenSafe?
> }
>
> Thanks for any help.
>
> Doug
>
>
>

Thanks for the tip Eric.

In my case, I’m calling FltDoCompletionProcessingWhenSafe with the exact
same callback function, so I’m checking the IRQL myself to avoid a circular
loop. Or so I thought – my VM just crashed and VMWare reported that the
kernel ran out of stack space (and the blue screen showed an error with the
wrong IRQL level).

I don’t understand how that is possible, unless
FltDoCompletionProcessingWhenSafe called the callback and was still at >=
DISPATCH_LEVEL.

FLT_POSTOP_CALLBACK_STATUS
AppPostOperationCallback ( <----- this is the same function I’m passing
to FltDoCompletionProcessingWhenSafe
IN OUT PFLT_CALLBACK_DATA Data,
IN PCFLT_RELATED_OBJECTS FltObjects,
IN PVOID CompletionContext,
IN FLT_POST_OPERATION_FLAGS Flags
)
{
switch(Data->Iopb->MajorFunction)
{
case IRP_MJ_SET_INFORMATION:
{
if(FileRenameInformation ==
Data->Iopb->Parameters.SetFileInformation.FileInformationClass)
{
//we need to make some calls that aren’t safe at
IRQL DISPATCH_LEVEL, and we might be at that level right now, so defer if
needed
if(KeGetCurrentIrql() >= DISPATCH_LEVEL)
{
FLT_POSTOP_CALLBACK_STATUS stat = 0;
FltDoCompletionProcessingWhenSafe(Data,
FltObjects, CompletionContext, Flags, AppPostOperationCallback, &stat);
//it either worked or it didn’t – can’t do
much about it either way, so ignoring return codes
}
else
{
//OK to proceed because now at APC_LEVEL or
lower
Call FltGetDestinationFileNameInformation,
etc …
}
}
}
break;
}

return FLT_POSTOP_FINISHED_PROCESSING; //is this correct even after
having called FltDoCompletionProcessingWhenSafe?
}

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Eric Diven
Sent: Friday, August 08, 2008 9:47 AM
To: Windows File Systems Devs Interest List
Subject: RE: [ntfsd] return code after calling
FltDoCompletionProcessingWhenSafe

You’ll want to return the RetPostOperationStatus that
FltDoCompletionProcessingWhenSafe returns to you. If your callback runs
immediately, it’s the value returned by your callback. If the callback
is run later at a safe level it’s MORE_PROCESSING_REQUIRED. If the op
can’t be posted, it’s FINISHED_PROCESSING and FltDCPWS returns FALSE.

I’ll agree that the use of this function is a bit confusing.

Your code should probably look something like this:

if (!FltDCPWS (Data, FltObjects, CompletionContext, Flags, callback,
&post_op_status)) {
Data->IoStatus.Status = STATUS_OH_SHIT;
}
return post_op_status;

The beauty of it is that the same callback handles both cases (and you
don’t have to check IRQL yourself).

~Eric


NTFSD is sponsored by OSR

For our schedule debugging and file system seminars
(including our new fs mini-filter seminar) visit:
http://www.osr.com/seminars

You are currently subscribed to ntfsd as: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com

I might need to do that. I was hoping to do it the other way because I
don’t even have a PreOp callback so far, but I guess it isn’t that bad to
add one for this specific case.

Doug

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Frank
Sent: Friday, August 08, 2008 12:41 PM
To: Windows File Systems Devs Interest List
Subject: Re:[ntfsd] return code after calling
FltDoCompletionProcessingWhenSafe

Hi!

Why not simply returning “FLT_PREOP_SYNCHRONIZE” in PreOp? This guarantees
your PostOp to be called at passive level.

“Doug” wrote news:xxxxx@ntfsd…
> I’m writing a mini-filter that needs to grab the name of a file during a
> rename operation. Since the PostOp could be called at IPC_DISPATCH I’m
> using FltDoCompletionProcessingWhenSafe to get to a safe IRQL so I can get
> the filename.
>
> My question is, do I just return FLT_POSTOP_FINISHED_PROCESSING after
> having
> called FltDoCompletionProcessingWhenSafe?
>
> Please see the example code below:
>
> FLT_POSTOP_CALLBACK_STATUS
> AppPostOperationCallback (
> IN OUT PFLT_CALLBACK_DATA Data,
> IN PCFLT_RELATED_OBJECTS FltObjects,
> IN PVOID CompletionContext,
> IN FLT_POST_OPERATION_FLAGS Flags
> )
> {
> switch(Data->Iopb->MajorFunction)
> {
> case IRP_MJ_SET_INFORMATION:
> {
> if(FileRenameInformation ==
> Data->Iopb->Parameters.SetFileInformation.FileInformationClass)
> {
> //we need to make some calls that aren’t safe at
> IRQL DISPATCH_LEVEL, and we might be at that level right now, so defer if
> needed
> if(KeGetCurrentIrql() >= DISPATCH_LEVEL)
> {
> FLT_POSTOP_CALLBACK_STATUS stat = 0;
> FltDoCompletionProcessingWhenSafe(Data,
> FltObjects, CompletionContext, Flags, AppPostOperationCallback, &stat);
> //it either worked or it didn’t – can’t do
> much about it either way, so ignoring return codes
> }
> else
> {
> //OK to proceed because now at APC_LEVEL or
> lower
> Call FltGetDestinationFileNameInformation,
> etc …
> }
> }
> }
> break;
> }
>
> return FLT_POSTOP_FINISHED_PROCESSING; //is this correct even after
> having called FltDoCompletionProcessingWhenSafe?
> }
>
> Thanks for any help.
>
> Doug
>
>
>


NTFSD is sponsored by OSR

For our schedule debugging and file system seminars
(including our new fs mini-filter seminar) visit:
http://www.osr.com/seminars

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