Update to be compatible with the latest RPXLoaderModule

This commit is contained in:
Maschell 2022-08-25 11:34:43 +02:00
parent 49ae50d68a
commit c07f616c29
3 changed files with 241 additions and 89 deletions

View File

@ -6,64 +6,112 @@ extern "C" {
#include <stdint.h> #include <stdint.h>
enum RPXLoaderStatus { typedef enum RPXLoaderStatus {
RPX_LOADER_RESULT_SUCCESS = 0, RPX_LOADER_RESULT_SUCCESS = 0,
RPX_LOADER_RESULT_MODULE_NOT_FOUND = -1, RPX_LOADER_RESULT_INVALID_ARGUMENT = -0x01,
RPX_LOADER_RESULT_MODULE_MISSING_EXPORT = -2, RPX_LOADER_RESULT_NOT_FOUND = -0x06,
RPX_LOADER_RESULT_UNSUPPORTED_VERSION = -3, RPX_LOADER_RESULT_UNSUPPORTED_API_VERSION = -0x10,
RPX_LOADER_RESULT_INVALID_ARG = -10, RPX_LOADER_RESULT_UNSUPPORTED_COMMAND = -0x11,
RPX_LOADER_RESULT_LIB_UNINITIALIZED = -20, RPX_LOADER_RESULT_LIB_UNINITIALIZED = -0x20,
RPX_LOADER_RESULT_UNKNOWN_ERROR = -1000, RPX_LOADER_RESULT_MODULE_NOT_FOUND = -0x30,
}; RPX_LOADER_RESULT_MODULE_MISSING_EXPORT = -0x31,
RPX_LOADER_RESULT_UNKNOWN_ERROR = -0x100,
} RPXLoaderStatus;
typedef uint32_t RPXLoaderVersion; typedef uint32_t RPXLoaderVersion;
#define RPX_LOADER_MODULE_VERSION 0x00000001 #define RPX_LOADER_MODULE_VERSION_ERROR 0xFFFFFFFF
const char *RPXLoader_GetStatusStr(RPXLoaderStatus status);
/** /**
* This function has to be called before any other function of this lib (except RPXLoader_GetVersion) can be used. * This function has to be called before any other function of this lib (except RPXLoader_GetVersion) can be used.
* *
* @return RPX_LOADER_RESULT_SUCCESS: The library has been initialized successfully. Other functions can now be used. * @return RPX_LOADER_RESULT_SUCCESS: The library has been initialized successfully. Other functions can now be used.<br>
* RPX_LOADER_RESULT_MODULE_NOT_FOUND: The module could not be found. Make sure the module is loaded. * RPX_LOADER_RESULT_MODULE_NOT_FOUND: The module could not be found. Make sure the module is loaded.<br>
* RPX_LOADER_RESULT_MODULE_MISSING_EXPORT: The module is missing an expected export. * RPX_LOADER_RESULT_MODULE_MISSING_EXPORT: The module is missing an expected export.<br>
* RPX_LOADER_RESULT_UNSUPPORTED_VERSION: The version of the loaded module is not compatible with this version of the lib. * RPX_LOADER_RESULT_UNSUPPORTED_API_VERSION: The version of the loaded module is not compatible with this version of the lib.
*/ */
RPXLoaderStatus RPXLoader_Init(); RPXLoaderStatus RPXLoader_InitLibrary();
/** /**
* Returns the API Version of the RPXLoader Module. * Deinitializes the RPXLoader lib
* @return The RPXLoaderVersion of the Module. * @return RPX_LOADER_RESULT_SUCCESS
*/ */
RPXLoaderVersion RPXLoader_GetVersion(); RPXLoaderStatus RPXLoader_DeInitLibrary();
/** /**
* Setups the given .rpx or .wuhb to be loaded on the next application restart. * Retrieves the API Version of the loaded RPXLoaderModule.<br>
* Make sure to (re-)launch the H&S app after calling this function. * <br>
* @param outVersion pointer to the variable where the version will be stored.
* *
* Calling this for a .rpx while the .wuhb is running while keep the bundle mounted, * @return RPX_LOADER_RESULT_SUCCESS: The API version has been store in the version ptr.<br>
* just the .rpx will be replaced. * RPX_LOADER_RESULT_MODULE_NOT_FOUND: The module could not be found. Make sure the module is loaded.<br>
* RPX_LOADER_RESULT_MODULE_MISSING_EXPORT: The module is missing an expected export.<br>
* RPX_LOADER_RESULT_INVALID_ARGUMENT: Invalid version pointer.<br>
* RPX_LOADER_RESULT_UNKNOWN_ERROR: Retrieving the module version failed.
*/
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).<br>
* 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.<br>
* <br>
* The path is **relative** to the root of the given target device.<br>
* <br>
* To launch the prepared RPX call RPXLoader_LaunchPreparedHomebrew if this call was successful.<br>
* *
* @param bundle_path relative path the root of the sd card (e.g. "/apps/test.wuhb") * @param path: path to the .rpx/.wuhb that should be loaded.
* @return RPX_LOADER_RESULT_SUCCESS: The given homebrew will be executed on the next Launch of Health and Safety * @return RPX_LOADER_RESULT_SUCCESS: Loading of the next RPX will be redirected. <br>
* RPX_LOADER_RESULT_LIB_UNINITIALIZED: "RPXLoader_Init()" was not called. * RPX_LOADER_RESULT_LIB_UNINITIALIZED: Library was not initialized. Call RPXLoader_InitLibrary() before using this function.<br>
* RPX_LOADER_RESULT_INVALID_ARG: "bundle_path" was NULL * RPX_LOADER_RESULT_UNSUPPORTED_COMMAND: Command not supported by the currently loaded RPXLoaderModule version.<br><br>
* RPX_LOADER_RESULT_UNKNOWN_ERROR: Error. No effect. * RPX_LOADER_RESULT_INVALID_ARGUMENT: Given path was NULL<br>
*/ * RPX_LOADER_RESULT_UNKNOWN_ERROR: Unexpected error.<br>
RPXLoaderStatus RPXLoader_LoadFromSDOnNextLaunch(const char *bundle_path); */
RPXLoaderStatus RPXLoader_PrepareLaunchFromSD(const char *path);
/**
* Launches the wrapper app for launching the .rpx/.wuhb that has been set via RPXLoader_PrepareLaunchFromSD<br>
* Works similar similar to the SYSLaunch* functions.<br>
* <br>
* see: `RPXLoader_LaunchHomebrew` to prepare and launch a RPX in one command. <br>
*
* @return RPX_LOADER_RESULT_SUCCESS: App is launching<br>
* RPX_LOADER_RESULT_LIB_UNINITIALIZED: Library was not initialized. Call RPX_LOADER_InitLibrary() before using this function.<br>
* RPX_LOADER_RESULT_UNSUPPORTED_COMMAND: Command not supported by the currently loaded RPXLoaderModule version.<br>
* RPX_LOADER_RESULT_NOT_FOUND: No application that can be used as homebrew wrapper found.<br>
* RPX_LOADER_RESULT_UNKNOWN_ERROR: Unexpected error.
*/
RPXLoaderStatus RPXLoader_LaunchPreparedHomebrew();
/**
* Launches a given .rpx/.wuhb by launching a wrapper application and replacing the RPX on the fly. <br>
* See RPXLoader_PrepareLaunchFromSD for more information. <br>
* <br>
* Note: Combines RPXLoader_PrepareLaunchFromSD and RPXLoader_LaunchPreparedHomebrew.
* @param bundle_path path to the .rpx/.wuhb that should be loaded.
* @return RPX_LOADER_RESULT_SUCCESS: Requested RPX/WUHB will be launched<br>
* RPX_LOADER_RESULT_LIB_UNINITIALIZED: Library was not initialized. Call RPXLoader_InitLibrary() before using this function.<br>
* RPX_LOADER_RESULT_UNSUPPORTED_COMMAND: Command not supported by the currently loaded RPXLoaderModule version.<br>
* RPX_LOADER_RESULT_INVALID_ARGUMENT: The given path was NULL <br>
* RPX_LOADER_RESULT_NOT_FOUND: No application that can be used as homebrew wrapper found.<br>
* RPX_LOADER_RESULT_UNKNOWN_ERROR: Unexpected error.
*/
RPXLoaderStatus RPXLoader_LaunchHomebrew(const char *bundle_path);
/** /**
* Enables the /vol/content redirection (is enabled by default if a .wuhb is running) * Enables the /vol/content redirection (is enabled by default if a .wuhb is running)
* *
* @return RPX_LOADER_RESULT_SUCCESS: /vol/content has been enabled or was already enabled. * @return RPX_LOADER_RESULT_SUCCESS: /vol/content has been enabled or was already enabled. <br>
* RPX_LOADER_RESULT_LIB_UNINITIALIZED: "RPXLoader_Init()" was not called. * RPX_LOADER_RESULT_LIB_UNINITIALIZED: "RPXLoader_Init()" was not called. <br>
* RPX_LOADER_RESULT_UNKNOWN_ERROR: Error * RPX_LOADER_RESULT_UNKNOWN_ERROR: Error
*/ */
RPXLoaderStatus RPXLoader_EnableContentRedirection(); RPXLoaderStatus RPXLoader_EnableContentRedirection();
/** /**
* Disables the /vol/content redirection * Disables the /vol/content redirection
* *
* @return RPX_LOADER_RESULT_SUCCESS: /vol/content has been disabled or was already disabled. * @return RPX_LOADER_RESULT_SUCCESS: /vol/content has been disabled or was already disabled. <br>
* RPX_LOADER_RESULT_LIB_UNINITIALIZED: "RPXLoader_Init()" was not called. * RPX_LOADER_RESULT_LIB_UNINITIALIZED: "RPXLoader_Init()" was not called. <br>
* RPX_LOADER_RESULT_UNKNOWN_ERROR: Error * RPX_LOADER_RESULT_UNKNOWN_ERROR: Error
*/ */
RPXLoaderStatus RPXLoader_DisableContentRedirection(); RPXLoaderStatus RPXLoader_DisableContentRedirection();
@ -71,9 +119,9 @@ RPXLoaderStatus RPXLoader_DisableContentRedirection();
/** /**
* Unmounts the currently running bundle. This also disables the /vol/content redirection * Unmounts the currently running bundle. This also disables the /vol/content redirection
* *
* @return RPX_LOADER_RESULT_SUCCESS: /vol/content has been unmounted or was not previously mounted. * @return RPX_LOADER_RESULT_SUCCESS: /vol/content has been unmounted or was not previously mounted.<br>
* RPX_LOADER_RESULT_LIB_UNINITIALIZED: "RPXLoader_Init()" was not called. * RPX_LOADER_RESULT_LIB_UNINITIALIZED: "RPXLoader_Init()" was not called.<br>
* RPX_LOADER_RESULT_UNKNOWN_ERROR: Unable to unmount the currently running bundle. * RPX_LOADER_RESULT_UNKNOWN_ERROR: Unable to unmount the currently running bundle.<br>
*/ */
RPXLoaderStatus RPXLoader_UnmountCurrentRunningBundle(); RPXLoaderStatus RPXLoader_UnmountCurrentRunningBundle();

