How to delete a file with minifilter IRP_MJ_CLEANUP

Hi, All:

I am working on a project of minifilter. The minifilter driver is running
on the file server (win2003 or win2008). The file server has a share folder
which is accessed by a read-only user from remote client. The reparse-point
file(stub) in the share folder is opened by the user (double click). The
stub open is redirected to another file (with the real contents of the stub
file) in the same folder.

I have the following questions:

  1. Is it possible to delete the content file when the user closes the file?
    The user has read-only permissions(share permissions set by windows
    explorer) for the share folder.

  2. I tried the following within the postcreate function, it seems the
    content file can be deleted even if the user has the read-only permission

FltCreateFile(HSMData.Filter, FltObjects->Instance, &FileHandle,
FILE_WRITE_ATTRIBUTES|STANDARD_RIGHTS_ALL, &ObjectAttributes,
&IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, FILE_COMPLETE_IF_OPLOCKED,
NULL, 0, IO_IGNORE_SHARE_ACCESS_CHECK);
FltClose(FileHandle);

  1. But I won’t delete the content file in the postcreate function, because
    I need the file for stub redirection. So I wonder how could I delete the
    content file? I am thinking of putting the delete in precleanup(), but not
    sure how to generate IRP_MJ_CLEANUP within the driver.

  2. within the postcreate() function, after replacing the filename for stub
    redirection, I change the following settings for the new file (content
    file). Data in the following is the FLT_CALLBACK_DATA

Data->Iopb->Parameters.Create.SecurityContext->DesiredAccess |= DELETE;
Data->Iopb->Parameters.Create.FileAttributes |= FILE_ATTRIBUTE_NORMAL;
Data->Iopb->Parameters.Create.ShareAccess |=
(FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE);
Data->Iopb->Parameters.Create.Options |= FILE_DELETE_ON_CLOSE;
Data->IoStatus.Status = STATUS_REPARSE;
Data->IoStatus.Information = IO_REPARSE;

I don’t know whether my settings are right for file delete, why it is not
working (the content file is not deleted after the file is closed)

  1. Should I set Data->Iopb->TargetFileObject (DeletePending, DeleteAccess,
    and SharedDelete) instead of the Data->Iopb->Parameters.Create ? what is
    the difference ?

  2. The pseudo code of precleanup() function is like the following, the
    corresponding FltSetStreamHandleContext( ) is called within postcreate()

FLT_PREOP_CALLBACK_STATUS
PreCleanup (
IN OUT PFLT_CALLBACK_DATA Data,
IN PCFLT_RELATED_OBJECTS FltObjects,
OUT PVOID *CompletionContext
)
{

status = FltGetStreamHandleContext(
FltObjects->Instance, FltObjects->FileObject, &context );

FltReleaseContext(context);
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}

Thank you

In general you cannot delete a file on a remote server that you do not have permissions to access. The remote server is in charge of arbitrating this, not you or your filter (compare local disks where things are much more relaxed because you are in the same security domain).

So if you want to get a file changed on a remote server then you have to use an account which has rights to delete. You then impersonate that account open the file for delete and then delete it (yea I know, gross simplification).

  1. I tried the following within the postcreate function, it seems the
    content file can be deleted even if the user has the read-only permission

That I find suprising (for a REMOTE file, not for a local filesystem), but I’ll note that Read permission != no delete permission, equally you may be being confused by the read only attribute.

I’m not sure I understand your requirements, or architecture, but have you considered what DELETE_ON_CLOSE can do for you?

“Song Zhang” wrote in message news:xxxxx@ntfsd…
Hi, All:

I am working on a project of minifilter. The minifilter driver is running
on the file server (win2003 or win2008). The file server has a share folder
which is accessed by a read-only user from remote client. The reparse-point
file(stub) in the share folder is opened by the user (double click). The
stub open is redirected to another file (with the real contents of the stub
file) in the same folder.

