Preventing file writes to specific location

Hi,

in my minifilter I’m trying to cancel all file writes to specific location (e.g. “C:\location”) but can’t get things to work properly. With “preventing writes” I mean I don’t want the file-to-be-written to appear in that location at all - or appear and have a size of 0 bytes, whichever of these two options.
Before I “prevent” the file from being written, I still need access to its WriteBuffer, which I pass to user-space application.

Roughly, what I’ve been trying so far is:

  1. send WriteBuffer to user application (works);
  2. check where the file is being written to (works);
  3. if the file is being written to unwanted location, set (after WriteBuffer has been sent to user app):
    Data->Iopb->Parameters.Write.WriteBuffer = NULL;
    Data->Iopb->Parameters.Write.Length = 0;
  4. Call FltSetCallbackDataDirty().

This does what I want for simple writes where only one IRP_MJ_WRITE occurs - e.g. saving a text file created with notepad. A file of 0 bytes is created in this case, which is fine.

However, when there are multiple consequent IRP_MJ_WRITEs, saving of that file will fail - the file won’t get created in undesired location, but only the first WriteBuffer will be send to user-app, while the following won’t. Examples of this behavior: saving a .bmp image created in Paint (paint return errors), saving a .doc file.

I also tried redirecting TargetFileObject to RecycleBin - didn’t work either + I don’t really like the solution.

Any ideas what to do? Any help would be appreciated.

Thanks in advance.

Hi,

You can base your code on the WDK example
(\src\filesys\miniFilter\scanner\filter

  • line 1001 to 1008). In this case you can just deny the first write and
    return STATUS_ACCESS_DENIED to the caller.

Something like in the example code:

if (!FlagOn( Data->Iopb->IrpFlags, IRP_PAGING_IO )) {

DbgPrint( “!!! scanner.sys – blocking the write !!!\n” );

Data->IoStatus.Status = STATUS_ACCESS_DENIED;
Data->IoStatus.Information = 0;
returnStatus = FLT_PREOP_COMPLETE;
}

I think that it can solve your problem.

Thiago Brito

On Tue, Aug 19, 2008 at 11:03 AM, wrote:

> Hi,
>
> in my minifilter I’m trying to cancel all file writes to specific location
> (e.g. “C:\location”) but can’t get things to work properly. With “preventing
> writes” I mean I don’t want the file-to-be-written to appear in that
> location at all - or appear and have a size of 0 bytes, whichever of these
> two options.
> Before I “prevent” the file from being written, I still need access to its
> WriteBuffer, which I pass to user-space application.
>
> Roughly, what I’ve been trying so far is:
> 1. send WriteBuffer to user application (works);
> 2. check where the file is being written to (works);
> 3. if the file is being written to unwanted location, set (after
> WriteBuffer has been sent to user app):
> Data->Iopb->Parameters.Write.WriteBuffer = NULL;
> Data->Iopb->Parameters.Write.Length = 0;
> 4. Call FltSetCallbackDataDirty().
>
> This does what I want for simple writes where only one IRP_MJ_WRITE occurs
> - e.g. saving a text file created with notepad. A file of 0 bytes is created
> in this case, which is fine.
>
> However, when there are multiple consequent IRP_MJ_WRITEs, saving of that
> file will fail - the file won’t get created in undesired location, but only
> the first WriteBuffer will be send to user-app, while the following won’t.
> Examples of this behavior: saving a .bmp image created in Paint (paint
> return errors), saving a .doc file.
>
> I also tried redirecting TargetFileObject to RecycleBin - didn’t work
> either + I don’t really like the solution.
>
>
> Any ideas what to do? Any help would be appreciated.
>
> Thanks in advance.
>
>
>
> —
> NTFSD is sponsored by OSR
>
> For our schedule debugging and file system seminars
> (including our new fs mini-filter seminar) visit:
> http://www.osr.com/seminars
>
> You are currently subscribed to ntfsd as: xxxxx@gasinf.com.br
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>

There’s no way you can make something like this work often enough. Consider this scenario:

  • User writes uncached 64K
  • User reads uncached 64K at the same location.
    He would get some sort of an error at the read part.
    What you can at best do is return STATUS_SUCCESS for IRP_NOCACHE writes, but you’d still be left with the above problem, unless you buffer and keep the writes in memory for subsequent reads, which you can’t do on a real system due to possible amount of written data.
    You cannot return STATUS_ACCESS_DENIED for paging reads/writes, it will cause an endless loop of retries.
    Can you shed some light on the purpose of this application?

Regards, Dejan.

xxxxx@hermes.si wrote:

Hi,

in my minifilter I’m trying to cancel all file writes to specific location (e.g. “C:\location”) but can’t get things to work properly. With “preventing writes” I mean I don’t want the file-to-be-written to appear in that location at all - or appear and have a size of 0 bytes, whichever of these two options.
Before I “prevent” the file from being written, I still need access to its WriteBuffer, which I pass to user-space application.

Roughly, what I’ve been trying so far is:

  1. send WriteBuffer to user application (works);
  2. check where the file is being written to (works);
  3. if the file is being written to unwanted location, set (after WriteBuffer has been sent to user app):
    Data->Iopb->Parameters.Write.WriteBuffer = NULL;
    Data->Iopb->Parameters.Write.Length = 0;
  4. Call FltSetCallbackDataDirty().

