FltReadFile

I am writing a minifilter driver in which i am monitoring whatsoever process is being created by using PsSetCreateProcessNotifyRoutine callback routine as:

status = PsSetCreateProcessNotifyRoutine( CreateProcessNotifyProc,
FALSE
) ;
Now inside CreateProcessNotifyProc i am using FltCreateFile which doesnt create any problems

VOID
CreateProcessNotifyProc (
IN HANDLE ParentId,
IN HANDLE ProcessId,
IN BOOLEAN Create
)
{

status = FltCreateFile( ScannerData.Filter,
NULL,//FltObjects->Instance,
&handle,
//NULL,
GENERIC_READ,
&objAttr,
&iosblock,
(PLARGE_INTEGER)0,
(ULONG)FILE_ATTRIBUTE_NORMAL,
(ULONG)FILE_SHARE_READ,
(ULONG)FILE_OPEN,
(ULONG)0,
NULL,
(ULONG)0,
(ULONG)0
);

}

Now if i need to use FltReadFile its documentation states that 1st param
IN PFLT_INSTANCE InitiatingInstance:
Opaque instance pointer for the minifilter driver instance that is initiating the read request. This parameter is required and cannot be NULL.

But here i don’t have InitiatingInstance. Can anybody suggest what can be done to get InitiatingInstance inside CreateProcessNotifyProc calback, so that i can use FltReadFile.

Thanks in advance
SR

  1. you can use ZwReadFile.

  2. I remember about saving instance pointer somewhere in some callback and using them later as required though missing which callback exactly at this point of time, but i did it for sure.

Aditya

i think it was in instancesetup callback where I cached them, you may want to take a look in PCFLT_RELATED_OBJECTS structure.

Ok
I am trying with 1st option thats using ZwReadFile.

UCHAR Buffer[1024];
LARGE_INTEGER ByteOffset;

status = ZwReadFile( handle,
NULL,
NULL,
NULL,
&iosblock,
Buffer,
sizeof(Buffer),
&ByteOffset,
NULL
);

Here i am getting STATUS_INVALID_PARAMETER error. Can anybody point me where i am wrong.

Thanks
SR

Is ByteOffset initialized?
Is handle opened by ZwCreateFile (not by FltCreateFile)?

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: 17. dubna 2009 9:34
To: Windows File Systems Devs Interest List
Subject: RE:[ntfsd] FltReadFile

Ok
I am trying with 1st option thats using ZwReadFile.

UCHAR Buffer[1024];
LARGE_INTEGER ByteOffset;

status = ZwReadFile( handle,

NULL,

NULL,

NULL,

&iosblock,

Buffer,

sizeof(Buffer),

&ByteOffset,

NULL
);

Here i am getting STATUS_INVALID_PARAMETER error. Can anybody point me where
i am wrong.

Thanks
SR


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

Does it means that I cant do ZwReadFile on file handle opened by FltCreateFile?

Regards
SR

Hi!

Does it means that I cant do
ZwReadFile on file handle opened by FltCreateFile?

You can use the handle obtained by FltCreateFile in ZwxxxFile calls.

Regards,
Ayush Gupta
http://windows-internals.blogspot.com/

Add more friends to your messenger and enjoy! Go to http://messenger.yahoo.com/invite/

@Sandeep

Please pay attention to Petr’s post
"Is ByteOffset initialized? "

Next using ZwReadFile will post IRP on top of stack so be prepare for that.

> Next using ZwReadFile will post IRP on top of stack so be

prepare for that.

Only if the handle was opened with FltCreateFile by passing NULL as Instance parameter. And i think, he is passing NULL. So in this case it will go to top of the stack.

Regards,
Ayush Gupta
http://windows-internals.blogspot.com/

Add more friends to your messenger and enjoy! Go to http://messenger.yahoo.com/invite/

Thanks all
I have set FILE_SYNCHRONOUS_IO_ALERT for CreateOptions in FltCreateFile and used ByteOffset as NULL in ZwReadFile. Now its working.

@Aditya
I feel i need to look more into if posting IRP on top of stack will not create problems for me or not.

>>Only if the handle was opened with FltCreateFile by passing NULL as Instance parameter