I have the following questions:

1) Is it possible to delete the content file when the user closes the file?
The user has read-only permissions(share permissions set by windows
explorer) for the share folder.

2) I tried the following within the postcreate function, it seems the
content file can be deleted even if the user has the read-only permission

FltCreateFile(HSMData.Filter, FltObjects->Instance, &FileHandle,
FILE_WRITE_ATTRIBUTES|STANDARD_RIGHTS_ALL, &ObjectAttributes,
&IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, FILE_COMPLETE_IF_OPLOCKED,
NULL, 0, IO_IGNORE_SHARE_ACCESS_CHECK);
FltClose(FileHandle);

3) But I won’t delete the content file in the postcreate function, because
I need the file for stub redirection. So I wonder how could I delete the
content file? I am thinking of putting the delete in precleanup(), but not
sure how to generate IRP_MJ_CLEANUP within the driver.

4) within the postcreate() function, after replacing the filename for stub
redirection, I change the following settings for the new file (content
file). Data in the following is the FLT_CALLBACK_DATA

Data->Iopb->Parameters.Create.SecurityContext->DesiredAccess |= DELETE;
Data->Iopb->Parameters.Create.FileAttributes |= FILE_ATTRIBUTE_NORMAL;
Data->Iopb->Parameters.Create.ShareAccess |=
(FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE);
Data->Iopb->Parameters.Create.Options |= FILE_DELETE_ON_CLOSE;
Data->IoStatus.Status = STATUS_REPARSE;
Data->IoStatus.Information = IO_REPARSE;

I don’t know whether my settings are right for file delete, why it is not
working (the content file is not deleted after the file is closed)

5) Should I set Data->Iopb->TargetFileObject (DeletePending, DeleteAccess,
and SharedDelete) instead of the Data->Iopb->Parameters.Create ? what is
the difference ?

6) The pseudo code of precleanup() function is like the following, the
corresponding FltSetStreamHandleContext( ) is called within postcreate()

FLT_PREOP_CALLBACK_STATUS
PreCleanup (
IN OUT PFLT_CALLBACK_DATA Data,
IN PCFLT_RELATED_OBJECTS FltObjects,
OUT PVOID *CompletionContext
)
{

status = FltGetStreamHandleContext(
FltObjects->Instance, FltObjects->FileObject, &context );

FltReleaseContext(context);
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}

Thank you

Hi, Rod:

Many thanks for reply!

My minifilter driver is running on the same server with the shared files.
So there is nothing on the client, read-only user just tries to access the
file through shared folder.

I am quite new to windows driver so not have much knowledge about the basic
concept. My current problem is:

  1. the file the user firstly tries to open(by double click) is a stub file
    (offline reparse-point file), when the user click on the file, the real
    content file will be put in the same folder as the stub file

  2. I used the method to redirect the open to the real content file (
    replace the filename in callback data fileobject, change the callback
    status to STATUS_REPARSE and information to IO_REPARSE). These are done at
    the postcreate() callback function

  3. I need to delete the content file after the user closes the file. I am
    stucking here.
    if I use DELETE_ON_CLOSE with fltcreateFile(), when the fltclose(handle),
    the content file will be deleted, then I can’t redirect to it
    if I use FltSetInformationFile(), I have the similar problem, the
    FltSetInformation() needs the FileObject for the 2nd parameter, and I only
    know the content file name (the FileObject in the callback data represents
    the old stub file). It seems I need to find a method to get the FileObject
    of content file.

Sorry for the stupid questions.
Thank you!

2012/3/23 Rod Widdowson