23
source/logger.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include <coreinit/debug.h>
#include <cstring>
#define __FILENAME__ ({ \
const char *__filename = __FILE__; \
const char *__pos = strrchr(__filename, '/'); \
if (!__pos) __pos = strrchr(__filename, '\\'); \
__pos ? __pos + 1 : __filename; \
})
#define LOG_APP_TYPE "L"
#define LOG_APP_NAME "librpxloader"
#define LOG_EX(FILENAME, FUNCTION, LINE, 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 LOG_EX_DEFAULT(LOG_FUNC, LOG_LEVEL, LINE_END, FMT, ARGS...) LOG_EX(__FILENAME__, __FUNCTION__, __LINE__, LOG_FUNC, LOG_LEVEL, LINE_END, FMT, ##ARGS)
#define DEBUG_FUNCTION_LINE_ERR(FMT, ARGS...) LOG_EX_DEFAULT(OSReport, "##ERROR## ", "\n", FMT, ##ARGS)
#define DEBUG_FUNCTION_LINE_WARN(FMT, ARGS...) LOG_EX_DEFAULT(OSReport, "##WARNING## ", "\n", FMT, ##ARGS)

View File

@ -1,3 +1,4 @@
#include "logger.h"
#include <coreinit/debug.h> #include <coreinit/debug.h>
#include <coreinit/dynload.h> #include <coreinit/dynload.h>
#include <rpxloader/rpxloader.h> #include <rpxloader/rpxloader.h>
@ -5,100 +6,180 @@
static OSDynLoad_Module sModuleHandle = nullptr; static OSDynLoad_Module sModuleHandle = nullptr;
static RPXLoaderVersion (*sRLGetVersion)() = nullptr; static RPXLoaderVersion (*sRLGetVersion)() = nullptr;
static bool (*sRLLoadFromSDOnNextLaunch)() = nullptr;
static bool (*sRLDisableContentRedirection)() = nullptr;
static bool (*sRLEnableContentRedirection)() = nullptr;
static bool (*sRLUnmountCurrentRunningBundle)() = nullptr;
RPXLoaderStatus RPXLoader_Init() { static RPXLoaderStatus (*sRLPrepareLaunchFromSD)() = nullptr;
static RPXLoaderStatus (*sRLLaunchPreparedHomebrew)() = nullptr;
static RPXLoaderStatus (*sRLLaunchHomebrew)() = nullptr;
static RPXLoaderStatus (*sRLDisableContentRedirection)() = nullptr;
static RPXLoaderStatus (*sRLEnableContentRedirection)() = nullptr;
static RPXLoaderStatus (*sRLUnmountCurrentRunningBundle)() = nullptr;
const char *RPXLoader_GetStatusStr(RPXLoaderStatus status) {
switch (status) {
case RPX_LOADER_RESULT_SUCCESS:
return "RPX_LOADER_RESULT_SUCCESS";
case RPX_LOADER_RESULT_MODULE_NOT_FOUND:
return "RPX_LOADER_RESULT_MODULE_NOT_FOUND";
case RPX_LOADER_RESULT_MODULE_MISSING_EXPORT:
return "RPX_LOADER_RESULT_MODULE_MISSING_EXPORT";
case RPX_LOADER_RESULT_LIB_UNINITIALIZED:
return "RPX_LOADER_RESULT_LIB_UNINITIALIZED";
case RPX_LOADER_RESULT_UNKNOWN_ERROR:
return "RPX_LOADER_RESULT_UNKNOWN_ERROR";
case RPX_LOADER_RESULT_INVALID_ARGUMENT:
return "RPX_LOADER_RESULT_INVALID_ARGUMENT";
case RPX_LOADER_RESULT_NOT_FOUND:
return "RPX_LOADER_RESULT_NOT_FOUND";
case RPX_LOADER_RESULT_UNSUPPORTED_API_VERSION:
return "RPX_LOADER_RESULT_UNSUPPORTED_API_VERSION";
case RPX_LOADER_RESULT_UNSUPPORTED_COMMAND:
return "RPX_LOADER_RESULT_UNSUPPORTED_COMMAND";
}
return "MOCHA_RESULT_UNKNOWN_ERROR";
}
static RPXLoaderVersion rpxLoaderVersion = RPX_LOADER_MODULE_VERSION_ERROR;
RPXLoaderStatus RPXLoader_InitLibrary() {
if (OSDynLoad_Acquire("homebrew_rpx_loader", &sModuleHandle) != OS_DYNLOAD_OK) { if (OSDynLoad_Acquire("homebrew_rpx_loader", &sModuleHandle) != OS_DYNLOAD_OK) {
OSReport("RPXLoader_Init: OSDynLoad_Acquire failed.\n"); DEBUG_FUNCTION_LINE_ERR("OSDynLoad_Acquire homebrew_rpx_loader failed.");
return RPX_LOADER_RESULT_MODULE_NOT_FOUND; return RPX_LOADER_RESULT_MODULE_NOT_FOUND;
} }
if (OSDynLoad_FindExport(sModuleHandle, FALSE, "RL_GetVersion", (void **) &sRLGetVersion) != OS_DYNLOAD_OK) { if (OSDynLoad_FindExport(sModuleHandle, FALSE, "RL_GetVersion", (void **) &sRLGetVersion) != OS_DYNLOAD_OK) {
OSReport("RPXLoader_Init: RL_GetVersion failed.\n"); DEBUG_FUNCTION_LINE_ERR("FindExport RL_GetVersion failed.");
return RPX_LOADER_RESULT_MODULE_MISSING_EXPORT; return RPX_LOADER_RESULT_MODULE_MISSING_EXPORT;
} }
auto res = RPXLoader_GetVersion();
if (res != RPX_LOADER_MODULE_VERSION) {
return RPX_LOADER_RESULT_UNSUPPORTED_VERSION;
}
if (OSDynLoad_FindExport(sModuleHandle, FALSE, "RL_LoadFromSDOnNextLaunch", (void **) &sRLLoadFromSDOnNextLaunch) != OS_DYNLOAD_OK) { auto res = RPXLoader_GetVersion(&rpxLoaderVersion);
OSReport("RPXLoader_Init: RL_LoadFromSDOnNextLaunch failed.\n"); if (res != RPX_LOADER_RESULT_SUCCESS) {
return RPX_LOADER_RESULT_MODULE_MISSING_EXPORT; return RPX_LOADER_RESULT_UNSUPPORTED_API_VERSION;
}
if (OSDynLoad_FindExport(sModuleHandle, FALSE, "RL_PrepareLaunchFromSD", (void **) &sRLPrepareLaunchFromSD) != OS_DYNLOAD_OK) {
DEBUG_FUNCTION_LINE_WARN("FindExport RL_PrepareLaunchFromSD failed.");
sRLPrepareLaunchFromSD = nullptr;
}
if (OSDynLoad_FindExport(sModuleHandle, FALSE, "RL_LaunchPreparedHomebrew", (void **) &sRLLaunchPreparedHomebrew) != OS_DYNLOAD_OK) {
DEBUG_FUNCTION_LINE_WARN("FindExport RL_LaunchPreparedHomebrew failed.");
sRLLaunchPreparedHomebrew = nullptr;
}
if (OSDynLoad_FindExport(sModuleHandle, FALSE, "RL_LaunchHomebrew", (void **) &sRLLaunchHomebrew) != OS_DYNLOAD_OK) {
DEBUG_FUNCTION_LINE_WARN("FindExport RL_LaunchHomebrew failed.");
sRLLaunchHomebrew = nullptr;
} }
if (OSDynLoad_FindExport(sModuleHandle, FALSE, "RL_DisableContentRedirection", (void **) &sRLDisableContentRedirection) != OS_DYNLOAD_OK) { if (OSDynLoad_FindExport(sModuleHandle, FALSE, "RL_DisableContentRedirection", (void **) &sRLDisableContentRedirection) != OS_DYNLOAD_OK) {
OSReport("RPXLoader_Init: RL_DisableContentRedirection failed.\n"); DEBUG_FUNCTION_LINE_WARN("FindExport RL_DisableContentRedirection failed.");
return RPX_LOADER_RESULT_MODULE_MISSING_EXPORT; sRLDisableContentRedirection = nullptr;
} }
if (OSDynLoad_FindExport(sModuleHandle, FALSE, "RL_EnableContentRedirection", (void **) &sRLEnableContentRedirection) != OS_DYNLOAD_OK) { if (OSDynLoad_FindExport(sModuleHandle, FALSE, "RL_EnableContentRedirection", (void **) &sRLEnableContentRedirection) != OS_DYNLOAD_OK) {
OSReport("RPXLoader_Init: RL_EnableContentRedirection failed.\n"); DEBUG_FUNCTION_LINE_WARN("FindExport RL_EnableContentRedirection failed.");
return RPX_LOADER_RESULT_MODULE_MISSING_EXPORT; sRLEnableContentRedirection = nullptr;
} }
if (OSDynLoad_FindExport(sModuleHandle, FALSE, "RL_UnmountCurrentRunningBundle", (void **) &sRLUnmountCurrentRunningBundle) != OS_DYNLOAD_OK) { if (OSDynLoad_FindExport(sModuleHandle, FALSE, "RL_UnmountCurrentRunningBundle", (void **) &sRLUnmountCurrentRunningBundle) != OS_DYNLOAD_OK) {
OSReport("RPXLoader_Init: RL_UnmountCurrentRunningBundle failed.\n"); DEBUG_FUNCTION_LINE_WARN("FindExport RL_UnmountCurrentRunningBundle failed.");
return RPX_LOADER_RESULT_MODULE_MISSING_EXPORT; sRLUnmountCurrentRunningBundle = nullptr;
} }
return RPX_LOADER_RESULT_SUCCESS; return RPX_LOADER_RESULT_SUCCESS;
} }
RPXLoaderStatus RPXLoader_DeInitLibrary() {
RPXLoaderVersion GetVersion(); return RPX_LOADER_RESULT_SUCCESS;
RPXLoaderVersion RPXLoader_GetVersion() {
if (sRLGetVersion == nullptr) {
return RPX_LOADER_RESULT_LIB_UNINITIALIZED;
}
return reinterpret_cast<decltype(&GetVersion)>(sRLGetVersion)();
} }
bool LoadFromSDOnNextLaunch(const char *); RPXLoaderStatus GetVersion(uint32_t *version);
RPXLoaderStatus RPXLoader_LoadFromSDOnNextLaunch(const char *path) { RPXLoaderStatus RPXLoader_GetVersion(uint32_t *version) {
if (sRLLoadFromSDOnNextLaunch == nullptr) { if (sRLGetVersion == nullptr) {
if (OSDynLoad_Acquire("homebrew_rpx_loader", &sModuleHandle) != OS_DYNLOAD_OK) {
DEBUG_FUNCTION_LINE_WARN("OSDynLoad_Acquire failed.");
return RPX_LOADER_RESULT_MODULE_NOT_FOUND;
}
if (OSDynLoad_FindExport(sModuleHandle, FALSE, "RL_GetVersion", (void **) &sRLGetVersion) != OS_DYNLOAD_OK) {
DEBUG_FUNCTION_LINE_WARN("FindExport RL_GetVersion failed.");
return RPX_LOADER_RESULT_MODULE_MISSING_EXPORT;
}
}
if (version == nullptr) {
return RPX_LOADER_RESULT_INVALID_ARGUMENT;
}
return reinterpret_cast<decltype(&GetVersion)>(sRLGetVersion)(version);
}
RPXLoaderStatus PrepareLaunchFromSD(const char *bundle_path);
RPXLoaderStatus RPXLoader_PrepareLaunchFromSD(const char *path) {
if (rpxLoaderVersion == RPX_LOADER_MODULE_VERSION_ERROR) {
return RPX_LOADER_RESULT_LIB_UNINITIALIZED; return RPX_LOADER_RESULT_LIB_UNINITIALIZED;
} }
if (sRLPrepareLaunchFromSD == nullptr || rpxLoaderVersion < 1) {
return RPX_LOADER_RESULT_UNSUPPORTED_COMMAND;
}
if (path == nullptr) { if (path == nullptr) {
return RPX_LOADER_RESULT_INVALID_ARG; return RPX_LOADER_RESULT_INVALID_ARGUMENT;
} }
auto res = reinterpret_cast<decltype(&LoadFromSDOnNextLaunch)>(sRLLoadFromSDOnNextLaunch)(path); return reinterpret_cast<decltype(&PrepareLaunchFromSD)>(sRLPrepareLaunchFromSD)(path);
return res ? RPX_LOADER_RESULT_SUCCESS : RPX_LOADER_RESULT_UNKNOWN_ERROR;
} }
bool DisableContentRedirection(); RPXLoaderStatus LaunchPreparedHomebrew();
RPXLoaderStatus RPXLoader_DisableContentRedirection() { RPXLoaderStatus RPXLoader_LaunchPreparedHomebrew() {
if (sRLDisableContentRedirection == nullptr) { if (rpxLoaderVersion == RPX_LOADER_MODULE_VERSION_ERROR) {
return RPX_LOADER_RESULT_LIB_UNINITIALIZED; return RPX_LOADER_RESULT_LIB_UNINITIALIZED;
} }
auto res = reinterpret_cast<decltype(&DisableContentRedirection)>(sRLDisableContentRedirection)(); if (sRLLaunchPreparedHomebrew == nullptr || rpxLoaderVersion < 1) {
return RPX_LOADER_RESULT_UNSUPPORTED_COMMAND;
return res ? RPX_LOADER_RESULT_SUCCESS : RPX_LOADER_RESULT_UNKNOWN_ERROR; }
return reinterpret_cast<decltype(&LaunchPreparedHomebrew)>(sRLLaunchPreparedHomebrew)();
} }
bool EnableContentRedirection(); RPXLoaderStatus LaunchHomebrew();
RPXLoaderStatus RPXLoader_LaunchHomebrew(const char *bundle_path) {
if (rpxLoaderVersion == RPX_LOADER_MODULE_VERSION_ERROR) {
return RPX_LOADER_RESULT_LIB_UNINITIALIZED;
}
if (sRLLaunchHomebrew == nullptr || rpxLoaderVersion < 1) {
return RPX_LOADER_RESULT_UNSUPPORTED_COMMAND;
}
return reinterpret_cast<decltype(&LaunchHomebrew)>(sRLLaunchHomebrew)();
}
RPXLoaderStatus EnableContentRedirection();
RPXLoaderStatus RPXLoader_EnableContentRedirection() { RPXLoaderStatus RPXLoader_EnableContentRedirection() {
if (sRLEnableContentRedirection == nullptr) { if (rpxLoaderVersion == RPX_LOADER_MODULE_VERSION_ERROR) {
return RPX_LOADER_RESULT_LIB_UNINITIALIZED; return RPX_LOADER_RESULT_LIB_UNINITIALIZED;
} }
if (sRLEnableContentRedirection == nullptr || rpxLoaderVersion < 1) {
return RPX_LOADER_RESULT_UNSUPPORTED_COMMAND;
}
auto res = reinterpret_cast<decltype(&EnableContentRedirection)>(sRLEnableContentRedirection)(); return reinterpret_cast<decltype(&EnableContentRedirection)>(sRLEnableContentRedirection)();
return res ? RPX_LOADER_RESULT_SUCCESS : RPX_LOADER_RESULT_UNKNOWN_ERROR;
} }
bool UnmountCurrentRunningBundle();
RPXLoaderStatus DisableContentRedirection();
RPXLoaderStatus RPXLoader_DisableContentRedirection() {
if (rpxLoaderVersion == RPX_LOADER_MODULE_VERSION_ERROR) {
return RPX_LOADER_RESULT_LIB_UNINITIALIZED;
}
if (sRLDisableContentRedirection == nullptr || rpxLoaderVersion < 1) {
return RPX_LOADER_RESULT_UNSUPPORTED_COMMAND;
}
return reinterpret_cast<decltype(&DisableContentRedirection)>(sRLDisableContentRedirection)();
}
RPXLoaderStatus UnmountCurrentRunningBundle();
RPXLoaderStatus RPXLoader_UnmountCurrentRunningBundle() { RPXLoaderStatus RPXLoader_UnmountCurrentRunningBundle() {
if (sRLUnmountCurrentRunningBundle == nullptr) { if (rpxLoaderVersion == RPX_LOADER_MODULE_VERSION_ERROR) {
return RPX_LOADER_RESULT_LIB_UNINITIALIZED; return RPX_LOADER_RESULT_LIB_UNINITIALIZED;
} }
if (sRLUnmountCurrentRunningBundle == nullptr || rpxLoaderVersion < 1) {
return RPX_LOADER_RESULT_UNSUPPORTED_COMMAND;
}
auto res = reinterpret_cast<decltype(&UnmountCurrentRunningBundle)>(sRLUnmountCurrentRunningBundle)(); return reinterpret_cast<decltype(&UnmountCurrentRunningBundle)>(sRLUnmountCurrentRunningBundle)();
return res ? RPX_LOADER_RESULT_SUCCESS : RPX_LOADER_RESULT_UNKNOWN_ERROR;
} }