From 548ceb77ff4744978641ee6923a6290785991f31 Mon Sep 17 00:00:00 2001 From: Maschell Date: Tue, 13 Jan 2026 20:01:45 +0100 Subject: [PATCH 1/4] Use std::recusive_mutex --- src/FSWrapper.cpp | 2 +- src/FSWrapper.h | 4 ++-- src/FileUtils.cpp | 8 ++++---- src/FileUtils.h | 2 +- src/utils/utils.h | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/FSWrapper.cpp b/src/FSWrapper.cpp index cc007a9..8b82f23 100644 --- a/src/FSWrapper.cpp +++ b/src/FSWrapper.cpp @@ -249,7 +249,7 @@ FSError FSWrapper::FSOpenFileWrapper(const char *path, const char *mode, FSFileH if (fd >= 0) { auto fileHandle = getNewFileHandle(); if (fileHandle) { - std::lock_guard lock(openFilesMutex); + std::lock_guard lock(openFilesMutex); fileHandle->handle = (((uint32_t) fileHandle.get()) & 0x0FFFFFFF) | 0x30000000; *handle = fileHandle->handle; diff --git a/src/FSWrapper.h b/src/FSWrapper.h index 84d5280..6163539 100644 --- a/src/FSWrapper.h +++ b/src/FSWrapper.h @@ -134,8 +134,8 @@ class FSWrapper : public IFSWrapper { std::string pPathToReplace; std::string pReplacePathWith; bool pIsWriteable = false; - std::mutex openFilesMutex; - std::mutex openDirsMutex; + std::recursive_mutex openFilesMutex; + std::recursive_mutex openDirsMutex; std::vector> openFiles; std::vector> openDirs; }; diff --git a/src/FileUtils.cpp b/src/FileUtils.cpp index ef23d62..bfce102 100644 --- a/src/FileUtils.cpp +++ b/src/FileUtils.cpp @@ -12,14 +12,14 @@ #include namespace { - std::mutex sWorkingDirMutex; + std::recursive_mutex sWorkingDirMutex; std::map sWorkingDirs; } // namespace -std::mutex gFSLayerMutex; +std::recursive_mutex gFSLayerMutex; std::vector> gFSLayers; -std::string getFullPathGeneric(const FSAClientHandle client, const char *path, std::mutex &mutex, const std::map &map) { +std::string getFullPathGeneric(const FSAClientHandle client, const char *path, std::recursive_mutex &mutex, const std::map &map) { std::lock_guard workingDirLock(mutex); std::string res; @@ -39,7 +39,7 @@ std::string getFullPathGeneric(const FSAClientHandle client, const char *path, s return res; } -void setWorkingDirGeneric(const FSAClientHandle client, const char *path, std::mutex &mutex, std::map &map) { +void setWorkingDirGeneric(const FSAClientHandle client, const char *path, std::recursive_mutex &mutex, std::map &map) { if (!path) { DEBUG_FUNCTION_LINE_WARN("Path was NULL"); return; diff --git a/src/FileUtils.h b/src/FileUtils.h index 5095d4a..36db017 100644 --- a/src/FileUtils.h +++ b/src/FileUtils.h @@ -55,7 +55,7 @@ struct FSShimWrapperMessage { extern bool gThreadsRunning; extern FSIOThreadData gThreadData[3]; -extern std::mutex gFSLayerMutex; +extern std::recursive_mutex gFSLayerMutex; extern std::vector> gFSLayers; #define fsaShimPrepareRequestReadFile ((FSError(*)(FSAShimBuffer * shim, IOSHandle clientHandle, uint8_t * buffer, uint32_t size, uint32_t count, uint32_t pos, FSFileHandle handle, FSAReadFlag readFlags))(0x101C400 + 0x436cc)) diff --git a/src/utils/utils.h b/src/utils/utils.h index ef974ce..d35fbca 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -15,8 +15,8 @@ std::shared_ptr make_shared_nothrow(Args &&...args) noexcept(noexcept(T(std:: } template -bool remove_locked_first_if(std::mutex &mutex, std::vector &list, Predicate pred) { - std::lock_guard lock(mutex); +bool remove_locked_first_if(std::recursive_mutex &mutex, std::vector &list, Predicate pred) { + std::lock_guard lock(mutex); auto it = list.begin(); while (it != list.end()) { if (pred(*it)) { From bac71e89dbb336c2e218495d0b762534ece7fc12 Mon Sep 17 00:00:00 2001 From: Maschell Date: Tue, 13 Jan 2026 20:02:07 +0100 Subject: [PATCH 2/4] Fix stack allocation test --- src/FileUtils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FileUtils.cpp b/src/FileUtils.cpp index bfce102..574321b 100644 --- a/src/FileUtils.cpp +++ b/src/FileUtils.cpp @@ -527,7 +527,7 @@ void startFSIOThreads() { continue; } threadData->stack = (uint8_t *) memalign(0x20, stackSize); - if (!threadData->thread) { + if (!threadData->stack) { free(threadData->thread); DEBUG_FUNCTION_LINE_ERR("Failed to allocate threadData stack"); OSFatal("ContentRedirectionModule: Failed to allocate IO Thread stack"); From 35324be3bad7825f313a28503951151699255608 Mon Sep 17 00:00:00 2001 From: Maschell Date: Tue, 13 Jan 2026 20:16:19 +0100 Subject: [PATCH 3/4] Fix compiling with latest wut version --- Makefile | 2 +- src/FSWrapper.cpp | 26 +++++++++++++------------- src/FSWrapperMergeDirsWithParent.cpp | 6 +++--- src/FSWrapperReplaceSingleFile.cpp | 2 +- src/FileUtils.cpp | 8 ++++---- src/utils/utils.cpp | 2 +- 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index c21d96f..da53d2b 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ INCLUDES := src #------------------------------------------------------------------------------- # options for code generation #------------------------------------------------------------------------------- -CFLAGS := -Wall -Wextra -Os -ffunction-sections\ +CFLAGS := -Wall -Werror -Wextra -Os -ffunction-sections\ $(MACHDEP) CFLAGS += $(INCLUDE) -D__WIIU__ -D__WUT__ diff --git a/src/FSWrapper.cpp b/src/FSWrapper.cpp index 8b82f23..f4a0989 100644 --- a/src/FSWrapper.cpp +++ b/src/FSWrapper.cpp @@ -75,7 +75,7 @@ FSError FSWrapper::FSReadDirWrapper(const FSDirectoryHandle handle, FSDirectoryE DIR *dir = dirHandle->dir; FSError result = FS_ERROR_END_OF_DIR; - DEBUG_FUNCTION_LINE_VERBOSE("[%s] readdir %08X (handle %08X)", getName().c_str(), dir, handle); + DEBUG_FUNCTION_LINE_VERBOSE("[%s] readdir %p (handle %08X)", getName().c_str(), dir, handle); do { errno = 0; struct dirent *entry_ = readdir(dir); @@ -128,7 +128,7 @@ FSError FSWrapper::FSReadDirWrapper(const FSDirectoryHandle handle, FSDirectoryE } else { auto err = errno; if (err != 0) { - DEBUG_FUNCTION_LINE_ERR("[%s] Failed to read dir %08X (handle %08X). errno %d (%s)", getName().c_str(), dir, handle, err, strerror(err)); + DEBUG_FUNCTION_LINE_ERR("[%s] Failed to read dir %p (handle %08X). errno %d (%s)", getName().c_str(), dir, handle, err, strerror(err)); result = FS_ERROR_MEDIA_ERROR; } } @@ -146,9 +146,9 @@ FSError FSWrapper::FSCloseDirWrapper(const FSDirectoryHandle handle) { DIR *dir = dirHandle->dir; FSError result = FS_ERROR_OK; - DEBUG_FUNCTION_LINE_VERBOSE("[%s] closedir %08X (handle %08X)", getName().c_str(), dir, handle); + DEBUG_FUNCTION_LINE_VERBOSE("[%s] closedir %p (handle %08X)", getName().c_str(), dir, handle); if (closedir(dir) < 0) { - DEBUG_FUNCTION_LINE_ERR("[%s] Failed to close dir %08X (handle %08X)", getName().c_str(), dir, handle); + DEBUG_FUNCTION_LINE_ERR("[%s] Failed to close dir %p (handle %08X)", getName().c_str(), dir, handle); result = FS_ERROR_MEDIA_ERROR; } dirHandle->dir = nullptr; @@ -164,7 +164,7 @@ FSError FSWrapper::FSRewindDirWrapper(const FSDirectoryHandle handle) { DIR *dir = dirHandle->dir; - DEBUG_FUNCTION_LINE_VERBOSE("[%s] rewinddir %08X (handle %08X)", getName().c_str(), dir, handle); + DEBUG_FUNCTION_LINE_VERBOSE("[%s] rewinddir %p (handle %08X)", getName().c_str(), dir, handle); rewinddir(dir); return FS_ERROR_OK; @@ -397,7 +397,7 @@ FSError FSWrapper::FSReadFileWrapper(void *buffer, const uint32_t size, const ui auto fileHandle = getFileFromHandle(handle); int real_fd = fileHandle->fd; - DEBUG_FUNCTION_LINE_VERBOSE("[%s] Read %u bytes of fd %08X (FSFileHandle %08X) to buffer %08X", getName().c_str(), size * count, real_fd, handle, buffer); + DEBUG_FUNCTION_LINE_VERBOSE("[%s] Read %u bytes of fd %08X (FSFileHandle %08X) to buffer %p", getName().c_str(), size * count, real_fd, handle, buffer); int64_t read = readIntoBuffer(real_fd, buffer, size, count); FSError result; @@ -468,7 +468,7 @@ FSError FSWrapper::FSGetPosFileWrapper(const FSFileHandle handle, uint32_t *pos) DEBUG_FUNCTION_LINE_VERBOSE("[%s] lseek fd %08X (FSFileHandle %08X) to get current position for truncation", getName().c_str(), real_fd, handle); off_t currentPos = lseek(real_fd, (off_t) 0, SEEK_CUR); if (currentPos == -1) { - DEBUG_FUNCTION_LINE_ERR("[%s] Failed to get current position (res: %lld) of fd (handle %08X) to check EoF", getName().c_str(), currentPos, real_fd, handle); + DEBUG_FUNCTION_LINE_ERR("[%s] Failed to get current position (res: %lld) of fd %08X (handle %08X) to check EoF", getName().c_str(), currentPos, real_fd, handle); result = FS_ERROR_MEDIA_ERROR; } else { *pos = currentPos; @@ -493,7 +493,7 @@ FSError FSWrapper::FSIsEofWrapper(const FSFileHandle handle) { if (currentPos == -1 || endPos == -1) { // TODO: check errno - DEBUG_FUNCTION_LINE_ERR("[%s] Failed to get current position (res: %lld) or endPos (res: %lld) of fd (handle %08X) to check EoF", getName().c_str(), currentPos, endPos, real_fd, handle); + DEBUG_FUNCTION_LINE_ERR("[%s] Failed to get current position (res: %lld) or endPos (res: %lld) of fd %08X (handle %08X) to check EoF", getName().c_str(), currentPos, endPos, real_fd, handle); result = FS_ERROR_MEDIA_ERROR; } else if (currentPos == endPos) { DEBUG_FUNCTION_LINE_VERBOSE("[%s] FSIsEof END for %d\n", getName().c_str(), real_fd); @@ -512,7 +512,7 @@ FSError FSWrapper::FSTruncateFileWrapper(const FSFileHandle handle) { return FS_ERROR_FORCE_PARENT_LAYER; } - if (!pIsWriteable) { + if (pIsWriteable) { DEBUG_FUNCTION_LINE_VERBOSE("[%s] Tried to truncate fd %d (handle %08X) but layer is not writeable", getName().c_str(), getFileFromHandle(handle)->fd, handle); return FS_ERROR_ACCESS_ERROR; } @@ -527,7 +527,7 @@ FSError FSWrapper::FSTruncateFileWrapper(const FSFileHandle handle) { off_t currentPos = lseek(real_fd, (off_t) 0, SEEK_CUR); if (currentPos == -1) { // TODO check errno - DEBUG_FUNCTION_LINE_ERR("[%s] Failed to get current position of fd (handle %08X) to truncate file", getName().c_str(), real_fd, handle); + DEBUG_FUNCTION_LINE_ERR("[%s] Failed to get current position of fd %08X (handle %08X) to truncate file", getName().c_str(), real_fd, handle); result = FS_ERROR_MEDIA_ERROR; } else { DEBUG_FUNCTION_LINE_VERBOSE("[%s] Truncate fd %08X (FSFileHandle %08X) to %lld bytes ", getName().c_str(), real_fd, handle, currentPos); @@ -554,11 +554,11 @@ FSError FSWrapper::FSWriteFileWrapper(const uint8_t *buffer, const uint32_t size int real_fd = fileHandle->fd; - DEBUG_FUNCTION_LINE_VERBOSE("[%s] Write %u bytes to fd %08X (FSFileHandle %08X) from buffer %08X", getName().c_str(), count * size, real_fd, handle, buffer); + DEBUG_FUNCTION_LINE_VERBOSE("[%s] Write %u bytes to fd %08X (FSFileHandle %08X) from buffer %p", getName().c_str(), count * size, real_fd, handle, buffer); auto writeRes = writeFromBuffer(real_fd, buffer, size, count); if (writeRes < 0) { auto err = errno; - DEBUG_FUNCTION_LINE_ERR("[%s] Write failed %u bytes to fd %08X (FSFileHandle %08X) from buffer %08X errno %d", getName().c_str(), count * size, real_fd, handle, buffer, err); + DEBUG_FUNCTION_LINE_ERR("[%s] Write failed %u bytes to fd %08X (FSFileHandle %08X) from buffer %p errno %d", getName().c_str(), count * size, real_fd, handle, buffer, err); if (err == EFBIG) { result = FS_ERROR_FILE_TOO_BIG; } else if (err == EACCES) { @@ -640,7 +640,7 @@ FSError FSWrapper::FSFlushFileWrapper(const FSFileHandle handle) { const auto fileHandle = getFileFromHandle(handle); const int real_fd = fileHandle->fd; - DEBUG_FUNCTION_LINE_VERBOSE("[%s] fsync fd %08X (FSFileHandle %08X)", real_fd, handle); + DEBUG_FUNCTION_LINE_VERBOSE("[%s] fsync fd %08X (FSFileHandle %08X)", getName().c_str(), real_fd, handle); FSError result = FS_ERROR_OK; if (fsync(real_fd) < 0) { DEBUG_FUNCTION_LINE_ERR("[%s] fsync failed for fd %08X (FSFileHandle %08X)", getName().c_str(), real_fd, handle); diff --git a/src/FSWrapperMergeDirsWithParent.cpp b/src/FSWrapperMergeDirsWithParent.cpp index 9a2bc91..7c746e1 100644 --- a/src/FSWrapperMergeDirsWithParent.cpp +++ b/src/FSWrapperMergeDirsWithParent.cpp @@ -68,7 +68,7 @@ FSError FSWrapperMergeDirsWithParent::FSReadDirWrapper(FSADirectoryHandle handle if (dirHandle->readResultCapacity == 0) { dirHandle->readResult = (FSDirectoryEntryEx *) malloc(sizeof(FSDirectoryEntryEx)); if (dirHandle->readResult == nullptr) { - DEBUG_FUNCTION_LINE_ERR("[%s] Failed to alloc memory for %08X (handle %08X)", getName().c_str(), dirHandle.get(), handle); + DEBUG_FUNCTION_LINE_ERR("[%s] Failed to alloc memory for %p (handle %08X)", getName().c_str(), dirHandle.get(), handle); OSFatal("ContentRedirectionModule: Failed to alloc memory for read result"); } dirHandle->readResultCapacity = 1; @@ -79,7 +79,7 @@ FSError FSWrapperMergeDirsWithParent::FSReadDirWrapper(FSADirectoryHandle handle dirHandle->readResult = (FSDirectoryEntryEx *) realloc(dirHandle->readResult, newCapacity * sizeof(FSDirectoryEntryEx)); dirHandle->readResultCapacity = newCapacity; if (dirHandle->readResult == nullptr) { - DEBUG_FUNCTION_LINE_ERR("[%s] Failed to realloc memory for %08X (handle %08X)", getName().c_str(), dirHandle.get(), handle); + DEBUG_FUNCTION_LINE_ERR("[%s] Failed to realloc memory for %p (handle %08X)", getName().c_str(), dirHandle.get(), handle); OSFatal("ContentRedirectionModule: Failed to alloc memory for read result"); } } @@ -242,7 +242,7 @@ FSWrapperMergeDirsWithParent::~FSWrapperMergeDirsWithParent() { if (mClientHandle) { FSError res; if ((res = FSADelClient(mClientHandle)) != FS_ERROR_OK) { - DEBUG_FUNCTION_LINE_ERR("[%s] FSADelClient failed: %s (%d)", FSAGetStatusStr(res), res); + DEBUG_FUNCTION_LINE_ERR("[%s] FSADelClient failed: %s (%d)", pName.c_str(), FSAGetStatusStr(res), res); } mClientHandle = 0; } diff --git a/src/FSWrapperReplaceSingleFile.cpp b/src/FSWrapperReplaceSingleFile.cpp index 640ce9d..f62ede5 100644 --- a/src/FSWrapperReplaceSingleFile.cpp +++ b/src/FSWrapperReplaceSingleFile.cpp @@ -41,7 +41,7 @@ FSWrapperReplaceSingleFile::FSWrapperReplaceSingleFile(const std::string &name, FSWrapperReplaceSingleFile::~FSWrapperReplaceSingleFile() { if (mClientHandle) { if (const FSError res = FSADelClient(mClientHandle); res != FS_ERROR_OK) { - DEBUG_FUNCTION_LINE_ERR("[%s] FSADelClient failed: %s (%d)", FSAGetStatusStr(res), res); + DEBUG_FUNCTION_LINE_ERR("[%s] FSADelClient failed: %s (%d)", pName.c_str(), FSAGetStatusStr(res), res); } mClientHandle = 0; } diff --git a/src/FileUtils.cpp b/src/FileUtils.cpp index 574321b..f678b4d 100644 --- a/src/FileUtils.cpp +++ b/src/FileUtils.cpp @@ -209,10 +209,10 @@ FSError doForLayer(FSShimWrapper *param) { auto *request = ¶m->shim->request.readFile; if (request->readFlags == FSA_READ_FLAG_NONE) { - DEBUG_FUNCTION_LINE_VERBOSE("[%s] ReadFile: buffer %08X size %08X count %08X handle %08X", layer->getName().c_str(), request->buffer, request->size, request->count, request->handle); + DEBUG_FUNCTION_LINE_VERBOSE("[%s] ReadFile: buffer %p size %08X count %08X handle %08X", layer->getName().c_str(), request->buffer, request->size, request->count, request->handle); layerResult = layer->FSReadFileWrapper(request->buffer, request->size, request->count, request->handle, 0); } else if (request->readFlags == FSA_READ_FLAG_READ_WITH_POS) { - DEBUG_FUNCTION_LINE_VERBOSE("[%s] ReadFileWithPos: buffer %08X size %08X count %08X pos %08X handle %08X", layer->getName().c_str(), request->buffer, request->size, request->count, request->pos, request->handle); + DEBUG_FUNCTION_LINE_VERBOSE("[%s] ReadFileWithPos: buffer %p size %08X count %08X pos %08X handle %08X", layer->getName().c_str(), request->buffer, request->size, request->count, request->pos, request->handle); layerResult = layer->FSReadFileWithPosWrapper(request->buffer, request->size, request->count, request->pos, request->handle, 0); } break; @@ -250,10 +250,10 @@ FSError doForLayer(FSShimWrapper *param) { auto *request = ¶m->shim->request.writeFile; if (request->writeFlags == FSA_WRITE_FLAG_NONE) { - DEBUG_FUNCTION_LINE_VERBOSE("[%s] WriteFile: buffer %08X size %08X count %08X handle %08X", layer->getName().c_str(), request->buffer, request->size, request->count, request->handle); + DEBUG_FUNCTION_LINE_VERBOSE("[%s] WriteFile: buffer %p size %08X count %08X handle %08X", layer->getName().c_str(), request->buffer, request->size, request->count, request->handle); layerResult = layer->FSWriteFileWrapper(request->buffer, request->size, request->count, request->handle, 0); } else if (request->writeFlags == FSA_WRITE_FLAG_READ_WITH_POS) { - DEBUG_FUNCTION_LINE_VERBOSE("[%s] WriteFileWithPos: buffer %08X size %08X count %08X pos %08X handle %08X", layer->getName().c_str(), request->buffer, request->size, request->count, request->pos, request->handle); + DEBUG_FUNCTION_LINE_VERBOSE("[%s] WriteFileWithPos: buffer %p size %08X count %08X pos %08X handle %08X", layer->getName().c_str(), request->buffer, request->size, request->count, request->pos, request->handle); layerResult = layer->FSWriteFileWithPosWrapper(request->buffer, request->size, request->count, request->pos, request->handle, 0); } break; diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp index b141d9f..6d9b876 100644 --- a/src/utils/utils.cpp +++ b/src/utils/utils.cpp @@ -12,7 +12,7 @@ void dumpHex(const void *data, size_t size) { char ascii[17]; size_t i, j; ascii[16] = '\0'; - DEBUG_FUNCTION_LINE("0x%08X (0x0000): ", data); + DEBUG_FUNCTION_LINE("0x%p (0x0000): ", data); for (i = 0; i < size; ++i) { WHBLogWritef("%02X ", ((unsigned char *) data)[i]); if (((unsigned char *) data)[i] >= ' ' && ((unsigned char *) data)[i] <= '~') { From f5a5a1be621b0715e881aa344fc336cfa618eb76 Mon Sep 17 00:00:00 2001 From: Maschell Date: Wed, 18 Mar 2026 20:28:58 +0100 Subject: [PATCH 4/4] Update Dockerfile --- Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index f15b2d9..1127b2f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ -FROM ghcr.io/wiiu-env/devkitppc:20241128 +FROM ghcr.io/wiiu-env/devkitppc:20260225 -COPY --from=ghcr.io/wiiu-env/libfunctionpatcher:20230621 /artifacts $DEVKITPRO -COPY --from=ghcr.io/wiiu-env/wiiumodulesystem:20250208 /artifacts $DEVKITPRO -COPY --from=ghcr.io/wiiu-env/libcontentredirection:20250208 /artifacts $DEVKITPRO +COPY --from=ghcr.io/wiiu-env/libfunctionpatcher:20260208 /artifacts $DEVKITPRO +COPY --from=ghcr.io/wiiu-env/wiiumodulesystem:20260225 /artifacts $DEVKITPRO +COPY --from=ghcr.io/wiiu-env/libcontentredirection:20260131 /artifacts $DEVKITPRO WORKDIR project