As ZwRead/Write Apis are implemented before FltMgr, so they shouldn?t know anything related and hence I believe that this will always go on top of the stack. Also as ZwReadFile knows nothing about where to send this call to; it is not the one who can take this decision.

But I wrote some code and found it otherwise. So further dig it and deduce this.

It looks like that FltMgr is the entity taking the decision. Firstly, because FltMgr knows about instances and secondly as the handle is created using its API. It looks like it is performing some sort of bookkeeping (handle vs instance), which it is using later on.

I wrote some sample code to test this and found that ZwReadFile->NtReadFile is simply posting it to the top of stack and as FltMgr is at the top it is getting first chance to handle this, here it is making decision about the where exactly it needs to send this, if it does not have a handle in its database it simply starts from first driver else will post this to the next driver after mentioned instance.

Kindly correct me in case I am wrong in deducing this.

Thanks
Aditya

@Aditya
Trying with the 2nd option of saving the Instance and FltObjects in InstanceSetup callback i am using FltCreateFile and FltReadFile so that IRP should not be added to top of the stack.
FltCreateFile opens a file with success but FltReadFile gives STATUS_VOLUME_DISMOUNTED error.

Any sugggessions…

Regards
SR

> As ZwRead/Write Apis are implemented before FltMgr, so they shouldn?t know anything related and

hence I believe that this will always go on top of the stack. Also as ZwReadFile knows nothing about
where to send this call to; it is not the one who can take this decision.

From what I understand:

  1. ZwRead/Write send IRPs to the DO referenced by the file object
  2. if the file object was created by IoCreateFileSpecifyDeviceObjectHint, then this DO is not top of stack, otherwise, it is top of stack
  3. FltCreateFile is a wrapper around IoCreateFileSpecifyDeviceObjectHint

as FltMgr is at the top

Not so if the legacy filters are present.


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

Not so sure on this as never faced but you could be passing a wrong instance pointer which is not recognized by FltMgr.

Also make sure you are passing correct pointer, i.e. pointer you received in instancesetup callback for \Device\HddVol1, should be used for \Device\HddVol1 request.

>>1) ZwRead/Write send IRPs to the DO referenced by the file object

>2) if the file object was created by IoCreateFileSpecifyDeviceObjectHint, then this DO is not top of stack, otherwise, it is top of stack
>3) FltCreateFile is a wrapper around IoCreateFileSpecifyDeviceObjectHint

Thanks for the clearer view Max,

But mini filter do not create a device object, so if there is a mini filter below my driver how IoCreateFileSpecifyDeviceObjectHint can be used to pass a request to the driver. Or is it like fltmgr initialized fileobject DO field to fltmgr DO, and than taking decision based on what I mentioned.

I should debug it on your given points (and will do that soon) but as you are answering I thought to take the privilege.

Aditya

Global variables:
PFILE_OBJECT PFltObj;
PFLT_INSTANCE PFltInstance;

In InstanceSetup call back i am saving these as

PFltObj = FltObjects->FileObject;
PFltInstance = FltObjects->Instance;

and in CreateProcessNotifyProc callback i am reading the contents as:

