How Can I process the first NonCache read IRP in my filter?

Dear all,

Thank you for your precious time first.

When we want to read a file first time, we usually use CreateFile, ReadFile API in application layer. After CreateFile executed and just before ReadFile, we can track the NonCache Read IRPs, the Read-ahead mechanism can account for this phenomenon.

If we read file first time,when FSD complete Create IRP,it immediately notify Cc to read the file data ahead(cause the first NonCache Read IRP).Am I right?

I am now doing a filter driver based sfilter,I use generic table to track file open instance from application,using the FsContext as key to counting the open FileObject(not include stream file object created by system).In the create routine of my filter,before per file structure(includes FsContext) to be inserted to generic table,I have to call FSD to initialize the FsContext of FileObject. According to my debug result, just after FSD return the Create IRP result to filter,but before the executing of generic table inserting code in my filter’s create routine, the first noncache Read IRP issued and my filter jump to run read routine without FsContext in table.

So my question is: How can I ensure that the create routine has completed the FsContext insertion when execute the read routine?

The key code segment follows up:

Create routine:

//Initialize FsContext of FileObject
status =ForwardIrpSyncronously(devExt->AttachedToDeviceObject, Irp);
if (NT_SUCCESS(status) && (STATUS_REPARSE != status) )
{
PFILE_CONTEXT FileCtxPtr2 = NULL;
BOOLEAN NewElement = FALSE;
FileCtxPtr->FsContext = irpSp->FileObject->FsContext;
ExAcquireFastMutex(&devExt->FsCtxTableMutex);
FileCtxPtr2= RtlLookupElementGenericTable(&devExt->FsCtxTable, &FileCtxHdr);
if (FileCtxPtr2)
++FileCtxPtr2->RefCount;
else
{
FileCtxPtr2 = RtlInsertElementGenericTable(&devExt->FsCtxTable, FileCtxPtr, sizeof(FILE_CONTEXT),&NewElement);

FileCtxPtr2->RefCount = 1;
ASSERT(&fileName->Name);
}
ExReleaseFastMutex(&devExt->FsCtxTableMutex);
}

read routine:


ExAcquireFastMutex(&devExt->FsCtxTableMutex);
KdPrint((“Look up table…\n”));
FileCtxHdr.FsContext = FileObject->FsContext;
FileCtxPtr = RtlLookupElementGenericTable(&devExt->FsCtxTable, &FileCtxHdr);
ExReleaseFastMutex(&devExt->FsCtxTableMutex);

if (!FileCtxPtr)
{
//for first NonCache read IRP,always execute the following code,because FsConext is not in generic table.
if(Irp->Flags==0x43)
KdPrint((“not capture the 0x43 Read IRP, fscontext not in table…\n”));
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(devExt->NLExtHeader.AttachedToDeviceObject, Irp);
}

…Process read data…

Thanks for any suggestion.

Stephen Li

>inserted to generic table,I have to call FSD to initialize the FsContext of FileObject.

First insert, then call the FSD.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

Before calling the FSD, the FsContext field is not initialized, it’s value
is 0x00000000.

2010/11/6 Maxim S. Shatskih

> >inserted to generic table,I have to call FSD to initialize the FsContext
> of FileObject.
>
> First insert, then call the FSD.
>
> –
> Maxim S. Shatskih
> Windows DDK MVP
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>
> —
> NTFSD is sponsored by OSR
>
> For our schedule of debugging and file system seminars
> (including our new fs mini-filter seminar) 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
>

Why not use a minifilter ?

Anyway, I think you will need to register your own completion routine for
IRP_MJ_CREATE and I think that when your routine gets called the
FileObject->FsContext will be initialized and you will need to insert it in
your hash. Make sure you do this synchronously so that when the
IRP_MJ_CREATE returns to the IO manager, your table will be set up. You must
do this before the IRP_MJ_CREATE completes back to the IO manager since
there are no guarantees about the order of operations after that.

A minifilter would take care of all this complexity for you.

Thanks,

Alex.

>Before calling the FSD, the FsContext field is not initialized, it’s value is 0x00000000.

Maintain the generic table of per-file-object contexts, add to this table before passing CREATE down. Then, if CREATE failed, remove this just-added entry.

Same way maintain the per-FCB (FsContext) contexts.

Or write a minifilter, where FltMgr does all of this for you.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

“shoudi li” wrote in message news:xxxxx@ntfsd…
>Before calling the FSD, the FsContext field is not initialized, it’s value
>is 0x00000000.

