-
Notifications
You must be signed in to change notification settings - Fork 129
Virtual File System
The VFS maps Xbox 360 guest paths to host filesystem paths, allowing recompiled game code to perform file I/O using the original path conventions (game:\content\data.bin, d:\media\video.wmv, etc.).
The VFS is built on a device abstraction:
-
Device(base class): defines the interface for a mounted filesystem (Initialize(),ResolvePath(), mount path, read-only flag, and disk statistics). -
VirtualFileSystem: manages the device registry, symbolic link table, and path resolution. Devices are resolved in registration order.
HostPathDevice: Maps a device mount path to a host directory. This is the primary device type. Constructor takes a mount path, a std::filesystem::path to the host directory, and a read-only flag. ResolvePath() walks the host directory tree to find the requested entry.
NullDevice: Accepts all I/O and returns success without performing actual operations. Used for paths that games expect to exist (cache partitions, raw disk) but whose data is not needed for recompilation. Constructor takes a base mount path and a list of sub-paths to handle (e.g., \Partition0, \Cache0, \Cache1).
Runtime::SetupVfs() configures the following devices:
| Device Path | Type | Host Path | Symlinks | Purpose |
|---|---|---|---|---|
\Device\Harddisk0\Partition1 |
HostPathDevice |
game_data_root |
game:, d:
|
Game data (ROM contents) |
\Device\Harddisk0\PartitionUpdate |
HostPathDevice |
update_data_root |
update: |
Title updates / DLC (only if path is non-empty and exists) |
\Device\Harddisk0 |
NullDevice |
(none) | (none) | Catches \Partition0, \Cache0, \Cache1 (graceful no-op) |
The NullDevice is registered after Partition1 because the VFS resolves devices in registration order. This ensures Partition1 requests go to the real HostPathDevice, not the NullDevice.
Paths are configured via PathConfig in ReXApp::OnConfigurePaths(), or via the user_data_root / update_data_root CVars.
Note
VFS mounts may change as the filesystem subsystem evolves. Verify actual mount behavior against current source if you depend on specific device paths.
The cache: symbolic link is intentionally not registered. Games handle "device not found" for cache paths gracefully, but do not handle device errors (like NAME_COLLISION) well. Letting cache: fail with "not found" is the safer behavior.
When guest code opens a file:
- The raw guest path (e.g.,
game:\content\data.bin) is passed toVirtualFileSystem::ResolvePath(). - Symbolic links are expanded:
game:resolves to\Device\Harddisk0\Partition1. - The device registry is searched (in registration order) for a device whose mount path is a prefix of the resolved path.
- The remaining path suffix is passed to
Device::ResolvePath(), which walks the device's entry tree to locate the target. - Returns an
Entry*(file or directory), ornullptrif not found.
Symbolic link resolution is recursive (a link can point to another link), but the VFS handles this internally.
- Guest code calls a file-open kernel import (e.g.,
NtCreateFile). - The kernel import implementation calls
VirtualFileSystem::OpenFile(root_entry, path, disposition, access, ...). - Path is resolved via
ResolvePath()to anEntry*. -
Entry::Open(desired_access, &file)creates aFileobject from the device. - An XFile kernel object is created wrapping the
File, and a handle is returned to guest code.
XFile operations:
| Operation | Description |
|---|---|
Read |
Synchronous read at current or specified offset |
ReadScatter |
Scatter-gather read into multiple buffers |
Write |
Synchronous write |
SetLength |
Truncate or extend the file |
Rename |
Rename the file |
QueryDirectory |
Iterate directory children with wildcard matching |
Async I/O: XFile supports overlapped I/O via CompleteOverlapped and CompleteOverlappedDeferred on the KernelState. Completion is routed through the DPC dispatch queue, matching Xbox 360 I/O completion port semantics.
File disposition modes (matching Windows/Xbox 360 NtCreateFile semantics):
| Disposition | Exists | Does Not Exist |
|---|---|---|
| Supersede | Replace | Create |
| Open | Open | Error |
| Create | Error | Create |
| OpenIf | Open | Create |
| Overwrite | Overwrite | Error |
| OverwriteIf | Overwrite | Create |
Entries carry FileAttributeFlags matching Xbox 360 semantics:
| Flag | Value | Meaning |
|---|---|---|
kFileAttributeReadOnly |
0x0001 |
File is read-only |
kFileAttributeHidden |
0x0002 |
Hidden file |
kFileAttributeSystem |
0x0004 |
System file |
kFileAttributeDirectory |
0x0010 |
Entry is a directory |
kFileAttributeArchive |
0x0020 |
Archive flag |
kFileAttributeNormal |
0x0080 |
No other attributes set |
kFileAttributeTemporary |
0x0100 |
Temporary file |
Entries also carry timestamps: create_timestamp, access_timestamp, write_timestamp.
Directory entries support child iteration via IterateChildren(wildcard_engine, &index) for QueryDirectory operations with glob pattern matching.
ReXGlue SDK
CLI Reference
Recompilation Pipeline
Runtime Architecture
Technical Reference