diff --git a/include/arm9/config.h b/include/arm9/config.h index 29ee3ae..4df1887 100644 --- a/include/arm9/config.h +++ b/include/arm9/config.h @@ -27,3 +27,4 @@ void *configCopyText(int key); const void *configGetData(int key); const char *configGetKeyText(int key); +bool configSetKeyData(int key, void *data); diff --git a/source/arm9/config.c b/source/arm9/config.c index 0aa5324..c347a10 100644 --- a/source/arm9/config.c +++ b/source/arm9/config.c @@ -64,7 +64,7 @@ { parseBootOptionPad, NULL }, { parseBootOptionPad, NULL }, { parseBootOptionPad, NULL }, - { parseBootMode, NULL } + { parseBootMode, writeBootMode } }; static AttributeEntryType attributes[numKeys]; @@ -92,7 +92,7 @@ goto fail; } - filebuf = (char *) malloc(MAX_FILE_SIZE); + filebuf = (char *) malloc(MAX_FILE_SIZE + 1); if(!filebuf) { @@ -113,10 +113,11 @@ goto fail; } + f_close(&file); + // terminate string buf filebuf[fileSize] = '\0'; - return parseConfigFile(); fail: @@ -124,6 +125,34 @@ return false; } +static bool writeConfigFile() +{ + const u32 fileSize = strlen(filebuf); + u32 bytesWritten; + + if(fileSize > MAX_FILE_SIZE) + panic(); + + if(f_open(&file, filepath, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK) + { + goto fail; + } + + if((f_write(&file, filebuf, fileSize, &bytesWritten) != FR_OK) || (bytesWritten != fileSize)) + { + f_close(&file); + goto fail; + } + + f_close(&file); + + return true; + +fail: + + return false; +} + /* returns the start of an attribute's data. */ static char *findDefinition(const char *attrName) { @@ -220,7 +249,7 @@ { const char *def = " = "; u32 curLen = strlen(filebuf); - u32 remainingLen = MAX_FILE_SIZE - curLen - 1; + u32 remainingLen = MAX_FILE_SIZE - curLen; u32 totalLen = strlen(textData); u32 defLen = strlen(def); totalLen += strlen(keyName); @@ -242,7 +271,7 @@ u32 diff; u32 newLen = strlen(newText); u32 curLen = strlen(filebuf); - u32 remainingLen = MAX_FILE_SIZE - curLen - 1; + u32 remainingLen = MAX_FILE_SIZE - curLen; if(newLen > remainingLen) return 0; @@ -272,6 +301,20 @@ return newLen; } +static writeAttributeText(AttributeEntryType *attr, const char *newText, int key) +{ + // text data doesn't exist yet? + if(!attr->textData) + { + attr->textData = writeAddDefinitionText(configGetKeyText(key), newText); + attr->textLength = strlen(newText); + } + else // update definition + { + attr->textLength = writeUpdateDefinitionText(attr->textData, attr->textLength, newText); + } +} + static bool isValidPath(char *path) { char c; @@ -405,23 +448,17 @@ return false; if(!attr->data) + { attr->data = (u32 *) malloc(sizeof(u32)); - if(!attr->data) - return false; + if(!attr->data) + return false; + } *(u32 *)attr->data = mode; const char *data = modeTable[mode]; - if(!attr->textData) - { - attr->textData = writeAddDefinitionText(configGetKeyText(key), data); - attr->textLength = strlen(attr->textData); - } - else - { - attr->textLength = writeUpdateDefinitionText(attr->textData, attr->textLength, data); - } + writeAttributeText(attr, data, key); return true; } @@ -460,7 +497,7 @@ return keyStrings[key]; } -void configSetKeyData(int key, void *data) +bool configSetKeyData(int key, void *data) { AttributeEntryType *attr; @@ -469,6 +506,9 @@ attr = &attributes[key]; - keyFunctions[key].write(attr, data, key); + if(!keyFunctions[key].write) + panic(); + + return keyFunctions[key].write(attr, data, key); } diff --git a/source/arm9/firm.c b/source/arm9/firm.c index 011d899..00d2285 100644 --- a/source/arm9/firm.c +++ b/source/arm9/firm.c @@ -116,7 +116,7 @@ continue; printf("Section %i:\noffset: 0x%"PRIX32", addr: 0x%"PRIX32", size 0x%"PRIX32"\n", - i, section->offset, section->address, section->size); + (int) i, section->offset, section->address, section->size); if(section->offset >= fwSize) { diff --git a/source/arm9/main.c b/source/arm9/main.c index a323101..d5a9ee0 100644 --- a/source/arm9/main.c +++ b/source/arm9/main.c @@ -308,7 +308,15 @@ path = (const char *)configGetData(keyBootOption); if(path) { - printf("Boot Option #%i:\n", i + 1); + printf("Boot Option #%i:\n%s\n", i + 1, path); + + // check if fw still exists + if(!statFirmware(path)) + { + printf("Couldn't find firmware...\n"); + continue; + } + // check pad value const u32 *temp; temp = (const u32 *)configGetData(keyPad); @@ -346,6 +354,16 @@ consoleClear(); } +void clearConsole(int which) +{ + if(which) + consoleSelect(&con_top); + else + consoleSelect(&con_bottom); + + consoleClear(); +} + void power_off_safe() { clearConsoles(); diff --git a/source/arm9/menu.c b/source/arm9/menu.c index 0fd984b..53c3578 100644 --- a/source/arm9/menu.c +++ b/source/arm9/menu.c @@ -229,6 +229,8 @@ case MENU_EVENT_STATE_CHANGE: if(menu_next_state == MENU_STATE_EXIT) goto exitAndLaunchFirm; + else + clearConsole(0); default: break; } diff --git a/source/arm9/menu_firmloader.c b/source/arm9/menu_firmloader.c index a894da9..e831dd9 100644 --- a/source/arm9/menu_firmloader.c +++ b/source/arm9/menu_firmloader.c @@ -33,7 +33,7 @@ if(!tryLoadFirmware(filePath)) { - printf("\x1B[31mBad firmware.\e[0m\n"); + printf("\n\x1B[31mBad firmware.\e[0m\n\n"); printf("Press B to return.\n"); do { @@ -45,7 +45,7 @@ goto fail; } - printf("\x1B[32mFirmware verification SUCCESS!\e[0m\n\n"); + printf("\n\x1B[32mFirmware verification SUCCESS!\e[0m\n\n"); printf("Attempting to run firmware, press B to exit...\n"); @@ -73,6 +73,29 @@ return false; } +// Does very basic checks whether the firmware actually exists. +bool statFirmware(const char *filePath) +{ + FILINFO fileStat; + u32 fileSize; + + if(strncmp(filePath, "sdmc:", 5) == 0) + { + if(f_stat(filePath, &fileStat) != FR_OK) + return false; + + fileSize = fileStat.fsize; + + if(fileSize == 0 || FIRM_MAX_SIZE > FIRM_MAX_SIZE) + return false; + + return true; + } + + // unknown mountpoint + return false; +} + static bool tryLoadFirmware(const char *filepath) { u32 fw_size;