Not to split hairs, but…Note that there are actually some cases in a
pre-Vista legacy filter where it won’t be NULL, it will point to a private
structure between DFS and RDR. So, don’t make any assumptions about it
actually being NULL, just know that it isn’t an initialized FCB header
structure.

Though if you’re writing a mini-filter then filter manager guarantees that
it will always be NULL in pre-create.

(For more details on the specific case I’m talking about, see:
http://osronline.com/article.cfm?article=557)

-scott


Scott Noone
Consulting Associate
OSR Open Systems Resources, Inc.
http://www.osronline.com

“shoudi li” wrote in message news:xxxxx@ntfsd…
Before calling the FSD, the FsContext field is not initialized, it’s value
is 0x00000000.

2010/11/6 Maxim S. Shatskih

>inserted to generic table,I have to call FSD to initialize the FsContext of
>FileObject.

First insert, then call the FSD.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com


NTFSD is sponsored by OSR

For our schedule of debugging and file system seminars
(including our new fs mini-filter seminar) 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

Dear Maxim,

Thanks for your advice.

Stephen Li

2010/11/7 Maxim S. Shatskih

> >Before calling the FSD, the FsContext field is not initialized, it’s
> value is 0x00000000.
>
> Maintain the generic table of per-file-object contexts, add to this table
> before passing CREATE down. Then, if CREATE failed, remove this just-added
> entry.
>
> Same way maintain the per-FCB (FsContext) contexts.
>
> Or write a minifilter, where FltMgr does all of this for you.
>
> –
> Maxim S. Shatskih
> Windows DDK MVP
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>
> —
> NTFSD is sponsored by OSR
>
> For our schedule of debugging and file system seminars
> (including our new fs mini-filter seminar) 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
>

Thanks for Scott.

I debug my filter in Window XP,beform initializing FsContext,its value is
NULL;
Under different OS version,the uninitialized value may be different. Thanks.

I have read your article: *Writing Filters is Hard Work: Undocumented DFS &
RDR Interactions.*
I learned a lot from it.

*Thanks for your job.*

Stephen Li

2010/11/7 Scott Noone

> “shoudi li” wrote in message news:xxxxx@ntfsd…
>
> Before calling the FSD, the FsContext field is not initialized, it’s value
>> is 0x00000000.
>>
>
> Not to split hairs, but…Note that there are actually some cases in a
> pre-Vista legacy filter where it won’t be NULL, it will point to a private
> structure between DFS and RDR. So, don’t make any assumptions about it
> actually being NULL, just know that it isn’t an initialized FCB header
> structure.
>

>
> Though if you’re writing a mini-filter then filter manager guarantees that
> it will always be NULL in pre-create.
>
> (For more details on the specific case I’m talking about, see:
> http://osronline.com/article.cfm?article=557)
>
> -scott
>
> –
> Scott Noone
> Consulting Associate
> OSR Open Systems Resources, Inc.
> http://www.osronline.com
>
>
> “shoudi li” wrote in message news:xxxxx@ntfsd…
>
> Before calling the FSD, the FsContext field is not initialized, it’s value
> is 0x00000000.
>
>
> 2010/11/6 Maxim S. Shatskih
>
> inserted to generic table,I have to call FSD to initialize the FsContext
>> of FileObject.
>>
>
>
> First insert, then call the FSD.
>
> –
> Maxim S. Shatskih
> Windows DDK MVP
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>
>
> —
> NTFSD is sponsored by OSR
>
> For our schedule of debugging and file system seminars
> (including our new fs mini-filter seminar) 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
>
> —
> NTFSD is sponsored by OSR
>
> For our schedule of debugging and file system seminars
> (including our new fs mini-filter seminar) 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
>

Alex, Thanks a lot.

We can obtain much knowledge from learning legacy filter,especially the IRP
processing details.
But projects based on legacy filter seem to be more difficult than
minifilter.

Thanks for your suggestion, minifilter is worth learning for practical
project.

Stephen Li

2010/11/7 Alex Carp

> Why not use a minifilter ?
>
>
>
> Anyway, I think you will need to register your own completion routine for
> IRP_MJ_CREATE and I think that when your routine gets called the
> FileObject->FsContext will be initialized and you will need to insert it in
> your hash. Make sure you do this synchronously so that when the
> IRP_MJ_CREATE returns to the IO manager, your table will be set up. You must
> do this before the IRP_MJ_CREATE completes back to the IO manager since
> there are no guarantees about the order of operations after that.
>
>
>
> A minifilter would take care of all this complexity for you.
>
>
>
> Thanks,
>
> Alex.
>
> —
> NTFSD is sponsored by OSR
>
> For our schedule of debugging and file system seminars
> (including our new fs mini-filter seminar) 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
>