From cf51d1f724c6cd5a064fbcee0e2beadd6d148d86 Mon Sep 17 00:00:00 2001 From: Maschell Date: Tue, 9 Aug 2022 00:28:29 +0200 Subject: [PATCH] Implement support for redirecting FSA function --- src/FSADirReplacements.cpp | 82 +++++++++++++ src/FSADirReplacements.h | 10 ++ src/FSAFileReplacements.cpp | 238 ++++++++++++++++++++++++++++++++++++ src/FSAFileReplacements.h | 15 +++ src/FileUtils.cpp | 84 +++++++++++-- src/FileUtils.h | 14 +++ src/main.cpp | 12 ++ 7 files changed, 444 insertions(+), 11 deletions(-) create mode 100644 src/FSADirReplacements.cpp create mode 100644 src/FSADirReplacements.h create mode 100644 src/FSAFileReplacements.cpp create mode 100644 src/FSAFileReplacements.h diff --git a/src/FSADirReplacements.cpp b/src/FSADirReplacements.cpp new file mode 100644 index 0000000..dea7038 --- /dev/null +++ b/src/FSADirReplacements.cpp @@ -0,0 +1,82 @@ +#include "FSDirReplacements.h" +#include "FileUtils.h" +#include "IFSWrapper.h" +#include "utils/logger.h" +#include +#include + +DECL_FUNCTION(FSError, FSAOpenDir, FSAClientHandle client, const char *path, FSADirectoryHandle *dirHandle) { + DEBUG_FUNCTION_LINE_VERBOSE("%s", path); + return doForLayerFSA( + [c = client, p = path, h = dirHandle]() -> FSError { + return real_FSAOpenDir(c, p, h); + }, + [p = path, h = dirHandle](std::unique_ptr &layer) -> FSError { + return layer->FSOpenDirWrapper(p, h); + }, + SYNC_RESULT_HANDLER_FSA); +} + +DECL_FUNCTION(FSError, FSAReadDir, FSAClientHandle client, FSADirectoryHandle dirHandle, FSADirectoryEntry *directoryEntry) { + DEBUG_FUNCTION_LINE_VERBOSE("%08X", dirHandle); + return doForLayerFSA( + [c = client, h = dirHandle, de = directoryEntry]() -> FSError { + return real_FSAReadDir(c, h, de); + }, + [h = dirHandle, de = directoryEntry](std::unique_ptr &layer) -> FSError { + return layer->FSReadDirWrapper(h, de); + }, + SYNC_RESULT_HANDLER_FSA); +} + +DECL_FUNCTION(FSError, FSARewindDir, FSAClientHandle client, FSADirectoryHandle dirHandle) { + DEBUG_FUNCTION_LINE_VERBOSE("%08X", dirHandle); + return doForLayerFSA( + [c = client, h = dirHandle]() -> FSError { + return real_FSARewindDir(c, h); + }, + [h = dirHandle](std::unique_ptr &layer) -> FSError { + return layer->FSRewindDirWrapper(h); + }, + SYNC_RESULT_HANDLER_FSA); +} + +DECL_FUNCTION(FSError, FSACloseDir, FSAClientHandle client, FSADirectoryHandle dirHandle) { + DEBUG_FUNCTION_LINE_VERBOSE("%08X", dirHandle); + return doForLayerFSA( + [c = client, h = dirHandle]() -> FSError { + return real_FSACloseDir(c, h); + }, + [h = dirHandle](std::unique_ptr &layer) -> FSError { + return layer->FSCloseDirWrapper(h); + }, + SYNC_RESULT_HANDLER_FSA); +} + +DECL_FUNCTION(FSError, FSAMakeDir, FSAClientHandle client, const char *path, FSMode mode) { + DEBUG_FUNCTION_LINE_VERBOSE("%s", path); + return doForLayerFSA( + [c = client, p = path, m = mode]() -> FSError { + return real_FSAMakeDir(c, p, m); + }, + [p = path, m = mode](std::unique_ptr &layer) -> FSError { + return layer->FSMakeDirWrapper(p); + }, + SYNC_RESULT_HANDLER_FSA); +} + +DECL_FUNCTION(FSError, FSAChangeDir, FSAClientHandle client, const char *path) { + DEBUG_FUNCTION_LINE_VERBOSE("%s", path); + setWorkingDirForFSAClient(client, path); + return real_FSAChangeDir(client, path); +} + +function_replacement_data_t fsa_dir_function_replacements[] = { + REPLACE_FUNCTION(FSAOpenDir, LIBRARY_COREINIT, FSAOpenDir), + REPLACE_FUNCTION(FSAReadDir, LIBRARY_COREINIT, FSAReadDir), + REPLACE_FUNCTION(FSARewindDir, LIBRARY_COREINIT, FSARewindDir), + REPLACE_FUNCTION(FSACloseDir, LIBRARY_COREINIT, FSACloseDir), + REPLACE_FUNCTION(FSAMakeDir, LIBRARY_COREINIT, FSAMakeDir), + REPLACE_FUNCTION(FSAChangeDir, LIBRARY_COREINIT, FSAChangeDir), +}; +uint32_t fsa_dir_function_replacements_size = sizeof(fsa_dir_function_replacements) / sizeof(function_replacement_data_t); diff --git a/src/FSADirReplacements.h b/src/FSADirReplacements.h new file mode 100644 index 0000000..c45b93d --- /dev/null +++ b/src/FSADirReplacements.h @@ -0,0 +1,10 @@ +#pragma once + +#include "IFSWrapper.h" +#include +#include +#include +#include + +extern function_replacement_data_t fsa_dir_function_replacements[]; +extern uint32_t fsa_dir_function_replacements_size; diff --git a/src/FSAFileReplacements.cpp b/src/FSAFileReplacements.cpp new file mode 100644 index 0000000..760b70c --- /dev/null +++ b/src/FSAFileReplacements.cpp @@ -0,0 +1,238 @@ +#include "FSFileReplacements.h" +#include "FileUtils.h" +#include "utils/logger.h" +#include + +DECL_FUNCTION(FSError, FSAOpenFileEx, FSAClientHandle client, const char *path, const char *mode, FSMode createMode, FSOpenFileFlags openFlag, uint32_t preallocSize, FSAFileHandle *handle) { + DEBUG_FUNCTION_LINE_VERBOSE("path: %s mode: %d", path, mode); + + return doForLayerFSA( + [c = client, p = path, m = mode, cm = createMode, of = openFlag, pa = preallocSize, h = handle]() -> FSError { + return real_FSAOpenFileEx(c, p, m, cm, of, pa, h); + }, + [f = getFullPathForFSAClient(client, path), m = mode, h = handle](std::unique_ptr &layer) -> FSError { + // FSAFileHandle is just an alias for FSFileHandle + return layer->FSOpenFileWrapper(f.c_str(), m, h); + }, + SYNC_RESULT_HANDLER_FSA); +} + +DECL_FUNCTION(FSError, FSACloseFile, FSAClientHandle client, FSAFileHandle fileHandle) { + DEBUG_FUNCTION_LINE_VERBOSE("handle: %08X", fileHandle); + + return doForLayerFSA( + [c = client, h = fileHandle]() -> FSError { + return real_FSACloseFile(c, h); + }, + [h = fileHandle](std::unique_ptr &layer) -> FSError { + // FSAFileHandle is just an alias for FSFileHandle + return layer->FSCloseFileWrapper(h); + }, + [h = fileHandle, filename = __FILENAME__, func = __FUNCTION__, line = __LINE__](std::unique_ptr &layer, FSError res) -> FSError { + if (layer->isValidFileHandle(h)) { + layer->deleteFileHandle(h); + } else { + DEBUG_FUNCTION_LINE_ERR_LAMBDA(filename, func, line, "Expected to delete fileHandle by handle %08X but it was not found", h); + } + DEBUG_FUNCTION_LINE_VERBOSE_EX(filename, func, line, "Sync result %d", res); + return res; + }); +} + +DECL_FUNCTION(FSError, FSAFlushFile, FSAClientHandle client, FSAFileHandle fileHandle) { + DEBUG_FUNCTION_LINE_VERBOSE("handle: %08X", fileHandle); + return doForLayerFSA( + [c = client, h = fileHandle]() -> FSError { + return real_FSAFlushFile(c, h); + }, + [h = fileHandle](std::unique_ptr &layer) -> FSError { + // FSAFileHandle is just an alias for FSFileHandle + return layer->FSFlushFileWrapper(h); + }, + SYNC_RESULT_HANDLER_FSA); +} + +DECL_FUNCTION(FSError, FSAGetStat, FSAClientHandle client, const char *path, FSAStat *stat) { + DEBUG_FUNCTION_LINE_VERBOSE("%s", path); + return doForLayerFSA( + + [c = client, p = path, s = stat]() -> FSError { + return real_FSAGetStat(c, p, s); + }, + [f = getFullPathForFSAClient(client, path), s = stat](std::unique_ptr &layer) -> FSError { + // FSAStat is just an alias for FSStat + return layer->FSGetStatWrapper(f.c_str(), s); + }, + SYNC_RESULT_HANDLER_FSA); +} + +DECL_FUNCTION(FSError, FSAGetStatFile, FSAClientHandle client, FSAFileHandle fileHandle, FSAStat *stat) { + DEBUG_FUNCTION_LINE_VERBOSE("handle: %08X", fileHandle); + return doForLayerFSA( + [c = client, h = fileHandle, s = stat]() -> FSError { + return real_FSAGetStatFile(c, h, s); + }, + [h = fileHandle, s = stat](std::unique_ptr &layer) -> FSError { + // FSAFileHandle is just an alias for FSFileHandle + // FSAStat is just an alias for FSStat + return layer->FSGetStatFileWrapper(h, s); + }, + SYNC_RESULT_HANDLER_FSA); +} + +DECL_FUNCTION(FSError, FSARemove, FSAClientHandle client, const char *path) { + DEBUG_FUNCTION_LINE_VERBOSE("%s", path); + return doForLayerFSA( + [c = client, p = path]() -> FSError { + return real_FSARemove(c, p); + }, + [f = getFullPathForFSAClient(client, path)](std::unique_ptr &layer) -> FSError { + return layer->FSRemoveWrapper(f.c_str()); + }, + SYNC_RESULT_HANDLER_FSA); +} + +DECL_FUNCTION(FSError, FSARename, FSAClientHandle client, const char *oldPath, const char *newPath) { + DEBUG_FUNCTION_LINE_VERBOSE("%s %s", oldPath, newPath); + return doForLayerFSA( + [c = client, op = oldPath, np = newPath]() -> FSError { + return real_FSARename(c, op, np); + }, + [op = getFullPathForFSAClient(client, oldPath), np = getFullPathForFSAClient(client, newPath)](std::unique_ptr &layer) -> FSError { + return layer->FSRenameWrapper(op.c_str(), np.c_str()); + }, + SYNC_RESULT_HANDLER_FSA); +} + +DECL_FUNCTION(FSError, FSASetPosFile, FSAClientHandle client, FSAFileHandle fileHandle, uint32_t pos) { + DEBUG_FUNCTION_LINE_VERBOSE("handle: %08X pos: %08X", fileHandle, pos); + return doForLayerFSA( + [c = client, h = fileHandle, p = pos]() -> FSError { + return real_FSASetPosFile(c, h, p); + }, + [h = fileHandle, p = pos](std::unique_ptr &layer) -> FSError { + return layer->FSSetPosFileWrapper(h, p); + }, + SYNC_RESULT_HANDLER_FSA); +} + +DECL_FUNCTION(FSError, FSATruncateFile, FSAClientHandle client, FSAFileHandle fileHandle) { + DEBUG_FUNCTION_LINE_VERBOSE("%08X", fileHandle); + return doForLayerFSA( + [c = client, h = fileHandle]() -> FSError { + return real_FSATruncateFile(c, h); + }, + [h = fileHandle](std::unique_ptr &layer) -> FSError { + return layer->FSTruncateFileWrapper(h); + }, + SYNC_RESULT_HANDLER_FSA); +} + +DECL_FUNCTION(FSError, FSAReadFile, FSAClientHandle client, void *buffer, uint32_t size, uint32_t count, FSAFileHandle handle, uint32_t flags) { + DEBUG_FUNCTION_LINE_VERBOSE("handle: %08X buffer: %08X size: %08X", handle, buffer, size * count); + return doForLayerFSA( + [c = client, b = buffer, s = size, co = count, h = handle, f = flags]() -> FSError { + return real_FSAReadFile(c, b, s, co, h, f); + }, + [b = buffer, s = size, co = count, h = handle, f = flags](std::unique_ptr &layer) -> FSError { + return layer->FSReadFileWrapper(b, s, co, h, f); + }, + SYNC_RESULT_HANDLER_FSA); +} + +DECL_FUNCTION(FSError, FSAWriteFile, FSAClientHandle client, void *buffer, uint32_t size, uint32_t count, FSAFileHandle handle, uint32_t flags) { + DEBUG_FUNCTION_LINE_VERBOSE("handle: %08X buffer: %08X size: %08X", handle, buffer, size * count); + return doForLayerFSA( + [c = client, b = buffer, s = size, co = count, h = handle, f = flags]() -> FSError { + return real_FSAWriteFile(c, b, s, co, h, f); + }, + [b = buffer, s = size, co = count, h = handle, f = flags](std::unique_ptr &layer) -> FSError { + return layer->FSWriteFileWrapper((uint8_t *) b, s, co, h, f); + }, + SYNC_RESULT_HANDLER_FSA); +} + +DECL_FUNCTION(FSError, FSAGetPosFile, FSAClientHandle client, FSAFileHandle handle, uint32_t *outPos) { + DEBUG_FUNCTION_LINE_VERBOSE("handle: %08X", handle); + return doForLayerFSA( + [c = client, h = handle, o = outPos]() -> FSError { + return real_FSAGetPosFile(c, h, o); + }, + [h = handle, o = outPos](std::unique_ptr &layer) -> FSError { + return layer->FSGetPosFileWrapper(h, o); + }, + SYNC_RESULT_HANDLER_FSA); +} + +DECL_FUNCTION(FSError, FSAIsEof, FSAClientHandle client, FSAFileHandle handle) { + DEBUG_FUNCTION_LINE_VERBOSE("handle: %08X", handle); + return doForLayerFSA( + [c = client, h = handle]() -> FSError { + return real_FSAIsEof(c, h); + }, + [h = handle](std::unique_ptr &layer) -> FSError { + return layer->FSIsEofWrapper(h); + }, + SYNC_RESULT_HANDLER_FSA); +} + +DECL_FUNCTION(FSError, FSAFlushMultiQuota, FSAClientHandle client, const char *path) { + DEBUG_FUNCTION_LINE("NOT IMPLEMENTED. path %s", path); + return real_FSAFlushMultiQuota(client, path); +} + +DECL_FUNCTION(FSError, FSAFlushQuota, FSAClientHandle client, const char *path) { + DEBUG_FUNCTION_LINE("NOT IMPLEMENTED. path %s", path); + return real_FSAFlushQuota(client, path); +} + +DECL_FUNCTION(FSError, FSAChangeMode, FSAClientHandle client, const char *path, FSMode permission) { + DEBUG_FUNCTION_LINE_ERR("NOT IMPLEMENTED path %s permission: %08X", path, permission); + return real_FSAChangeMode(client, path, permission); +} + +DECL_FUNCTION(FSError, FSAOpenFileByStat, FSAClientHandle client, FSAStat *stat, const char *mode, const char *path, FSAFileHandle *outFileHandle) { + DEBUG_FUNCTION_LINE_ERR("NOT IMPLEMENTED"); + return real_FSAOpenFileByStat(client, stat, mode, path, outFileHandle); +} + +DECL_FUNCTION(FSError, FSAAppendFile, FSAClientHandle client, FSAFileHandle fileHandle, uint32_t size, uint32_t count) { + DEBUG_FUNCTION_LINE_ERR("NOT IMPLEMENTED"); + return real_FSAAppendFile(client, fileHandle, size, count); +} + +DECL_FUNCTION(FSError, FSAAppendFileEx, FSAClientHandle client, FSAFileHandle fileHandle, uint32_t size, uint32_t count, uint32_t flags) { + DEBUG_FUNCTION_LINE_ERR("NOT IMPLEMENTED"); + return real_FSAAppendFileEx(client, fileHandle, size, count, flags); +} + +DECL_FUNCTION(FSStatus, FSAWriteFileWithPos, FSAClientHandle client, uint8_t *buffer, uint32_t size, uint32_t count, uint32_t pos, FSFileHandle handle, uint32_t flags) { + DEBUG_FUNCTION_LINE_ERR("NOT IMPLEMENTED. handle %08X size %08X", handle, size * count); + return real_FSAWriteFileWithPos(client, buffer, size, count, pos, handle, flags); +} + +function_replacement_data_t fsa_file_function_replacements[] = { + REPLACE_FUNCTION(FSAOpenFileEx, LIBRARY_COREINIT, FSAOpenFileEx), + REPLACE_FUNCTION(FSACloseFile, LIBRARY_COREINIT, FSACloseFile), + REPLACE_FUNCTION(FSAFlushFile, LIBRARY_COREINIT, FSAFlushFile), + REPLACE_FUNCTION(FSAGetStat, LIBRARY_COREINIT, FSAGetStat), + REPLACE_FUNCTION(FSAGetStatFile, LIBRARY_COREINIT, FSAGetStatFile), + REPLACE_FUNCTION(FSARemove, LIBRARY_COREINIT, FSARemove), + REPLACE_FUNCTION(FSARename, LIBRARY_COREINIT, FSARename), + REPLACE_FUNCTION(FSASetPosFile, LIBRARY_COREINIT, FSASetPosFile), + REPLACE_FUNCTION(FSATruncateFile, LIBRARY_COREINIT, FSATruncateFile), + REPLACE_FUNCTION(FSAReadFile, LIBRARY_COREINIT, FSAReadFile), + REPLACE_FUNCTION(FSAWriteFile, LIBRARY_COREINIT, FSAWriteFile), + REPLACE_FUNCTION(FSAGetPosFile, LIBRARY_COREINIT, FSAGetPosFile), + REPLACE_FUNCTION(FSAIsEof, LIBRARY_COREINIT, FSAIsEof), + + REPLACE_FUNCTION(FSAFlushMultiQuota, LIBRARY_COREINIT, FSAFlushMultiQuota), + REPLACE_FUNCTION(FSAFlushQuota, LIBRARY_COREINIT, FSAFlushQuota), + REPLACE_FUNCTION(FSAChangeMode, LIBRARY_COREINIT, FSAChangeMode), + REPLACE_FUNCTION(FSAOpenFileByStat, LIBRARY_COREINIT, FSAOpenFileByStat), + REPLACE_FUNCTION(FSAAppendFile, LIBRARY_COREINIT, FSAAppendFile), + REPLACE_FUNCTION(FSAAppendFileEx, LIBRARY_COREINIT, FSAAppendFileEx), + REPLACE_FUNCTION(FSAWriteFileWithPos, LIBRARY_COREINIT, FSAWriteFileWithPos), +}; + +uint32_t fsa_file_function_replacements_size = sizeof(fsa_file_function_replacements) / sizeof(function_replacement_data_t); \ No newline at end of file diff --git a/src/FSAFileReplacements.h b/src/FSAFileReplacements.h new file mode 100644 index 0000000..7b1dc9c --- /dev/null +++ b/src/FSAFileReplacements.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern function_replacement_data_t fsa_file_function_replacements[]; +extern uint32_t fsa_file_function_replacements_size; + +#ifdef __cplusplus +} +#endif diff --git a/src/FileUtils.cpp b/src/FileUtils.cpp index cc30ec5..79238dd 100644 --- a/src/FileUtils.cpp +++ b/src/FileUtils.cpp @@ -10,22 +10,25 @@ #include std::mutex workingDirMutexFS; -std::map workingDirsFS; +std::map workingDirsFS; + +std::mutex workingDirMutexFSA; +std::map workingDirsFSA; std::mutex fsLayerMutex; std::vector> fsLayers; -std::string getFullPathForFSClient(FSClient *pClient, const char *path) { - std::lock_guard workingDirLock(workingDirMutexFS); +std::string getFullPathGeneric(uint32_t client, const char *path, std::mutex &mutex, std::map &map) { + std::lock_guard workingDirLock(mutex); std::string res; if (path[0] != '/' && path[0] != '\\') { - if (workingDirsFS.count(pClient) == 0) { - DEBUG_FUNCTION_LINE_WARN("No working dir found for FS client %08X, fallback to \"/\"", pClient); - workingDirsFS[pClient] = "/"; + if (map.count(client) == 0) { + DEBUG_FUNCTION_LINE_WARN("No working dir found for client %08X, fallback to \"/\"", client); + workingDirsFS[client] = "/"; } - res = string_format("%s%s", workingDirsFS.at(pClient).c_str(), path); + res = string_format("%s%s", map.at(client).c_str(), path); } else { res = path; } @@ -35,33 +38,92 @@ std::string getFullPathForFSClient(FSClient *pClient, const char *path) { return res; } -void setWorkingDirForFSClient(FSClient *client, const char *path) { +void setWorkingDirGeneric(uint32_t client, const char *path, std::mutex &mutex, std::map &map) { if (!path) { DEBUG_FUNCTION_LINE_WARN("Path was NULL"); return; } - std::lock_guard workingDirLock(workingDirMutexFS); + + std::lock_guard workingDirLock(mutex); std::string cwd(path); if (cwd.empty() || cwd.back() != '/') { cwd.push_back('/'); } - - workingDirsFS[client] = cwd; + map[client] = cwd; OSMemoryBarrier(); } + +std::string getFullPathForFSClient(FSClient *pClient, const char *path) { + return getFullPathGeneric((uint32_t) pClient, path, workingDirMutexFS, workingDirsFS); +} + +void setWorkingDirForFSClient(FSClient *client, const char *path) { + setWorkingDirGeneric((uint32_t) client, path, workingDirMutexFS, workingDirsFS); +} + +std::string getFullPathForFSAClient(FSAClientHandle client, const char *path) { + return getFullPathGeneric((uint32_t) client, path, workingDirMutexFSA, workingDirsFSA); +} + +void setWorkingDirForFSAClient(FSAClientHandle client, const char *path) { + setWorkingDirGeneric(client, path, workingDirMutexFSA, workingDirsFSA); +} + void clearFSLayer() { { std::lock_guard workingDirLock(workingDirMutexFS); workingDirsFS.clear(); } + { + std::lock_guard workingDirLock(workingDirMutexFSA); + workingDirsFSA.clear(); + } { std::lock_guard layerLock(fsLayerMutex); fsLayers.clear(); } } + +FSError doForLayerFSA(const std::function &real_function, + const std::function &layer)> &layer_callback, + const std::function &layer, FSError)> &result_handler) { + + + std::lock_guard lock(fsLayerMutex); + if (!fsLayers.empty()) { + uint32_t startIndex = fsLayers.size(); + + if (startIndex > 0) { + for (uint32_t i = startIndex; i > 0; i--) { + auto &layer = fsLayers[i - 1]; + if (!layer->isActive()) { + continue; + } + FSError layerResult = layer_callback(layer); + if (layerResult != FS_ERROR_FORCE_PARENT_LAYER) { + auto result = layerResult >= 0 ? layerResult : (FSError) ((layerResult & FS_ERROR_REAL_MASK) | FS_ERROR_EXTRA_MASK); + + if (result < FS_ERROR_OK && result != FS_ERROR_END_OF_DIR && result != FS_ERROR_END_OF_FILE && result != FS_ERROR_CANCELLED) { + if (layer->fallbackOnError()) { + // Only fallback if FS_ERROR_FORCE_NO_FALLBACK flag is not set. + if (static_cast(layerResult & FS_ERROR_EXTRA_MASK) != FS_ERROR_FORCE_NO_FALLBACK) { + continue; + } + } + } + + return result_handler(layer, result); + } + } + } + } + + return real_function(); +} + // FUN_0204cc20 #define fsClientHandleFatalErrorAndBlock ((void (*)(FSClientBody *, uint32_t))(0x101C400 + 0x4cc20)) #define fsaDecodeFsaStatusToFsStatus ((FSStatus(*)(FSError))(0x101C400 + 0x4b148)) diff --git a/src/FileUtils.h b/src/FileUtils.h index 1276c32..51be2fd 100644 --- a/src/FileUtils.h +++ b/src/FileUtils.h @@ -2,6 +2,7 @@ #include "IFSWrapper.h" #include +#include #include #include #include @@ -20,6 +21,11 @@ extern std::vector> fsLayers; return send_result_async(c, b, a, res); \ } +#define SYNC_RESULT_HANDLER_FSA [filename = __FILENAME__, func = __FUNCTION__, line = __LINE__]([[maybe_unused]] std::unique_ptr &layer, FSError res) -> FSError { \ + DEBUG_FUNCTION_LINE_VERBOSE_EX(filename, func, line, "Sync result was %d", res); \ + return res; \ +} + #define FS_ERROR_FLAG_EXTRA_MASK (FSErrorFlag) 0xFFFF0000 #define FS_ERROR_FLAG_REAL_MASK (FSErrorFlag) 0x0000FFFF #define FS_ERROR_FLAG_FORCE_REAL (FSErrorFlag) 0xFEDC0000 @@ -42,6 +48,14 @@ std::string getFullPathForFSClient(FSClient *pClient, const char *path); void setWorkingDirForFSClient(FSClient *client, const char *path); +std::string getFullPathForFSAClient(FSAClientHandle client, const char *path); + +void setWorkingDirForFSAClient(FSAClientHandle client, const char *path); + +FSError doForLayerFSA(const std::function &real_function, + const std::function &layer)> &layer_callback, + const std::function &layer, FSError)> &result_handler); + FSStatus doForLayer(FSClient *client, FSErrorFlag errorMask, const std::function &real_function, diff --git a/src/main.cpp b/src/main.cpp index b4629f7..821fa7f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,3 +1,5 @@ +#include "FSADirReplacements.h" +#include "FSAFileReplacements.h" #include "FSDirReplacements.h" #include "FSFileReplacements.h" #include "FileUtils.h" @@ -15,11 +17,21 @@ WUMS_INITIALIZE() { OSFatal("homebrew_content_redirection: Failed to patch function"); } } + for (uint32_t i = 0; i < fsa_file_function_replacements_size; i++) { + if (!FunctionPatcherPatchFunction(&fsa_file_function_replacements[i], nullptr)) { + OSFatal("homebrew_content_redirection: Failed to patch function"); + } + } for (uint32_t i = 0; i < fs_dir_function_replacements_size; i++) { if (!FunctionPatcherPatchFunction(&fs_dir_function_replacements[i], nullptr)) { OSFatal("homebrew_content_redirection: Failed to patch function"); } } + for (uint32_t i = 0; i < fsa_dir_function_replacements_size; i++) { + if (!FunctionPatcherPatchFunction(&fsa_dir_function_replacements[i], nullptr)) { + OSFatal("homebrew_content_redirection: Failed to patch function"); + } + } DEBUG_FUNCTION_LINE("Patch functions finished"); deinitLogging(); }