Tracking down the data in a filter driver

I’m working on an encryption file filter driver and could really user some
help getting over a couple of obstacles. This is my first endeavor in the
file system world. I have read Rajeev Nagar’s book and I am using the
famous filemon code as a starting point. There are two main questions
that I have.

  1. How do I grab the buffer where the data is on IRP_MJ_READ and
    IRP_MJ_WRITE? I understand there are three ways that buffer can be passed
    to the file system: Irp->MdlAddress, Irp->UserBuffer,
    Irp->AssociatedIrp.SystemBuffer. However, I’m not sure how to know which
    buffer to grab.

  2. How do I get the file name when filemon returns C:\DASD? I have been
    tracking the SOP address to signal when the request is for a file that I’m
    filtering (if I get C:\DASD back from the getfullpath call) I need to be
    able to filter all accesses to the files I filtering. What’s the best way
    to do this?

Thanks!
Scott

Scott,

The FAQ actually touch on this.

(1) If it is IRP_MJ_READ or IRP_MJ_WRITE and the minor function is zero,
then Irp->MdlAddress is used for paging I/O. If it is user I/O it will
either be Irp->UserBuffer (neither I/O, from the Device Object flags field),
Irp->MdlAddress (direct I/O, again from the Device Object flags field), or
Irp->AssociatedIrp.SystemBuffer (buffered I/O, ditto).

If the minor function is set, then you need to keep in mind that it is a
request to either OBTAIN an MDL from the FSD or to RETURN an MDL to the FSD,
since now the buffer is in the cache (this avoids a data copy). That’s the
case that can often screw up a filter driver. If the IRP_MN_COMPLETE bit is
set, it is a return. If it is NOT set, it is a request. Data is not
present on the request, only on the completion of the request (IRP_MJ_READ)
or on the return of the buffer (IRP_MJ_WRITE). Such I/O will also be
observed via the paging path, however.

The usual approach is to look for the IRP_NOCACHE bit and encrypt/decrypt
only those buffers. That catches both paging I/O (which is non-cached) and
user I/O that is non-cached (and bypasses the cache) while ignoring cached
user I/O.

(2) Get the name when the file is opened. That’s the only safe and reliable
way to do it. Also, keep in mind that names mean very little in this OS. A
file can be opened with a NUMBER and that’s as valid as using any one of its
available names (short name, long name, hard links, etc.) Everything else
comes with caveats and exceptions.

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

-----Original Message-----
From: Scott Elliott [mailto:scottel@us.ibm.com]
Sent: Thursday, March 21, 2002 1:40 PM
To: File Systems Developers
Subject: [ntfsd] Tracking down the data in a filter driver

I’m working on an encryption file filter driver and could really user some
help getting over a couple of obstacles. This is my first endeavor in the
file system world. I have read Rajeev Nagar’s book and I am using the
famous filemon code as a starting point. There are two main questions
that I have.

  1. How do I grab the buffer where the data is on IRP_MJ_READ and
    IRP_MJ_WRITE? I understand there are three ways that buffer can be passed
    to the file system: Irp->MdlAddress, Irp->UserBuffer,
    Irp->AssociatedIrp.SystemBuffer. However, I’m not sure how to know which
    buffer to grab.

  2. How do I get the file name when filemon returns C:\DASD? I have been
    tracking the SOP address to signal when the request is for a file that I’m
    filtering (if I get C:\DASD back from the getfullpath call) I need to be
    able to filter all accesses to the files I filtering. What’s the best way
    to do this?

Thanks!
Scott


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

Tony,

Thanks for your quick response. After reading your note, I went to the
FAQ. Other questions arose from reading some of the entries there. Can
you point out problems with the way I am attempting to implement our
encryption filter driver? This is basically how it works (or doesn’t work
as the case may be!!):
I filter on the path name to flag which IRP’s need to be intercepted.

On IRP_MJ_CREATE:
I set a completion routine that stores the address of the
SectionObjectPointer (or increments the count for that SOP if it has
already been stored.)

On IRP_MJ_WRITE:
If the filename matches the filter or if the SOP address matches an entry
in my linked list of SOP addresses, I check the IRP_NOCACHE bit. If true,
I get a pointer to the data buffer and encrypt the data using the Irp->
Parameters.Write.Length field to determine how much data to encrypt. Then
in the completion routine, after the data has been written to the disk, I
use the same method for getting the buffer and the length to decrypt the
data in the buffer.

