Add code to backup essential files
This commit is contained in:
parent
bc6e14ada7
commit
fcdb6a7ab5
111
arm9/source/fs.c
111
arm9/source/fs.c
@ -37,6 +37,8 @@
|
||||
#include "firm.h"
|
||||
#include "crypto.h"
|
||||
#include "strings.h"
|
||||
#include "alignedseqmemcpy.h"
|
||||
#include "i2c.h"
|
||||
|
||||
static FATFS sdFs,
|
||||
nandFs;
|
||||
@ -121,6 +123,79 @@ bool fileDelete(const char *path)
|
||||
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)
|
||||
{
|
||||
const char *pattern;
|
||||
@ -309,3 +384,39 @@ void findDumpFile(const char *folderPath, char *fileName)
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -35,7 +35,10 @@ u32 fileRead(void *dest, const char *path, u32 maxSize);
|
||||
u32 getFileSize(const char *path);
|
||||
bool fileWrite(const void *buffer, const char *path, u32 size);
|
||||
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 payloadMenu(char *path, bool *hasDisplayedMenu);
|
||||
u32 firmRead(void *dest, u32 firmType);
|
||||
void findDumpFile(const char *folderPath, char *fileName);
|
||||
|
||||
bool backupEssentialFiles(void);
|
||||
|
@ -49,6 +49,9 @@ bool isSdMode;
|
||||
u16 launchedPath[80+1];
|
||||
BootType bootType;
|
||||
|
||||
u16 mcuFwVersion;
|
||||
u8 mcuConsoleInfo[9];
|
||||
|
||||
void main(int argc, char **argv, u32 magicWord)
|
||||
{
|
||||
bool isFirmProtEnabled,
|
||||
@ -117,6 +120,11 @@ void main(int argc, char **argv, u32 magicWord)
|
||||
memcpy(__itcm_start__, __itcm_lma__, __itcm_bss_start__ - __itcm_start__);
|
||||
memset(__itcm_bss_start__, 0, __itcm_end__ - __itcm_bss_start__);
|
||||
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.");
|
||||
|
||||
installArm9Handlers();
|
||||
|
@ -130,3 +130,6 @@ extern BootType bootType;
|
||||
|
||||
extern u16 launchedFirmTidLow[8];
|
||||
extern u16 launchedPath[80+1];
|
||||
|
||||
extern u16 mcuFwVersion;
|
||||
extern u8 mcuConsoleInfo[9];
|
||||
|
Loading…
x
Reference in New Issue
Block a user