Minfilter - FLT_PREOP_PENDING

Hey, I am developing my own minfilter but there is something quite unclear about the use of FLT_PREOP_PENDING.
I don’t understand why is this status code needed, because I can always just delay my own response to the Filter Manager. For example if I need that another process will check if I should complete or pass the request I can just return the status only when i get the response from that other process. Why do I need to report for pending? Moreover, this example can also be apply to delaying a Fast I/O request.
What is the advantage of using FLT_PREOP_PENDING instead of just delaying and what are the disadvantages? because I fill like the documentation didnt explained it.
Can someone please clear things up for me?

> What is the advantage of using FLT_PREOP_PENDING instead of

just delaying and what are the disadvantages?

The most important point (for me) is that while you are stalling the thread
it cannot be doing anything else, like sending another IO, or doing
something else. It is the PREOP_PENDING think that allows asynchronous IO
to happen (in Win32 that is Overlapped IO). In general, if you do not
support this and spend a lot of time stalling requests you are going to
clobber performance because a great deal of the system assumes asynchrony.

A secondary point is that (IMO) it makes it easier for you to allow the user
to interrupt processing.

Moreover, this example can also be apply to delaying a Fast I/O request.

You cannot. The “Rules” for fastio are that you pass it on or complete it
quickly or you return FLT_PREOP_DENY_FASTIO and you’ll get the request
back as a pendable operation.

For other examples, I would download the examples, cd into the “filesys”
directory and do a findstr for _PENDING. I find the FAT example compelling,
but it requires knowing enough to be able to change conceptual gears from
IRP/STATUS_PENDING processing to FLT_CALLBACK_DATA/FLT_PREOP_PENDING so you
may want to avoid that.

Firstly, thank you very much for your quick reply.

But something still isn’t clear for me, does the minifilter work on one single thread of execuation and process one IRP/fast I/O and after it finished the minifilter starts to process the next?

Because I thought that each operation is going through all the fs legacy filters/minifilters seperatly, and that way my example work just fine because i can delay as long as i want and minwhile all the other requests will be processed seperatly. I always thought of the minifilter as an event-based mechanism - each request goes through the filters stack.

Just to make things clear so you are saying that the mechanism is like a queue and each IRP or fast I/O needs to wait before the stack of filters is empty and then to pass through all filters, one at a time?

> Because I thought that each operation is going through all the fs legacy

filters/minifilters seperatly,
and that way my example work just fine because i can delay as long as i
want and minwhile all the
other requests will be processed seperatly

You are correct

Just to make things clear so you are saying that the mechanism is like a
queue and each IRP or fast
I/O needs to wait before the stack of filters is empty and then to pass
through all filters, one at a time?

No, I’m not saying that. If 50 threads issue 50 WriteFile requests, you
will see 50 calls all happening at once. Further I am saying that if a
single thread issues 50 IO requests you will see all of them happening at
once - So long as you let them.

Consider this (artificial) user mode code segment:

WriteFile(Handle, &Buffer[0], 1024, &len1, &Overlapped1);
WriteFile(Handle, &Buffer[1024], 1024, &len2, &Overlapped2);
WriteFile(Handle, &Buffer[2048], 1024, &len3, &Overlapped3);
WriteFile(Handle, &Buffer[3072], 1024, &len4, &Overlapped4);
ImportantCalculations();

Without your minifilter, 4 separate writes would be happening at the same
time
and meanwhile the thread could get on with ImportantCalculations().

If you stall the thread waiting for something then neither the subsequent
writes, nor the ImportantCalculations() can happen.

If however you return PENDING, then the subsequent IOs can be started and
the ImportantCalculations() happen. When whatever you are waiting for
happens you can either complete the request, or pass it down or whatever
else you’d like to do, but the important thing is that you haven’t delayed
the thread needlessly.

Whilst the code above is artificial it is by not means unrepresentative in
Windows. You may not have met much code like that before (particularly if
you have been exposed to Unixen) but a great deal of the operating system
functions in this manner.

/Rod

Thanks again Rod!
But the subject i have trouble with about wasn’t about the option of async I/O operation in a single process. what i meant to ask is:

Process 1 - Call WriteFile but doesnt complete
Process 2 - Call WriteFile
In this scenario the minifilter is install, and lets assume that it was poorly written so it is taking 2 seconds to pass the call further (lets assumes it going to sleep for 2 seconds or trying to communicate with a server and there is slow connection.).

Okay, so my question is this: Will the the two calls happen in the same time or will happen one after the other. In the first case each operation has it own stack of minifilters and can delay 2 seconds but meanwhile the other operation is also going thourgh its own stack and waits the 2 seconds together (2 sec in total). In the second case there is only one stack of minifilters, and the operation go one after the other, so in this case it would take 4 seconds in total.
Which case is true?

Also note that all high performance UM application use overlapped IO, IO Completion ports, and or the thread pool in some way. They all want the kernel + driver stack to get the IRP ?under way? as fast as possible ? and tell me when it?s done sometime later

Sent from Mailhttps: for Windows 10

________________________________
From: xxxxx@lists.osr.com on behalf of Rod Widdowson
Sent: Sunday, May 27, 2018 8:57:58 AM
To: Windows File Systems Devs Interest List
Subject: Re:[ntfsd] Minfilter - FLT_PREOP_PENDING

> Because I thought that each operation is going through all the fs legacy
> filters/minifilters seperatly,
> and that way my example work just fine because i can delay as long as i
> want and minwhile all the
> other requests will be processed seperatly

You are correct

> Just to make things clear so you are saying that the mechanism is like a
> queue and each IRP or fast
> I/O needs to wait before the stack of filters is empty and then to pass
> through all filters, one at a time?

No, I’m not saying that. If 50 threads issue 50 WriteFile requests, you
will see 50 calls all happening at once. Further I am saying that if a
single thread issues 50 IO requests you will see all of them happening at
once - So long as you let them.

Consider this (artificial) user mode code segment:

WriteFile(Handle, &Buffer[0], 1024, &len1, &Overlapped1);
WriteFile(Handle, &Buffer[1024], 1024, &len2, &Overlapped2);
WriteFile(Handle, &Buffer[2048], 1024, &len3, &Overlapped3);
WriteFile(Handle, &Buffer[3072], 1024, &len4, &Overlapped4);
ImportantCalculations();

Without your minifilter, 4 separate writes would be happening at the same
time
and meanwhile the thread could get on with ImportantCalculations().

If you stall the thread waiting for something then neither the subsequent
writes, nor the ImportantCalculations() can happen.

If however you return PENDING, then the subsequent IOs can be started and
the ImportantCalculations() happen. When whatever you are waiting for
happens you can either complete the request, or pass it down or whatever
else you’d like to do, but the important thing is that you haven’t delayed
the thread needlessly.

Whilst the code above is artificial it is by not means unrepresentative in
Windows. You may not have met much code like that before (particularly if
you have been exposed to Unixen) but a great deal of the operating system
functions in this manner.

/Rod


NTFSD is sponsored by OSR

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></https:>

> Okay, so my question is this: Will the the two calls happen in the same

time
Yes.

As I said:

If 50 threads issue 50 WriteFile requests, you will see 50 calls all
happening at once