On IRP_MJ_READ:
If the filename matches the filter or if the SOP address matches an entry
in my linked list of SOP addresses, I check the NOCACHED bit. If true, I
set my completion routine. Then in the completion routine I use the same
method I described above to decrypt the data in the buffer.

On IRP_MJ_CLOSE:
I decrement the count for the SOP address and delete the node if the
count is zero.

That’s basically it. From your previous note and from the FAQ, I have
found some possible problems with this method. One definite problem is
that I don’t handle the case where the buffer is pointed to by the
AssociatedIrp.SystemBuffer field. Can you provide some insight into other
problems this method might cause? Or if the whole strategy is even
workable at all? (For your information, this method is working pretty
well - I’m seeing only extremely intermittant problems such as an
occasional blue screen in NT 4.0 and some corrupted data in non-filtered
files under Win2K. Interestingly, the affected data is only corrupted
until a reboot, and I have only seen this problem trying to build Visual
C++ projects in a filtered folder with MS Visual Studio - other apps such
as notepad, MS Word, Excel, WinZip etc. seem to work fine on W2k)

Thanks,
Scott

Scott,

The FAQ actually touch on this.

(1) If it is IRP_MJ_READ or IRP_MJ_WRITE and the minor function is zero,
then Irp->MdlAddress is used for paging I/O. If it is user I/O it will
either be Irp->UserBuffer (neither I/O, from the Device Object flags field),
Irp->MdlAddress (direct I/O, again from the Device Object flags field), or
Irp->AssociatedIrp.SystemBuffer (buffered I/O, ditto).

If the minor function is set, then you need to keep in mind that it is a
request to either OBTAIN an MDL from the FSD or to RETURN an MDL to the FSD,
since now the buffer is in the cache (this avoids a data copy). That’s the
case that can often screw up a filter driver. If the IRP_MN_COMPLETE bit is
set, it is a return. If it is NOT set, it is a request. Data is not
present on the request, only on the completion of the request (IRP_MJ_READ)
or on the return of the buffer (IRP_MJ_WRITE). Such I/O will also be
observed via the paging path, however.

The usual approach is to look for the IRP_NOCACHE bit and encrypt/decrypt
only those buffers. That catches both paging I/O (which is non-cached) and
user I/O that is non-cached (and bypasses the cache) while ignoring cached
user I/O.

(2) Get the name when the file is opened. That’s the only safe and reliable
way to do it. Also, keep in mind that names mean very little in this OS. A
file can be opened with a NUMBER and that’s as valid as using any one of its
available names (short name, long name, hard links, etc.) Everything else
comes with caveats and exceptions.

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

-----Original Message-----
From: Scott Elliott [mailto:scottel@us.ibm.com]
Sent: Thursday, March 21, 2002 1:40 PM
To: File Systems Developers
Subject: [ntfsd] Tracking down the data in a filter driver

I’m working on an encryption file filter driver and could really user some
help getting over a couple of obstacles. This is my first endeavor in the
file system world. I have read Rajeev Nagar’s book and I am using the
famous filemon code as a starting point. There are two main questions
that I have.

  1. How do I grab the buffer where the data is on IRP_MJ_READ and
    IRP_MJ_WRITE? I understand there are three ways that buffer can be passed
    to the file system: Irp->MdlAddress, Irp->UserBuffer,
    Irp->AssociatedIrp.SystemBuffer. However, I’m not sure how to know which
    buffer to grab.

  2. How do I get the file name when filemon returns C:\DASD? I have been
    tracking the SOP address to signal when the request is for a file that I’m
    filtering (if I get C:\DASD back from the getfullpath call) I need to be
    able to filter all accesses to the files I filtering. What’s the best way
    to do this?

Thanks!
Scott


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

Scott,

(1) On dispatch you need to store the name. The name is not valid after you
send the IRP_MJ_CREATE to the file system - the FSD is free to do whatever
it wants with that name (including free it!)

(2) YOU CANNOT ENCRYPT IN PLACE for an IRP_MJ_WRITE! The memory is SHARED
and by encrypting it in-place you are encrypting the shared data, which is
visible to everyone else.