status = FltCreateFile( ScannerData.Filter,
PFltInstance,
&handle,
//NULL,
GENERIC_READ,
&objAttr,
&iosblock,
(PLARGE_INTEGER)0,
(ULONG)FILE_ATTRIBUTE_NORMAL,
(ULONG)FILE_SHARE_READ,
(ULONG)FILE_OPEN,
(ULONG)NULL, //FILE_SYNCHRONOUS_IO_ALERT,
NULL,
(ULONG)0,
(ULONG)0
);
if( STATUS_SUCCESS == status )
{
DbgPrint(“FltCreateFile Success\n”);

status = ZwQueryInformationFile( handle,
&iosblock,
&StandardInfo,
sizeof(StandardInfo),
FileStandardInformation
);
if( STATUS_SUCCESS == status )
{
DbgPrint(“ZwQueryInformationFile Success\n”);
ByteOffset.QuadPart = 0;
FileLength = StandardInfo.EndOfFile.LowPart;
Buffer = (PUCHAR)ExAllocatePool(NonPagedPool, FileLength);
if( NULL != Buffer )
{

status = FltReadFile( PFltInstance,
PFltObj,
&ByteOffset,
FileLength,
Buffer,
(FLT_IO_OPERATION_FLAGS)NULL, //FLTFL_IO_OPERATION_NON_CACHED,
NULL,
NULL,
NULL
);

Here in FltReadFile i am getting STATUS_ACCESS_VIOLATION error now.

@Sandeep

Whay are you using the fileobject from instancesetup, in fact why are you caching it. you should retrieve a fileobject from the handle returned by fltcreatefile and than use that fileobject in fltreadfile.

>>is it like fltmgr initialized fileobject DO field to fltmgr DO, and than taking decision based on what I mentioned. I should debug it on your given points (and will do that soon)…

windbg revelead that FltCreateFile indeed setting DO to fltmgr DO, so directing call to FltMgr. I did not dig create further and found that the handle returned after calling IoCreateFileSpecifyDeviceObjectHint has DO set to DO of driver \Driver\Ftdisk.

But ZwReadFile calls reached to FltMgr as it use IoGetRelatedDeviceObject which returns FltMgr.sys (it is the topmost driver in the stack.)

So ZwRead/Write always sends IRP to the driver which is on the top of the stack of driver define by fileobject DO.

Why go through all this when you could build your own IRP and do whatever
with it ?

With respect,
Gabriel Bercea

GaMiTech Software Development
Mobile contact: (+40)0740049634
eMail: xxxxx@gmail.com
Blog: http://gamitech.blogspot.com/
Linkedin: http://www.linkedin.com/in/gamitech

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Friday, April 17, 2009 9:09 AM
To: Windows File Systems Devs Interest List
Subject: [ntfsd] FltReadFile

I am writing a minifilter driver in which i am monitoring whatsoever process
is being created by using PsSetCreateProcessNotifyRoutine callback routine
as:

status = PsSetCreateProcessNotifyRoutine( CreateProcessNotifyProc,

FALSE

) ;
Now inside CreateProcessNotifyProc i am using FltCreateFile which doesnt
create any problems

VOID
CreateProcessNotifyProc (
IN HANDLE ParentId,
IN HANDLE ProcessId,
IN BOOLEAN Create
)
{

status = FltCreateFile( ScannerData.Filter,

NULL,//FltObjects->Instance,

&handle,

//NULL,

GENERIC_READ,

&objAttr,

&iosblock,

(PLARGE_INTEGER)0,

(ULONG)FILE_ATTRIBUTE_NORMAL,

(ULONG)FILE_SHARE_READ,

(ULONG)FILE_OPEN,

(ULONG)0,

NULL,

(ULONG)0,

(ULONG)0
);

}

Now if i need to use FltReadFile its documentation states that 1st param
IN PFLT_INSTANCE InitiatingInstance:
Opaque instance pointer for the minifilter driver instance that is
initiating the read request. This parameter is required and cannot be NULL.

But here i don’t have InitiatingInstance. Can anybody suggest what can be
done to get InitiatingInstance inside CreateProcessNotifyProc calback, so
that i can use FltReadFile.

Thanks in advance
SR


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

Based on my experience, Maxim is correct.

Where the subsequent I/O is directed (top of stack vs next lower driver)
is determined by the FltCreateFile call, not the FltRead call. This is
why files opened for directed I/O must do unbuffered I/O. You don’t
want to risk the cache manager referencing and using your directed file
object.

Maxim S. Shatskih wrote:

> As ZwRead/Write Apis are implemented before FltMgr, so they shouldn?t know anything related and
> hence I believe that this will always go on top of the stack. Also as ZwReadFile knows nothing about
> where to send this call to; it is not the one who can take this decision.
>

>From what I understand:

  1. ZwRead/Write send IRPs to the DO referenced by the file object
  2. if the file object was created by IoCreateFileSpecifyDeviceObjectHint, then this DO is not top of stack, otherwise, it is top of stack
  3. FltCreateFile is a wrapper around IoCreateFileSpecifyDeviceObjectHint

> as FltMgr is at the top
>

Not so if the legacy filters are present.