Legacy file system filter driver support in Windows Server 2012

Hi All,

I have a legacy file system filter driver which runs on Windows 2008 R2
capturing file deletion using IRP_MJ_SET_INFORMATION. I would like to know
whether I have to make any modification in it to get it worked in Windows
Server 2012 without moving to mini filter.

Any thoughts on this would be much appreciated.

Cheers,
Vinayak

Hi Vinayak,

You don’t need to do any change to get your driver running.
Everything should work as before.

Regards,

Fernando Roberto da Silva
DriverEntry Kernel Development
http://www.driverentry.com.br

Bear in mind that if your filter is only looking for IRP_MJ_SET_INFORMATION when checking for deletes you are going to miss some deletes. In Windows 8/Server 2012 you’ll miss most deletes. You must also check IRP_MJ_CREATE with the FILE_DELETE_ON_CLOSE CreateOption flag.

This has always been true. Any filter trying to detect deletes that doesn’t check create w/ delete-on-close is broken by design, and always has been.

Christian [MSFT]
This posting is provided “AS IS” with no warranties, and confers no rights.

It is worth mentioning that what Christian said should be considered regardless of implementing the filter as a minifilter or not.


Fernando Roberto da Silva
DriverEntry Kernel Development
http://www.driverentry.com.br

Thanks for the update.

I have made the changes as you mentioned but still has some problems as I am not able to get the file properties of the deleted file.

Here is code snippet.

case IRP_MJ_CREATE:
{
if( ( pIrpStack->Parameters.Create.Options & iChk) == FILE_DELETE_ON_CLOSE )
{

pIrpStack = IoGetNextIrpStackLocation(pIrp);
pIrpStack->MajorFunction = IRP_MJ_QUERY_INFORMATION;
pIrpStack->DeviceObject = pDeviceObject;
pIrpStack->FileObject = pFileObject;
pIrpStack->Parameters.QueryFile.Length = sizeof(FILE_NETWORK_OPEN_INFORMATION);
pIrpStack->Parameters.QueryFile.FileInformationClass = FileNetworkOpenInformation;

IoSetCompletionRoutine(pIrp, IrpCompletion, 0, TRUE, TRUE, TRUE);
IoCallDriver(pDeviceObject, pIrp);

}
}

IOCallDriver returned Invalid Parameter error. Any Ideas why? The same code is working fine under IRP_MJ_SET_INFORMATION till 2008 R2. But unfortunately call is not coming there while deleting from Server 2012.

Also when I goggled things, I have seen that there are pre-create and post-create callbacks in minifilter. How to mange the same in a legacy filter using IRP_MJ_CREATE ?

Expecting warm responses from you guys!!

>IOCallDriver returned Invalid Parameter error. Any Ideas why? The same

code is working fine under IRP_MJ_SET_INFORMATION till 2008 R2. But
unfortunately call is not >coming there while deleting from Server 2012.
Also when I goggled things, I have seen that there are pre-create and
post-create callbacks in minifilter. How to mange the same in a legacy
filter using IRP_MJ_CREATE ?
Expecting warm responses from you guys!!

This is pre-create so obviously there is no file object created yet.
Fileobject should be bogus and you should not be able to send anything down
the stack until the create has completed.

Expecting warm responses from you guys!!

Considering your filter was never working properly there is work to be done,
now is a great time to do yourself a favor and rewrite it using minifilter
techonology. You will be glad you did because you will have load ordering
control, ability to unload your filter and much more:

http://msdn.microsoft.com/en-us/library/windows/hardware/ff538896(v=vs.85).aspx

//Daniel

>>Considering your filter was never working properly there is work to be done,

>now is a great time to do yourself a favor and rewrite it using minifilter
>techonology. You will be glad you did because you will have load ordering
>control, ability to unload your filter and much more:

It is working fine in all windows OS apart from sever 2012 and Windows 8. Would that be a good idea to write a mini filter to just for this purpose?

If you could answer how can I catch “post create” in a legacy filter using IRP_MJ_CREATE , that would be great.

I wouldn’t say it’s working fine if there is a case that’s not working. I often see people that describe their filter as working fine except for the BSOD when happens. It reminds me of the old “the operation was a success, however the patient didn’t survive” joke.