(3) How are you determining the file name during an IRP_MJ_WRITE? From the
FileObject->FileName? That isn’t valid after the IRP_MJ_CREATE is passed to
the file system. Calling ObQueryObjectName or IoQueryInformationFile during
an IRP_MJ_READ or IRP_MJ_WRITE operation is a very bad idea - you are
calling pageable code paths down I/O paths that should not be accessing
pageable memory/data. Decrypting in-place for IRP_MJ_READ is OK because
nobody can have a mapping to the memory yet.

(4) The reference counting scheme you are using will cause you to miss I/O
operations. You should only delete the node if the count is zero AND the
two section object pointers are NULL. Otherwise, keep it.

As for “works fine” all that this means is it is working OK in your
environment. As you increase usage of the system, you’ll see new and
interesting behavior and problems. Just wait until you give it to USERS!

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

-----Original Message-----
From: Scott Elliott [mailto:scottel@us.ibm.com]
Sent: Thursday, March 21, 2002 4:54 PM
To: File Systems Developers
Subject: [ntfsd] RE: Tracking down the data in a filter driver

Tony,

Thanks for your quick response. After reading your note, I went to the
FAQ. Other questions arose from reading some of the entries there. Can
you point out problems with the way I am attempting to implement our
encryption filter driver? This is basically how it works (or doesn’t work
as the case may be!!):
I filter on the path name to flag which IRP’s need to be intercepted.

On IRP_MJ_CREATE:
I set a completion routine that stores the address of the
SectionObjectPointer (or increments the count for that SOP if it has
already been stored.)

On IRP_MJ_WRITE:
If the filename matches the filter or if the SOP address matches an entry
in my linked list of SOP addresses, I check the IRP_NOCACHE bit. If true,
I get a pointer to the data buffer and encrypt the data using the Irp->
Parameters.Write.Length field to determine how much data to encrypt. Then
in the completion routine, after the data has been written to the disk, I
use the same method for getting the buffer and the length to decrypt the
data in the buffer.

On IRP_MJ_READ:
If the filename matches the filter or if the SOP address matches an entry
in my linked list of SOP addresses, I check the NOCACHED bit. If true, I
set my completion routine. Then in the completion routine I use the same
method I described above to decrypt the data in the buffer.

On IRP_MJ_CLOSE:
I decrement the count for the SOP address and delete the node if the
count is zero.

That’s basically it. From your previous note and from the FAQ, I have
found some possible problems with this method. One definite problem is
that I don’t handle the case where the buffer is pointed to by the
AssociatedIrp.SystemBuffer field. Can you provide some insight into other
problems this method might cause? Or if the whole strategy is even
workable at all? (For your information, this method is working pretty
well - I’m seeing only extremely intermittant problems such as an
occasional blue screen in NT 4.0 and some corrupted data in non-filtered
files under Win2K. Interestingly, the affected data is only corrupted
until a reboot, and I have only seen this problem trying to build Visual
C++ projects in a filtered folder with MS Visual Studio - other apps such
as notepad, MS Word, Excel, WinZip etc. seem to work fine on W2k)

Thanks,
Scott

Scott,

The FAQ actually touch on this.

(1) If it is IRP_MJ_READ or IRP_MJ_WRITE and the minor function is zero,
then Irp->MdlAddress is used for paging I/O. If it is user I/O it will
either be Irp->UserBuffer (neither I/O, from the Device Object flags
field),
Irp->MdlAddress (direct I/O, again from the Device Object flags field), or
Irp->AssociatedIrp.SystemBuffer (buffered I/O, ditto).

If the minor function is set, then you need to keep in mind that it is a
request to either OBTAIN an MDL from the FSD or to RETURN an MDL to the
FSD,
since now the buffer is in the cache (this avoids a data copy). That’s
the
case that can often screw up a filter driver. If the IRP_MN_COMPLETE bit
is
set, it is a return. If it is NOT set, it is a request. Data is not
present on the request, only on the completion of the request
(IRP_MJ_READ)
or on the return of the buffer (IRP_MJ_WRITE). Such I/O will also be
observed via the paging path, however.

