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