FileNode class represents individual files and directories in WinFsp-MemFs-Extended. Each node contains file metadata, security information, and a reference to the file’s data sectors.
FileNode structure
AFileNode combines several pieces of information:
File metadata
ThefileInfo member is an FSP_FSCTL_FILE_INFO structure that contains:
- File attributes: Directory, hidden, system, readonly, etc.
- Timestamps: Creation, access, write, and change times
- File sizes: Allocation size and actual file size
- Index number: Unique identifier for the file
- EA size: Total size of extended attributes
FileNode, all timestamps are initialized to the current system time and a unique index number is assigned:
Reference counting
FileNodes use reference counting for lifecycle management. When the reference count reaches zero, the node deletes itself automatically.Reference operations
You manage references through three methods:Reference()
Increments the reference count when opening or referencing a file:Dereference()
Decrements the reference count and self-deletes if it reaches zero:GetReferenceCount()
Reads the current reference count (thread-safe by default):Reference lifecycle
A typical file’s reference count changes as follows:- Creation: Reference count is 0
- Insert into FileNodeMap: Reference count becomes 1 (map holds a reference)
- Each file open: Reference count increases by 1
- Each file close: Reference count decreases by 1
- Remove from FileNodeMap: Reference count decreases by 1
- Deletion: When count reaches 0, the node self-deletes
- Files remain in memory while open or in the file map
- Nodes are automatically cleaned up when no longer needed
- No manual memory management is required
FileNodeMap integration
TheFileNodeMap is a case-aware map that stores all nodes:
FileLess respects the file system’s case sensitivity setting:
- Case-insensitive mode: “File.txt” and “file.txt” are the same
- Case-sensitive mode: “File.txt” and “file.txt” are different
MemFs::FindFile():
Named streams
NTFS supports alternate data streams (named streams) on files. WinFsp-MemFs-Extended represents these as separate FileNodes that reference a main node:Main node vs. stream node
You can check if a node is a main file or a named stream:Stream node relationships
Named streams:- Store their own
fileName(e.g., “file.txt:stream”) - Have their own
SectorNodefor data storage - Reference the main node’s metadata for attributes
- Share extended attributes with the main node
Extended attributes
Extended attributes (EA) are name-value pairs associated with files. They’re stored in an optional map:Lazy initialization
The EA map is only created when needed:Security descriptors
Each FileNode can have a security descriptor that defines access control:DynamicStruct template provides:
- Dynamic sizing: Allocates exactly the required space
- Type safety: Ensures correct structure layout
- Automatic cleanup: Frees memory on destruction
Reparse points
Reparse points (symbolic links, junctions, etc.) store their data in:- Reparse tag (e.g.,
IO_REPARSE_TAG_SYMLINK) - Target path information
- Additional reparse-specific data
Sector data access
You can access a node’s sector data through:SectorNode is owned by the FileNode and is automatically freed when the node is destroyed.
See nodes.cpp:180-182 for the accessor implementation.