The usual approach is to look for the IRP_NOCACHE bit and encrypt/decrypt
only those buffers. That catches both paging I/O (which is non-cached)
and
user I/O that is non-cached (and bypasses the cache) while ignoring cached
user I/O.

(2) Get the name when the file is opened. That’s the only safe and
reliable
way to do it. Also, keep in mind that names mean very little in this OS.
A
file can be opened with a NUMBER and that’s as valid as using any one of
its
available names (short name, long name, hard links, etc.) Everything else
comes with caveats and exceptions.

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

-----Original Message-----
From: Scott Elliott [mailto:scottel@us.ibm.com]
Sent: Thursday, March 21, 2002 1:40 PM
To: File Systems Developers
Subject: [ntfsd] Tracking down the data in a filter driver

I’m working on an encryption file filter driver and could really user some
help getting over a couple of obstacles. This is my first endeavor in the
file system world. I have read Rajeev Nagar’s book and I am using the
famous filemon code as a starting point. There are two main questions
that I have.

  1. How do I grab the buffer where the data is on IRP_MJ_READ and
    IRP_MJ_WRITE? I understand there are three ways that buffer can be passed
    to the file system: Irp->MdlAddress, Irp->UserBuffer,
    Irp->AssociatedIrp.SystemBuffer. However, I’m not sure how to know which
    buffer to grab.

  2. How do I get the file name when filemon returns C:\DASD? I have been
    tracking the SOP address to signal when the request is for a file that I’m
    filtering (if I get C:\DASD back from the getfullpath call) I need to be
    able to filter all accesses to the files I filtering. What’s the best way
    to do this?

Thanks!
Scott


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


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

Tony,

OK, so I have a long way to go. Thanks for getting me off the wrong path!

Now to try to get on the right path: Let me start with file name
acquisition. I understand that I can only safely find the file name on
the IRP_MJ_CREATE call. After that, what value or field should I
associate with that file name to be able to track subsequent calls
involving that file? SANITY CHECK: I get the file name from the
IRP->FileObject.FileName field, right? And this will always work on
IRP_MJ_CREATE calls, right?

I am also trying to come up with some way to encrypt the data headed to
the file system. Obviously, my current strategy is a dead end. Let me
run one idea by you to see if it might work. Here it is:

  1. Allocate another buffer and copy the contents from the original buffer
    into it.
  2. Construct an IRP with this buffer and send it to the FSD.
  3. Complete the original IRP.
    How does that sound? Do you have any ideas on this?

Thanks again!!
Scott

Scott,

The file names are only valid in the IRP_MJ_CREATE path before
completion (before the IRP is processed by the file system drivers).

Furthermore, please recognize that the IRP->FileObject.FileName field
does not neccesarily give you a full (absolute) file path. You will need
to do some tricks to contruct an absolute file path yourself. I don’t
know if that’s in the OSR faq, but I think this can be qualified as a
frequently asked question…


Bartjan.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Scott Elliott
Sent: vrijdag 22 maart 2002 17:09
To: File Systems Developers
Subject: [ntfsd] Re: Tracking down the data in a filter driver

Tony,

OK, so I have a long way to go. Thanks for getting me off
the wrong path!

Now to try to get on the right path: Let me start with file
name acquisition. I understand that I can only safely find
the file name on the IRP_MJ_CREATE call. After that, what
value or field should I associate with that file name to be
able to track subsequent calls involving that file? SANITY
CHECK: I get the file name from the
IRP->FileObject.FileName field, right? And this will always work on
IRP_MJ_CREATE calls, right?

I am also trying to come up with some way to encrypt the data
headed to the file system. Obviously, my current strategy is
a dead end. Let me run one idea by you to see if it might
work. Here it is: 1. Allocate another buffer and copy the
contents from the original buffer into it. 2. Construct an
IRP with this buffer and send it to the FSD. 3. Complete the
original IRP. How does that sound? Do you have any ideas on this?

Thanks again!!
Scott


You are currently subscribed to ntfsd as: xxxxx@zeelandnet.nl
To unsubscribe send a blank email to %%email.unsub%%

Scott,

Right - IRP_MJ_CREATE before the FSD has touched the name. Normally, then
people use one of the file characteristics to associate with the file itself
(either the SectionObjectPointers value, or the FsContext value, both of
which are unique to a given file, whereas a file object is created for each
new call to open the file.)

