Redirection of File Access with CBFS Filter


CBFilter is a component of CBFS Filter, an SDK and library designed for controlling various system activities, including filesystem operations. This component—available as a class, struct, or trait depending on your programming language — enables you to control all types of filesystem operations within your Windows applications. The article reviews the ways and available mechanisms for redirection of filesystem requests using the CBFilter component.

Redirection of file access (file creation and opening, directory access, file reading or writing, etc.) can be used in multiple scenarios such as

  • Data migration and integration of legacy systems. Old applications often use hard-coded paths to directories and files. Sometimes, having the data at the expected location is not possible or requires specific user rights, that are not feasible to grant and maintain.
  • Virtualization and remote access. File access redirection can direct file operations to a central server or cloud storage, enabling remote users to access files seamlessly as if they were on a local drive. This is crucial for maintaining productivity and collaboration in distributed teams.
  • Improved security and compliance. Organizations need to enforce data security and compliance measures. By redirecting file access to secure locations or encrypted storage, businesses can ensure sensitive data is handled according to compliance requirements (e.g., GDPR, HIPAA). For instance, files might be redirected to a secure server where access can be controlled and monitored.
  • Dynamic file management. Businesses often experience variable workloads and need to manage storage efficiently. Redirection can be used to route file access to different storage solutions based on load, performance, or cost. For example, less frequently accessed files can be redirected to lower-cost cloud storage, while frequently accessed files remain on faster local disks.
  • User-specific customizations. Different users or departments have varying file access needs. Redirection can be configured to send specific users or departments to customized file locations based on their roles. For example, the finance department could have access redirected to financial databases, while the HR department accesses personnel files stored in a different location.
  • Version Control and Backup Solutions. Redirection can point file access requests to a version control system or backup location. This ensures that any changes to files are saved with versioning in place, facilitating easier recovery and management of different file versions.
  • Testing and Development Environments. During development and testing of applications, file access redirection can direct file operations to a sandbox environment, allowing developers to test changes without affecting production data. This minimizes risk and allows for thorough testing before deployment.

CBFilter offers several mechanisms for file redirection, providing varying speeds of handling and levels of control over operations based on application needs. The following mechanisms are explored in depth in this article:

  1. Reparse Rules: These rules can be added or removed at will. When present, they are processed directly by the driver without reverting to user mode, which enhances processing speed.
  2. Event-based redirection: An event is fired when for each creation or opening of a file or directory, allowing for real-time handling.
  3. File isolation: applications can dynamically decide how each file event is processed, with the option to redirect requests to remote locations such as cloud storage, document management systems, or databases.
  4. Reparse points: They are applied to files and directories; when such a file or directory is accessed, the filesystem returns a special kind of response. Applications can manage reparse points and utilize CBFilter to handle these specialized responses for the reparse points they create.

Note: In Windows, the terms "reparse" and "reparsing" refer to changing the destination of a file creation or opening operation. Consequently, the rules and events in CBFilter also use the term "Reparse."

Reparse Rules

CBFilter includes a powerful mechanism for defining rules, which dictate how the driver handles requests and makes the CBFilter component fire events. An application can define a rule that reparses a file, directory, or group of files based on a specified mask to redirect them to another location. These rules are processed by the driver whenever a file or directory is created or opened, and no events occur in the case of a rule (unless explicitly configured otherwise).

Once added, reparse rules remain active until they are removed or until the system is rebooted if the application that added them terminates without removing them. Unlike default rules, reparse rules are not stored in the registry and are not reactivated after a system restart.

Reparse rules are added using the AddReparseRule method:

filter.AddReparseRule("C:\\Users\\Username\\Documents\\*.docx", "C:\\ProgramData\\MyEncryptor\\Username\\*.docx", "{your application GUID here}", Constants.FS_REPARSE_USE_REPARSE_POINT);

The first two parameters specify the source and destination for the reparse operation. Details regarding mask matching are covered in the AddReparseRule help topic. The application GUID allows the driver to differentiate between applications that add and remove rules, protecting the rules from being removed by other applications.

The final parameter, Flags, indicates to the driver which mechanism to use for reparsing. The driver can either modify the path on-the-fly and forward the request with the new path, or it can return the STATUS_REPARSE result code as a response to a file creation or opening request.

The first mechanism is internal to the driver, while the second mechanism is the one that OS developers provide for redirections (the flag in the above call corresponds to this mechanism). However, using reparse points and STATUS_REPARSE can pose challenges for some applications, while substituting the path within the driver is transparent to the caller.

