mirror of
https://github.com/wiiu-env/MochaPayload.git
synced 2024-11-14 12:15:12 +01:00
mcp_load: try to load real H&S .rpx from backup
This commit is contained in:
parent
2702e3cb77
commit
bab43f18af
@ -29,8 +29,14 @@
|
|||||||
#include <sys/unistd.h>
|
#include <sys/unistd.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MOCHA_LOAD_TARGET_DEVICE_NONE = 0,
|
||||||
|
MOCHA_LOAD_TARGET_DEVICE_SD = 1,
|
||||||
|
MOCHA_LOAD_TARGET_DEVICE_MLC = 2,
|
||||||
|
} LoadTargetDevice;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
MCP_LoadCustomFile(int target, char *path, uint32_t filesize, uint32_t fileoffset, void *buffer_out,
|
MCP_LoadCustomFile(LoadTargetDevice target, char *path, uint32_t filesize, uint32_t fileoffset, void *buffer_out,
|
||||||
uint32_t buffer_len,
|
uint32_t buffer_len,
|
||||||
uint32_t pos, bool isRPX);
|
uint32_t pos, bool isRPX);
|
||||||
|
|
||||||
@ -68,8 +74,10 @@ typedef enum {
|
|||||||
PATH_RELATIVE_INVALID = 0,
|
PATH_RELATIVE_INVALID = 0,
|
||||||
PATH_RELATIVE_TO_ENVIRONMENT = 1,
|
PATH_RELATIVE_TO_ENVIRONMENT = 1,
|
||||||
PATH_RELATIVE_TO_SD_ROOT = 2,
|
PATH_RELATIVE_TO_SD_ROOT = 2,
|
||||||
|
PATH_RELATIVE_TO_MLC_ROOT = 3,
|
||||||
} PathRelativeTo;
|
} PathRelativeTo;
|
||||||
|
|
||||||
|
|
||||||
typedef struct RPXFileReplacements {
|
typedef struct RPXFileReplacements {
|
||||||
ReplacementType type;
|
ReplacementType type;
|
||||||
ReplacementLifetime lifetime;
|
ReplacementLifetime lifetime;
|
||||||
@ -84,17 +92,24 @@ typedef struct RPXFileReplacements {
|
|||||||
static bool gMemHookCompleted = false;
|
static bool gMemHookCompleted = false;
|
||||||
static bool sReplacedLastRPX = false;
|
static bool sReplacedLastRPX = false;
|
||||||
|
|
||||||
|
|
||||||
|
// Dynamic replacements have priority over default replacements
|
||||||
|
static RPXFileReplacements *gDynamicReplacements[5] = {};
|
||||||
|
|
||||||
static const RPXFileReplacements gDefaultReplacements[] = {
|
static const RPXFileReplacements gDefaultReplacements[] = {
|
||||||
// Redirect men.rpx [ENVIRONMENT]/root.rpx until IPC_CUSTOM_MEN_RPX_HOOK_COMPLETED has been called. (e.g. to init PPC homebrew after iosu-reload)
|
// Redirect men.rpx [ENVIRONMENT]/root.rpx until IPC_CUSTOM_MEN_RPX_HOOK_COMPLETED has been called. (e.g. to init PPC homebrew after iosu-reload)
|
||||||
{REPLACEMENT_TYPE_UNTIL_MEM_HOOK_COMPLETED_BUT_BY_PATH, REPLACEMENT_LIFETIME_UNLIMITED, "men.rpx", "root.rpx", PATH_RELATIVE_TO_ENVIRONMENT, 0, 0, 0},
|
{REPLACEMENT_TYPE_UNTIL_MEM_HOOK_COMPLETED_BUT_BY_PATH, REPLACEMENT_LIFETIME_UNLIMITED, "men.rpx", "root.rpx", PATH_RELATIVE_TO_ENVIRONMENT, 0, 0, 0},
|
||||||
// Redirect men.rpx to [ENVIRONMENT]/men.rpx
|
// Redirect men.rpx to [ENVIRONMENT]/men.rpx
|
||||||
{REPLACEMENT_TYPE_BY_PATH, REPLACEMENT_LIFETIME_UNLIMITED, "men.rpx", "men.rpx", PATH_RELATIVE_TO_ENVIRONMENT, 0, 0, 0},
|
{REPLACEMENT_TYPE_BY_PATH, REPLACEMENT_LIFETIME_UNLIMITED, "men.rpx", "men.rpx", PATH_RELATIVE_TO_ENVIRONMENT, 0, 0, 0},
|
||||||
|
// Try to load the real H&S safe.rpx from backup
|
||||||
|
{REPLACEMENT_TYPE_BY_PATH, REPLACEMENT_LIFETIME_UNLIMITED, "safe.rpx", "sys/title/00050010/1004e000/content/safe.rpx.bak", PATH_RELATIVE_TO_MLC_ROOT, 0, 0, 0},
|
||||||
|
{REPLACEMENT_TYPE_BY_PATH, REPLACEMENT_LIFETIME_UNLIMITED, "safe.rpx", "sys/title/00050010/1004e100/content/safe.rpx.bak", PATH_RELATIVE_TO_MLC_ROOT, 0, 0, 0},
|
||||||
|
{REPLACEMENT_TYPE_BY_PATH, REPLACEMENT_LIFETIME_UNLIMITED, "safe.rpx", "sys/title/00050010/1004e200/content/safe.rpx.bak", PATH_RELATIVE_TO_MLC_ROOT, 0, 0, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
static RPXFileReplacements *gDynamicReplacements[5] = {};
|
|
||||||
|
|
||||||
// should be at least the size of gDefaultReplacements and gDynamicReplacements
|
// should be at least the size of gDefaultReplacements and gDynamicReplacements
|
||||||
#define TEMP_ARRAY_SIZE 7
|
#define TEMP_ARRAY_SIZE 10
|
||||||
|
|
||||||
bool addDynamicReplacement(RPXFileReplacements *pReplacements) {
|
bool addDynamicReplacement(RPXFileReplacements *pReplacements) {
|
||||||
for (uint32_t i = 0; i < sizeof(gDynamicReplacements) / sizeof(gDynamicReplacements[0]); i++) {
|
for (uint32_t i = 0; i < sizeof(gDynamicReplacements) / sizeof(gDynamicReplacements[0]); i++) {
|
||||||
@ -138,7 +153,7 @@ static inline int EndsWith(const char *str, const char *suffix) {
|
|||||||
|
|
||||||
// Set filesize to 0 if unknown.
|
// Set filesize to 0 if unknown.
|
||||||
static int
|
static int
|
||||||
MCP_LoadCustomFile(int target, char *path, uint32_t filesize, uint32_t fileoffset, void *buffer_out,
|
MCP_LoadCustomFile(LoadTargetDevice target, char *path, uint32_t filesize, uint32_t fileoffset, void *buffer_out,
|
||||||
uint32_t buffer_len,
|
uint32_t buffer_len,
|
||||||
uint32_t pos, bool isRPX) {
|
uint32_t pos, bool isRPX) {
|
||||||
if (path == NULL || (filesize > 0 && (pos > filesize))) {
|
if (path == NULL || (filesize > 0 && (pos > filesize))) {
|
||||||
@ -151,7 +166,7 @@ MCP_LoadCustomFile(int target, char *path, uint32_t filesize, uint32_t fileoffse
|
|||||||
|
|
||||||
char mountpath[] = "/vol/storage_iosu_homebrew";
|
char mountpath[] = "/vol/storage_iosu_homebrew";
|
||||||
|
|
||||||
if (target == LOAD_RPX_TARGET_SD_CARD) {
|
if (target == MOCHA_LOAD_TARGET_DEVICE_SD) {
|
||||||
int fsa_h = svcOpen("/dev/fsa", 0);
|
int fsa_h = svcOpen("/dev/fsa", 0);
|
||||||
FSA_Mount(fsa_h, "/dev/sdcard01", mountpath, 2, NULL, 0);
|
FSA_Mount(fsa_h, "/dev/sdcard01", mountpath, 2, NULL, 0);
|
||||||
svcClose(fsa_h);
|
svcClose(fsa_h);
|
||||||
@ -181,7 +196,7 @@ MCP_LoadCustomFile(int target, char *path, uint32_t filesize, uint32_t fileoffse
|
|||||||
|
|
||||||
// Unmount the sd card once the whole file has been read or there was an error
|
// Unmount the sd card once the whole file has been read or there was an error
|
||||||
if ((result >= 0 && result < 0x400000) || result < 0) {
|
if ((result >= 0 && result < 0x400000) || result < 0) {
|
||||||
if (target == LOAD_RPX_TARGET_SD_CARD) {
|
if (target == MOCHA_LOAD_TARGET_DEVICE_SD) {
|
||||||
int fsa_h = svcOpen("/dev/fsa", 0);
|
int fsa_h = svcOpen("/dev/fsa", 0);
|
||||||
FSA_Unmount(fsa_h, mountpath, 0x80000002);
|
FSA_Unmount(fsa_h, mountpath, 0x80000002);
|
||||||
svcClose(fsa_h);
|
svcClose(fsa_h);
|
||||||
@ -209,7 +224,7 @@ int DoSDRedirectionByPath(ipcmessage *msg, MCPLoadFileRequest *request) {
|
|||||||
curPtr++;
|
curPtr++;
|
||||||
}
|
}
|
||||||
// DEBUG_FUNCTION_LINE("Trying to load %s from sd\n", &request->name[2]);
|
// DEBUG_FUNCTION_LINE("Trying to load %s from sd\n", &request->name[2]);
|
||||||
int result = MCP_LoadCustomFile(LOAD_RPX_TARGET_SD_CARD, &request->name[2], 0, 0, msg->ioctl.buffer_io,
|
int result = MCP_LoadCustomFile(MOCHA_LOAD_TARGET_DEVICE_SD, &request->name[2], 0, 0, msg->ioctl.buffer_io,
|
||||||
msg->ioctl.length_io, request->pos, EndsWith(request->name, ".rpx"));
|
msg->ioctl.length_io, request->pos, EndsWith(request->name, ".rpx"));
|
||||||
|
|
||||||
if (result >= 0) {
|
if (result >= 0) {
|
||||||
@ -230,8 +245,11 @@ bool isCurrentHomebrewWrapperReplacement(MCPLoadFileRequest *request) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const RPXFileReplacements *GetCurrentRPXReplacementEx(MCPLoadFileRequest *request, const RPXFileReplacements **list, uint32_t list_size) {
|
const RPXFileReplacements *GetCurrentRPXReplacementEx(MCPLoadFileRequest *request, const RPXFileReplacements **list, uint32_t list_size, int *offset) {
|
||||||
for (uint32_t i = 0; i < list_size; i++) {
|
if (!offset || *offset >= list_size) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (uint32_t i = *offset; i < list_size; i++) {
|
||||||
const RPXFileReplacements *cur = list[i];
|
const RPXFileReplacements *cur = list[i];
|
||||||
if (cur == NULL || cur->lifetime == REPLACEMENT_LIFETIME_INVALID) {
|
if (cur == NULL || cur->lifetime == REPLACEMENT_LIFETIME_INVALID) {
|
||||||
continue;
|
continue;
|
||||||
@ -283,6 +301,7 @@ const RPXFileReplacements *GetCurrentRPXReplacementEx(MCPLoadFileRequest *reques
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
*offset = i + 1;
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -291,16 +310,6 @@ const RPXFileReplacements *GetCurrentRPXReplacementEx(MCPLoadFileRequest *reques
|
|||||||
|
|
||||||
static uint32_t getReplacementDataInSingleArray(const RPXFileReplacements **tmpArray, uint32_t tmpArraySize) {
|
static uint32_t getReplacementDataInSingleArray(const RPXFileReplacements **tmpArray, uint32_t tmpArraySize) {
|
||||||
uint32_t offsetInResult = 0;
|
uint32_t offsetInResult = 0;
|
||||||
for (uint32_t i = 0; i < sizeof(gDefaultReplacements) / sizeof(gDefaultReplacements[0]); i++) {
|
|
||||||
if (offsetInResult >= tmpArraySize) {
|
|
||||||
DEBUG_FUNCTION_LINE("ELEMENTS DO NOT FIT INTO ARRAY");
|
|
||||||
return offsetInResult;
|
|
||||||
}
|
|
||||||
if (gDefaultReplacements[i].lifetime != REPLACEMENT_LIFETIME_INVALID) {
|
|
||||||
tmpArray[offsetInResult] = &gDefaultReplacements[i];
|
|
||||||
offsetInResult++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < sizeof(gDynamicReplacements) / sizeof(gDynamicReplacements[0]); i++) {
|
for (uint32_t i = 0; i < sizeof(gDynamicReplacements) / sizeof(gDynamicReplacements[0]); i++) {
|
||||||
if (offsetInResult >= tmpArraySize) {
|
if (offsetInResult >= tmpArraySize) {
|
||||||
@ -312,30 +321,45 @@ static uint32_t getReplacementDataInSingleArray(const RPXFileReplacements **tmpA
|
|||||||
offsetInResult++;
|
offsetInResult++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < sizeof(gDefaultReplacements) / sizeof(gDefaultReplacements[0]); i++) {
|
||||||
|
if (offsetInResult >= tmpArraySize) {
|
||||||
|
DEBUG_FUNCTION_LINE("ELEMENTS DO NOT FIT INTO ARRAY");
|
||||||
|
return offsetInResult;
|
||||||
|
}
|
||||||
|
if (gDefaultReplacements[i].lifetime != REPLACEMENT_LIFETIME_INVALID) {
|
||||||
|
tmpArray[offsetInResult] = &gDefaultReplacements[i];
|
||||||
|
offsetInResult++;
|
||||||
|
}
|
||||||
|
}
|
||||||
return offsetInResult;
|
return offsetInResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
const RPXFileReplacements *GetCurrentRPXReplacement(MCPLoadFileRequest *request) {
|
const RPXFileReplacements *GetCurrentRPXReplacement(MCPLoadFileRequest *request, int *offset) {
|
||||||
const RPXFileReplacements *tmpArray[TEMP_ARRAY_SIZE] = {};
|
const RPXFileReplacements *tmpArray[TEMP_ARRAY_SIZE] = {};
|
||||||
uint32_t elementsInArray = getReplacementDataInSingleArray(tmpArray, TEMP_ARRAY_SIZE);
|
uint32_t elementsInArray = getReplacementDataInSingleArray(tmpArray, TEMP_ARRAY_SIZE);
|
||||||
if (elementsInArray == 0) {
|
if (elementsInArray == 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetCurrentRPXReplacementEx(request, tmpArray, elementsInArray);
|
return GetCurrentRPXReplacementEx(request, tmpArray, elementsInArray, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
int DoReplacementByStruct(ipcmessage *msg, MCPLoadFileRequest *request, const RPXFileReplacements *curReplacement) {
|
int DoReplacementByStruct(ipcmessage *msg, MCPLoadFileRequest *request, const RPXFileReplacements *curReplacement) {
|
||||||
char _rpxpath[256] = {};
|
char _rpxpath[256] = {};
|
||||||
|
|
||||||
int target = -1;
|
LoadTargetDevice target = MOCHA_LOAD_TARGET_DEVICE_NONE;
|
||||||
if (curReplacement->relativeTo == PATH_RELATIVE_TO_ENVIRONMENT) {
|
if (curReplacement->relativeTo == PATH_RELATIVE_TO_ENVIRONMENT) {
|
||||||
char *environmentPath = &((char *) 0x0511FF00)[19];
|
char *environmentPath = &((char *) 0x0511FF00)[19];
|
||||||
snprintf(_rpxpath, sizeof(_rpxpath) - 1, "%s/%s", environmentPath, curReplacement->replacementPath); // Copy in environment path
|
snprintf(_rpxpath, sizeof(_rpxpath) - 1, "%s/%s", environmentPath, curReplacement->replacementPath); // Copy in environment path
|
||||||
target = LOAD_RPX_TARGET_SD_CARD;
|
target = MOCHA_LOAD_TARGET_DEVICE_SD;
|
||||||
} else if (curReplacement->relativeTo == PATH_RELATIVE_TO_SD_ROOT) {
|
} else if (curReplacement->relativeTo == PATH_RELATIVE_TO_SD_ROOT) {
|
||||||
strncpy(_rpxpath, curReplacement->replacementPath, sizeof(_rpxpath) - 1);
|
strncpy(_rpxpath, curReplacement->replacementPath, sizeof(_rpxpath) - 1);
|
||||||
target = LOAD_RPX_TARGET_SD_CARD;
|
target = MOCHA_LOAD_TARGET_DEVICE_SD;
|
||||||
|
} else if (curReplacement->relativeTo == PATH_RELATIVE_TO_MLC_ROOT) {
|
||||||
|
strncpy(_rpxpath, curReplacement->replacementPath, sizeof(_rpxpath) - 1);
|
||||||
|
snprintf(_rpxpath, sizeof(_rpxpath) - 1, "/vol/storage_mlc01/%s", curReplacement->replacementPath); // Copy in environment path
|
||||||
|
target = MOCHA_LOAD_TARGET_DEVICE_MLC;
|
||||||
} else {
|
} else {
|
||||||
DEBUG_FUNCTION_LINE("Unknown relativeTo: %d\n", curReplacement->relativeTo);
|
DEBUG_FUNCTION_LINE("Unknown relativeTo: %d\n", curReplacement->relativeTo);
|
||||||
return -1;
|
return -1;
|
||||||
@ -359,17 +383,25 @@ int MCPLoadFileReplacement(ipcmessage *msg, MCPLoadFileRequest *request) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
const RPXFileReplacements *curReplacement = GetCurrentRPXReplacement(request);
|
// Try any fitting rpx replacement
|
||||||
if (curReplacement == NULL) {
|
int offset = 0;
|
||||||
// DEBUG_FUNCTION_LINE("Couldn't find replacement for %s!\n", request->name);
|
const RPXFileReplacements *curReplacement = NULL;
|
||||||
return -1;
|
do {
|
||||||
}
|
// the offset is used as input AND output.
|
||||||
|
// The start index for looking for a replacement will be read from "offset"
|
||||||
|
// if the function returns != NULL, offset will be set to the next possible index/offset
|
||||||
|
curReplacement = GetCurrentRPXReplacement(request, &offset);
|
||||||
|
if (curReplacement == NULL) {
|
||||||
|
// DEBUG_FUNCTION_LINE("Couldn't find replacement for %s!\n", request->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if ((res = DoReplacementByStruct(msg, request, curReplacement)) >= 0) {
|
if ((res = DoReplacementByStruct(msg, request, curReplacement)) >= 0) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
} while (curReplacement);
|
||||||
|
|
||||||
return res;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IncreaseApplicationStartCounter() {
|
void IncreaseApplicationStartCounter() {
|
||||||
|
Loading…
Reference in New Issue
Block a user