How to prevent explorer from writing the file?

I’m delveloping a filter based on minifilter, my filter need to do some encryption work in the IRP_MJ_WRITE(with PAGING_IO).
It works fine when I use notepad.exe to write some contents, but it can not catch the IRP_MJ_WRITE(with PAGING_IO) when I use wordpad.exe to test. After debugging, I found that when I use wordpad.exe, it is explorer.exe who create a new FILE_OBJECT and do the paging io operation instead of wordpad.exe, so I can not catch the IRP(I use File Stream Handle Context to store process name and file name).
Is there any method to prevent explorer.exe from doing the paging io operation? Because in such condition, I can not tell which process is the real starter of Write Operation. Or is there any other method to tell which is the real starter of Write Operation(instead of File Stream Handle Context)?

The one who have open the file with write access is the real starter of a write.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

wrote in message news:xxxxx@ntfsd…
> I’m delveloping a filter based on minifilter, my filter need to do some encryption work in the IRP_MJ_WRITE(with PAGING_IO).
> It works fine when I use notepad.exe to write some contents, but it can not catch the IRP_MJ_WRITE(with PAGING_IO) when I use wordpad.exe to test. After debugging, I found that when I use wordpad.exe, it is explorer.exe who create a new FILE_OBJECT and do the paging io operation instead of wordpad.exe, so I can not catch the IRP(I use File Stream Handle Context to store process name and file name).
> Is there any method to prevent explorer.exe from doing the paging io operation? Because in such condition, I can not tell which process is the real starter of Write Operation. Or is there any other method to tell which is the real starter of Write Operation(instead of File Stream Handle Context)?
>

But why I use wordpad.exe to write the file, the explorer.exe do the paging io operation?

In general, the first process to open the file is the file object which
is used to initiate the cache map (depending on the underlying file
system) and thus paging IO will be issued using this file object. But
the process which the paging IO is received under, in these cases, is
the system process. So it may be possible that since you are using
Stream Handle contexts, explorer is the first to open the file and that
file object, which is associated to your handle context, is used later
to perform the paging IO. There is nothing you can do about this, it is
a function of how the underlying file system initiate caching.

In the end there is no guaranteed method, in general, to associate a
given paging IO which is received to an originator of a write. You can
collect heuristics such as tracking who the last cached IO was received
and make a guess but memory mapped files will break this approach.

Pete

On 9/2/2014 9:52 PM, xxxxx@serpurity.com wrote:

But why I use wordpad.exe to write the file, the explorer.exe do the paging io operation?


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars 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


Kernel Drivers
Windows File System and Device Driver Consulting
www.KernelDrivers.com
866.263.9295

Before proceeding any further, from what I read here and in your pervious
post make sure your design requirements are realistic or better yet are
they necessary?
Why do you want to associate the encryption status of a file with a name (
be it a process name or something else). Is it relevant in any situation.
You cannot encrypt/decrypt unless you know the process name?
The handle that explorer opens for a file does not mean that only explorer
can read/write from there while the handle is opened. More, if the handle
is closed that does not mean there are no other references left to the
object. In this case who does the file “belong” to? What if a process
opens a file, duplicates the handle in the context of another process and
then exists? Who’s file is that?
Why this association name<->encryption context?
There are system created threads that will do delayed writes to files that
they did not open in the first place.
Try to explain better to us why and what are you trying to do so you might
hear a better solution.
On Sep 3, 2014 5:01 AM, wrote:

> I’m delveloping a filter based on minifilter, my filter need to do some
> encryption work in the IRP_MJ_WRITE(with PAGING_IO).
> It works fine when I use notepad.exe to write some contents, but it can
> not catch the IRP_MJ_WRITE(with PAGING_IO) when I use wordpad.exe to test.
> After debugging, I found that when I use wordpad.exe, it is explorer.exe
> who create a new FILE_OBJECT and do the paging io operation instead of
> wordpad.exe, so I can not catch the IRP(I use File Stream Handle Context to
> store process name and file name).
> Is there any method to prevent explorer.exe from doing the paging io
> operation? Because in such condition, I can not tell which process is the
> real starter of Write Operation. Or is there any other method to tell which
> is the real starter of Write Operation(instead of File Stream Handle
> Context)?
>
> —
> NTFSD is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
> For our schedule of debugging and file system seminars 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
>

The reason why I relate process name with the FILE_OBJECT is that I need to make sure the process which is trying to operate a file have the coresponding access.
For example, I need only notepad.exe have the access to read the txt files. So when my filter catch an IRP trying to read the content of txt, I need to know whether this FILE_OBJECT is created or opened by notepad.exe, if not, this read operation will not be permitted.
Besieds, I need only notepad.exe have the access to write the txt files. So I do not want explorer.exe to write it, and that’s why I asked the previous question, I found sometimes the PAGING_IO(IRP_MJ_WRITE) was finished by explorer.exe instead of notepad.exe.

Well, maybe then you should do this “access check” of yours in the Create
path, and deny the access from there to the processes or entities you don’t
want to have the certain access to the file.
Afterwards if you do it per request(read/write) you are either asking for
trouble or performance issues. You need to take into account all sorts of
FSCTLs or SetFileInfos, on Windows 8, offload read/writes and so on.
Implement your access checks in the create path and build a context to do
your encryption from there. If you allow the Create, then you know the
process is in fact allowed to write/read and you don’t have to go through
all of this useless struggle to find out who “owns” the file.

