Cleanup, add boundary checks for files loaded from SD
This commit is contained in:
parent
934c4bed0b
commit
ffaa5790c2
@ -31,7 +31,7 @@
|
||||
|
||||
bool readConfig(void)
|
||||
{
|
||||
if(fileRead(&configData, CONFIG_PATH) != sizeof(CfgData) ||
|
||||
if(fileRead(&configData, CONFIG_PATH, sizeof(CfgData)) != sizeof(CfgData) ||
|
||||
memcmp(configData.magic, "CONF", 4) != 0 ||
|
||||
configData.formatVersionMajor != CONFIG_VERSIONMAJOR ||
|
||||
configData.formatVersionMinor != CONFIG_VERSIONMINOR)
|
||||
@ -87,8 +87,8 @@ void configMenu(bool oldPinStatus)
|
||||
};
|
||||
|
||||
struct multiOption {
|
||||
int posXs[4];
|
||||
int posY;
|
||||
u32 posXs[4];
|
||||
u32 posY;
|
||||
u32 enabled;
|
||||
} multiOptions[] = {
|
||||
{ .posXs = {19, 24, 29, 34} },
|
||||
@ -107,7 +107,7 @@ void configMenu(bool oldPinStatus)
|
||||
selectedOption = multiOptionsAmount;
|
||||
|
||||
struct singleOption {
|
||||
int posY;
|
||||
u32 posY;
|
||||
bool enabled;
|
||||
} singleOptions[singleOptionsAmount];
|
||||
|
||||
@ -125,7 +125,7 @@ void configMenu(bool oldPinStatus)
|
||||
//Character to display a selected option
|
||||
char selected = 'x';
|
||||
|
||||
int endPos = 42;
|
||||
u32 endPos = 42;
|
||||
|
||||
//Display all the multiple choice options in white
|
||||
for(u32 i = 0; i < multiOptionsAmount; i++)
|
||||
|
@ -36,14 +36,20 @@ static bool bottomScreenSelected = false;
|
||||
|
||||
bool loadSplash(void)
|
||||
{
|
||||
//Don't delay boot nor init the screens if no splash image is on the SD
|
||||
if(getFileSize("/luma/splash.bin") + getFileSize("/luma/splashbottom.bin") == 0)
|
||||
u32 topSplashSize = getFileSize("/luma/splash.bin"),
|
||||
bottomSplashSize = getFileSize("/luma/splashbottom.bin");
|
||||
|
||||
bool isTopSplashValid = topSplashSize == SCREEN_TOP_FBSIZE,
|
||||
isBottomSplashValid = bottomSplashSize == SCREEN_BOTTOM_FBSIZE;
|
||||
|
||||
//Don't delay boot nor init the screens if no splash images or invalid splash images are on the SD
|
||||
if(!isTopSplashValid && !isBottomSplashValid)
|
||||
return false;
|
||||
|
||||
|
||||
initScreens();
|
||||
|
||||
fileRead(fb->top_left, "/luma/splash.bin");
|
||||
fileRead(fb->bottom, "/luma/splashbottom.bin");
|
||||
if(isTopSplashValid) fileRead(fb->top_left, "/luma/splash.bin", topSplashSize);
|
||||
if(isBottomSplashValid) fileRead(fb->bottom, "/luma/splashbottom.bin", bottomSplashSize);
|
||||
|
||||
chrono(3);
|
||||
|
||||
@ -55,18 +61,18 @@ void selectScreen(bool isBottomScreen)
|
||||
bottomScreenSelected = isBottomScreen;
|
||||
}
|
||||
|
||||
void drawCharacter(char character, int posX, int posY, u32 color)
|
||||
void drawCharacter(char character, u32 posX, u32 posY, u32 color)
|
||||
{
|
||||
u8 *const select = bottomScreenSelected ? fb->bottom : fb->top_left;
|
||||
|
||||
for(int y = 0; y < 8; y++)
|
||||
for(u32 y = 0; y < 8; y++)
|
||||
{
|
||||
char charPos = font[character * 8 + y];
|
||||
|
||||
for(int x = 7; x >= 0; x--)
|
||||
if((charPos >> x) & 1)
|
||||
for(u32 x = 0; x < 8; x++)
|
||||
if((charPos >> (7 - x)) & 1)
|
||||
{
|
||||
int screenPos = (posX * SCREEN_HEIGHT * 3 + (SCREEN_HEIGHT - y - posY - 1) * 3) + (7 - x) * 3 * SCREEN_HEIGHT;
|
||||
u32 screenPos = (posX * SCREEN_HEIGHT * 3 + (SCREEN_HEIGHT - y - posY - 1) * 3) + x * 3 * SCREEN_HEIGHT;
|
||||
|
||||
select[screenPos] = color >> 16;
|
||||
select[screenPos + 1] = color >> 8;
|
||||
@ -75,9 +81,9 @@ void drawCharacter(char character, int posX, int posY, u32 color)
|
||||
}
|
||||
}
|
||||
|
||||
int drawString(const char *string, int posX, int posY, u32 color)
|
||||
u32 drawString(const char *string, u32 posX, u32 posY, u32 color)
|
||||
{
|
||||
for(int i = 0, line_i = 0; i < strlen(string); i++, line_i++)
|
||||
for(u32 i = 0, line_i = 0; i < strlen(string); i++, line_i++)
|
||||
{
|
||||
if(string[i] == '\n')
|
||||
{
|
||||
|
@ -29,9 +29,11 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define SCREEN_TOP_WIDTH 400
|
||||
#define SCREEN_BOTTOM_WIDTH 320
|
||||
#define SCREEN_HEIGHT 240
|
||||
#define SCREEN_TOP_WIDTH 400
|
||||
#define SCREEN_BOTTOM_WIDTH 320
|
||||
#define SCREEN_HEIGHT 240
|
||||
#define SCREEN_TOP_FBSIZE (3 * SCREEN_TOP_WIDTH * SCREEN_HEIGHT)
|
||||
#define SCREEN_BOTTOM_FBSIZE (3 * SCREEN_BOTTOM_WIDTH * SCREEN_HEIGHT)
|
||||
|
||||
#define SPACING_Y 10
|
||||
#define SPACING_X 8
|
||||
@ -44,5 +46,5 @@
|
||||
|
||||
bool loadSplash(void);
|
||||
void selectScreen(bool isBottomScreen);
|
||||
void drawCharacter(char character, int posX, int posY, u32 color);
|
||||
int drawString(const char *string, int posX, int posY, u32 color);
|
||||
void drawCharacter(char character, u32 posX, u32 posY, u32 color);
|
||||
u32 drawString(const char *string, u32 posX, u32 posY, u32 color);
|
@ -108,7 +108,7 @@ void detectAndProcessExceptionDumps(void)
|
||||
initScreens();
|
||||
|
||||
drawString("An exception occurred", 10, 10, COLOR_RED);
|
||||
int posY = drawString(dumpHeader->processor == 11 ? "Processor: ARM11 (core )" : "Processor: ARM9", 10, 30, COLOR_WHITE);
|
||||
u32 posY = drawString(dumpHeader->processor == 11 ? "Processor: ARM11 (core )" : "Processor: ARM9", 10, 30, COLOR_WHITE);
|
||||
if(dumpHeader->processor == 11) drawCharacter('0' + dumpHeader->core, 10 + 29 * SPACING_X, 30, COLOR_WHITE);
|
||||
|
||||
posY = drawString("Exception type: ", 10, posY + SPACING_Y, COLOR_WHITE);
|
||||
@ -160,7 +160,7 @@ void detectAndProcessExceptionDumps(void)
|
||||
|
||||
selectScreen(true);
|
||||
|
||||
int posYBottom = drawString("Stack dump:", 10, 10, COLOR_WHITE) + SPACING_Y;
|
||||
u32 posYBottom = drawString("Stack dump:", 10, 10, COLOR_WHITE) + SPACING_Y;
|
||||
|
||||
for(u32 line = 0; line < 19 && stackDump < additionalData; line++)
|
||||
{
|
||||
|
@ -294,12 +294,12 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource)
|
||||
}
|
||||
|
||||
//Check that the SD FIRM is right for the console from the ARM9 section address
|
||||
if(fileRead(firm, *firmType == NATIVE_FIRM1X2X ? firmwareFiles[0] : firmwareFiles[(u32)*firmType]) &&
|
||||
if(fileRead(firm, *firmType == NATIVE_FIRM1X2X ? firmwareFiles[0] : firmwareFiles[(u32)*firmType], 0x400000) &&
|
||||
((section[3].offset ? section[3].address : section[2].address) == (isN3DS ? (u8 *)0x8006000 : (u8 *)0x8006800)))
|
||||
firmVersion = 0xFFFFFFFF;
|
||||
else
|
||||
{
|
||||
if(loadFromSd) error("An old unsupported FIRM has been detected.\nCopy firmware.bin in /luma to boot");
|
||||
if(loadFromSd) error("An old unsupported FIRM has been detected.\nCopy a valid firmware.bin in /luma to boot");
|
||||
decryptExeFs((u8 *)firm);
|
||||
}
|
||||
|
||||
@ -329,8 +329,8 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource)
|
||||
//We can't boot a 3.x/4.x NATIVE_FIRM, load one from SD
|
||||
else if(firmVersion < 0x25)
|
||||
{
|
||||
if(!fileRead(firm, "/luma/firmware.bin") || section[2].address != (u8 *)0x8006800)
|
||||
error("An old unsupported FIRM has been detected.\nCopy firmware.bin in /luma to boot");
|
||||
if(!fileRead(firm, "/luma/firmware.bin", 0x400000) || section[2].address != (u8 *)0x8006800)
|
||||
error("An old unsupported FIRM has been detected.\nCopy a valid firmware.bin in /luma to boot");
|
||||
|
||||
//No assumption regarding FIRM version
|
||||
firmVersion = 0xFFFFFFFF;
|
||||
@ -499,7 +499,7 @@ static inline void copySection0AndInjectSystemModules(FirmwareType firmType)
|
||||
concatenateStrings(fileName, moduleName);
|
||||
concatenateStrings(fileName, ext);
|
||||
|
||||
u32 fileSize = fileRead(dst, fileName);
|
||||
u32 fileSize = fileRead(dst, fileName, 2 * srcModuleSize);
|
||||
if(fileSize) dstModuleSize = fileSize;
|
||||
else
|
||||
{
|
||||
|
37
source/fs.c
37
source/fs.c
@ -38,27 +38,26 @@ void mountFs(void)
|
||||
f_mount(&nandFs, "1:", 0);
|
||||
}
|
||||
|
||||
u32 fileRead(void *dest, const char *path)
|
||||
u32 fileRead(void *dest, const char *path, u32 maxSize)
|
||||
{
|
||||
FIL file;
|
||||
u32 size;
|
||||
u32 ret = 0;
|
||||
|
||||
if(f_open(&file, path, FA_READ) == FR_OK)
|
||||
{
|
||||
unsigned int read;
|
||||
size = f_size(&file);
|
||||
if(dest != NULL)
|
||||
f_read(&file, dest, size, &read);
|
||||
u32 size = f_size(&file);
|
||||
if(dest == NULL) ret = size;
|
||||
else if(!(maxSize > 0 && size > maxSize))
|
||||
f_read(&file, dest, size, (unsigned int *)&ret);
|
||||
f_close(&file);
|
||||
}
|
||||
else size = 0;
|
||||
|
||||
return size;
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 getFileSize(const char *path)
|
||||
{
|
||||
return fileRead(NULL, path);
|
||||
return fileRead(NULL, path, 0);
|
||||
}
|
||||
|
||||
bool fileWrite(const void *buffer, const char *path, u32 size)
|
||||
@ -125,21 +124,27 @@ void loadPayload(u32 pressed)
|
||||
|
||||
if(result == FR_OK && info.fname[0])
|
||||
{
|
||||
initScreens();
|
||||
|
||||
u32 *loaderAddress = (u32 *)0x24FFFF00;
|
||||
u8 *payloadAddress = (u8 *)0x24F00000;
|
||||
|
||||
memcpy(loaderAddress, loader, loader_size);
|
||||
|
||||
concatenateStrings(path, "/");
|
||||
concatenateStrings(path, info.altname);
|
||||
|
||||
loaderAddress[1] = fileRead((void *)0x24F00000, path);
|
||||
u32 payloadSize = fileRead(payloadAddress, path, (u8 *)loaderAddress - payloadAddress);
|
||||
|
||||
flushDCacheRange(loaderAddress, loader_size);
|
||||
flushICacheRange(loaderAddress, loader_size);
|
||||
if(payloadSize > 0)
|
||||
{
|
||||
loaderAddress[1] = payloadSize;
|
||||
|
||||
((void (*)())loaderAddress)();
|
||||
initScreens();
|
||||
|
||||
flushDCacheRange(loaderAddress, loader_size);
|
||||
flushICacheRange(loaderAddress, loader_size);
|
||||
|
||||
((void (*)())loaderAddress)();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,7 +192,7 @@ u32 firmRead(void *dest, u32 firmType)
|
||||
//Convert back the .app name from integer to array
|
||||
hexItoa(firmVersion, &path[35], 8);
|
||||
|
||||
fileRead(dest, path);
|
||||
fileRead(dest, path, 0);
|
||||
|
||||
return firmVersion;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
||||
extern bool isN3DS;
|
||||
|
||||
void mountFs(void);
|
||||
u32 fileRead(void *dest, const char *path);
|
||||
u32 fileRead(void *dest, const char *path, u32 maxSize);
|
||||
u32 getFileSize(const char *path);
|
||||
bool fileWrite(const void *buffer, const char *path, u32 size);
|
||||
void fileDelete(const char *path);
|
||||
|
@ -108,7 +108,7 @@ bool verifyPin(void)
|
||||
{
|
||||
PinData pin;
|
||||
|
||||
if(fileRead(&pin, PIN_PATH) != sizeof(PinData) ||
|
||||
if(fileRead(&pin, PIN_PATH, sizeof(PinData)) != sizeof(PinData) ||
|
||||
memcmp(pin.magic, "PINF", 4) != 0 ||
|
||||
pin.formatVersionMajor != PIN_VERSIONMAJOR ||
|
||||
pin.formatVersionMinor != PIN_VERSIONMINOR ||
|
||||
|
@ -111,13 +111,13 @@ void clearScreens(void)
|
||||
//Setting up two simultaneous memory fills using the GPU
|
||||
vu32 *REGs_PSC0 = (vu32 *)0x10400010;
|
||||
REGs_PSC0[0] = (u32)fb->top_left >> 3; //Start address
|
||||
REGs_PSC0[1] = (u32)(fb->top_left + 0x46500) >> 3; //End address
|
||||
REGs_PSC0[1] = (u32)(fb->top_left + SCREEN_TOP_FBSIZE) >> 3; //End address
|
||||
REGs_PSC0[2] = 0; //Fill value
|
||||
REGs_PSC0[3] = (2 << 8) | 1; //32-bit pattern; start
|
||||
|
||||
vu32 *REGs_PSC1 = (vu32 *)0x10400020;
|
||||
REGs_PSC1[0] = (u32)fb->bottom >> 3; //Start address
|
||||
REGs_PSC1[1] = (u32)(fb->bottom + 0x38400) >> 3; //End address
|
||||
REGs_PSC1[1] = (u32)(fb->bottom + SCREEN_BOTTOM_FBSIZE) >> 3; //End address
|
||||
REGs_PSC1[2] = 0; //Fill value
|
||||
REGs_PSC1[3] = (2 << 8) | 1; //32-bit pattern; start
|
||||
|
||||
@ -126,7 +126,7 @@ void clearScreens(void)
|
||||
if(fb->top_right != fb->top_left)
|
||||
{
|
||||
REGs_PSC0[0] = (u32)fb->top_right >> 3; //Start address
|
||||
REGs_PSC0[1] = (u32)(fb->top_right + 0x46500) >> 3; //End address
|
||||
REGs_PSC0[1] = (u32)(fb->top_right + SCREEN_TOP_FBSIZE) >> 3; //End address
|
||||
REGs_PSC0[2] = 0; //Fill value
|
||||
REGs_PSC0[3] = (2 << 8) | 1; //32-bit pattern; start
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "strings.h"
|
||||
#include "memory.h"
|
||||
|
||||
int strlen(const char *string)
|
||||
u32 strlen(const char *string)
|
||||
{
|
||||
char *stringEnd = (char *)string;
|
||||
|
||||
@ -40,16 +40,16 @@ void concatenateStrings(char *destination, const char *source)
|
||||
memcpy(&destination[j], source, i + 1);
|
||||
}
|
||||
|
||||
void hexItoa(u32 number, char *out, u32 nbDigits)
|
||||
void hexItoa(u32 number, char *out, u32 digits)
|
||||
{
|
||||
const char hexDigits[] = "0123456789ABCDEF";
|
||||
u32 i = 0;
|
||||
|
||||
while(number > 0)
|
||||
{
|
||||
out[nbDigits - 1 - i++] = hexDigits[number & 0xF];
|
||||
out[digits - 1 - i++] = hexDigits[number & 0xF];
|
||||
number >>= 4;
|
||||
}
|
||||
|
||||
for(; i < nbDigits; i++) out[nbDigits - 1 - i] = '0';
|
||||
for(; i < digits; i++) out[digits - 1 - i] = '0';
|
||||
}
|
@ -24,6 +24,6 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
int strlen(const char *string);
|
||||
u32 strlen(const char *string);
|
||||
void concatenateStrings(char *destination, const char *source);
|
||||
void hexItoa(u32 number, char *out, u32 nbDigits);
|
||||
void hexItoa(u32 number, char *out, u32 digits);
|
@ -116,7 +116,7 @@ void error(const char *message)
|
||||
initScreens();
|
||||
|
||||
drawString("An error has occurred:", 10, 10, COLOR_RED);
|
||||
int posY = drawString(message, 10, 30, COLOR_WHITE);
|
||||
u32 posY = drawString(message, 10, 30, COLOR_WHITE);
|
||||
drawString("Press any button to shutdown", 10, posY + 2 * SPACING_Y, COLOR_WHITE);
|
||||
|
||||
waitInput();
|
||||
|
Reference in New Issue
Block a user