This does what I want for simple writes where only one IRP_MJ_WRITE occurs - e.g. saving a text file created with notepad. A file of 0 bytes is created in this case, which is fine.

However, when there are multiple consequent IRP_MJ_WRITEs, saving of that file will fail - the file won’t get created in undesired location, but only the first WriteBuffer will be send to user-app, while the following won’t. Examples of this behavior: saving a .bmp image created in Paint (paint return errors), saving a .doc file.

I also tried redirecting TargetFileObject to RecycleBin - didn’t work either + I don’t really like the solution.

Any ideas what to do? Any help would be appreciated.

Thanks in advance.


NTFSD is sponsored by OSR

For our schedule debugging and file system seminars
(including our new fs mini-filter seminar) visit:
http://www.osr.com/seminars

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


Kind regards, Dejan (MSN support: xxxxx@alfasp.com)
http://www.alfasp.com
File system audit, security and encryption kits.

Failing the writes with STATUS_ACCESS_DENIED is a bad idea.

What the OP might want to do is keep the write IRPs from going down to the file system and complete the writes with STATUS_SUCCESS and IoStatus.Information set to the number of bytes to be written.

Regards,
Razvan

Hi,

Now I understood what OP want. Just to better understand the piece of code,
the access is denied only when IRP in *non-paged* like the follow line show:

*if (!FlagOn( Data->Iopb->IrpFlags, IRP_PAGING_IO ))

Regards,
*Thiago Brito

On Tue, Aug 19, 2008 at 5:08 PM, Razvan Hobeanu wrote:

> Failing the writes with STATUS_ACCESS_DENIED is a bad idea.
>
> What the OP might want to do is keep the write IRPs from going down to the
> file system and complete the writes with STATUS_SUCCESS and
> IoStatus.Information set to the number of bytes to be written.
>
> Regards,
> Razvan
>
>
>
>
> —
> NTFSD is sponsored by OSR
>
> For our schedule debugging and file system seminars
> (including our new fs mini-filter seminar) visit:
> http://www.osr.com/seminars
>
> You are currently subscribed to ntfsd as: xxxxx@gmail.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>

This has been asked and answered so many times it should be easy to find it in either the FAQ or via the search UI on the OSR online web interface. You cannot prohibit writes either at the storage level or at the file system level (except for IRP_MJ_CREATE). Change the create to disallow writes and then it will just work automagically (automatically).
“Thiago Brito” wrote in message news:xxxxx@ntfsd…
Hi,

Now I understood what OP want. Just to better understand the piece of code, the access is denied only when IRP in non-paged like the follow line show:

if (!FlagOn( Data->Iopb->IrpFlags, IRP_PAGING_IO ))

Regards,
Thiago Brito

On Tue, Aug 19, 2008 at 5:08 PM, Razvan Hobeanu wrote:

Failing the writes with STATUS_ACCESS_DENIED is a bad idea.

What the OP might want to do is keep the write IRPs from going down to the file system and complete the writes with STATUS_SUCCESS and IoStatus.Information set to the number of bytes to be written.

Regards,
Razvan


NTFSD is sponsored by OSR

For our schedule debugging and file system seminars
(including our new fs mini-filter seminar) visit:
http://www.osr.com/seminars

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

David:
I’m sorry if this has been asked before, I’d searched but hadn’t found anything useful. If I missed something, links and/or search keywords are just as welcome.
As for your advice - but wouldn’t that prevent me from accessing write buffers in pre-write (since there would be none)?

Razvan:
thanks, I’ve tried what you said and it’s worked partially… for some files yes, for some no (some files still get written, although it is possible this is due to some unidentified bugs in my code, not sure). What I do in pre-write (for files written to unwanted location) is:
Data->IoStatus.Information = Data->Iopb->Parameters.Write.Length;
return FLT_PREOP_COMPLETE; // not sure if this is ok?

Dejan:
"- User writes uncached 64K

  • User reads uncached 64K at the same location."
    You can suppose this won’t happen (isolated environment). Unfortunately I can’t disclose details about what I’m doing; what I can tell is that there is a single application writing a series of files to “unwanted” folder (there are more - about 5 to 20 - IRP_MJ_WRITEs per each file);
    I want to send data-to-be-written (each buffer) to user-space application (which I successfully do) and afterwards fail the original write (=problematic part).

Thanks for quick replies everyone.

In that case, add
Data->IoStatus.Status = STATUS_SUCCESS;

Data->IoStatus.Information = Data->Iopb->Parameters.Write.Length;
return FLT_PREOP_COMPLETE; // not sure if this is ok?

These 3 lines will work. Note: check for IRP_NOCACHE not IRP_PAGING_IO.

Dejan:
"- User writes uncached 64K

  • User reads uncached 64K at the same location."
    You can suppose this won’t happen (isolated environment). Unfortunately I can’t disclose details about what I’m doing; what I can tell is that there is a single application writing a series of files to “unwanted” folder (there are more - about 5 to 20 - IRP_MJ_WRITEs per each file);
    I want to send data-to-be-written (each buffer) to user-space application (which I successfully do) and afterwards fail the original write (=problematic part).

Thanks for quick replies everyone.


NTFSD is sponsored by OSR

For our schedule debugging and file system seminars
(including our new fs mini-filter seminar) visit:
http://www.osr.com/seminars

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


Kind regards, Dejan (MSN support: xxxxx@alfasp.com)
http://www.alfasp.com
File system audit, security and encryption kits.