Is there an easy (if any) way to detect and filter out the RAW read/write operations targeted to the volume on which an instance of my minifilter exits (FAT32 currently)?
Basically I want to avoid swapping buffers (and modyfing them) for any RAW operations targeted to a volume because if I do so I mess up the entire filesystem structure (i.e. when using Format /r or Chkdsk).
Konrad
It is easy to detect by a file object.
If someone opens the disk, you see this in create request by the file name.
If FSD has created a stream file object, you see this by the stream flag in
FO and FsContext which is not related with any file stream opened in create
request.
–
Slava Imameyev, xxxxx@hotmail.com
wrote in message news:xxxxx@ntfsd…
> Is there an easy (if any) way to detect and filter out the RAW read/write
> operations targeted to the volume on which an instance of my minifilter
> exits (FAT32 currently)?
>
> Basically I want to avoid swapping buffers (and modyfing them) for any RAW
> operations targeted to a volume because if I do so I mess up the entire
> filesystem structure (i.e. when using Format /r or Chkdsk).
>
> Konrad
>
Correction. Instead “which is not related with any file stream opened in
create
request” read “which is not related with any file stream opened in create
request, except the direct disk opening”, because user’s applications may
open the disk and the FsContext for this FOs and the stream FOs might be the
same.
–
Slava Imameyev, xxxxx@hotmail.com
“Slava Imameyev” wrote in message news:xxxxx@ntfsd…
> It is easy to detect by a file object.
> If someone opens the disk, you see this in create request by the file
> name.
> If FSD has created a stream file object, you see this by the stream flag
> in FO and FsContext which is not related with any file stream opened in
> create request.
>
> –
> Slava Imameyev, xxxxx@hotmail.com
>
>
> wrote in message news:xxxxx@ntfsd…
>> Is there an easy (if any) way to detect and filter out the RAW read/write
>> operations targeted to the volume on which an instance of my minifilter
>> exits (FAT32 currently)?
>>
>> Basically I want to avoid swapping buffers (and modyfing them) for any
>> RAW operations targeted to a volume because if I do so I mess up the
>> entire filesystem structure (i.e. when using Format /r or Chkdsk).
>>
>> Konrad
>>
>
>
>
Thanks Slava. That sound promising but although I read it couple of times I’m lost. Can you explain this issue in more detail to my tired brain?
K.
For each read/write you have a file object.
You may use the FSD and query the name for the file object, read in DDK
about where you can call FltGetFileNameInformation and
FltGetFileNameInformationUnsafe. But for the stream file object the FSD can
return any name.
File objects for the same data stream have the same FsContext ( Stream
Context ) field, this field is initialized by a File System Driver( see
http://www.osronline.com/article.cfm?id=102 ).
The file object may be
- object opened by the Object Manager, i.e. initialized in IRP_MJ_CREATE
- object created by IoCreateStremFileObject(), then the FO_STREAM_FILE flag
is set. Such FOs are created internally by the FSD.
Let’s use the word ‘volume’ instead ‘disk’ otherwise we will be corrected.
If an application opens a volume, then the Object Manager calls the IO
Manager which creates an IRP with IRP_MJ_CREATE major function and
FileObject with the empty name( FileObject->FileName ), if
FileObject->RelatedFileObject is present it must be already opened file
object for the volume. So you know exactly what this FO represents.
If you receive read/write request and the file object has the
FO_STREAM_FILE flag you must decide whether this stream file describes the
entire volume or internal FSD’s data( which may be a file on a volume) or a
simple file from the volume. You must connect this stream FO with the
FsContext for FOs opened in IRP_MJ_CREATE request. About Stream Context and
what to do with it read in http://www.osronline.com/article.cfm?id=102 .
If you failed to find Stream Context , then this is
- a stream file object for which all FOs opened in IRP_MJ_CREATE have been
closed and you have never seen this stream FO before and this stream FO is
not used to back a section. Very infrequent scenario( maybe impossible ).
- a Stream FO which is used by the FSD to map its internal data( not
necessary the volume, may be a file ).
How to distinguish the first from the second? For me, it seems that w/o
FSD’s support it is impossible and currently there is no such support. You
can try to query FO’s name, but FSD can return any name for a stream file
object. Try to develop your own heuristic algorithm.
–
Slava Imameyev, xxxxx@hotmail.com
wrote in message news:xxxxx@ntfsd…
> Thanks Slava. That sound promising but although I read it couple of times
> I’m lost. Can you explain this issue in more detail to my tired brain?
>
> K.
>
Thanks for this indeed comprehensive lecture. It seems to be clearer for me. I think the NTFSD FAQ should be updated with such info.
As I’m interested ONLY in real data being written to the FAT32 volume (non cached and paging I/Os) I do the following:
In the PostCreate routine:
- I process only I/Os with the following characteristics:
- Data->IoStatus.Status is successful and is not set to STATUS_REPARSE;
- FltObjects->FileObject != NULL;
- FltIsDirectory() gives false;
- FltGetFileNameInformation() is succssful;
- FltParseFileNameInformation() is succssful and fills in all necessary fields;
- pNameInfo->FinalComponent.Length is not NULL;
- I then try to get a stream context for them using FltGetStreamContext();
- If that failed (there is no context) I set it up with FltAllocateContext();
- I set the BOOLEAN variable in that context to TRUE (means I marked this I/O in PostCreate)
Then in the PreWrite routine:
- I process only I/Os with the following characteristics:
- FltObjects->FileObject != NULL;
- Data->Iopb->Parameters.Write.Length != NULL;
- FltIsDirectory() gives FALSE;
- Data->Iopb->TargetFileObject->Flags does not contain the FO_STREAM_FILE flag;
- I can get the context for this particulat I/O through FltGetStreamContext();
- I then check the BOOLEAN. If it’s set to TRUE it means my minifliter ‘saw’ this I/O in PostCreate;
I have checked this algotithm with the following applications (results in brackets):
- FORMAT (no IRP_MJ_WRITE I/Os received - works fine),
- CHKDSK /F /X /R (no IRP_MJ_WRITE I/Os received - works fine),
- Notepad (only IRP_MJ_WRITE I/Os with stream data received),
- Wordpad (only IRP_MJ_WRITE I/Os with stream data received),
- Word 2003 (only IRP_MJ_WRITE I/Os with stream data received).
It seems to be working fine as I’m not getting any I/Os that are not interesting to my minifilter, though I would like to have some comments from list members (especially comments that point out any inconsistence in the above algorithm).
Are there any other ‘challenging applications’ that I should run on that volume to check the minifilter works fine?
Konrad
>I’m interested ONLY in real data being written to the FAT32 volume (non
cached and paging I/Os)
Good for current design of the FAT 32 driver( it always uses the Cache
Manager ), but not good for other FSDs and future FAT’s releases, because
FSD may decide not to use the cache Manager for some files or requests.
Data->Iopb->TargetFileObject->Flags does not contain the FO_STREAM_FILE
flag;
Reasonable for FAT 32 FSD( it uses stream file objects only for mapping the
entire disk and directory files ), but other FSDs( i.e. NTFS ) can create a
stream file object which is used to back segment objects( i.e. memory mapped
files ) for a real data file.
–
Slava Imameyev, xxxxx@hotmail.com
wrote in message news:xxxxx@ntfsd…
> Thanks for this indeed comprehensive lecture. It seems to be clearer for
> me. I think the NTFSD FAQ should be updated with such info.
>
> As I’m interested ONLY in real data being written to the FAT32 volume (non
> cached and paging I/Os) I do the following:
>
> In the PostCreate routine:
>
> 1) I process only I/Os with the following characteristics:
> - Data->IoStatus.Status is successful and is not set to STATUS_REPARSE;
> - FltObjects->FileObject != NULL;
> - FltIsDirectory() gives false;
> - FltGetFileNameInformation() is succssful;
> - FltParseFileNameInformation() is succssful and fills in all necessary
> fields;
> - pNameInfo->FinalComponent.Length is not NULL;
> 2) I then try to get a stream context for them using
> FltGetStreamContext();
> 3) If that failed (there is no context) I set it up with
> FltAllocateContext();
> 4) I set the BOOLEAN variable in that context to TRUE (means I marked this
> I/O in PostCreate)
>
> Then in the PreWrite routine:
>
> 1) I process only I/Os with the following characteristics:
> - FltObjects->FileObject != NULL;
> - Data->Iopb->Parameters.Write.Length != NULL;
> - FltIsDirectory() gives FALSE;
> - Data->Iopb->TargetFileObject->Flags does not contain the FO_STREAM_FILE
> flag;
> - I can get the context for this particulat I/O through
> FltGetStreamContext();
> 2) I then check the BOOLEAN. If it’s set to TRUE it means my minifliter
> ‘saw’ this I/O in PostCreate;
>
> I have checked this algotithm with the following applications (results in
> brackets):
> - FORMAT (no IRP_MJ_WRITE I/Os received - works fine),
> - CHKDSK /F /X /R (no IRP_MJ_WRITE I/Os received - works fine),
> - Notepad (only IRP_MJ_WRITE I/Os with stream data received),
> - Wordpad (only IRP_MJ_WRITE I/Os with stream data received),
> - Word 2003 (only IRP_MJ_WRITE I/Os with stream data received).
>
> It seems to be working fine as I’m not getting any I/Os that are not
> interesting to my minifilter, though I would like to have some comments
> from list members (especially comments that point out any inconsistence in
> the above algorithm).
>
> Are there any other ‘challenging applications’ that I should run on that
> volume to check the minifilter works fine?
>
> Konrad
>
>disk
As usual instead of ‘volume’ I wrote ‘disk’. The FAT FSD maps the volume( in
memory only a small part of the volume with the internal data ).
–
Slava Imameyev, xxxxx@hotmail.com
“Slava Imameyev” wrote in message news:xxxxx@ntfsd…
> >I’m interested ONLY in real data being written to the FAT32 volume (non
> >cached and paging I/Os)
>
> Good for current design of the FAT 32 driver( it always uses the Cache
> Manager ), but not good for other FSDs and future FAT’s releases, because
> FSD may decide not to use the cache Manager for some files or requests.
>
>>Data->Iopb->TargetFileObject->Flags does not contain the FO_STREAM_FILE
>>flag;
>
> Reasonable for FAT 32 FSD( it uses stream file objects only for mapping
> the entire disk and directory files ), but other FSDs( i.e. NTFS ) can
> create a stream file object which is used to back segment objects( i.e.
> memory mapped files ) for a real data file.
>
>
> –
> Slava Imameyev, xxxxx@hotmail.com
>
>
> wrote in message news:xxxxx@ntfsd…
>> Thanks for this indeed comprehensive lecture. It seems to be clearer for
>> me. I think the NTFSD FAQ should be updated with such info.
>>
>> As I’m interested ONLY in real data being written to the FAT32 volume
>> (non cached and paging I/Os) I do the following:
>>
>> In the PostCreate routine:
>>
>> 1) I process only I/Os with the following characteristics:
>> - Data->IoStatus.Status is successful and is not set to STATUS_REPARSE;
>> - FltObjects->FileObject != NULL;
>> - FltIsDirectory() gives false;
>> - FltGetFileNameInformation() is succssful;
>> - FltParseFileNameInformation() is succssful and fills in all necessary
>> fields;
>> - pNameInfo->FinalComponent.Length is not NULL;
>> 2) I then try to get a stream context for them using
>> FltGetStreamContext();
>> 3) If that failed (there is no context) I set it up with
>> FltAllocateContext();
>> 4) I set the BOOLEAN variable in that context to TRUE (means I marked
>> this I/O in PostCreate)
>>
>> Then in the PreWrite routine:
>>
>> 1) I process only I/Os with the following characteristics:
>> - FltObjects->FileObject != NULL;
>> - Data->Iopb->Parameters.Write.Length != NULL;
>> - FltIsDirectory() gives FALSE;
>> - Data->Iopb->TargetFileObject->Flags does not contain the FO_STREAM_FILE
>> flag;
>> - I can get the context for this particulat I/O through
>> FltGetStreamContext();
>> 2) I then check the BOOLEAN. If it’s set to TRUE it means my minifliter
>> ‘saw’ this I/O in PostCreate;
>>
>> I have checked this algotithm with the following applications (results in
>> brackets):
>> - FORMAT (no IRP_MJ_WRITE I/Os received - works fine),
>> - CHKDSK /F /X /R (no IRP_MJ_WRITE I/Os received - works fine),
>> - Notepad (only IRP_MJ_WRITE I/Os with stream data received),
>> - Wordpad (only IRP_MJ_WRITE I/Os with stream data received),
>> - Word 2003 (only IRP_MJ_WRITE I/Os with stream data received).
>>
>> It seems to be working fine as I’m not getting any I/Os that are not
>> interesting to my minifilter, though I would like to have some comments
>> from list members (especially comments that point out any inconsistence
>> in the above algorithm).
>>
>> Are there any other ‘challenging applications’ that I should run on that
>> volume to check the minifilter works fine?
>>
>> Konrad
>>
>
>
>