However, to answer your question, you would generally implement “post create” in a legacy filter like you would implement any post operation, you would set an IoCompletion routine on the IRP. There is a page on MSDN on this topic, “Using IoCompletion Routines” (http://msdn.microsoft.com/en-us/library/windows/hardware/ff565398(v=vs.85).aspx). Older WDKs had lots of samples (they are not file systems specific so look for samples for other types of devices as well).

Thanks,
Alex.
On Apr 19, 2013, at 1:37 AM, xxxxx@gmail.com wrote:

>>> Considering your filter was never working properly there is work to be done,
>>> now is a great time to do yourself a favor and rewrite it using minifilter
>>> techonology. You will be glad you did because you will have load ordering
>>> control, ability to unload your filter and much more:
>
> It is working fine in all windows OS apart from sever 2012 and Windows 8. Would that be a good idea to write a mini filter to just for this purpose?
>
> If you could answer how can I catch “post create” in a legacy filter using IRP_MJ_CREATE , that would be great.
>
>
> —
> 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

> It is working fine in all windows OS apart from sever 2012 and Windows 8.

You only *think* that’s the case because DELETE_ON_CLOSE was relatively uncommon prior to Windows 8/Server 2012. But uncommon != nonexistent. If the filter wasn’t checking for DELETE_ON_CLOSE, then there were deletes the filter didn’t even know were taking place.

The reason it’s more obviously broken in Windows 8 is that the Win32 DeleteFile() API and the shell’s delete API changed in Windows 8 to use IRP_MJ_CREATE w/ DELETE_ON_CLOSE. Windows 7 and earlier used IRP_MJ_SET_INFORMATION w/ FileDispositionInformation. We made the change so that deleting files would be more efficient on network shares (open-close vs. open-setinfo-close; cuts out a third of the round trips).

I’d also like to encourage you to move to the minifilter model. That’s all we support now, in terms of producing samples and adding new functionality. The legacy model is strongly discouraged for new filters, and existing filters are strongly encouraged to move to the minifilter model. Besides the load ordering control, unload support and other things Daniel mentioned (and pointed to on MSDN), I’d expect that future enhancements to the file system stack in Windows might tend to assume that no legacy filters are present. I can imagine scenarios where some enhancement would be doable if only minifilters are present, but not if a legacy filter were present, causing performance of the whole machine to suffer.

Christian [MSFT]
This posting is provided “AS IS” with no warranties, and confers no rights.

Presumably you mean “other than filter manager”. I don’t see any realistic scenario in which filter manager would cease to be a legacy filter driver.

Tony
OSR

Catching “post create” in a legacy filter is just like catching post ANYTHING in a legacy filter - you register a completion routine and in the completion routine you check to see if you must post the operation, and if you must post the operation you do so (or you could set an event and synchronize back to the dispatch handler). Then you do whatever operation you needed in the first place.

Tony
OSR

Thank you Guys for your responses!

I do understand that writing a mini filter is much better than this legacy one. However, we may not be able to afford writing a mini filter from scratch. So we better would like to continue with the legacy one for the time being.

This is how we are calling in our driver as well. However, the IOCallDriver returns invalid parameter for shared files in Windows 8/server 2012. We would like to know the answer for this.
It would be great , if anyone can let me the reason behind that. The same code is working fine in Windows 7 for IRP_MJ_SETINFORMATION.

// initialize the synchronization event
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);

// allocate the irp to pass to the next driver
pIrp = IoAllocateIrp(pDeviceObject->StackSize, FALSE);

// build the irp
pIrp->AssociatedIrp.SystemBuffer = pInformation;
pIrp->UserEvent = &Event;
pIrp->UserIosb = &IoSb;
pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
pIrp->Tail.Overlay.OriginalFileObject = pFileObject;
pIrp->RequestorMode = KernelMode;
pIrp->Flags = 0;

// get the next stack location and build it
pIrpStack = IoGetNextIrpStackLocation(pIrp);
pIrpStack->MajorFunction = IRP_MJ_QUERY_INFORMATION;
pIrpStack->DeviceObject = pDeviceObject;
pIrpStack->FileObject = pFileObject;
pIrpStack->Parameters.QueryFile.Length = sizeof(FILE_NETWORK_OPEN_INFORMATION);
pIrpStack->Parameters.QueryFile.FileInformationClass = FileNetworkOpenInformation;

// set the completion routine and call the next driver
// wait for the synchronization event to be set before
// proceeding to implement synchronous behaviour
IoSetCompletionRoutine(pIrp, IrpCompletion, 0, TRUE, TRUE, TRUE);

IoCallDriver(pDeviceObject, pIrp);

KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0);

>able to afford writing a mini filter from scratch.

Minifilters are very simple, they are like lesser then a screen of code for an empty skeleton.


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