On Thu, Sep 4, 2014 at 10:45 AM, wrote:

> The reason why I relate process name with the FILE_OBJECT is that I need
> to make sure the process which is trying to operate a file have the
> coresponding access.
> For example, I need only notepad.exe have the access to read the txt
> files. So when my filter catch an IRP trying to read the content of txt, I
> need to know whether this FILE_OBJECT is created or opened by notepad.exe,
> if not, this read operation will not be permitted.
> Besieds, I need only notepad.exe have the access to write the txt files.
> So I do not want explorer.exe to write it, and that’s why I asked the
> previous question, I found sometimes the PAGING_IO(IRP_MJ_WRITE) was
> finished by explorer.exe instead of notepad.exe.
>
> —
> NTFSD is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
> For our schedule of debugging and file system seminars 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
>


Bercea. G.

Thank you for your advice.
After dicussing with you, I just think of the same method as you have mentioned above.
It may be able to implement my design.
Thank you so much! :slight_smile:

This is because the way the VM system works: both Mm and Cc use the *first* file object that is given to them. Typically this is the same, but it is possible for Mm to get one file object and Cc to get a different file object.

For paging I/O, the file object Mm has attached to the section object is used. If this was the file object created to service explorer, then it will be used to perform paging I/O operations.

If you refuse the paging write operation that you associate with “explorer” the changes Notepad has made will be lost (because the paging I/O won’t ever be done against the file object that notepad uses). I suspect that is not what you want to do.

Once data is in virtual memory, it is comingled with all users of that data. That is why in our own encryption work we maintain different Section Object Pointers structures (So FileObject->SectionObjectPointers->DataSectionObject and that’s the Mm control structure that then is used to call back for paging I/O).

Tony
OSR

Thanks for your response, Tony, I’m quite interested in your advice.
But there is one thing I do not understand, how can two FILE_OBJECTs (belongs to the same file stream) have two different DataSectionObject Structures?
If so, how can Mm knows which structure to use to start the paging io?

One way to look at things (that I found helps me) is to think about the
various file related abstractions (handles, FILE_OBJECTs, streams,
sections) as views of various components of the OS of files and at the same
time think about “files” as an abstraction. For example, is the encrypted
data stream and the same decrypted stream the same data or not ? Well, for
some abstractions they’re the same and for others they’re not. From the
user, they’re the same. But from a component that uses handles for example
(IO Manager), they’re different if they have different handles.

To answer your question in this context, my interpretation is that Mm
doesn’t care about file names, FILE_OBJECTs, alternate data streams,
volumes and such. Mm only cares about pages that are either saved on disk
or not (paged vs. non-paged) and for those that are saved, it must know
about the section (ok, maybe I’m oversimplifying things a little but hey,
it’s a model). So Mm doesn’t need to about file streams or FILE_OBJECTs, it
simply must know about Section objects. The association between Section and
FILE_OBJECT happens when the section is created. After that Mm doesn’t
really need to know “well, the user is writing to C:\foo.txt so let me see
which section that is…”, instead Mm always sees writes to pages and it
looks up the section for that view and from there it gets the FILE_OBJECT.
Whether the same data appears in any other section (encrypted or compressed
or simply duplicated) is not a concern for Mm (so that’s how you can have
pages backed by files on a volume that is a ram disk for example).

In short, the “same file stream” is not a concern for Mm. The file system
on the other hand must try to make sure that the various views of the
stream are kept consistent.

Well, hope this actually helps and doesn’t confuse you further :).

Alex.

On Fri, Sep 5, 2014 at 7:39 AM, wrote:

> Thanks for your response, Tony, I’m quite interested in your advice.
> But there is one thing I do not understand, how can two FILE_OBJECTs
> (belongs to the same file stream) have two different DataSectionObject
> Structures?
> If so, how can Mm knows which structure to use to start the paging io?
>
> —
> NTFSD is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
> For our schedule of debugging and file system seminars 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
>

NTFS has been using this trick for 18+ years, so it’s nothing new.

For example, a compressed file has TWO Section Object Pointer (SOP) structures: one that represents the compressed data, and one that represents the uncompressed data. To do this there must be at least two file objects: one that represents the “logical view” of the (uncompressed) file and one that represents the “physical view” of the (compressed) file.

When a page fault occurs on a given address, Mm has data structures that point it to the “right place” from which to get that specific data (VAD trees, for example, though that’s not the only control structure used by Mm). Those control structures point (ultimately) to a “control area” and each control area references a file object.

I’d suggest looking at two different APIs that provide some insight into this: CcGetFileObjectFromSectionPtrs and FsRtlChangeBackingFileObject.

The first tells you what file object is being used by the *cache* manager. The second swaps the current file object for a different file object for both Cc and Mm. That’s because both are maintaining references to a file object.

Tony
OSR

Thanks for your response, Ales and Tony, your repsonse give me a deeper insight into the file system.
Now I understand that different FILE_OBJECTs can have different SectionObjects although they have the same FileStream. But I’m curious about how does Mm deal with the SectionObject created in my filter. Can I just create another SectionObject and set it as the SECTION_OBJECT_POINTERS member in FILE_OBJECT without any notice to Mm? Or maybe there is an API to do this but I do not find it?