windowsfilesystemsdriverwindows-kernelfilter-driver

File System Filter Driver - Deny file creation


I created a file system filter driver.

My driver filters IRP_MJ_CREATE and prints the file name.

NTSTATUS DispatchCreate(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp)
{
    PFILE_OBJECT FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;

    DbgPrint("DispatchCreate() : %wZ\n", &FileObject->FileName;)

    return DispatchPassThrough(DeviceObject, Irp);
}

This works fine.

And now I want to get Access Denied on every request to create a new file.

(If possible, 'you do not have permission.')

So I tried a few things.

First, I did the following.

NTSTATUS DispatchCreate(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp)
{
    PFILE_OBJECT FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
    PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);

    ULONG Option = Stack->Parameters.Create.Options;

    if ((Option >> 24) == FILE_CREATE)
    {
        DbgPrint("DispatchCreate() : File Create Denied, %wZ, %x \n", &FileObject->FileName, Option);

        return STATUS_ACCESS_VIOLATION; // or any error code
    }

    return DispatchPassThrough(DeviceObject, Irp);
}

This worked fine, but it worked a bit strange.

For example, if you do not have administrator privileges, you have a little bit of a say when you try to create something in "C:\".

At this time, I don't know the FileObject may be deleted normally.

So I made the following changes.

NTSTATUS DispatchCreate(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp)
{
    PFILE_OBJECT FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
    PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);

    ULONG Option = Stack->Parameters.Create.Options;

    if ((Option >> 24) == FILE_CREATE)
    {
        DbgPrint("DispatchCreate() : File Create Denied, %wZ, %x \n", &FileObject->FileName, Option);

        Irp->IoStatus.Status = STATUS_ACCESS_VIOLATION;
        return Irp->IoStatus.Status;
    }

    return DispatchPassThrough(DeviceObject, Irp);
}

However, a slightly different error message occurs.

I want it to behave exactly the same as when "Access Denied" occurs because I do not have normal privileges.



And there is another question.

Unlike other Dispatch routines, IRP_MJ_CREATE and IRP_MJ_CLOSE do not need IoCompleteRequest().

I confirmed that the handle was returned normally even if I only had the following part. (In user mode.)

return STATUS_SUCCESS;



Thank you for reading.

Please answer about my question.


Solution

  • if you need deny some request in filter - not need pass it to attached device - you need yourself set error status and complete IRP

    Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
    IofCompleteRequest(Irp);// !!!
    return STATUS_ACCESS_DENIED; // ! not Irp->IoStatus.Status - you can not access Irp after call IofCompleteRequest
    

    Unlike other Dispatch routines, IRP_MJ_CREATE and IRP_MJ_CLOSE do not need IoCompleteRequest().

    of course this is absolute false. every Irp must be completed by call IofCompleteRequest