RPXLoadingModule/src/main.cpp

171 lines
7.7 KiB
C++
Raw Normal View History

2021-01-01 01:39:28 +01:00
#include "FileUtils.h"
#include "RPXLoading.h"
2022-02-04 16:35:35 +01:00
#include "globals.h"
#include "utils/StringTools.h"
#include "utils/logger.h"
#include "version.h"
#include <content_redirection/redirection.h>
#include <coreinit/cache.h>
2022-02-04 16:35:35 +01:00
#include <coreinit/debug.h>
#include <coreinit/title.h>
2022-08-24 14:36:20 +02:00
#include <mocha/mocha.h>
#include <nn/act.h>
2022-02-04 16:35:35 +01:00
#include <romfs_dev.h>
#include <string>
#include <sysapp/title.h>
#include <wuhb_utils/utils.h>
#include <wums.h>
2021-01-01 01:39:28 +01:00
2023-01-10 18:28:50 +01:00
#define VERSION "v0.3.1"
2021-01-01 01:39:28 +01:00
WUMS_MODULE_EXPORT_NAME("homebrew_rpx_loader");
2021-09-24 17:15:04 +02:00
WUMS_USE_WUT_DEVOPTAB();
2023-01-07 16:11:12 +01:00
WUMS_DEPENDS_ON(homebrew_content_redirection);
WUMS_DEPENDS_ON(homebrew_wuhb_utils);
WUMS_DEPENDS_ON(homebrew_functionpatcher);
2021-01-24 15:45:30 +01:00
WUMS_INITIALIZE() {
initLogging();
2023-01-07 16:17:29 +01:00
if (FunctionPatcher_InitLibrary() != FUNCTION_PATCHER_RESULT_SUCCESS) {
OSFatal("homebrew_rpx_loader: FunctionPatcher_InitLibrary failed");
}
2021-01-01 01:39:28 +01:00
DEBUG_FUNCTION_LINE("Patch functions");
2022-05-08 19:31:18 +02:00
for (uint32_t i = 0; i < rpx_utils_function_replacements_size; i++) {
2023-01-07 16:17:29 +01:00
bool wasPatched = false;
if (FunctionPatcher_AddFunctionPatch(&rpx_utils_function_replacements[i], nullptr, &wasPatched) != FUNCTION_PATCHER_RESULT_SUCCESS || !wasPatched) {
2022-05-08 19:31:18 +02:00
OSFatal("homebrew_rpx_loader: Failed to patch function");
}
}
2021-01-01 01:39:28 +01:00
DEBUG_FUNCTION_LINE("Patch functions finished");
2021-02-19 20:32:44 +01:00
gReplacementInfo = {};
ContentRedirectionStatus error;
2022-09-04 14:43:42 +02:00
if ((error = ContentRedirection_InitLibrary()) != CONTENT_REDIRECTION_RESULT_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to init ContentRedirection. Error %d", error);
OSFatal("Failed to init ContentRedirection.");
2021-04-05 19:54:50 +02:00
}
WUHBUtilsStatus error2;
2022-09-04 14:43:42 +02:00
if ((error2 = WUHBUtils_InitLibrary()) != WUHB_UTILS_RESULT_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to init WUHBUtils. Error %d", error2);
OSFatal("Failed to init WUHBUtils.");
2021-01-01 01:39:28 +01:00
}
2022-08-24 14:36:20 +02:00
// Init libmocha
MochaUtilsStatus error3;
if ((error3 = Mocha_InitLibrary()) != MOCHA_RESULT_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to init libmocha. Error %s", Mocha_GetStatusStr(error3));
OSFatal("Failed to init libmocha. Make sure to use the latest version of MochaPayload");
}
deinitLogging();
}
WUMS_APPLICATION_ENDS() {
RL_UnmountCurrentRunningBundle();
gReplacementInfo.rpxReplacementInfo.isRPXReplaced = false;
RPXLoadingCleanUp();
deinitLogging();
2021-01-01 01:39:28 +01:00
}
WUMS_APPLICATION_STARTS() {
uint32_t upid = OSGetUPID();
if (upid != 2 && upid != 15) {
return;
}
OSReport("Running RPXLoadingModule " VERSION VERSION_EXTRA "\n");
initLogging();
if (gReplacementInfo.rpxReplacementInfo.willRPXBeReplaced) {
gReplacementInfo.rpxReplacementInfo.willRPXBeReplaced = false;
2022-02-04 16:35:35 +01:00
gReplacementInfo.rpxReplacementInfo.isRPXReplaced = true;
}
if (_SYSGetSystemApplicationTitleId(SYSTEM_APP_ID_HEALTH_AND_SAFETY) != OSGetTitleID()) {
gReplacementInfo.lastFileLoaded[0] = '\0';
}
if (_SYSGetSystemApplicationTitleId(SYSTEM_APP_ID_HEALTH_AND_SAFETY) == OSGetTitleID() &&
strlen(gReplacementInfo.contentReplacementInfo.bundleMountInformation.toMountPath) > 0) {
uint32_t currentHash = StringTools::hash(gReplacementInfo.contentReplacementInfo.bundleMountInformation.toMountPath);
std::string shortNameSanitized = sanitizeName(gReplacementInfo.rpxReplacementInfo.metaInformation.shortname);
2021-04-05 19:54:50 +02:00
nn::act::Initialize();
nn::act::PersistentId persistentId = nn::act::GetPersistentId();
nn::act::Finalize();
2022-08-09 16:16:18 +02:00
std::string basePath = string_format("fs:/vol/external01/wiiu/apps/save/%08X", currentHash);
if (!shortNameSanitized.empty()) {
basePath += string_format(" (%s)", shortNameSanitized.c_str());
}
std::string common = basePath + "/common";
std::string user = basePath + string_format("/%08X", 0x80000000 | persistentId);
CreateSubfolder(common.c_str());
CreateSubfolder(user.c_str());
DEBUG_FUNCTION_LINE("Created %s and %s", common.c_str(), user.c_str());
if (romfsMount(WUHB_ROMFS_NAME, gReplacementInfo.contentReplacementInfo.bundleMountInformation.toMountPath, RomfsSource_FileDescriptor_CafeOS) == 0) {
auto device = GetDeviceOpTab(WUHB_ROMFS_PATH);
if (device == nullptr || strcmp(device->name, WUHB_ROMFS_NAME) != 0) {
romfsUnmount(WUHB_ROMFS_NAME);
2021-04-05 19:54:50 +02:00
gReplacementInfo.contentReplacementInfo.bundleMountInformation.isMounted = false;
DEBUG_FUNCTION_LINE_ERR("DeviceOpTab for %s not found.", WUHB_ROMFS_PATH);
return;
}
int outRes = -1;
if (ContentRedirection_AddDevice(device, &outRes) != CONTENT_REDIRECTION_RESULT_SUCCESS || outRes < 0) {
DEBUG_FUNCTION_LINE_ERR("Failed to AddDevice to ContentRedirection");
romfsUnmount(WUHB_ROMFS_NAME);
gReplacementInfo.contentReplacementInfo.bundleMountInformation.isMounted = false;
return;
}
auto res = ContentRedirection_AddFSLayer(&contentLayerHandle,
"WUHB Content",
WUHB_ROMFS_CONTENT_PATH,
FS_LAYER_TYPE_CONTENT_REPLACE);
if (res == CONTENT_REDIRECTION_RESULT_SUCCESS) {
res = ContentRedirection_AddFSLayer(&saveLayerHandle,
"WUHB Save",
basePath.c_str(),
FS_LAYER_TYPE_SAVE_REPLACE);
if (res == CONTENT_REDIRECTION_RESULT_SUCCESS) {
gReplacementInfo.contentReplacementInfo.bundleMountInformation.mountedPath[0] = '\0';
strncpy(gReplacementInfo.contentReplacementInfo.bundleMountInformation.mountedPath,
gReplacementInfo.contentReplacementInfo.bundleMountInformation.toMountPath,
sizeof(gReplacementInfo.contentReplacementInfo.bundleMountInformation.mountedPath));
DEBUG_FUNCTION_LINE_VERBOSE("Mounted %s to /vol/content", gReplacementInfo.contentReplacementInfo.bundleMountInformation.mountedPath);
gReplacementInfo.contentReplacementInfo.bundleMountInformation.isMounted = true;
gReplacementInfo.contentReplacementInfo.bundleMountInformation.toMountPath[0] = '\0';
OSMemoryBarrier();
return;
} else {
if (contentLayerHandle != 0) {
ContentRedirection_RemoveFSLayer(contentLayerHandle);
contentLayerHandle = 0;
}
DEBUG_FUNCTION_LINE_ERR("ContentRedirection_AddFSLayer had failed for save");
}
} else {
int outRes = -1;
if (ContentRedirection_RemoveDevice(WUHB_ROMFS_PATH, &outRes) != CONTENT_REDIRECTION_RESULT_SUCCESS || res < 0) {
DEBUG_FUNCTION_LINE_ERR("Failed to remove device");
}
romfsUnmount(WUHB_ROMFS_PATH);
DEBUG_FUNCTION_LINE_ERR("ContentRedirection_AddFSLayer had failed for content");
2021-01-01 01:39:28 +01:00
}
}
DEBUG_FUNCTION_LINE_ERR("Failed to mount %s", gReplacementInfo.contentReplacementInfo.bundleMountInformation.toMountPath);
gReplacementInfo.contentReplacementInfo.bundleMountInformation.isMounted = false;
OSMemoryBarrier();
2021-01-01 01:39:28 +01:00
}
}