Removable Devices and Per-Volume Rules
Applications often need to monitor or control filesystem operations on some or all removable drives within a system. This article explains how to use the CBFilter component to implement selective monitoring of these drives.
Volume Names
Whether your application needs to track file operations in real-time or log them asynchronously, it instructs CBFilter on which files to report by adding specific rules. Each rule in CBFilter is based on a file name or a mask, often accompanied by an optional path. For example, you can add rules for "somefile.txt", "*.txt", or "C:\Users\Public\Documents*.txt".
If a path is specified, it must point to an existing volume (drive). Most of us are familiar with Windows paths that start with drive letters, such as "C:" in the previous example. However, Windows internally does not use drive letters to identify files and volumes. Instead, it employs the NT-native format, where paths begin with "\Device\HarddiskVolumeN\" (where N is a number). Drive letters are essentially "DOS device names," which the Win32 subsystem translates into volume names.
With CBFilter, you can reference a volume using a drive letter, a volume GUID, or an NT-native volume name, and the first two names are translated into the NT-native volume name by the component. However, with removable devices, you cannot know the names of these devices before insertion, making it impossible to add rules in advance. Furthermore, the names can change when the device is removed and reinserted. This necessitates adding rules when a new device is connected and removing outdated rules once the device is disconnected.
Events to Use
Both CBFilter and its lightweight counterpart, CBMonitor, provide events that trigger when a device is added or removed. These events include BeforeFilterAttachToVolume, AfterFilterAttachToVolume, AfterFilterDetachFromVolume, NotifyFilterAttachToVolume, and NotifyFilterDetachFromVolume.
Internally, the operating system directs the filter driver to attach to a new volume or detach from it when the volume is unmounted. In turn, the driver informs the user-mode code to fire the corresponding events, which is why they are named FilterAttachToVolume, etc.
Similar to operational events related to filesystem operations, these component events are divided into control events and notifications. The component features synchronous BeforeFilter* and AfterFilter* events, as well as asynchronous NotifyFilter* events for volume-related notifications.
The application specifies which events to fire by adjusting the FireVolumeEvents property. If the events are not needed, this property should be set to 0. If control events, notification events, or both are required, the property should be set accordingly:
filter.FireVolumeEvents = Constants.FS_MOUNT_BOTH;
Which events should the application use when adding and removing rules?
For simpler logging applications, NotifyFilter* events will suffice. Although asynchronous, these events fire quickly after the relevant notification comes to the driver and may be triggered even before the system completes notifying all filter drivers.
Applications that cannot afford to miss any filesystem operations or that selectively attach to specific volumes should use BeforeFilter* or AfterFilter* events. The BeforeFilterAttachToVolume event allows the application to skip the volume entirely and ignore future events, positively impacting system performance.
Both BeforeFilterAttachToVolume and AfterFilterAttachToVolume may provide a volume name as a drive letter in the VolumeName, though this isn't always guaranteed. Regardless, the VolumeNameNT parameter contains the volume name in the NT-native format described earlier.
When adding path-based rules in any of these events, avoid using the value in the VolumeName parameter, as this may lead to a deadlock when trying to resolve the name. Instead, utilize the value in the VolumeNameNT parameter to construct the path, which is safer and faster.
When a device is unplugged and then plugged in again, its volume name may change. Therefore, it is crucial to remove obsolete rules. The application can remove the newly added rule at any time, but if the rule needs to persist until the device is removed, the appropriate place to delete the rule is within an AfterFilterDetachFromVolume or NotifyFilterDetachFromVolume event handler.
Getting Started with CBFilter
You can find an evaluation version of the SDK for your platform and programming language in the Download Center. After downloading and installing the SDK, you will receive a library, sample code, and comprehensive documentation on your system. The documentation includes a "Getting Started" section with programming instructions. Additionally, free technical support is available during the evaluation phase.
We appreciate your feedback. If you have any questions, comments, or suggestions about this article please contact our support team at support@callback.com.