Tips for Writing a File System Filter

There have been a few questions posted to the newsgroup over the past few months on the scope the initial setup, and the registry settings of file system filters. I hope to answer some of the most commonly asked questions here.

File system filter scope:

With Windows CE version 4.0 any file system can be filtered with the exception of the ROM\RAM file system. Because version 4.0 allows the boot device to be something other than ROM\RAM when using the hive-based registry, OEMs can put the registry hive on a boot device and filter it. OEMs can filter the boot device but others may not be able to because the image used to boot must include the registry settings pertaining to the filter early in the boot phase, which requires changing the ROM image.

With other media besides the boot device, the filter registry keys can be added to the registry then the media dismounted and remounted, which loads the filter. If you dismount and remount the boot device, the registry hive will become "invalid" leading to crashes, strange behavior, etc. Needless to say, dismounting the boot device is not recommended.

Initial setup

:

The initial setup of the filter can be taken from the filter example FSDSPY which is under

%_WINCEROOT%\public\common\oak\drivers\fsd\fsdspy\

The filter is initialized during HookVolume, which will need to set up some type of volume object that will store the FilterHook. Make sure to actually memcpy() the FilterHook. Simply using a pointer to the FilterHook can lead to problems if there are filters loaded above yours because the API set that the FSDMGR is pointing to can change.

The .def file needs to include every file system function that you plan to implement or pass through to the underlying file system. If you are stubbing a function entirely, then it can be left out of the .def file.

The FILTERHOOK file system functions are declared as .pReadFile, pFlushFileBuffers, etc. (listed in full here https://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceobjst/html/cerefFILTERHOOK.asp ) Below the FilterHook declaration are pointers to the various MyFSD functions that describe the function parameters.

Registry Keys:

The most important registry key is that which gets your filter loaded. There are three places that the FSDMGR will look for the dll for non-autoload file systems when media is loaded. If we are using MSFlash, using FATFS, the filter is named MyFilter, and the filter's dll is named myfilterdll.dll, then the three places are:

This key will add the filter to every volume:
  [HKEY_LOCAL_MACHINE\System\StorageManager\Filters\MyFilter]
This key will add the filter to every volume that has the profile MSFLASH:
  [HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MSFlash\Filters\MyFilter]
This key will add the filter to every volume that has the profile MSFLASH and uses FATFS:
  [HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MSFlash\FATFS\Filters\MyFilter]

There are similar places for autoload file system filters to be loaded, such as RELFSD:
  [HKEY_LOCAL_MACHINE\System\StorageManager\AutoLoad\Relfsd\Filters\MyFilter]

The value and its value are: "Dll"="myfilterdll.dll" An additional value "Order" can be used, with the values from 0 to (DWORD)-1. The lower the filter's order, the higher it is on the file system stack (the farther it is from the FSD, and the closer to it is to the user). In other words, the filter with the highest order number is loaded first, with the next highest being loaded on top of it.  If there is only one filter, this does not matter, but if you're layering filters, this is quite important. If the order is left unspecified then the ordering of the filters is also unspecified.

If you are able to make your own images, and you want to put the filter on the boot device, wrap the registry key containing your "Dll" value in a hive boot section:

  ; HIVE BOOT SECTION
  [HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MSFlash\FATFS\Filters\MyFilter]
       "Dll"="myfilterdll.dll"
       "Order"=dword:2
  ; END HIVE BOOT SECTION

In Windows CE version 4.0 and up, there are functions available to filters that can be called to easily open registry keys. The functions are those that are prefixed with FSDMGR_GetRegistry*. The full list is located here:

https://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcedata5/html/wce50grffsdfunctions.asp

The HDSK used as the first parameter for the GetRegistry functions is the HDSK passed to the FilterHook during HookVolume.  The registry key these functions look at is:

[HKEY_LOCAL_MACHINE\System\StorageManager\Filters\MyFilter]
   "MyValue"=dword:4

Other registry keys can be used or created, but they need to be opened, read, and closed as usual

-- Please note, when the filter is installed on the boot device, reading or writing to the registry anytime outside of the HookVolume call is not a good idea, regardless of whether the filter or a function the filter calls does the registry operation. Registry access in this situation can and will lead to deadlocks within the file system.--

Ariane