Also, as Bartjan noted, you may need to construct a path by combining the
information for the FileObject->RelatedFileObject with the name for the file
object itself (fair warning -
FileObject->RelatedFileObject->RelatedFileObject is *NOT* guaranteed to be
valid, and will not be in all cases). You can also query the FSD in the
completion routine of IRP_MJ_CREATE (or a work item spawned from the
completion routine if you are called at elevated IRQL). To do this, call
ObQueryObjectName on the newly-created file object (preferably using the
security credentials of the original caller, to avoid some rather esoteric
conditions where this call will fail on NTFS because you do not have
TRAVERSE right to some directory along the path. Did I mention this is a
field littered with too many special cases?)

The IRP-based approach you describe is one way to achieve it. The key thing
to remember here is that the IRP you use must have Irp->UserBuffer =
MmGetVirtualAddressForMdl(mdl) or it will periodically fail in strange ways
(want to see why? Look at fat, FatMultiAsync in deviosup.c - it uses
Irp->UserBuffer as an index value for traversing through the MDL.)

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

“Whoever would overthrow the liberty of a nation must begin by subduing the
freeness of speech.”
– Benjamin Franklin

-----Original Message-----
From: Scott Elliott [mailto:scottel@us.ibm.com]
Sent: Friday, March 22, 2002 11:09 AM
To: File Systems Developers
Subject: [ntfsd] Re: Tracking down the data in a filter driver

Tony,

OK, so I have a long way to go. Thanks for getting me off the wrong path!

Now to try to get on the right path: Let me start with file name
acquisition. I understand that I can only safely find the file name on
the IRP_MJ_CREATE call. After that, what value or field should I
associate with that file name to be able to track subsequent calls
involving that file? SANITY CHECK: I get the file name from the
IRP->FileObject.FileName field, right? And this will always work on
IRP_MJ_CREATE calls, right?

I am also trying to come up with some way to encrypt the data headed to
the file system. Obviously, my current strategy is a dead end. Let me
run one idea by you to see if it might work. Here it is:

  1. Allocate another buffer and copy the contents from the original buffer
    into it.
  2. Construct an IRP with this buffer and send it to the FSD.
  3. Complete the original IRP.
    How does that sound? Do you have any ideas on this?

Thanks again!!
Scott


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

Tony,

I have implemented most of what you have suggested with positive results
for the most part. I am getting one perplexing result, however. When
dealing with WordPad documents that I am encrypting, I get an incorrect
value for the file size. Instead of the 4608 bytes that should be in the
pFcb->FileSize.LowPart field (pFcb = FileObject->FsContext), I get 16600
or something like that. Interestingly, if I reboot and open the same
file, thus decrypting it, I get the correct file size value, 4608. This
may be a picky detail but it’s actually a show-stopper for me right now.
BTW, before I made the changes, the file size returned was correct in
cases like this. Is there something I’m missing??

On another note: are there any issues with the DDK and WindowsXP that I
should be aware of? Is there some release of the DDK that WindowsXP
requires?

Thanks,
Scott

Scott,

The mistake is that you assume you can just “reach into” the file system’s
data structure and find the correct size information.

Not even the VM system assumes that (and IT assumes lots of things about FS
data structures). If you want to know what the size is, you need to ask.
Using the FCB values directly will lead to unpredictable results.

You should use the Windows XP DDK for device drivers for Windows XP. You
should use the Windows XP IFS Kit for file systems and filter drivers for
Windows XP.

Oh - my usual suggestion as well is to build FAT from the IFS Kit and use
that for most of your debugging - walk through the code, see what it is
doing. In the case of the question here, for instance, you could watch and
see when/how FAT sets that value, if for no other reason than to convince
yourself that it isn’t nearly as simple as you might think it is!

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

-----Original Message-----
From: Scott Elliott [mailto:scottel@us.ibm.com]
Sent: Tuesday, March 26, 2002 4:08 PM
To: File Systems Developers
Subject: [ntfsd] Re: Tracking down the data in a filter driver

Tony,