Event-Based Redirection

If static rules are not feasible for any reason, you can set up a filter rule that triggers the ReparesFileName event. This event will fire whenever a file or directory matching a specified mask is created or opened, allowing the event handler to dynamically redirect access to that file.

To add a filter rule, an application should use the following call:

filter.AddFilterRule("C:\\path\\to\\directory\\*.txt", Constants.ACCESS_NONE, Constants.FS_CE_REPARSE_FILENAME, Constants.FS_NE_NONE);

This rule will tell the component to fire the ReparseFileName event, which is triggered before the BeforeCreateFile or BeforeOpenFile events.

Within the event handler for ReparseFileName, the application can inspect details related to the request, such as the name and PID of the process that initiated it (please refer to the GetOriginator* methods for more details). The application can then decide whether to redirect the request and specify the destination.

Redirection via events offers greater flexibility in two key ways: the event handler can evaluate various conditions, and the rule can be extended using the AddFilterRuleEx method. An extended rule considers not just the path but also the file size and attributes. However, be aware that querying file metadata necessitates an additional request to the underlying filesystem, which is relatively slow.

File Isolation

File isolation is a mechanism where the CBFilter driver acts as a proxy. It receives filesystem requests from the operating system and processes them independently, without passing them to the underlying filters or the filesystem. The driver can perform operations requested by the OS on the same file, direct requests to different files, or deal with them entirely in user mode. This topic is discussed in more detail in the article about file isolation.

To implement file isolation, an application must handle BeforeCreateFile and BeforeOpenFile events. A sample call to add the corresponding rule is as follows:

filter.AddFilterRule("C:\\path\\to\\directory\\*.*", Constants.ACCESS_NONE, Constants.FS_CE_BEFORE_CREATE | Constants.FS_CE_BEFORE_OPEN, Constants.FS_NE_NONE);

In the associated event handlers, the application can inspect details of the request, such as the name and PID of the originator process, user token, or username, and decide whether isolation is necessary. If isolation is required, the handler should set the Isolate parameter to true. Once isolation is enabled, the handler must specify the target of the isolation—the backend file to which the driver will redirect requests. This can either be the same file or a different one.

If the handler enables isolation and specifies a path to the backend file in the BackendFileName parameter, the CBFilter driver will open this backend file and handle all subsequent operations for the original file (the “frontend file”) on this backend file.

Alternatively, the handler may decide that the application will manage all operations after the file is opened via the event handlers. This approach is often used to implement on-the-fly selective encryption of files, which is detailed in a separate article about dynamic encryption of files.

To handle all operations, the application should leave BackendFileName empty. If no file is specified for redirecting requests, the application must manage all requests for the isolated file. It is free to open any file on any filesystem as needed, or it can use a remote location (such as cloud storage or a database). This represents a redirection to a custom backend — something not natively supported by the OS but made possible through CBFilter.

Reparse Points

Reparse points are a mechanism provided by the operating system to extend filesystems without altering their format. For example, symbolic links utilize reparse points.

In the context of redirection, applications can set a reparse point of the type "symbolic link" on a file or directory, enabling static redirection of requests. Various system components use reparse points extensively to implement functionalities such as mounting a drive or volume into a directory and creating a unified namespace in distributed file systems.

CBFilter offers events that allow control over the creation, modification, and deletion of reparse points. Additionally, CBFilter can modify the outcomes of requests involving reparse points, potentially blocking access to them.

However, the more interesting use of reparse points for redirection purposes is as follows:

When a file that is a reparse point is opened, the filesystem returns a STATUS_REPARSE status (result code) along with the reparse point tag. Filesystem filters can then take action based on this event.

The concept behind using reparse points is that an application (via its filter driver) can respond to access requests for a file with a reparse point, take appropriate action, and then instruct the operating system to access the file again.

For instance, an application might create an empty file and apply a reparse point with a custom tag. When the file is opened, the application can use CBFilter and its ReparseWithTag event to populate the file with data, remove the reparse point, and then request the operating system to access the file once more. To receive the ReparseWithTag event, an application adds a filter rule like this:

filter.AddFilterRule("C:\\path\\to\\cloud\\*.*", Constants.ACCESS_NONE, Constants.FS_CE_REPARSE_TAG, Constants.FS_NE_NONE);

A benefit of the ReparseWithTag event is that if the request has been redirected by the filesystem or a lower-level filter driver, the event parameters will contain the new file path, informing the application of the redirection.

When handling this event, the application can process the request or deny it based on details such as the originator process name or ID, username, or security token.

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.