2022-08-25 11:34:43 +02:00
|
|
|
#include "logger.h"
|
2022-04-17 19:27:56 +02:00
|
|
|
#include <coreinit/debug.h>
|
|
|
|
#include <coreinit/dynload.h>
|
|
|
|
#include <rpxloader/rpxloader.h>
|
|
|
|
|
|
|
|
static OSDynLoad_Module sModuleHandle = nullptr;
|
|
|
|
|
2022-08-25 11:34:43 +02:00
|
|
|
static RPXLoaderVersion (*sRLGetVersion)() = nullptr;
|
|
|
|
|
|
|
|
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";
|
|
|
|
}
|
2022-04-17 19:27:56 +02:00
|
|
|
|
2022-08-25 11:34:43 +02:00
|
|
|
static RPXLoaderVersion rpxLoaderVersion = RPX_LOADER_MODULE_VERSION_ERROR;
|
|
|
|
|
|
|
|
RPXLoaderStatus RPXLoader_InitLibrary() {
|
2022-04-17 19:27:56 +02:00
|
|
|
if (OSDynLoad_Acquire("homebrew_rpx_loader", &sModuleHandle) != OS_DYNLOAD_OK) {
|
2022-08-25 11:34:43 +02:00
|
|
|
DEBUG_FUNCTION_LINE_ERR("OSDynLoad_Acquire homebrew_rpx_loader failed.");
|
2022-04-17 19:27:56 +02:00
|
|
|
return RPX_LOADER_RESULT_MODULE_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (OSDynLoad_FindExport(sModuleHandle, FALSE, "RL_GetVersion", (void **) &sRLGetVersion) != OS_DYNLOAD_OK) {
|
2022-08-25 11:34:43 +02:00
|
|
|
DEBUG_FUNCTION_LINE_ERR("FindExport RL_GetVersion failed.");
|
2022-04-17 19:27:56 +02:00
|
|
|
return RPX_LOADER_RESULT_MODULE_MISSING_EXPORT;
|
|
|
|
}
|
2022-08-25 11:34:43 +02:00
|
|
|
|
|
|
|
auto res = RPXLoader_GetVersion(&rpxLoaderVersion);
|
|
|
|
if (res != RPX_LOADER_RESULT_SUCCESS) {
|
|
|
|
return RPX_LOADER_RESULT_UNSUPPORTED_API_VERSION;
|
2022-04-17 19:27:56 +02:00
|
|
|
}
|
|
|
|
|
2022-08-25 11:34:43 +02:00
|
|
|
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;
|
2022-04-17 19:27:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (OSDynLoad_FindExport(sModuleHandle, FALSE, "RL_DisableContentRedirection", (void **) &sRLDisableContentRedirection) != OS_DYNLOAD_OK) {
|
2022-08-25 11:34:43 +02:00
|
|
|
DEBUG_FUNCTION_LINE_WARN("FindExport RL_DisableContentRedirection failed.");
|
|
|
|
sRLDisableContentRedirection = nullptr;
|
2022-04-17 19:27:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (OSDynLoad_FindExport(sModuleHandle, FALSE, "RL_EnableContentRedirection", (void **) &sRLEnableContentRedirection) != OS_DYNLOAD_OK) {
|
2022-08-25 11:34:43 +02:00
|
|
|
DEBUG_FUNCTION_LINE_WARN("FindExport RL_EnableContentRedirection failed.");
|
|
|
|
sRLEnableContentRedirection = nullptr;
|
2022-04-17 19:27:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (OSDynLoad_FindExport(sModuleHandle, FALSE, "RL_UnmountCurrentRunningBundle", (void **) &sRLUnmountCurrentRunningBundle) != OS_DYNLOAD_OK) {
|
2022-08-25 11:34:43 +02:00
|
|
|
DEBUG_FUNCTION_LINE_WARN("FindExport RL_UnmountCurrentRunningBundle failed.");
|
|
|
|
sRLUnmountCurrentRunningBundle = nullptr;
|
2022-04-17 19:27:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return RPX_LOADER_RESULT_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2022-08-25 11:34:43 +02:00
|
|
|
RPXLoaderStatus RPXLoader_DeInitLibrary() {
|
|
|
|
return RPX_LOADER_RESULT_SUCCESS;
|
|
|
|
}
|
2022-04-17 19:27:56 +02:00
|
|
|
|
2022-08-25 11:34:43 +02:00
|
|
|
RPXLoaderStatus GetVersion(uint32_t *version);
|
|
|
|
RPXLoaderStatus RPXLoader_GetVersion(uint32_t *version) {
|
2022-04-17 19:27:56 +02:00
|
|
|
if (sRLGetVersion == nullptr) {
|
2022-08-25 11:34:43 +02:00
|
|
|
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;
|
2022-04-17 19:27:56 +02:00
|
|
|
}
|
|
|
|
|
2022-08-25 11:34:43 +02:00
|
|
|
return reinterpret_cast<decltype(&GetVersion)>(sRLGetVersion)(version);
|
2022-04-17 19:27:56 +02:00
|
|
|
}
|
|
|
|
|
2022-08-25 11:34:43 +02:00
|
|
|
RPXLoaderStatus PrepareLaunchFromSD(const char *bundle_path);
|
|
|
|
RPXLoaderStatus RPXLoader_PrepareLaunchFromSD(const char *path) {
|
|
|
|
if (rpxLoaderVersion == RPX_LOADER_MODULE_VERSION_ERROR) {
|
2022-04-17 19:27:56 +02:00
|
|
|
return RPX_LOADER_RESULT_LIB_UNINITIALIZED;
|
|
|
|
}
|
2022-08-25 11:34:43 +02:00
|
|
|
if (sRLPrepareLaunchFromSD == nullptr || rpxLoaderVersion < 1) {
|
|
|
|
return RPX_LOADER_RESULT_UNSUPPORTED_COMMAND;
|
|
|
|
}
|
2022-04-17 19:27:56 +02:00
|
|
|
if (path == nullptr) {
|
2022-08-25 11:34:43 +02:00
|
|
|
return RPX_LOADER_RESULT_INVALID_ARGUMENT;
|
2022-04-17 19:27:56 +02:00
|
|
|
}
|
2022-08-25 11:34:43 +02:00
|
|
|
return reinterpret_cast<decltype(&PrepareLaunchFromSD)>(sRLPrepareLaunchFromSD)(path);
|
2022-04-17 19:27:56 +02:00
|
|
|
}
|
|
|
|
|
2022-08-25 11:34:43 +02:00
|
|
|
RPXLoaderStatus LaunchPreparedHomebrew();
|
|
|
|
RPXLoaderStatus RPXLoader_LaunchPreparedHomebrew() {
|
|
|
|
if (rpxLoaderVersion == RPX_LOADER_MODULE_VERSION_ERROR) {
|
2022-04-17 19:27:56 +02:00
|
|
|
return RPX_LOADER_RESULT_LIB_UNINITIALIZED;
|
|
|
|
}
|
2022-08-25 11:34:43 +02:00
|
|
|
if (sRLLaunchPreparedHomebrew == nullptr || rpxLoaderVersion < 1) {
|
|
|
|
return RPX_LOADER_RESULT_UNSUPPORTED_COMMAND;
|
|
|
|
}
|
|
|
|
return reinterpret_cast<decltype(&LaunchPreparedHomebrew)>(sRLLaunchPreparedHomebrew)();
|
|
|
|
}
|
2022-04-17 19:27:56 +02:00
|
|
|
|
2022-08-25 11:34:43 +02:00
|
|
|
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)();
|
2022-04-17 19:27:56 +02:00
|
|
|
}
|
|
|
|
|
2022-08-25 11:34:43 +02:00
|
|
|
RPXLoaderStatus EnableContentRedirection();
|
2022-04-17 19:27:56 +02:00
|
|
|
RPXLoaderStatus RPXLoader_EnableContentRedirection() {
|
2022-08-25 11:34:43 +02:00
|
|
|
if (rpxLoaderVersion == RPX_LOADER_MODULE_VERSION_ERROR) {
|
2022-04-17 19:27:56 +02:00
|
|
|
return RPX_LOADER_RESULT_LIB_UNINITIALIZED;
|
|
|
|
}
|
2022-08-25 11:34:43 +02:00
|
|
|
if (sRLEnableContentRedirection == nullptr || rpxLoaderVersion < 1) {
|
|
|
|
return RPX_LOADER_RESULT_UNSUPPORTED_COMMAND;
|
|
|
|
}
|
2022-04-17 19:27:56 +02:00
|
|
|
|
2022-08-25 11:34:43 +02:00
|
|
|
return reinterpret_cast<decltype(&EnableContentRedirection)>(sRLEnableContentRedirection)();
|
|
|
|
}
|
2022-04-17 19:27:56 +02:00
|
|
|
|
2022-08-25 11:34:43 +02:00
|
|
|
|
|
|
|
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)();
|
2022-04-17 19:27:56 +02:00
|
|
|
}
|
|
|
|
|
2022-08-25 11:34:43 +02:00
|
|
|
RPXLoaderStatus UnmountCurrentRunningBundle();
|
2022-04-17 19:27:56 +02:00
|
|
|
RPXLoaderStatus RPXLoader_UnmountCurrentRunningBundle() {
|
2022-08-25 11:34:43 +02:00
|
|
|
if (rpxLoaderVersion == RPX_LOADER_MODULE_VERSION_ERROR) {
|
2022-04-17 19:27:56 +02:00
|
|
|
return RPX_LOADER_RESULT_LIB_UNINITIALIZED;
|
|
|
|
}
|
2022-08-25 11:34:43 +02:00
|
|
|
if (sRLUnmountCurrentRunningBundle == nullptr || rpxLoaderVersion < 1) {
|
|
|
|
return RPX_LOADER_RESULT_UNSUPPORTED_COMMAND;
|
|
|
|
}
|
2022-04-17 19:27:56 +02:00
|
|
|
|
2022-08-25 11:34:43 +02:00
|
|
|
return reinterpret_cast<decltype(&UnmountCurrentRunningBundle)>(sRLUnmountCurrentRunningBundle)();
|
2022-04-17 19:27:56 +02:00
|
|
|
}
|