I have implemented most of what you have suggested with positive results
for the most part. I am getting one perplexing result, however. When
dealing with WordPad documents that I am encrypting, I get an incorrect
value for the file size. Instead of the 4608 bytes that should be in the
pFcb->FileSize.LowPart field (pFcb = FileObject->FsContext), I get 16600
or something like that. Interestingly, if I reboot and open the same
file, thus decrypting it, I get the correct file size value, 4608. This
may be a picky detail but it’s actually a show-stopper for me right now.
BTW, before I made the changes, the file size returned was correct in
cases like this. Is there something I’m missing??

On another note: are there any issues with the DDK and WindowsXP that I
should be aware of? Is there some release of the DDK that WindowsXP
requires?

Thanks,
Scott


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

Tony,

We’re getting closer… Asking for the file size is working much better.
I wanted to revisit something you said in an earlier note concerning the
related file object. You said
“FileObject->RelatedFileObject->RelatedFileObject is *NOT* guaranteed to
be valid, and will not be in all cases.” Does this mean that I won’t
always be able to get the file name even in IRP_MJ_CREATE?

Thanks again,
Scott

FYI. If file is open with FILE_OPEN_BY_FILE_ID and you need a “readable”
filename in your FSFD, then you will have to query FS (e.g. NTFS) for it,
even in IRP_MJ_CREATE.
WBR Primoz

-----Original Message-----
From: Scott Elliott [mailto:scottel@us.ibm.com]
Sent: Thursday, March 28, 2002 10:20 PM
To: File Systems Developers
Subject: [ntfsd] Re: Tracking down the data in a filter driver

Tony,

We’re getting closer… Asking for the file size is working much better.
I wanted to revisit something you said in an earlier note concerning the
related file object. You said
“FileObject->RelatedFileObject->RelatedFileObject is *NOT* guaranteed to
be valid, and will not be in all cases.” Does this mean that I won’t
always be able to get the file name even in IRP_MJ_CREATE?

Thanks again,
Scott


You are currently subscribed to ntfsd as: xxxxx@hermes.si
To unsubscribe send a blank email to %%email.unsub%%

What’s the best way to determine if the file is opened with
FILE_OPEN_BY_FILE_ID?

Thanks,
Scott

Filter open and look for the flag.

-----Original Message-----
From: Scott Elliott [mailto:scottel@us.ibm.com]
Sent: Friday, March 29, 2002 12:22 PM
To: File Systems Developers
Subject: [ntfsd] Re: Tracking down the data in a filter driver

What’s the best way to determine if the file is opened with
FILE_OPEN_BY_FILE_ID?

Thanks,
Scott


You are currently subscribed to ntfsd as: xxxxx@inin.com
To unsubscribe send a blank email to %%email.unsub%%

Also keep in mind that the returned name is subject to restrictions:

* If there are hard links, this returns ONE of the paths to the file;
* If the caller does not have TRAVERSE right on every directory, the file
system cannot return a path.

Both of these are “rare” but not “non-existent” and if you are not prepared
to handle them it is quite likely you will introduce a scenario in which the
system will crash.

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

At 02:49 AM 3/29/02, you wrote:

Tony,

We’re getting closer… Asking for the file size is working much better.
I wanted to revisit something you said in an earlier note concerning the
related file object. You said
“FileObject->RelatedFileObject->RelatedFileObject is *NOT* guaranteed to
be valid, and will not be in all cases.” Does this mean that I won’t
always be able to get the file name even in IRP_MJ_CREATE?

I would like to add that you can get the path name of
“FileObject->RelatedFileObject” by sending an IRP to the FSD
(IRP_MJ_QUERY_INFORMATION, FileNameInformation). Then you can add
FileObject->FileName to this related path to get the full path name of the
file in your IRP_MJ_CREATE handler. Other restrictions apply as stated in
other replies.

Regards,
Robin

Ah, but keep in mind that if the open request is an open by id, the related
file object may have NOTHING to do with the original name.

See - the wonderful thing about this file systems stuff is that it is this
nice short list of rules, with this long list of special cases, exceptions,
errata, and observations.

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

-----Original Message-----
From: Robin [mailto:xxxxx@xpsonline.com]
Sent: Saturday, March 30, 2002 12:48 PM
To: File Systems Developers
Subject: [ntfsd] Re: Tracking down the data in a filter driver

At 02:49 AM 3/29/02, you wrote:

Tony,

