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;
|
|
|
|
|
2023-02-18 09:20:23 +01:00
|
|
|
static RPXLoaderVersion (*sRLGetVersion)(uint32_t *version) = nullptr;
|
2022-08-25 11:34:43 +02:00
|
|
|
|
2023-02-18 09:20:23 +01:00
|
|
|
static RPXLoaderStatus (*sRLPrepareLaunchFromSD)(const char *path) = nullptr;
|
|
|
|
static RPXLoaderStatus (*sRLLaunchPreparedHomebrew)() = nullptr;
|
|
|
|
static RPXLoaderStatus (*sRLLaunchHomebrew)(const char *bundle_path) = nullptr;
|
2022-08-25 11:34:43 +02:00
|
|
|
|
2023-02-18 09:20:45 +01:00
|
|
|
static RPXLoaderStatus (*sRLDisableContentRedirection)() = nullptr;
|
|
|
|
static RPXLoaderStatus (*sRLEnableContentRedirection)() = nullptr;
|
|
|
|
static RPXLoaderStatus (*sRLUnmountCurrentRunningBundle)() = nullptr;
|
|
|
|
static RPXLoaderStatus (*sRL_GetPathOfRunningExecutable)(char *outBuffer, uint32_t outSize) = nullptr;
|
2022-08-25 11:34:43 +02:00
|
|
|
|
|
|
|
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";
|
2023-02-18 09:20:45 +01:00
|
|
|
case RPX_LOADER_RESULT_NOT_AVAILABLE:
|
|
|
|
return "RPX_LOADER_RESULT_NOT_AVAILABLE";
|
2022-08-25 11:34:43 +02:00
|
|
|
}
|
2022-09-03 14:52:05 +02:00
|
|
|
return "RPX_LOADER_RESULT_UNKNOWN_ERROR";
|
2022-08-25 11:34:43 +02:00
|
|
|
}
|
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;
|
|
|
|
}
|
|
|
|
|
2023-06-21 21:57:32 +02:00
|
|
|
if (OSDynLoad_FindExport(sModuleHandle, OS_DYNLOAD_EXPORT_FUNC, "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
|
|
|
}
|
|
|
|
|
2023-06-21 21:57:32 +02:00
|
|
|
if (OSDynLoad_FindExport(sModuleHandle, OS_DYNLOAD_EXPORT_FUNC, "RL_PrepareLaunchFromSD", (void **) &sRLPrepareLaunchFromSD) != OS_DYNLOAD_OK) {
|
2022-08-25 11:34:43 +02:00
|
|
|
DEBUG_FUNCTION_LINE_WARN("FindExport RL_PrepareLaunchFromSD failed.");
|
|
|
|
sRLPrepareLaunchFromSD = nullptr;
|
|
|
|
}
|
2023-06-21 21:57:32 +02:00
|
|
|
if (OSDynLoad_FindExport(sModuleHandle, OS_DYNLOAD_EXPORT_FUNC, "RL_LaunchPreparedHomebrew", (void **) &sRLLaunchPreparedHomebrew) != OS_DYNLOAD_OK) {
|
2022-08-25 11:34:43 +02:00
|
|
|
DEBUG_FUNCTION_LINE_WARN("FindExport RL_LaunchPreparedHomebrew failed.");
|
|
|
|
sRLLaunchPreparedHomebrew = nullptr;
|
|
|
|
}
|
2023-06-21 21:57:32 +02:00
|
|
|
if (OSDynLoad_FindExport(sModuleHandle, OS_DYNLOAD_EXPORT_FUNC, "RL_LaunchHomebrew", (void **) &sRLLaunchHomebrew) != OS_DYNLOAD_OK) {
|
2022-08-25 11:34:43 +02:00
|
|
|
DEBUG_FUNCTION_LINE_WARN("FindExport RL_LaunchHomebrew failed.");
|
|
|
|
sRLLaunchHomebrew = nullptr;
|
2022-04-17 19:27:56 +02:00
|
|
|
}
|
|
|
|
|
2023-06-21 21:57:32 +02:00
|
|
|
if (OSDynLoad_FindExport(sModuleHandle, OS_DYNLOAD_EXPORT_FUNC, "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
|
|
|
}
|
|
|
|
|
2023-06-21 21:57:32 +02:00
|
|
|
if (OSDynLoad_FindExport(sModuleHandle, OS_DYNLOAD_EXPORT_FUNC, "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
|
|
|
}
|
|
|
|
|
2023-06-21 21:57:32 +02:00
|
|
|
if (OSDynLoad_FindExport(sModuleHandle, OS_DYNLOAD_EXPORT_FUNC, "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
|
|
|
}
|
|
|
|
|
2023-06-21 21:57:32 +02:00
|
|
|
if (OSDynLoad_FindExport(sModuleHandle, OS_DYNLOAD_EXPORT_FUNC, "RL_GetPathOfRunningExecutable", (void **) &sRL_GetPathOfRunningExecutable) != OS_DYNLOAD_OK) {
|
2023-02-18 09:20:45 +01:00
|
|
|
DEBUG_FUNCTION_LINE_WARN("FindExport RL_GetPathOfRunningExecutable failed.");
|
|
|
|
sRL_GetPathOfRunningExecutable = 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 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;
|
|
|
|
}
|
|
|
|
|
2023-06-21 21:57:32 +02:00
|
|
|
if (OSDynLoad_FindExport(sModuleHandle, OS_DYNLOAD_EXPORT_FUNC, "RL_GetVersion", (void **) &sRLGetVersion) != OS_DYNLOAD_OK) {
|
2022-08-25 11:34:43 +02:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2023-02-18 09:20:23 +01:00
|
|
|
return reinterpret_cast<decltype(&RPXLoader_GetVersion)>(sRLGetVersion)(version);
|
2022-04-17 19:27:56 +02:00
|
|
|
}
|
|
|
|
|
2022-08-25 11:34:43 +02:00
|
|
|
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
|
|
|
}
|
2023-02-18 09:20:23 +01:00
|
|
|
return reinterpret_cast<decltype(&RPXLoader_PrepareLaunchFromSD)>(sRLPrepareLaunchFromSD)(path);
|
2022-04-17 19:27:56 +02:00
|
|
|
}
|
|
|
|
|
2022-08-25 11:34:43 +02:00
|
|
|
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;
|
|
|
|
}
|
2023-02-18 09:20:23 +01:00
|
|
|
return reinterpret_cast<decltype(&RPXLoader_LaunchPreparedHomebrew)>(sRLLaunchPreparedHomebrew)();
|
2022-08-25 11:34:43 +02:00
|
|
|
}
|
2022-04-17 19:27:56 +02:00
|
|
|
|
2022-08-25 11:34:43 +02:00
|
|
|
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;
|
|
|
|
}
|
2023-02-18 09:19:11 +01:00
|
|
|
return reinterpret_cast<decltype(&RPXLoader_LaunchHomebrew)>(sRLLaunchHomebrew)(bundle_path);
|
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
|
|
|
|
2023-02-18 09:20:23 +01:00
|
|
|
return reinterpret_cast<decltype(&RPXLoader_EnableContentRedirection)>(sRLEnableContentRedirection)();
|
2022-08-25 11:34:43 +02:00
|
|
|
}
|
2022-04-17 19:27:56 +02:00
|
|
|
|
2022-08-25 11:34:43 +02:00
|
|
|
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;
|
|
|
|
}
|
2023-02-18 09:20:23 +01:00
|
|
|
return reinterpret_cast<decltype(&RPXLoader_DisableContentRedirection)>(sRLDisableContentRedirection)();
|
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
|
|
|
|
2023-02-18 09:20:23 +01:00
|
|
|
return reinterpret_cast<decltype(&RPXLoader_UnmountCurrentRunningBundle)>(sRLUnmountCurrentRunningBundle)();
|
2023-02-18 09:20:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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<decltype(&RPXLoader_GetPathOfRunningExecutable)>(sRL_GetPathOfRunningExecutable)(outBuffer, outSize);
|
2022-04-17 19:27:56 +02:00
|
|
|
}
|