#include #include #include #include #include "mini-hb-menu/common.h" extern const loaderFuncs_s loader_Ninjhax2; extern const loaderFuncs_s loader_Rosalina; static void (*launch_3dsx)(const char* path, argData_s* args, executableMetadata_s* em); static int exec_3dsx_actual(const char* path, const char** args, bool appendPath) { bool inited; bool fileExists; struct stat sBuff; argData_s newProgramArgs; unsigned int argChars = 0; unsigned int argNum = 0; if (!path || path[0] == '\0') { errno = EINVAL; return -1; } fileExists = stat(path, &sBuff) == 0; if (!fileExists) { errno = ENOENT; return -1; } else if (S_ISDIR(sBuff.st_mode)) { errno = EINVAL; return -1; } /* args the string functions write to the passed string, * this will cause a write to read only memory, * so the string must be cloned */ memset(newProgramArgs.buf, '\0', sizeof(newProgramArgs.buf)); newProgramArgs.dst = (char*)&newProgramArgs.buf[1]; if (appendPath) { strcpy(newProgramArgs.dst, path); newProgramArgs.dst += strlen(path) + 1; newProgramArgs.buf[0]++; } while(args[argNum]) { strcpy(newProgramArgs.dst, args[argNum]); newProgramArgs.dst += strlen(args[argNum]) + 1; newProgramArgs.buf[0]++; argNum++; } inited = loader_Rosalina.init(); launch_3dsx = loader_Rosalina.launchFile; if (!inited) { inited = loader_Ninjhax2.init(); launch_3dsx = loader_Ninjhax2.launchFile; } if (inited) { osSetSpeedupEnable(false); launch_3dsx(path, &newProgramArgs, NULL); exit(0); } /* should never be reached */ errno = ENOTSUP; return -1; } int exec_3dsx(const char* path, const char** args) { return exec_3dsx_actual(path, args, true/*appendPath*/); } int exec_3dsx_no_path_in_args(const char* path, const char** args) { return exec_3dsx_actual(path, args, false/*appendPath*/); }