We’re getting closer… Asking for the file size is working much better.
I wanted to revisit something you said in an earlier note concerning the
related file object. You said
“FileObject->RelatedFileObject->RelatedFileObject is *NOT* guaranteed to
be valid, and will not be in all cases.” Does this mean that I won’t
always be able to get the file name even in IRP_MJ_CREATE?

I would like to add that you can get the path name of
“FileObject->RelatedFileObject” by sending an IRP to the FSD
(IRP_MJ_QUERY_INFORMATION, FileNameInformation). Then you can add
FileObject->FileName to this related path to get the full path name of the
file in your IRP_MJ_CREATE handler. Other restrictions apply as stated in
other replies.

Regards,
Robin


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

Tony,

In a previous note you said to get the file name in the IRP_MJ_CREATE call
and “Normally, then
people use one of the file characteristics to associate with the file
itself (either the SectionObjectPointers value, or the FsContext value,
both of which are unique to a given file, whereas a file object is created
for each
new call to open the file.)” In order to save the trouble of chasing down
the SOP in the completion routine (and perhaps having to kick off worker
threads), I am currently just tracking the file object address. This way,
for every open I add the file object to my list and for every successful
close, I delete the file object from my list. Is this acceptable?

Thanks,
Scott

It depends. Do you ever need to know if you have multiple FileObjects for a
single file on disk? If yes, your logic won’t work. I recommend using
FsContext in the completion routine and I see no need for worker threads
unless you need to get more information about the file. But, why not use
worker threads anyway? They work just fine and using DriverWorks they are
easy to create and handle. Using the OSR NT Insider article about worker
threads it is very easy to implement them.

BTW, the FileObject that is given for a file might not be the FileObject
used by the cache manager. I have seen that the cache manager seems to use
only one FileObject for the paging reads and writes and not necessarily the
first one seen.

The simplest logic means just passing the create thru in the dispatch
routine after setting up a completion routine. In the completion routine,
get the status and if it didn’t error out, schedule a worker thread or not
since both NTFS & FASTFAT process creates at PASSIVE_LEVEL IRQL. Then set
the flag that shows the file is open and use that file object to query name,
attributes, etc. You can then reset the flag and then complete the request
after you are done.

----- Original Message -----
From: “Scott Elliott”
To: “File Systems Developers”
Sent: Tuesday, April 02, 2002 6:36 PM
Subject: [ntfsd] Re: Tracking down the data in a filter driver

> Tony,
>
> In a previous note you said to get the file name in the IRP_MJ_CREATE call
> and “Normally, then
> people use one of the file characteristics to associate with the file
> itself (either the SectionObjectPointers value, or the FsContext value,
> both of which are unique to a given file, whereas a file object is created
> for each
> new call to open the file.)” In order to save the trouble of chasing down
> the SOP in the completion routine (and perhaps having to kick off worker
> threads), I am currently just tracking the file object address. This way,
> for every open I add the file object to my list and for every successful
> close, I delete the file object from my list. Is this acceptable?
>
> Thanks,
> Scott
>
>
> —
> You are currently subscribed to ntfsd as: xxxxx@yoshimuni.com
> To unsubscribe send a blank email to %%email.unsub%%

Are you referring to FO_FILE_OPEN or some other flag?

-----Original Message-----
From: David J. Craig [mailto:xxxxx@yoshimuni.com]
Sent: Tuesday, April 02, 2002 7:14 PM
To: File Systems Developers
Subject: [ntfsd] Re: Tracking down the data in a filter driver

It depends. Do you ever need to know if you have multiple FileObjects for a
single file on disk? If yes, your logic won’t work. I recommend using
FsContext in the completion routine and I see no need for worker threads
unless you need to get more information about the file. But, why not use
worker threads anyway? They work just fine and using DriverWorks they are
easy to create and handle. Using the OSR NT Insider article about worker
threads it is very easy to implement them.

BTW, the FileObject that is given for a file might not be the FileObject
used by the cache manager. I have seen that the cache manager seems to use
only one FileObject for the paging reads and writes and not necessarily the
first one seen.

The simplest logic means just passing the create thru in the dispatch
routine after setting up a completion routine. In the completion routine,
get the status and if it didn’t error out, schedule a worker thread or not
since both NTFS & FASTFAT process creates at PASSIVE_LEVEL IRQL. Then set
the flag that shows the file is open and use that file object to query name,
attributes, etc. You can then reset the flag and then complete the request
after you are done.

