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.
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