From 278e2b895bdfa8b8da34678036bb9e5f0dd923a2 Mon Sep 17 00:00:00 2001 From: Maschell Date: Sat, 18 Feb 2023 09:20:45 +0100 Subject: [PATCH] Add support for RPXLoader_GetPathOfRunningExecutable --- include/rpxloader/rpxloader.h | 20 +++++++++++++++++++- source/rpxloader.cpp | 25 ++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/include/rpxloader/rpxloader.h b/include/rpxloader/rpxloader.h index de8d7b0..00d34b8 100644 --- a/include/rpxloader/rpxloader.h +++ b/include/rpxloader/rpxloader.h @@ -15,6 +15,7 @@ typedef enum RPXLoaderStatus { RPX_LOADER_RESULT_LIB_UNINITIALIZED = -0x20, RPX_LOADER_RESULT_MODULE_NOT_FOUND = -0x30, RPX_LOADER_RESULT_MODULE_MISSING_EXPORT = -0x31, + RPX_LOADER_RESULT_NOT_AVAILABLE = -0x40, RPX_LOADER_RESULT_UNKNOWN_ERROR = -0x100, } RPXLoaderStatus; @@ -56,7 +57,7 @@ RPXLoaderStatus RPXLoader_GetVersion(uint32_t *outVersion); * Sets the .rpx or .wuhb that will be loaded the next time the homebrew wrapper application is launched (e.g. Health & Safety or Daily Log).
* When a .wuhb will be loaded, accesses to /vol/content will be redirected to the .wuhb, /vol/save will be redirected to the sd card.
*
- * The path is **relative** to the root of the given target device.
+ * The path is **relative** to the root of the sd card
*
* To launch the prepared RPX call RPXLoader_LaunchPreparedHomebrew if this call was successful.
*
@@ -138,6 +139,23 @@ RPXLoaderStatus RPXLoader_DisableContentRedirection(); */ RPXLoaderStatus RPXLoader_UnmountCurrentRunningBundle(); +/** + * Returns the path of the currently running executable
+ * This function is not guaranteed to succeed, it only works if the executable is loaded via the RPXLoadingModule
+ * The returned path is relative to the root of the sd card.
+ *
+ * Requires API version 2 or higher.
+ * + * @param outBuffer buffer where the result will be stored + * @param outSize size of outBuffer + * @return RPX_LOADER_RESULT_SUCCESS: The path of the currently running executable has been written to outBuffer + * RPX_LOADER_RESULT_UNSUPPORTED_COMMAND: Command not supported by the currently loaded RPXLoaderModule version.
+ * RPX_LOADER_RESULT_INVALID_ARGUMENT: The given outBuffer was NULL or outSize was 0
+ * RPX_LOADER_RESULT_LIB_UNINITIALIZED: "RPXLoader_Init()" was not called.
+ * RPX_LOADER_RESULT_NOT_AVAILABLE: The path is not available.
+*/ +RPXLoaderStatus RPXLoader_GetPathOfRunningExecutable(char *outBuffer, uint32_t outSize); + #ifdef __cplusplus } // extern "C" #endif \ No newline at end of file diff --git a/source/rpxloader.cpp b/source/rpxloader.cpp index 8d231c7..d43f42a 100644 --- a/source/rpxloader.cpp +++ b/source/rpxloader.cpp @@ -11,9 +11,10 @@ static RPXLoaderStatus (*sRLPrepareLaunchFromSD)(const char *path) = nullptr; static RPXLoaderStatus (*sRLLaunchPreparedHomebrew)() = nullptr; static RPXLoaderStatus (*sRLLaunchHomebrew)(const char *bundle_path) = nullptr; -static RPXLoaderStatus (*sRLDisableContentRedirection)() = nullptr; -static RPXLoaderStatus (*sRLEnableContentRedirection)() = nullptr; -static RPXLoaderStatus (*sRLUnmountCurrentRunningBundle)() = nullptr; +static RPXLoaderStatus (*sRLDisableContentRedirection)() = nullptr; +static RPXLoaderStatus (*sRLEnableContentRedirection)() = nullptr; +static RPXLoaderStatus (*sRLUnmountCurrentRunningBundle)() = nullptr; +static RPXLoaderStatus (*sRL_GetPathOfRunningExecutable)(char *outBuffer, uint32_t outSize) = nullptr; const char *RPXLoader_GetStatusStr(RPXLoaderStatus status) { switch (status) { @@ -35,6 +36,8 @@ const char *RPXLoader_GetStatusStr(RPXLoaderStatus status) { return "RPX_LOADER_RESULT_UNSUPPORTED_API_VERSION"; case RPX_LOADER_RESULT_UNSUPPORTED_COMMAND: return "RPX_LOADER_RESULT_UNSUPPORTED_COMMAND"; + case RPX_LOADER_RESULT_NOT_AVAILABLE: + return "RPX_LOADER_RESULT_NOT_AVAILABLE"; } return "RPX_LOADER_RESULT_UNKNOWN_ERROR"; } @@ -85,6 +88,11 @@ RPXLoaderStatus RPXLoader_InitLibrary() { sRLUnmountCurrentRunningBundle = nullptr; } + if (OSDynLoad_FindExport(sModuleHandle, FALSE, "RL_GetPathOfRunningExecutable", (void **) &sRL_GetPathOfRunningExecutable) != OS_DYNLOAD_OK) { + DEBUG_FUNCTION_LINE_WARN("FindExport RL_GetPathOfRunningExecutable failed."); + sRL_GetPathOfRunningExecutable = nullptr; + } + return RPX_LOADER_RESULT_SUCCESS; } @@ -174,4 +182,15 @@ RPXLoaderStatus RPXLoader_UnmountCurrentRunningBundle() { } return reinterpret_cast(sRLUnmountCurrentRunningBundle)(); +} + +RPXLoaderStatus RPXLoader_GetPathOfRunningExecutable(char *outBuffer, uint32_t outSize) { + if (rpxLoaderVersion == RPX_LOADER_MODULE_VERSION_ERROR) { + return RPX_LOADER_RESULT_LIB_UNINITIALIZED; + } + if (sRL_GetPathOfRunningExecutable == nullptr || rpxLoaderVersion < 2) { + return RPX_LOADER_RESULT_UNSUPPORTED_COMMAND; + } + + return reinterpret_cast(sRL_GetPathOfRunningExecutable)(outBuffer, outSize); } \ No newline at end of file