diff --git a/Dockerfile b/Dockerfile index 7729a7a..ff9fafe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,9 @@ FROM ghcr.io/wiiu-env/devkitppc:20260225 -COPY --from=ghcr.io/wiiu-env/wiiumodulesystem:20260225 /artifacts $DEVKITPRO -COPY --from=ghcr.io/wiiu-env/libiopshell:20260318-4d267a2 /artifacts $DEVKITPRO -COPY --from=ghcr.io/wiiu-env/libfunctionpatcher:20260208 /artifacts $DEVKITPRO -COPY --from=ghcr.io/wiiu-env/libkernel:20260208 /artifacts $DEVKITPRO -COPY --from=ghcr.io/wiiu-env/libmocha:20260126 /artifacts $DEVKITPRO +COPY --from=ghcr.io/wiiu-env/wiiumodulesystem:20260418 /artifacts $DEVKITPRO +COPY --from=ghcr.io/wiiu-env/libiopshell:20260318 /artifacts $DEVKITPRO +COPY --from=ghcr.io/wiiu-env/libfunctionpatcher:20260331 /artifacts $DEVKITPRO +COPY --from=ghcr.io/wiiu-env/libkernel:20260331 /artifacts $DEVKITPRO +COPY --from=ghcr.io/wiiu-env/libmocha:20260331 /artifacts $DEVKITPRO WORKDIR project diff --git a/source/aroma_shell_userland.cpp b/source/aroma_shell_userland.cpp index 1928499..c2caf38 100644 --- a/source/aroma_shell_userland.cpp +++ b/source/aroma_shell_userland.cpp @@ -18,6 +18,8 @@ #define QUEUE_CAPACITY 4 #define CMD_MAX_SIZE 0x200 +#define THREAD_NAME "IOShell Aroma Command Receiving Thread" + namespace { OSThread *sThread = nullptr; void *sStack = nullptr; @@ -133,7 +135,7 @@ void StartAromaShellUserlandCommandReceiveThread() { sThreadRunning = true; OSMemoryBarrier(); - OSSetThreadName(sThread, "IOShell Aroma Command Receiving Thread"); + OSSetThreadName(sThread, THREAD_NAME); OSResumeThread(sThread); } @@ -177,4 +179,18 @@ void AromaShellWakeUpReceiverThread() { __OSUnlockScheduler(sThread); } OSRestoreInterrupts(enabled); -} \ No newline at end of file +} + +DECL_FUNCTION(void, OSCancelThread, OSThread *thread) { + + if (sThreadRunning && thread == sThread) { + DEBUG_FUNCTION_LINE_INFO("Prevent calling OSCancelThread for \"%s\", instead stop it", THREAD_NAME); + StopAromaShellUserlandCommandReceiveThread(); + return; + } + real_OSCancelThread(thread); +} + +// clang-format off +function_replacement_data_t OSCancelThreadReplacement = REPLACE_FUNCTION(OSCancelThread, LIBRARY_COREINIT, OSCancelThread); +// clang-format on \ No newline at end of file diff --git a/source/aroma_shell_userland.h b/source/aroma_shell_userland.h index db2651a..15b846d 100644 --- a/source/aroma_shell_userland.h +++ b/source/aroma_shell_userland.h @@ -1,4 +1,5 @@ #pragma once +#include #include #define AROMA_SHELL_QUEUE_CMD_STOP 0x40 @@ -8,3 +9,5 @@ void AddAromaShellCommandFromExceptionCallback(std::string_view command); void StopAromaShellUserlandCommandReceiveThread(); void StartAromaShellUserlandCommandReceiveThread(); + +extern function_replacement_data_t OSCancelThreadReplacement; \ No newline at end of file diff --git a/source/logger.h b/source/logger.h index 486a33a..e3a85b4 100644 --- a/source/logger.h +++ b/source/logger.h @@ -8,47 +8,61 @@ extern "C" { #endif -#define LOG_APP_TYPE "M" -#define LOG_APP_NAME "iopshellmodule" +#define LOG_APP_TYPE "M" +#define LOG_APP_NAME "iopshellmodule" -#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__) -#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__) +#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__) +#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__) -#define LOG(LOG_FUNC, FMT, ARGS...) LOG_EX(LOG_FUNC, "", "", FMT, ##ARGS) +#define LOG(LOG_FUNC, FMT, ARGS...) LOG_EX_DEFAULT(LOG_FUNC, "", "", "", FMT, ##ARGS) -#define LOG_EX(LOG_FUNC, LOG_LEVEL, LINE_END, FMT, ARGS...) \ - do { \ - LOG_FUNC("[(%s)%18s][%23s]%30s@L%04d: " LOG_LEVEL "" FMT "" LINE_END, LOG_APP_TYPE, LOG_APP_NAME, __FILENAME__, __FUNCTION__, __LINE__, ##ARGS); \ - } while (0) +#define CONSOLE_COLOR_RED "\033[31m" +#define CONSOLE_COLOR_YELLOW "\033[33m" +#define CONSOLE_COLOR_CYAN "\033[36m" +#define CONSOLE_COLOR_RESET "\033[0m" + +#define LOG_EX_DEFAULT(LOG_FUNC, LOG_COLOR, LOG_LEVEL, LINE_END, FMT, ARGS...) LOG_EX(__FILENAME__, __FUNCTION__, __LINE__, LOG_FUNC, LOG_COLOR, LOG_LEVEL, LINE_END, FMT, ##ARGS) +#define LOG_EX(FILENAME, FUNCTION, LINE, LOG_FUNC, LOG_COLOR, LOG_LEVEL, LINE_END, FMT, ARGS...) \ + do { \ + LOG_FUNC(LOG_COLOR "[(%s)%18s][%23s]%30s@L%04d: " LOG_LEVEL "" FMT "" LINE_END, LOG_APP_TYPE, LOG_APP_NAME, FILENAME, FUNCTION, LINE, ##ARGS); \ + } while (0) #ifdef DEBUG #ifdef VERBOSE_DEBUG -#define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) LOG_EX(OSReport, "", "\n", FMT, ##ARGS) +#define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) LOG(WHBLogPrintf, FMT, ##ARGS) +#define DEBUG_FUNCTION_LINE_VERBOSE_EX(FILENAME, FUNCTION, LINE, FMT, ARGS...) LOG_EX(FILENAME, FUNCTION, LINE, WHBLogPrintf, "", "", FMT, ##ARGS); #else -#define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) while (0) +#define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) while (0) +#define DEBUG_FUNCTION_LINE_VERBOSE_EX(FMT, ARGS...) while (0) #endif -#define DEBUG_FUNCTION_LINE(FMT, ARGS...) LOG_EX(OSReport, "", "\n", FMT, ##ARGS) +#define DEBUG_FUNCTION_LINE(FMT, ARGS...) LOG(WHBLogPrintf, FMT, ##ARGS) -#define DEBUG_FUNCTION_LINE_WRITE(FMT, ARGS...) LOG_EX(OSReport, "", "", FMT, ##ARGS) +#define DEBUG_FUNCTION_LINE_WRITE(FMT, ARGS...) LOG(WHBLogWritef, FMT, ##ARGS) -#define DEBUG_FUNCTION_LINE_INFO(FMT, ARGS...) LOG_EX(OSReport, "## INFO## ", "\n", FMT, ##ARGS) -#define DEBUG_FUNCTION_LINE_ERR(FMT, ARGS...) LOG_EX(OSReport, "##ERROR## ", "\n", FMT, ##ARGS) -#define DEBUG_FUNCTION_LINE_WARN(FMT, ARGS...) LOG_EX(OSReport, "## WARN## ", "\n", FMT, ##ARGS) +#define DEBUG_FUNCTION_LINE_ERR(FMT, ARGS...) LOG_EX_DEFAULT(WHBLogPrintf, CONSOLE_COLOR_RED, "## ERROR## ", CONSOLE_COLOR_RESET, FMT, ##ARGS) +#define DEBUG_FUNCTION_LINE_WARN(FMT, ARGS...) LOG_EX_DEFAULT(WHBLogPrintf, CONSOLE_COLOR_YELLOW, "##WARN ## ", CONSOLE_COLOR_RESET, FMT, ##ARGS) +#define DEBUG_FUNCTION_LINE_INFO(FMT, ARGS...) LOG_EX_DEFAULT(WHBLogPrintf, CONSOLE_COLOR_CYAN, "##INFO ## ", CONSOLE_COLOR_RESET, FMT, ##ARGS) + +#define DEBUG_FUNCTION_LINE_ERR_LAMBDA(FILENAME, FUNCTION, LINE, FMT, ARGS...) LOG_EX(FILENAME, FUNCTION, LINE, WHBLogPrintf, CONSOLE_COLOR_RED, "##ERROR## ", CONSOLE_COLOR_RESET, FMT, ##ARGS); #else -#define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) while (0) +#define DEBUG_FUNCTION_LINE_VERBOSE_EX(FMT, ARGS...) while (0) + +#define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) while (0) + +#define DEBUG_FUNCTION_LINE(FMT, ARGS...) while (0) -#define DEBUG_FUNCTION_LINE(FMT, ARGS...) while (0) +#define DEBUG_FUNCTION_LINE_WRITE(FMT, ARGS...) while (0) -#define DEBUG_FUNCTION_LINE_WRITE(FMT, ARGS...) while (0) +#define DEBUG_FUNCTION_LINE_ERR(FMT, ARGS...) LOG_EX_DEFAULT(OSReport, CONSOLE_COLOR_RED, "##ERROR## ", CONSOLE_COLOR_RESET "\n", FMT, ##ARGS) +#define DEBUG_FUNCTION_LINE_WARN(FMT, ARGS...) LOG_EX_DEFAULT(OSReport, CONSOLE_COLOR_YELLOW, "##WARN ## ", CONSOLE_COLOR_RESET "\n", FMT, ##ARGS) +#define DEBUG_FUNCTION_LINE_INFO(FMT, ARGS...) LOG_EX_DEFAULT(OSReport, CONSOLE_COLOR_CYAN, "##INFO ## ", CONSOLE_COLOR_RESET "\n", FMT, ##ARGS) -#define DEBUG_FUNCTION_LINE_INFO(FMT, ARGS...) LOG_EX(OSReport, "##ERROR## ", "\n", FMT, ##ARGS) -#define DEBUG_FUNCTION_LINE_ERR(FMT, ARGS...) LOG_EX(OSReport, "##ERROR## ", "\n", FMT, ##ARGS) -#define DEBUG_FUNCTION_LINE_WARN(FMT, ARGS...) LOG_EX(OSReport, "## WARN## ", "\n", FMT, ##ARGS) +#define DEBUG_FUNCTION_LINE_ERR_LAMBDA(FILENAME, FUNCTION, LINE, FMT, ARGS...) LOG_EX(FILENAME, FUNCTION, LINE, OSReport, CONSOLE_COLOR_RED, "##ERROR## ", CONSOLE_COLOR_RESET "\n", FMT, ##ARGS); #endif diff --git a/source/main.cpp b/source/main.cpp index 67285ef..cdc582f 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -43,6 +43,11 @@ WUMS_INITIALIZE() { } } + wasPatched = false; + if (FunctionPatcher_AddFunctionPatch(&OSCancelThreadReplacement, nullptr, &wasPatched) != FUNCTION_PATCHER_RESULT_SUCCESS || !wasPatched) { + OSFatal("homebrew_content_redirection: Failed to patch OSCancelThreadReplacement"); + } + // Start iopshell on kernel KernelPatchSyscall(0x51, (uint32_t) &IopShellInitInternal); SC_0x51();