Architecture diagram
The system consists of three main layers:Main components
You interact with these core components when working with WinFsp-MemFs-Extended:MemFs class
TheMemFs class is the central coordinator that manages the entire file system. It owns the WinFsp file system instance and coordinates between file metadata and data storage.
Key responsibilities:
- File system lifecycle management (start, stop, destroy)
- File and directory operations
- Volume information and labeling
- Memory limit enforcement
FileNodeMap
TheFileNodeMap is a case-aware map that stores all files and directories in the system. It uses std::map<std::wstring, FileNode*> with a custom comparator that respects the file system’s case sensitivity settings.
Key features:
- Fast file lookup by path
- Support for both case-sensitive and case-insensitive modes
- Stores pointers to FileNode instances
SectorManager
TheSectorManager handles all memory allocation for file data. Instead of allocating heap memory for each file individually, it uses a vector-based approach that dramatically improves performance for unpreallocated files.
Key responsibilities:
- Sector allocation and deallocation
- Read/write operations on sector data
- Memory usage tracking
- Private heap management
FileNode
EachFileNode represents a single file or directory in the system. It contains file metadata, security descriptors, extended attributes, and a reference to its sector data.
Key features:
- Reference counting for lifecycle management
- Support for named streams
- Extended attributes (EA) storage
- Reparse point data
SectorNode
TheSectorNode holds the actual file data as a vector of sector pointers. Each file owns one SectorNode that grows and shrinks dynamically as the file size changes.
Key features:
- Vector of sector pointers for dynamic allocation
- Thread-safe access with shared mutex
- Automatic cleanup on destruction
Data flow
When you write to a file, the data flows through the system as follows:- WinFsp receives the write request from the Windows kernel
- MemFs locates the FileNode using the FileNodeMap
- SectorManager allocates sectors if the file needs to grow
- Data is written to sector buffers in the SectorNode
- File metadata is updated (size, timestamps, etc.)
- WinFsp receives the read request from the Windows kernel
- MemFs locates the FileNode using the FileNodeMap
- SectorManager reads data from the SectorNode’s sectors
- Data is copied to the output buffer and returned to WinFsp
Memory management
The architecture uses a hybrid approach to memory management:- File metadata (FileNode objects) are allocated on the standard C++ heap
- File data (Sector buffers) are allocated from a private Windows heap managed by SectorManager
- Sector pointers are stored in std::vector containers for efficient resizing
- Dynamic allocation: Only allocate memory for actual file content
- Efficient resizing: Vectors handle reallocation efficiently
- Isolated heap: File data uses a dedicated heap for better performance
- Thread safety: Mutexes protect concurrent access to sectors