> In general you cannot delete a file on a remote server that you do not
> have permissions to access. The remote server is in charge of arbitrating
> this, not you or your filter (compare local disks where things are much
> more relaxed because you are in the same security domain).
>
> So if you want to get a file changed on a remote server then you have to
> use an account which has rights to delete. You then impersonate that
> account open the file for delete and then delete it (yea I know, gross
> simplification).
>
> > 2) I tried the following within the postcreate function, it seems the
> > content file can be deleted even if the user has the read-only permission
>
> That I find suprising (for a REMOTE file, not for a local filesystem), but
> I?ll note that Read permission != no delete permission, equally you may
> be being confused by the read only attribute.
>
> I?m not sure I understand your requirements, or architecture, but have you
> considered what DELETE_ON_CLOSE can do for you?
>
> “Song Zhang” wrote in message news:xxxxx@ntfsd.
> …
> Hi, All:
>
> I am working on a project of minifilter. The minifilter driver is running
> on the file server (win2003 or win2008). The file server has a share folder
> which is accessed by a read-only user from remote client. The reparse-point
> file(stub) in the share folder is opened by the user (double click). The
> stub open is redirected to another file (with the real contents of the stub
> file) in the same folder.
>
> I have the following questions:
>
> 1) Is it possible to delete the content file when the user closes the file?
> The user has read-only permissions(share permissions set by windows
> explorer) for the share folder.
>
> 2) I tried the following within the postcreate function, it seems the
> content file can be deleted even if the user has the read-only permission
>
> FltCreateFile(HSMData.Filter, FltObjects->Instance, &FileHandle,
> FILE_WRITE_ATTRIBUTES|STANDARD_RIGHTS_ALL, &ObjectAttributes,
> &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL,
> FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, FILE_COMPLETE_IF_OPLOCKED,
> NULL, 0, IO_IGNORE_SHARE_ACCESS_CHECK);
> FltClose(FileHandle);
>
> 3) But I won’t delete the content file in the postcreate function, because
> I need the file for stub redirection. So I wonder how could I delete the
> content file? I am thinking of putting the delete in precleanup(), but not
> sure how to generate IRP_MJ_CLEANUP within the driver.
>
> 4) within the postcreate() function, after replacing the filename for stub
> redirection, I change the following settings for the new file (content
> file). Data in the following is the FLT_CALLBACK_DATA
>
> Data->Iopb->Parameters.Create.SecurityContext->DesiredAccess |= DELETE;
> Data->Iopb->Parameters.Create.FileAttributes |= FILE_ATTRIBUTE_NORMAL;
> Data->Iopb->Parameters.Create.ShareAccess |=
> (FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE);
> Data->Iopb->Parameters.Create.Options |= FILE_DELETE_ON_CLOSE;
> Data->IoStatus.Status = STATUS_REPARSE;
> Data->IoStatus.Information = IO_REPARSE;
>
> I don’t know whether my settings are right for file delete, why it is not
> working (the content file is not deleted after the file is closed)
>
> 5) Should I set Data->Iopb->TargetFileObject (DeletePending, DeleteAccess,
> and SharedDelete) instead of the Data->Iopb->Parameters.Create ? what is
> the difference ?
>
> 6) The pseudo code of precleanup() function is like the following, the
> corresponding FltSetStreamHandleContext( ) is called within postcreate()
>
> FLT_PREOP_CALLBACK_STATUS
> PreCleanup (
> IN OUT PFLT_CALLBACK_DATA Data,
> IN PCFLT_RELATED_OBJECTS FltObjects,
> OUT PVOID *CompletionContext
> )
> {
>
> status = FltGetStreamHandleContext(
> FltObjects->Instance, FltObjects->FileObject, &context );
>
> FltReleaseContext(context);
> return FLT_PREOP_SUCCESS_NO_CALLBACK;
> }
>
>
> Thank you
>
> —
> NTFSD is sponsored by OSR
>
> 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
>

If you know the stub file name then in postCreate you can check if the file that was just opened has that name (only for successful creates). If so then this means this is the 2nd create (after you have reparsed from the stub file) and the FILE_OBJECT you have (FltObjects->FileObject) is the one you can use for the call to FltSetInformationFile.

Thanks,
Alex.