----- Original Message -----
From: “Scott Elliott”
To: “File Systems Developers”
Sent: Tuesday, April 02, 2002 6:36 PM
Subject: [ntfsd] Re: Tracking down the data in a filter driver

> Tony,
>
> In a previous note you said to get the file name in the IRP_MJ_CREATE call
> and “Normally, then
> people use one of the file characteristics to associate with the file
> itself (either the SectionObjectPointers value, or the FsContext value,
> both of which are unique to a given file, whereas a file object is created
> for each
> new call to open the file.)” In order to save the trouble of chasing down
> the SOP in the completion routine (and perhaps having to kick off worker
> threads), I am currently just tracking the file object address. This way,
> for every open I add the file object to my list and for every successful
> close, I delete the file object from my list. Is this acceptable?
>
> Thanks,
> Scott
>
>
> —
> You are currently subscribed to ntfsd as: xxxxx@yoshimuni.com
> To unsubscribe send a blank email to %%email.unsub%%


You are currently subscribed to ntfsd as: xxxxx@inin.com
To unsubscribe send a blank email to %%email.unsub%%

I think that is the flag, but I didn’t look at some code I have that uses it
when canceling creates on NT4. The FSDs might require that flag be set
before other requests are processed. I have seen some instances where
ZwCreateFile() is called during dispatch processing and the open flagged to
indicate it comes from that driver so it can be passed on down without it
getting checked.

----- Original Message -----
From: “Fuller, Rob”
To: “File Systems Developers”
Sent: Wednesday, April 03, 2002 9:20 AM
Subject: [ntfsd] Re: Tracking down the data in a filter driver

Are you referring to FO_FILE_OPEN or some other flag?

-----Original Message-----
From: David J. Craig [mailto:xxxxx@yoshimuni.com]
Sent: Tuesday, April 02, 2002 7:14 PM
To: File Systems Developers
Subject: [ntfsd] Re: Tracking down the data in a filter driver

It depends. Do you ever need to know if you have multiple FileObjects for a
single file on disk? If yes, your logic won’t work. I recommend using
FsContext in the completion routine and I see no need for worker threads
unless you need to get more information about the file. But, why not use
worker threads anyway? They work just fine and using DriverWorks they are
easy to create and handle. Using the OSR NT Insider article about worker
threads it is very easy to implement them.

BTW, the FileObject that is given for a file might not be the FileObject
used by the cache manager. I have seen that the cache manager seems to use
only one FileObject for the paging reads and writes and not necessarily the
first one seen.

The simplest logic means just passing the create thru in the dispatch
routine after setting up a completion routine. In the completion routine,
get the status and if it didn’t error out, schedule a worker thread or not
since both NTFS & FASTFAT process creates at PASSIVE_LEVEL IRQL. Then set
the flag that shows the file is open and use that file object to query name,
attributes, etc. You can then reset the flag and then complete the request
after you are done.

----- Original Message -----
From: “Scott Elliott”
To: “File Systems Developers”
Sent: Tuesday, April 02, 2002 6:36 PM
Subject: [ntfsd] Re: Tracking down the data in a filter driver

> Tony,
>
> In a previous note you said to get the file name in the IRP_MJ_CREATE call
> and “Normally, then
> people use one of the file characteristics to associate with the file
> itself (either the SectionObjectPointers value, or the FsContext value,
> both of which are unique to a given file, whereas a file object is created
> for each
> new call to open the file.)” In order to save the trouble of chasing down
> the SOP in the completion routine (and perhaps having to kick off worker
> threads), I am currently just tracking the file object address. This way,
> for every open I add the file object to my list and for every successful
> close, I delete the file object from my list. Is this acceptable?
>
> Thanks,
> Scott
>
>
> —
> You are currently subscribed to ntfsd as: xxxxx@yoshimuni.com
> To unsubscribe send a blank email to %%email.unsub%%


You are currently subscribed to ntfsd as: xxxxx@inin.com
To unsubscribe send a blank email to %%email.unsub%%


You are currently subscribed to ntfsd as: xxxxx@yoshimuni.com
To unsubscribe send a blank email to %%email.unsub%%