#include "util/helpers/helpers.h" #include "Cafe/Filesystem/fscDeviceHostFS.h" #include "FST/fstUtil.h" struct RedirectEntry { RedirectEntry(const fs::path& dstPath, sint32 priority) : dstPath(dstPath), priority(priority) {} fs::path dstPath; sint32 priority; }; FSAFileTree redirectTree; void fscDeviceRedirect_add(std::string_view virtualSourcePath, const fs::path& targetFilePath, sint32 priority) { // check if source already has a redirection RedirectEntry* existingEntry; if (redirectTree.getFile(virtualSourcePath, existingEntry)) { if (existingEntry->priority >= priority) return; // dont replace entries with equal or higher priority // unregister existing entry redirectTree.removeFile(virtualSourcePath); delete existingEntry; } RedirectEntry* entry = new RedirectEntry(targetFilePath, priority); redirectTree.addFile(virtualSourcePath, entry); } class fscDeviceTypeRedirect : public fscDeviceC { FSCVirtualFile* fscDeviceOpenByPath(std::wstring_view pathW, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override { RedirectEntry* redirectionEntry; std::string pathTmp = boost::nowide::narrow(pathW); if (redirectTree.getFile(pathTmp, redirectionEntry)) return FSCVirtualFile_Host::OpenFile(redirectionEntry->dstPath, accessFlags, *fscStatus); return nullptr; } public: static fscDeviceTypeRedirect& instance() { static fscDeviceTypeRedirect _instance; return _instance; } }; bool _redirectMapped = false; void fscDeviceRedirect_map() { if (_redirectMapped) return; fsc_mount("/", "/", &fscDeviceTypeRedirect::instance(), nullptr, FSC_PRIORITY_REDIRECT); _redirectMapped = true; }