Add code to backup essential files

This commit is contained in:
TuxSH 2022-03-26 23:09:55 +00:00
parent bc6e14ada7
commit fcdb6a7ab5
4 changed files with 125 additions and 0 deletions

View File

@ -37,6 +37,8 @@
#include "firm.h" #include "firm.h"
#include "crypto.h" #include "crypto.h"
#include "strings.h" #include "strings.h"
#include "alignedseqmemcpy.h"
#include "i2c.h"
static FATFS sdFs, static FATFS sdFs,
nandFs; nandFs;
@ -121,6 +123,79 @@ bool fileDelete(const char *path)
return f_unlink(path) == FR_OK; return f_unlink(path) == FR_OK;
} }
bool fileCopy(const char *pathSrc, const char *pathDst, bool replace, void *tmpBuffer, size_t bufferSize)
{
FIL fileSrc, fileDst;
FRESULT res;
res = f_open(&fileSrc, pathSrc, FA_READ);
if (res != FR_OK)
return true; // Succeed if the source file doesn't exist
size_t szSrc = f_size(&fileSrc), rem = szSrc;
res = f_open(&fileDst, pathDst, FA_WRITE | (replace ? FA_CREATE_ALWAYS : FA_CREATE_NEW));
if (res == FR_EXIST)
{
// We did not fail
f_close(&fileSrc);
return true;
}
else if (res == FR_NO_PATH)
{
const char *c;
for (c = pathDst + strlen(pathDst); *c != '/' && c >= pathDst; --c);
if (c >= pathDst && c - pathDst <= FF_MAX_LFN && *c != '\0')
{
char path[FF_MAX_LFN + 1];
strncpy(path, pathDst, c - pathDst);
path[FF_MAX_LFN] = '\0';
res = f_mkdir(path);
}
if (res == FR_OK)
res = f_open(&fileDst, pathDst, FA_WRITE | (replace ? FA_CREATE_ALWAYS : FA_CREATE_NEW));
}
if (res != FR_OK)
{
f_close(&fileSrc);
return false;
}
while (rem > 0)
{
size_t sz = rem >= bufferSize ? bufferSize : rem;
UINT n = 0;
res = f_read(&fileSrc, tmpBuffer, sz, &n);
if (n != sz)
res = FR_INT_ERR; // should not happen
if (res == FR_OK)
{
res = f_write(&fileDst, tmpBuffer, sz, &n);
if (n != sz)
res = FR_DENIED; // disk full
}
if (res != FR_OK)
{
f_close(&fileSrc);
f_close(&fileDst);
f_unlink(pathDst); // oops, failed
return false;
}
rem -= sz;
}
f_close(&fileSrc);
f_close(&fileDst);
return true;
}
bool findPayload(char *path, u32 pressed) bool findPayload(char *path, u32 pressed)
{ {
const char *pattern; const char *pattern;
@ -309,3 +384,39 @@ void findDumpFile(const char *folderPath, char *fileName)
if(result == FR_OK) f_closedir(&dir); if(result == FR_OK) f_closedir(&dir);
} }
static u8 fileCopyBuffer[0x1000];
bool backupEssentialFiles(void)
{
size_t sz = sizeof(fileCopyBuffer);
bool ok = !(isSdMode && !mountFs(false, false));
ok = ok && fileCopy("1:/ro/sys/HWCAL0.dat", "backups/HWCAL0.dat", false, fileCopyBuffer, sz);
ok = ok && fileCopy("1:/ro/sys/HWCAL1.dat", "backups/HWCAL1.dat", false, fileCopyBuffer, sz);
ok = ok && fileCopy("1:/rw/sys/LocalFriendCodeSeed_A", "backups/LocalFriendCodeSeed_A", false, fileCopyBuffer, sz); // often doesn't exist
ok = ok && fileCopy("1:/rw/sys/LocalFriendCodeSeed_B", "backups/LocalFriendCodeSeed_B", false, fileCopyBuffer, sz);
ok = ok && fileCopy("1:/rw/sys/SecureInfo_A", "backups/SecureInfo_A", false, fileCopyBuffer, sz);
ok = ok && fileCopy("1:/rw/sys/SecureInfo_B", "backups/SecureInfo_B", false, fileCopyBuffer, sz); // often doesn't exist
if (!ok) return false;
alignedseqmemcpy(fileCopyBuffer, (const void *)0x10012000, 0x100);
if (getFileSize("backups/otp.bin") != 0x100)
ok = ok && fileWrite(fileCopyBuffer, "backups/otp.bin", 0x100);
if (!ok) return false;
// On dev boards, but not O3DS IS_DEBUGGER, hwcal is on an EEPROM chip accessed via I2C
u8 c = mcuConsoleInfo[0];
if (c == 2 || c == 4 || (ISN3DS && c == 5) || c == 6)
{
I2C_readRegBuf(I2C_DEV_EEPROM, 0, fileCopyBuffer, 0x1000); // Up to two instances of hwcal, with the second one @0x800
if (getFileSize("backups/HWCAL_01_EEPROM.dat") != 0x1000)
ok = ok && fileWrite(fileCopyBuffer, "backups/HWCAL_01_EEPROM.dat", 0x1000);
}
return ok;
}

