# VFS Read-Write Spec
In this document is outlined the desired behavior of a Virtual File System with Read and Write capabilities.
## Base Assumptions:
The main goal of the VFS is that of adding files and folders from multiple different directories to a single specific directory.
This scenario is very common for the installation of mods for video games, where files from multiple mod folders need to be added to the game directory.
The assumption is that there are a few mod folder, the game folder and an override folder.
The override folder would serve as a known clean location where to place new files with the intent of preserving the game folder from unwanted clutter and unnecessary modifications.
In case the same file is present in multiple locations linked with the VFS, a priority system is used to decide which version of the file is shown the application.
In general the order is:
game < mod 1 < mod 2 < mod n < Override
So files in the game folder always get overridden by all other locations. Mods can override other mods with lower priority and the Override folder always overrides all other locations.
## File Operations:
### Open File
- Result: File with the highest priority is opened
### Enumerate Folder (file search)
- Result: Should compile a list of all the files matching the filter present in all the version of the folder (g,m,o), selecting the version of the file with higher priority in case of duplicates from different locations.
- It should be made possible to exclude files from the search (for example if a specific file was deleted in this session, the lower priority versions of the same file should not show up in this search)
- The list of results should be returned in the same order that would be returned where all the files located in the same physical folder (this order is often not documented, but there are known cases of applications relying on it)
### Create File
- Completely new file:
- Result: Create new file in Override (also create supporting folder structure if needed and expected to exist due to its presence in mods)
- File that was deleted or renamed in current session:
- Result: Create the file at the location of the recently removed file, to appear is if it was edited in place.
### Create Folder
- Result: Don't actually do anything, just keep track of the created structure. This is to avoid cluttering the Override folder uselessly with empty folders.
- Only create the folder structure in the override folder if needed for an actual file.
### Edit File
- Open file in writing:
- Result: Edit the file with the highest priority.
- Delete file and create new:
- Result: Keep track of removed files and create the replacement file at the location of the recently removed one.
- Rename original copy original, edit copy, rename copy, remove original:
- Result: Keep track of removed files and place the copy file at the location of the recetnly removed one.
### Delete File
- Result: Delete file with the highest priority and hide existence of any alternative underneath, both from other mods and from the game itself.
- Keep track of the deleted file and the original location for the duration of the session and place any new files withe the same name in that location.
- Attention! In the case where multiple versions of the same file exist, with this approach the application will get the desired result of removing the file only for the duration of the program execution. After the program is closed any further program launched from the VFS would now see the other version of the file that was previously hidden behind the now deleted version.
### Delete Folder (recursive)
- Result: Delete all the winning files contained in the folder from the mods/game/override.
- If, and only if the resulting folder is left empty in the mod or in the game directory, then delete the folder as well, otherwise leave the remaining files in place but make sure they will not turn up inside the program.
- If the folder is also present in override delete the folder directly.
- Attention! With this approach the application will get the desired effect of removing the folder only for the duration of the application execution. After that a new execution through the VFS would show the folder still existing, with it containing any files that were previously hidden by a higher priority mod.
### Move File
- Attention! Moving files has different semantics depending on whether src and dst are located on the same drive or on different ones.
- Care must be given to properly handle all the cases and simulate the presence of all the virtual files being on the same drive as the game managed folder.
- Basically if (IsOnSameDrive(actualSrc, actualDst) != IsOnSameDrive(originalSrc, originalDst)) => need to fix stuff.
- src Inside Managed Folder (IMF)
- g
- dst IMF
- dst replace deleted file:
- g
- Result: perform normal renaming between redirected location.
- m
- same drive:
- Result: perform normal renaming between redirected location.
- diff drive:
- Result: !!! need to doctor the operation to make sure it can succeed even across the drive.
- o
- same drive:
- Result: perform normal renaming between redirected locations.
- diff drive:
- Result: !!! need to doctor the operation to make sure it can succeed even across the drive.
- dst OMF
- Result: perform normal renaming (no need to doctor anything since origin is game already)
- m
- dst IMF
- dst replace deleted file:
- g
- same drive:
- Result: Perform normal renaming between redirected locations.
- diff drive:
- Result: !!! need to doctor the operation to make it appear as if the source was already on the game drive.
- m
- Result: Perform normal renaming between redirected locations.
- o
- same drive:
- Result: Perform normal renaming between redirected locations.
- diff drive:
- Result: !!! need to doctor operation to make dst look like it was on same drive as src.
- dst OMF
- same drive as game
- same drive as src:
- Result: Perform normal renaming between redirected locations.
- diff drive as src
- Result: !!! Need to doctor the operation to make it succeed even across drive
- diff drive than game
- same drive as src:
- Result: !!! Need to fake the dst being on a different drive, since that is what the app would expect.
- diff drive as src:
- Result: can perform normal renaming between redirected locations.
- o
- dst IMF
- dst replace deleted file:
- g
- same drive
- Result: perform normal renaming between redirected locations.
- diff drive
- Result: !!! Need to doctor the operation to make appear is if src was on g drive.
- m
- same drive
- Result: perform normal renaming between redirected locations.
- diff drive
- Result: !!! need to doctor operation to make it appear as if they are both on the same drive.
- o
- Result: perform normal renaming between redirected locations.
- dst OMF
- same drive as game
- same drive as src:
- Result: Perform normal renaming between redirected locations.
- diff drive as src
- Result: !!! Need to doctor the operation to make it succeed even across drive
- diff drive than game
- same drive as src:
- Result: !!! Need to fake the dst being on a different drive, since that is what the app would expect.
- diff drive as src:
- Result: can perform normal renaming between redirected locations.
- src Outside Managed Folder (OMF)
- dst OMF
- Result: not a managed operations
- dst IMF
- src on same drive as game
- dst replace deleted file:
- g
- Result: Perform normal renaming between redirected locations.
- m
- same drive:
- Result: Perform normal renaming between redirected locations.
- diff drive:
- Result: !!! Need to doctor operation to make it work across drives.
- o
- same drive:
- Result: Perform normal renaming between redirected locations.
- diff drive:
- Result: !!! Need to doctor operation to make it work across drives.
- src on diff drive as game
- dst replace deleted file:
- g
- Result: Perform normal renaming between redirected locations.
- m
- same drive as src
- Result: !!! Need to fake the dst being on a diff drive since the app would expect it
- diff drive as src
- Result: Perform normal renaming between redirected locations.
- o
- same drive as src
- Result: !!! Need to fake the dst being on a diff drive since the app would expect it
- diff drive as src
- Result: Perform normal renaming between redirected locations.
### Move Folder
### Start Child Process
- Result: The child process should inherit the VFS and see exactly the same resulting folder structure as the parent process.
- Any change made from one process (e.g. file deletion) should be propagated to all other processes currently being hooked.
## External manipulations of the physical folders:
### Create File
### Create Folder
### Edit File
### Delete File
### Delete Folder
### Move File
### Move Folder
### New Hooked process is started
## Scenarios
Considering a single mod scenario and a single file with the same name, there are 8 possible scenarios of presence of said file in those folders.
Considering the locations in the following order (game, mod, override), and a 0 to indicate the absence of the file and a 1 to indicate its presence, the following are the 8 possible combinations:
- : (g,m,o):
- 0: (0,0,0)
- 1: (1,0,0) g
- 2: (0,1,0) m
- 3: (0,0,1) o
- 4: (1,1,0) gm
- 5: (0,1,1) mo
- 6: (1,0,1) go
- 7: (1,1,1) gmo
Each of these file sources could be located on different drives (Like game on SSD, mods and override on HDD).
Using "()" to indicate a single drive, the possible location scenarios are 5:
- 0: (gmo)
- 1: (g), (mo)
- 2: (gm), (o)
- 3: (go), (m)
- 4: (g), (m), (o)