mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 13:42:47 +00:00
182 lines
4.8 KiB
C
182 lines
4.8 KiB
C
|
#ifndef NO_LUA
|
||
|
#include "gm9internalsys.h"
|
||
|
#include "bootfirm.h"
|
||
|
#include "fs.h"
|
||
|
#include "pxi.h"
|
||
|
#include "game.h"
|
||
|
#include "power.h"
|
||
|
#include "sha.h"
|
||
|
#include "nand.h"
|
||
|
#include "utils.h"
|
||
|
#include "ui.h"
|
||
|
#include "rtc.h"
|
||
|
#include "godmode.h"
|
||
|
|
||
|
#define UNUSED(x) ((void)(x))
|
||
|
|
||
|
static int internalsys_boot(lua_State* L) {
|
||
|
CheckLuaArgCount(L, 1, "_sys.boot");
|
||
|
const char* path = lua_tostring(L, 1);
|
||
|
|
||
|
u8* firm = (u8*) malloc(FIRM_MAX_SIZE);
|
||
|
if (!firm) {
|
||
|
return luaL_error(L, "out of memory");
|
||
|
}
|
||
|
|
||
|
size_t firm_size = FileGetData(path, firm, FIRM_MAX_SIZE, 0);
|
||
|
if (!(firm_size && IsBootableFirm(firm, firm_size))) {
|
||
|
return luaL_error(L, "not a bootable firm");
|
||
|
}
|
||
|
|
||
|
char fixpath[256] = { 0 };
|
||
|
if ((*path == '0') || (*path == '1'))
|
||
|
snprintf(fixpath, sizeof(fixpath), "%s%s", (*path == '0') ? "sdmc" : "nand", path + 1);
|
||
|
else strncpy(fixpath, path, 256);
|
||
|
fixpath[255] = '\0';
|
||
|
DeinitExtFS();
|
||
|
DeinitSDCardFS();
|
||
|
PXI_DoCMD(PXICMD_LEGACY_BOOT, NULL, 0);
|
||
|
PXI_Barrier(PXI_FIRMLAUNCH_BARRIER);
|
||
|
BootFirm((FirmHeader*)(void*)firm, fixpath);
|
||
|
while(1);
|
||
|
}
|
||
|
|
||
|
static int internalsys_reboot(lua_State* L) {
|
||
|
CheckLuaArgCount(L, 0, "_sys.reboot");
|
||
|
DeinitExtFS();
|
||
|
DeinitSDCardFS();
|
||
|
Reboot();
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int internalsys_power_off(lua_State* L) {
|
||
|
CheckLuaArgCount(L, 0, "_sys.power_off");
|
||
|
DeinitExtFS();
|
||
|
DeinitSDCardFS();
|
||
|
PowerOff();
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int internalsys_get_id0(lua_State* L) {
|
||
|
CheckLuaArgCount(L, 1, "_sys.get_id0");
|
||
|
const char* path = lua_tostring(L, 1);
|
||
|
|
||
|
char env_id0[32+1];
|
||
|
u8 sd_keyy[0x10] __attribute__((aligned(4)));
|
||
|
if (FileGetData(path, sd_keyy, 0x10, 0x110) == 0x10) {
|
||
|
u32 sha256sum[8];
|
||
|
sha_quick(sha256sum, sd_keyy, 0x10, SHA256_MODE);
|
||
|
snprintf(env_id0, sizeof(env_id0), "%08lx%08lx%08lx%08lx",
|
||
|
sha256sum[0], sha256sum[1], sha256sum[2], sha256sum[3]);
|
||
|
lua_pushstring(L, env_id0);
|
||
|
} else {
|
||
|
lua_pushnil(L);
|
||
|
}
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static int internalsys_next_emu(lua_State* L) {
|
||
|
CheckLuaArgCount(L, 0, "_sys.next_emu");
|
||
|
|
||
|
DismountDriveType(DRV_EMUNAND);
|
||
|
AutoEmuNandBase(false);
|
||
|
InitExtFS();
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int internalsys_get_emu_base(lua_State* L) {
|
||
|
CheckLuaArgCount(L, 0, "_sys.get_emu_base");
|
||
|
|
||
|
lua_pushinteger(L, GetEmuNandBase());
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static int internalsys_check_embedded_backup(lua_State* L) {
|
||
|
CheckLuaArgCount(L, 0, "_sys.check_embedded_backup");
|
||
|
|
||
|
if (PathExist("S:/essential.exefs")) {
|
||
|
lua_pushboolean(L, true);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
bool ncsd_check = CheckGenuineNandNcsd();
|
||
|
if (!ncsd_check) {
|
||
|
lua_pushnil(L);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
bool ret = false;
|
||
|
|
||
|
if (ncsd_check && ShowPrompt(true, "%s", STR_ESSENTIAL_BACKUP_NOT_FOUND_CREATE_NOW)) {
|
||
|
if (EmbedEssentialBackup("S:/nand.bin") == 0) {
|
||
|
u32 flags = BUILD_PATH | SKIP_ALL;
|
||
|
PathCopy(OUTPUT_PATH, "S:/essential.exefs", &flags);
|
||
|
ShowPrompt(false, STR_BACKUP_EMBEDDED_WRITTEN_TO_OUT, OUTPUT_PATH);
|
||
|
ret = true;
|
||
|
} else {
|
||
|
ret = false;
|
||
|
}
|
||
|
} else {
|
||
|
ret = false;
|
||
|
}
|
||
|
|
||
|
lua_pushboolean(L, ret);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static int internalsys_check_raw_rtc(lua_State* L) {
|
||
|
CheckLuaArgCount(L, 0, "_sys.check_raw_rtc");
|
||
|
|
||
|
bool result = false;
|
||
|
|
||
|
DsTime dstime;
|
||
|
get_dstime(&dstime);
|
||
|
if (DSTIMEGET(&dstime, bcd_Y) >= 18) {
|
||
|
result = true;
|
||
|
} else if (ShowPrompt(true, "%s", STR_RTC_DATE_TIME_SEEMS_TO_BE_WRONG_SET_NOW) &&
|
||
|
ShowRtcSetterPrompt(&dstime, "%s", STR_TITLE_SET_RTC_DATE_TIME)) {
|
||
|
//char timestr[UTF_BUFFER_BYTESIZE(32)];
|
||
|
set_dstime(&dstime);
|
||
|
// this is only in godmode.h
|
||
|
//GetTimeString(timestr, true, true);
|
||
|
// ShowPrompt(false, STR_NEW_RTC_DATE_TIME_IS_TIME, timestr);
|
||
|
result = true;
|
||
|
}
|
||
|
|
||
|
lua_pushboolean(L, result);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static int internalsys_global_bkpt(lua_State* L) {
|
||
|
UNUSED(L);
|
||
|
bkpt;
|
||
|
while(1);
|
||
|
}
|
||
|
|
||
|
static const luaL_Reg internalsys_lib[] = {
|
||
|
{"boot", internalsys_boot},
|
||
|
{"reboot", internalsys_reboot},
|
||
|
{"power_off", internalsys_power_off},
|
||
|
{"get_id0", internalsys_get_id0},
|
||
|
{"next_emu", internalsys_next_emu},
|
||
|
{"get_emu_base", internalsys_get_emu_base},
|
||
|
{"check_embedded_backup", internalsys_check_embedded_backup},
|
||
|
{"check_raw_rtc", internalsys_check_raw_rtc},
|
||
|
{NULL, NULL}
|
||
|
};
|
||
|
|
||
|
static const luaL_Reg internalsys_global_lib[] = {
|
||
|
{"bkpt", internalsys_global_bkpt},
|
||
|
{NULL, NULL}
|
||
|
};
|
||
|
|
||
|
int gm9lua_open_internalsys(lua_State* L) {
|
||
|
luaL_newlib(L, internalsys_lib);
|
||
|
lua_pushglobaltable(L); // push global table to stack
|
||
|
luaL_setfuncs(L, internalsys_global_lib, 0); // set global funcs
|
||
|
lua_pop(L, 1); // pop global table from stack
|
||
|
return 1;
|
||
|
}
|
||
|
#endif
|