View File

@ -35,7 +35,10 @@ u32 fileRead(void *dest, const char *path, u32 maxSize);
u32 getFileSize(const char *path); u32 getFileSize(const char *path);
bool fileWrite(const void *buffer, const char *path, u32 size); bool fileWrite(const void *buffer, const char *path, u32 size);
bool fileDelete(const char *path); bool fileDelete(const char *path);
bool fileCopy(const char *pathSrc, const char *pathDst, bool replace, void *tmpBuffer, size_t bufferSize);
bool findPayload(char *path, u32 pressed); bool findPayload(char *path, u32 pressed);
bool payloadMenu(char *path, bool *hasDisplayedMenu); bool payloadMenu(char *path, bool *hasDisplayedMenu);
u32 firmRead(void *dest, u32 firmType); u32 firmRead(void *dest, u32 firmType);
void findDumpFile(const char *folderPath, char *fileName); void findDumpFile(const char *folderPath, char *fileName);
bool backupEssentialFiles(void);

View File

@ -49,6 +49,9 @@ bool isSdMode;
u16 launchedPath[80+1]; u16 launchedPath[80+1];
BootType bootType; BootType bootType;
u16 mcuFwVersion;
u8 mcuConsoleInfo[9];
void main(int argc, char **argv, u32 magicWord) void main(int argc, char **argv, u32 magicWord)
{ {
bool isFirmProtEnabled, bool isFirmProtEnabled,
@ -117,6 +120,11 @@ void main(int argc, char **argv, u32 magicWord)
memcpy(__itcm_start__, __itcm_lma__, __itcm_bss_start__ - __itcm_start__); memcpy(__itcm_start__, __itcm_lma__, __itcm_bss_start__ - __itcm_start__);
memset(__itcm_bss_start__, 0, __itcm_end__ - __itcm_bss_start__); memset(__itcm_bss_start__, 0, __itcm_end__ - __itcm_bss_start__);
I2C_init(); I2C_init();
I2C_readRegBuf(I2C_DEV_MCU, 0x00, (u8 *)&mcuFwVersion, 2);
if ((mcuFwVersion & 0xFFF) < 0x0100) error("Unsupported MCU FW version.");
I2C_readRegBuf(I2C_DEV_MCU, 0x7F, mcuConsoleInfo, 9);
if(isInvalidLoader) error("Launched using an unsupported loader."); if(isInvalidLoader) error("Launched using an unsupported loader.");
installArm9Handlers(); installArm9Handlers();

View File

@ -130,3 +130,6 @@ extern BootType bootType;
extern u16 launchedFirmTidLow[8]; extern u16 launchedFirmTidLow[8];
extern u16 launchedPath[80+1]; extern u16 launchedPath[80+1];
extern u16 mcuFwVersion;
extern u8 mcuConsoleInfo[9];