This DLL hooks selected Win32 APIs so legacy games can keep their per-user data beside the executable instead of writing to the real user profile under C:\Users\<name>.
Run the target with the desired portable directory as its current working directory. When the target asks for supported user folders, the hook returns or rewrites them into that current directory:
%CD%\AppData\Roaming <- APPDATA / CSIDL_APPDATA / FOLDERID_RoamingAppData
%CD%\AppData\Local <- LOCALAPPDATA / CSIDL_LOCAL_APPDATA / FOLDERID_LocalAppData
%CD%\AppData\LocalLow <- FOLDERID_LocalAppDataLow and paths containing \AppData\LocalLow
%CD%\Documents <- CSIDL_PERSONAL / CSIDL_MYDOCUMENTS / FOLDERID_Documents
%CD%\Saved Games <- FOLDERID_SavedGames and %USERPROFILE%\Saved Games paths
This covers programs that use Shell known-folder APIs, environment-variable APIs, or direct file paths such as:
%APPDATA%\Vendor\Game\save.dat
%LOCALAPPDATA%\Vendor\Game\cache.dat
%USERPROFILE%\AppData\LocalLow\Vendor\Game\save.dat
%USERPROFILE%\Documents\Vendor\Game\config.ini
%USERPROFILE%\My Documents\Vendor\Game\config.ini
%USERPROFILE%\Saved Games\Vendor\Game\save.dat
C:\Users\Alice\Documents\Vendor\Game\config.ini
C:\Users\Alice\Saved Games\Vendor\Game\save.dat
SHGetFolderPathA/WSHGetKnownFolderPathSHGetSpecialFolderPathA/WSHGetPathFromIDListA/W
Supported folder IDs include AppData, Local AppData, LocalLow AppData, Documents, and Saved Games where the Windows API exposes them. SHGetKnownFolderPath is Unicode-only by design.
GetEnvironmentVariableA/WforAPPDATAandLOCALAPPDATAExpandEnvironmentStringsA/W, with pre-expansion and post-expansion path rewrite for supported%APPDATA%,%LOCALAPPDATA%, and%USERPROFILE%-based paths
USERPROFILE itself is not globally replaced. Instead, file paths under %USERPROFILE%\Documents, %USERPROFILE%\My Documents, and %USERPROFILE%\Saved Games are rewritten when the full path is observed.
CreateFileA/WGetFileAttributesA/WSetFileAttributesA/WCreateDirectoryA/WRemoveDirectoryA/WDeleteFileA/WCopyFileA/WMoveFileExA/WFindFirstFileA/WFindFirstFileExA/WPathFileExistsA/W
Both ANSI (A) and Unicode (W) variants are handled where Windows exposes both variants.
- Rust nightly toolchain
- Windows MSVC target/toolchain
rustup toolchain install nightly
rustup default nightly
rustup target add i686-pc-windows-msvc
rustup component add rust-src --toolchain nightly-x86_64-pc-windows-msvccargo +nightly build --releasecargo +nightly build --release --target=i686-pc-windows-msvc -Zbuild-stdInject or load the generated DLL into the game or application you own or are authorized to modify. Run the target with the desired portable directory as its current working directory. Redirected data will appear under the portable AppData, Documents, and Saved Games folders in that directory.
- This is a user-mode hook. It only affects APIs called inside the hooked process.
- It does not globally move Windows known folders.
- Apps using NT native APIs directly, custom syscalls, or already-open file handles may bypass these hooks.
- The hook creates parent directories for redirected file writes where practical.
Saved Gameshas no legacy CSIDL equivalent, so modern programs usually reach it throughSHGetKnownFolderPath(FOLDERID_SavedGames)or direct%USERPROFILE%\Saved Gamespaths.
MIT. See LICENSE.