Explicitly synchronize fat copies after install/uninstall operations are completed

Don't wait for the user to exit the program
This commit is contained in:
Edoardo Lolletti 2024-04-26 14:57:37 +02:00
parent 023fb29972
commit 4861ad5ab5
4 changed files with 54 additions and 47 deletions

View File

@ -223,6 +223,8 @@ int main(int argc, char **argv)
messageBox("\x1B[31mError:\x1B[33m Uninstall failed\n"); messageBox("\x1B[31mError:\x1B[33m Uninstall failed\n");
} }
nandio_lock_writing(); nandio_lock_writing();
printf("Synchronizing FAT tables...\n");
nandio_synchronize_fats();
} }
break; break;
@ -252,6 +254,8 @@ int main(int argc, char **argv)
messageBox("\x1B[31mError:\x1B[33m Install failed\n"); messageBox("\x1B[31mError:\x1B[33m Install failed\n");
} }
nandio_lock_writing(); nandio_lock_writing();
printf("Synchronizing FAT tables...\n");
nandio_synchronize_fats();
} }
break; break;

View File

@ -12,11 +12,11 @@
/************************ Function Protoypes **********************************/ /************************ Function Protoypes **********************************/
bool nandio_startup(); static bool nandio_startup();
bool nandio_is_inserted(); static bool nandio_is_inserted();
bool nandio_read_sectors(sec_t offset, sec_t len, void *buffer); static bool nandio_read_sectors(sec_t offset, sec_t len, void *buffer);
bool nandio_write_sectors(sec_t offset, sec_t len, const void *buffer); static bool nandio_write_sectors(sec_t offset, sec_t len, const void *buffer);
bool nandio_clear_status(); static bool nandio_clear_status();
bool nandio_shutdown(); bool nandio_shutdown();
/************************ Constants / Defines *********************************/ /************************ Constants / Defines *********************************/
@ -51,7 +51,7 @@ void nandio_set_fat_sig_fix(u32 offset)
fat_sig_fix_offset = offset; fat_sig_fix_offset = offset;
} }
void getConsoleID(u8 *consoleID) static void getConsoleID(u8 *consoleID)
{ {
u8 *fifo=(u8*)0x02300000; //shared mem address that has our computed key3 stuff u8 *fifo=(u8*)0x02300000; //shared mem address that has our computed key3 stuff
u8 key[16]; //key3 normalkey - keyslot 3 is used for DSi/twln NAND crypto u8 key[16]; //key3 normalkey - keyslot 3 is used for DSi/twln NAND crypto
@ -76,7 +76,7 @@ void getConsoleID(u8 *consoleID)
memcpy(&consoleID[4], &key_x[0xC], 4); memcpy(&consoleID[4], &key_x[0xC], 4);
} }
bool nandio_startup() static bool nandio_startup()
{ {
if (!nand_Startup()) if (!nand_Startup())
{ {
@ -115,7 +115,7 @@ bool nandio_startup()
return crypt_buf != 0; return crypt_buf != 0;
} }
bool nandio_is_inserted() static bool nandio_is_inserted()
{ {
return true; return true;
} }
@ -162,7 +162,7 @@ static bool write_sectors(sec_t start, sec_t len, const void *buffer)
} }
bool nandio_read_sectors(sec_t offset, sec_t len, void *buffer) static bool nandio_read_sectors(sec_t offset, sec_t len, void *buffer)
{ {
while (len >= CRYPT_BUF_LEN) while (len >= CRYPT_BUF_LEN)
{ {
@ -183,7 +183,7 @@ bool nandio_read_sectors(sec_t offset, sec_t len, void *buffer)
} }
} }
bool nandio_write_sectors(sec_t offset, sec_t len, const void *buffer) static bool nandio_write_sectors(sec_t offset, sec_t len, const void *buffer)
{ {
if (writingLocked) if (writingLocked)
return false; return false;
@ -209,47 +209,14 @@ bool nandio_write_sectors(sec_t offset, sec_t len, const void *buffer)
} }
} }
bool nandio_clear_status() static bool nandio_clear_status()
{ {
return true; return true;
} }
bool nandio_shutdown() bool nandio_shutdown()
{ {
if (nandWritten) nandio_synchronize_fats();
{
// at cleanup we synchronize the FAT statgings
// A FatFS might have multiple copies of the FAT.
// we will get them back synchonized as we just worked on the first copy
// this allows us to revert changes in the FAT if we did not properly finish
// and did not push the changes to the other copies
// to do this we read the first partition sector
nandio_read_sectors(fat_sig_fix_offset, 1, sector_buf);
u8 stagingLevels = sector_buf[0x10];
u8 reservedSectors = sector_buf[0x0E];
u16 sectorsPerFatCopy = sector_buf[0x16] | ((u16)sector_buf[0x17] << 8);
/*
iprintf("[i] Staging for %i FAT copies\n",stagingLevels);
iprintf("[i] Stages starting at %i\n",reservedSectors);
iprintf("[i] %i sectors per stage\n",sectorsPerFatCopy);
*/
if (stagingLevels > 1)
{
for (u32 sector = 0;sector < sectorsPerFatCopy; sector++)
{
// read fat sector
nandio_read_sectors(fat_sig_fix_offset + reservedSectors + sector, 1, sector_buf);
// write to each copy, except the source copy
writingLocked = false;
for (int stage = 1;stage < stagingLevels;stage++)
{
nandio_write_sectors(fat_sig_fix_offset + reservedSectors + sector + (stage *sectorsPerFatCopy), 1, sector_buf);
}
writingLocked = true;
}
}
nandWritten = false;
}
free(crypt_buf); free(crypt_buf);
crypt_buf = 0; crypt_buf = 0;
return true; return true;
@ -276,3 +243,39 @@ bool nandio_force_fat_fix()
return true; return true;
} }
void nandio_synchronize_fats()
{
if (!nandWritten) return;
// at cleanup we synchronize the FAT statgings
// A FatFS might have multiple copies of the FAT.
// we will get them back synchonized as we just worked on the first copy
// this allows us to revert changes in the FAT if we did not properly finish
// and did not push the changes to the other copies
// to do this we read the first partition sector
nandio_read_sectors(fat_sig_fix_offset, 1, sector_buf);
u8 stagingLevels = sector_buf[0x10];
u8 reservedSectors = sector_buf[0x0E];
u16 sectorsPerFatCopy = sector_buf[0x16] | ((u16)sector_buf[0x17] << 8);
/*
iprintf("[i] Staging for %i FAT copies\n",stagingLevels);
iprintf("[i] Stages starting at %i\n",reservedSectors);
iprintf("[i] %i sectors per stage\n",sectorsPerFatCopy);
*/
if (stagingLevels > 1)
{
for (u32 sector = 0;sector < sectorsPerFatCopy; sector++)
{
// read fat sector
nandio_read_sectors(fat_sig_fix_offset + reservedSectors + sector, 1, sector_buf);
// write to each copy, except the source copy
writingLocked = false;
for (int stage = 1;stage < stagingLevels;stage++)
{
nandio_write_sectors(fat_sig_fix_offset + reservedSectors + sector + (stage *sectorsPerFatCopy), 1, sector_buf);
}
writingLocked = true;
}
}
nandWritten = false;
}

View File

@ -18,13 +18,13 @@ extern const DISC_INTERFACE io_dsi_nand;
void nandio_set_fat_sig_fix(uint32_t offset); void nandio_set_fat_sig_fix(uint32_t offset);
void getConsoleID(uint8_t *consoleID);
extern bool nandio_shutdown(); extern bool nandio_shutdown();
extern bool nandio_lock_writing(); extern bool nandio_lock_writing();
extern bool nandio_unlock_writing(); extern bool nandio_unlock_writing();
extern bool nandio_force_fat_fix(); extern bool nandio_force_fat_fix();
extern void nandio_synchronize_fats();
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -354,7 +354,7 @@ static bool readUnlaunchInstaller(const char* path)
FILE* unlaunchInstaller = fopen(path, "rb"); FILE* unlaunchInstaller = fopen(path, "rb");
if (!unlaunchInstaller) if (!unlaunchInstaller)
{ {
messageBox("\x1B[31mError:\x1B[33m Failed to open unlaunch installer\n(sd:/unlaunch.dsi)\n"); messageBox("\x1B[31mError:\x1B[33m Failed to open unlaunch installer\n");
return false; return false;
} }