From 43f744326f75faaa13b2aba9137d556c3a45c7bf Mon Sep 17 00:00:00 2001 From: Pablo Curiel Date: Mon, 8 Mar 2021 07:11:28 -0400 Subject: [PATCH] Minor fixes. * The new logfile handler should now work properly. * A UTF-8 BOM is now written at the start of every new logfile. --- .gitignore | 18 +-- build.sh | 2 +- code_templates/nsp_dumper_stor.c | 8 +- code_templates/nsp_dumper_usb.c | 8 +- code_templates/sd_romfs_dumper.c | 8 +- code_templates/system_title_dumper.c | 8 +- code_templates/usb_gc_dumper.c | 8 +- code_templates/usb_romfs_dumper.c | 8 +- code_templates/xml_generator.c | 8 +- source/common.h | 7 ++ source/log.c | 176 ++++++++++++++++----------- source/log.h | 3 +- source/romfs.c | 38 ++++-- source/usb.c | 9 +- source/utils.c | 39 +++--- 15 files changed, 228 insertions(+), 120 deletions(-) diff --git a/.gitignore b/.gitignore index 5388b81..b6dd47b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,15 @@ build -/*.elf -/*.nacp -/*.nro -/*.nso -/*.map -/*.pfs0 -/*.lst -/*.tar.bz2 +*.elf +*.nacp +*.nro +*.nso +*.map +*.pfs0 +*.lst +*.tar.bz2 /code_templates/tmp/* /source/main.c -/*.log +*.log # Clion files .idea diff --git a/build.sh b/build.sh index 45fc8e5..c0aea4e 100644 --- a/build.sh +++ b/build.sh @@ -29,7 +29,7 @@ for f in ./code_templates/*.c; do cp ./$filename.nro ./code_templates/tmp/$filename/nxdumptool-rewrite.nro #cp ./$filename.elf ./code_templates/tmp/$filename/nxdumptool-rewrite.elf - rm -f ./build/main.o ./build/main.d ./build/utils.o ./build/utils.d ./build/usb.o ./build/usb.d ./$filename.* + rm -f ./build/main.o ./build/main.d ./build/utils.o ./build/utils.d ./build/usb.o ./build/usb.d ./build/log.o ./build/log.d ./$filename.* done make clean diff --git a/code_templates/nsp_dumper_stor.c b/code_templates/nsp_dumper_stor.c index 32b1324..c6a8111 100644 --- a/code_templates/nsp_dumper_stor.c +++ b/code_templates/nsp_dumper_stor.c @@ -31,6 +31,10 @@ #define BLOCK_SIZE 0x800000 #define OUTPATH "/nsp/" +int g_argc = 0; +char **g_argv = NULL; +const char *g_appLaunchPath = NULL; + static const char *dump_type_strings[] = { "dump base application", "dump update", @@ -748,8 +752,8 @@ end: int main(int argc, char *argv[]) { - (void)argc; - (void)argv; + g_argc = argc; + g_argv = argv; int ret = 0; diff --git a/code_templates/nsp_dumper_usb.c b/code_templates/nsp_dumper_usb.c index 037996c..79350ad 100644 --- a/code_templates/nsp_dumper_usb.c +++ b/code_templates/nsp_dumper_usb.c @@ -30,6 +30,10 @@ #define BLOCK_SIZE 0x800000 +int g_argc = 0; +char **g_argv = NULL; +const char *g_appLaunchPath = NULL; + typedef struct { void *data; @@ -906,8 +910,8 @@ static void nspDump(TitleInfo *title_info) int main(int argc, char *argv[]) { - (void)argc; - (void)argv; + g_argc = argc; + g_argv = argv; int ret = 0; diff --git a/code_templates/sd_romfs_dumper.c b/code_templates/sd_romfs_dumper.c index 7397914..6af3bd1 100644 --- a/code_templates/sd_romfs_dumper.c +++ b/code_templates/sd_romfs_dumper.c @@ -25,6 +25,10 @@ #define BLOCK_SIZE 0x800000 +int g_argc = 0; +char **g_argv = NULL; +const char *g_appLaunchPath = NULL; + static Mutex g_fileMutex = 0; static CondVar g_readCondvar = 0, g_writeCondvar = 0; @@ -323,8 +327,8 @@ u8 get_program_id_offset(TitleInfo *info, u32 program_count) int main(int argc, char *argv[]) { - (void)argc; - (void)argv; + g_argc = argc; + g_argv = argv; int ret = 0; diff --git a/code_templates/system_title_dumper.c b/code_templates/system_title_dumper.c index fa93034..3aa9464 100644 --- a/code_templates/system_title_dumper.c +++ b/code_templates/system_title_dumper.c @@ -27,6 +27,10 @@ #define BLOCK_SIZE 0x800000 #define OUTPATH "sdmc:/systitle_dumps" +int g_argc = 0; +char **g_argv = NULL; +const char *g_appLaunchPath = NULL; + static u8 *buf = NULL; static FILE *filefd = NULL; static char path[FS_MAX_PATH * 2] = {0}; @@ -220,8 +224,8 @@ static void dumpFsSection(TitleInfo *info, NcaFsSectionContext *nca_fs_ctx) int main(int argc, char *argv[]) { - (void)argc; - (void)argv; + g_argc = argc; + g_argv = argv; int ret = 0; diff --git a/code_templates/usb_gc_dumper.c b/code_templates/usb_gc_dumper.c index 5e2b750..35cf852 100644 --- a/code_templates/usb_gc_dumper.c +++ b/code_templates/usb_gc_dumper.c @@ -26,6 +26,10 @@ #define BLOCK_SIZE USB_TRANSFER_BUFFER_SIZE +int g_argc = 0; +char **g_argv = NULL; +const char *g_appLaunchPath = NULL; + /* Type definitions. */ typedef void (*MenuElementOptionFunction)(u32 idx); @@ -180,8 +184,8 @@ static char path[FS_MAX_PATH] = {0}; int main(int argc, char *argv[]) { - (void)argc; - (void)argv; + g_argc = argc; + g_argv = argv; int ret = 0; diff --git a/code_templates/usb_romfs_dumper.c b/code_templates/usb_romfs_dumper.c index 4a0736c..f6269de 100644 --- a/code_templates/usb_romfs_dumper.c +++ b/code_templates/usb_romfs_dumper.c @@ -26,6 +26,10 @@ #define BLOCK_SIZE USB_TRANSFER_BUFFER_SIZE +int g_argc = 0; +char **g_argv = NULL; +const char *g_appLaunchPath = NULL; + static Mutex g_fileMutex = 0; static CondVar g_readCondvar = 0, g_writeCondvar = 0; @@ -302,8 +306,8 @@ u8 get_program_id_offset(TitleInfo *info, u32 program_count) int main(int argc, char *argv[]) { - (void)argc; - (void)argv; + g_argc = argc; + g_argv = argv; int ret = 0; diff --git a/code_templates/xml_generator.c b/code_templates/xml_generator.c index ca50550..9c5e92d 100644 --- a/code_templates/xml_generator.c +++ b/code_templates/xml_generator.c @@ -26,6 +26,10 @@ #include "nacp.h" #include "legal_info.h" +int g_argc = 0; +char **g_argv = NULL; +const char *g_appLaunchPath = NULL; + static void consolePrint(const char *text, ...) { va_list v; @@ -48,8 +52,8 @@ static void writeFile(void *buf, size_t buf_size, const char *path) int main(int argc, char *argv[]) { - (void)argc; - (void)argv; + g_argc = argc; + g_argv = argv; int ret = 0; diff --git a/source/common.h b/source/common.h index 59972b0..afe0043 100644 --- a/source/common.h +++ b/source/common.h @@ -79,4 +79,11 @@ typedef struct { }; } VersionType2; +/// These are set in main(). +extern int g_argc; +extern char **g_argv; + +/// This is set in utilsInitializeResources(). +extern const char *g_appLaunchPath; + #endif /* __COMMON_H__ */ diff --git a/source/log.c b/source/log.c index e88bc1f..529604c 100644 --- a/source/log.c +++ b/source/log.c @@ -20,7 +20,7 @@ #include "utils.h" -#define LOG_FILE_PATH "./" APP_TITLE ".log" +#define LOG_FILE_NAME APP_TITLE ".log" #define LOG_BUF_SIZE 0x400000 /* 4 MiB. */ #define LOG_FORCE_FLUSH 0 /* Forces a log buffer flush each time the logfile is written to. */ @@ -34,19 +34,20 @@ static s64 g_logFileOffset = 0; static char *g_logBuffer = NULL; static size_t g_logBufferLength = 0; +static const char *g_utf8Bom = "\xEF\xBB\xBF"; static const char *g_logStrFormat = "[%d-%02d-%02d %02d:%02d:%02d.%lu] %s -> "; static const char *g_logLineBreak = "\r\n"; /* Function prototypes. */ -static bool logAllocateLogBuffer(void); - -static bool logOpenLogFile(void); -static void _logFlushLogFile(bool lock); - static void _logWriteStringToLogFile(const char *src, bool lock); static void _logWriteFormattedStringToLogFile(const char *func_name, const char *fmt, va_list args, bool lock); +static void _logFlushLogFile(bool lock); + +static bool logAllocateLogBuffer(void); +static bool logOpenLogFile(void); + void logWriteStringToLogFile(const char *src) { _logWriteStringToLogFile(src, true); @@ -66,7 +67,8 @@ void logWriteFormattedStringToBuffer(char **dst, size_t *dst_size, const char *f va_list args; - size_t str1_len = 0, str2_len = 0, log_str_len = 0; + int str1_len = 0, str2_len = 0; + size_t log_str_len = 0; char *dst_ptr = *dst, *tmp_str = NULL; size_t dst_cur_size = *dst_size, dst_str_len = (dst_ptr ? strlen(dst_ptr) : 0); @@ -86,12 +88,12 @@ void logWriteFormattedStringToBuffer(char **dst, size_t *dst_size, const char *f /* Get formatted string length. */ str1_len = snprintf(NULL, 0, g_logStrFormat, ts->tm_year, ts->tm_mon, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec, now.tv_nsec, func_name); - if ((int)str1_len <= 0) goto end; + if (str1_len <= 0) goto end; str2_len = vsnprintf(NULL, 0, fmt, args); - if ((int)str2_len <= 0) goto end; + if (str2_len <= 0) goto end; - log_str_len = (str1_len + str2_len + 3); + log_str_len = (size_t)(str1_len + str2_len + 3); if (!dst_cur_size || log_str_len > (dst_cur_size - dst_str_len)) { @@ -115,7 +117,7 @@ void logWriteFormattedStringToBuffer(char **dst, size_t *dst_size, const char *f /* Generate formatted string. */ sprintf(dst_ptr + dst_str_len, g_logStrFormat, ts->tm_year, ts->tm_mon, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec, now.tv_nsec, func_name); - vsprintf(dst_ptr + dst_str_len + str1_len, fmt, args); + vsprintf(dst_ptr + dst_str_len + (size_t)str1_len, fmt, args); strcat(dst_ptr, g_logLineBreak); end: @@ -198,58 +200,6 @@ void logControlMutex(bool lock) } } -static bool logAllocateLogBuffer(void) -{ - if (g_logBuffer) return true; - g_logBuffer = memalign(LOG_BUF_SIZE, LOG_BUF_SIZE); - return (g_logBuffer != NULL); -} - -static bool logOpenLogFile(void) -{ - if (serviceIsActive(&(g_logFile.s))) return true; - - Result rc = 0; - - /* Get SD card FsFileSystem object. */ - FsFileSystem *sdmc_fs = utilsGetSdCardFileSystemObject(); - if (!sdmc_fs) return false; - - /* Create file. This will fail if the logfile exists, so we don't check its return value. */ - fsFsCreateFile(sdmc_fs, LOG_FILE_PATH, 0, 0); - - /* Open file. */ - rc = fsFsOpenFile(sdmc_fs, LOG_FILE_PATH, FsOpenMode_Write | FsOpenMode_Append, &g_logFile); - if (R_SUCCEEDED(rc)) - { - /* Get file size. */ - rc = fsFileGetSize(&g_logFile, &g_logFileOffset); - if (R_FAILED(rc)) fsFileClose(&g_logFile); - } - - return R_SUCCEEDED(rc); -} - -static void _logFlushLogFile(bool lock) -{ - if (lock) mutexLock(&g_logMutex); - - if (!serviceIsActive(&(g_logFile.s)) || !g_logBuffer || !g_logBufferLength) goto end; - - /* Write log buffer contents and flush the written data right away. */ - Result rc = fsFileWrite(&g_logFile, g_logFileOffset, g_logBuffer, g_logBufferLength, FsWriteOption_Flush); - if (R_SUCCEEDED(rc)) - { - /* Update global variables. */ - g_logFileOffset += (s64)g_logBufferLength; - *g_logBuffer = '\0'; - g_logBufferLength = 0; - } - -end: - if (lock) mutexUnlock(&g_logMutex); -} - static void _logWriteStringToLogFile(const char *src, bool lock) { if (!src || !*src) return; @@ -315,7 +265,9 @@ static void _logWriteFormattedStringToLogFile(const char *func_name, const char if (lock) mutexLock(&g_logMutex); Result rc = 0; - size_t str1_len = 0, str2_len = 0, log_str_len = 0; + + int str1_len = 0, str2_len = 0; + size_t log_str_len = 0; char *tmp_str = NULL; size_t tmp_len = 0; @@ -334,12 +286,12 @@ static void _logWriteFormattedStringToLogFile(const char *func_name, const char /* Get formatted string length. */ str1_len = snprintf(NULL, 0, g_logStrFormat, ts->tm_year, ts->tm_mon, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec, now.tv_nsec, func_name); - if ((int)str1_len <= 0) goto end; + if (str1_len <= 0) goto end; str2_len = vsnprintf(NULL, 0, fmt, args); - if ((int)str2_len <= 0) goto end; + if (str2_len <= 0) goto end; - log_str_len = (str1_len + str2_len + 2); + log_str_len = (size_t)(str1_len + str2_len + 2); /* Check if the formatted string length is less than the log buffer size. */ if (log_str_len < LOG_BUF_SIZE) @@ -353,7 +305,7 @@ static void _logWriteFormattedStringToLogFile(const char *func_name, const char /* Nice and easy string formatting using the log buffer. */ sprintf(g_logBuffer + g_logBufferLength, g_logStrFormat, ts->tm_year, ts->tm_mon, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec, now.tv_nsec, func_name); - vsprintf(g_logBuffer + g_logBufferLength + str1_len, fmt, args); + vsprintf(g_logBuffer + g_logBufferLength + (size_t)str1_len, fmt, args); strcat(g_logBuffer, g_logLineBreak); g_logBufferLength += log_str_len; } else { @@ -367,7 +319,7 @@ static void _logWriteFormattedStringToLogFile(const char *func_name, const char /* Generate formatted string. */ sprintf(tmp_str, g_logStrFormat, ts->tm_year, ts->tm_mon, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec, now.tv_nsec, func_name); - vsprintf(tmp_str + str1_len, fmt, args); + vsprintf(tmp_str + (size_t)str1_len, fmt, args); strcat(tmp_str, g_logLineBreak); /* Write formatted string data until it no longer exceeds the log buffer size. */ @@ -399,3 +351,89 @@ end: if (lock) mutexUnlock(&g_logMutex); } + +static void _logFlushLogFile(bool lock) +{ + if (lock) mutexLock(&g_logMutex); + + if (!serviceIsActive(&(g_logFile.s)) || !g_logBuffer || !g_logBufferLength) goto end; + + /* Write log buffer contents and flush the written data right away. */ + Result rc = fsFileWrite(&g_logFile, g_logFileOffset, g_logBuffer, g_logBufferLength, FsWriteOption_Flush); + if (R_SUCCEEDED(rc)) + { + /* Update global variables. */ + g_logFileOffset += (s64)g_logBufferLength; + *g_logBuffer = '\0'; + g_logBufferLength = 0; + } + +end: + if (lock) mutexUnlock(&g_logMutex); +} + +static bool logAllocateLogBuffer(void) +{ + if (g_logBuffer) return true; + g_logBuffer = memalign(LOG_BUF_SIZE, LOG_BUF_SIZE); + return (g_logBuffer != NULL); +} + +static bool logOpenLogFile(void) +{ + if (serviceIsActive(&(g_logFile.s))) return true; + + Result rc = 0; + char path[FS_MAX_PATH] = {0}, *ptr1 = NULL, *ptr2 = NULL; + + /* Get SD card FsFileSystem object. */ + FsFileSystem *sdmc_fs = utilsGetSdCardFileSystemObject(); + if (!sdmc_fs) return false; + + /* Generate logfile path. */ + if (g_appLaunchPath) + { + ptr1 = strchr(g_appLaunchPath, '/'); + ptr2 = strrchr(g_appLaunchPath, '/'); + + if (ptr1 != ptr2) + { + /* Create logfile in the current working directory. */ + snprintf(path, sizeof(path), "%.*s", (int)((ptr2 - ptr1) + 1), ptr1); + + size_t path_len = strlen(path); + snprintf(path + path_len, sizeof(path) - path_len, LOG_FILE_NAME); + } else { + /* Create logfile in the SD card root directory. */ + sprintf(path, "/" LOG_FILE_NAME); + } + } else { + /* Create logfile in the SD card root directory. */ + sprintf(path, "/" LOG_FILE_NAME); + } + + /* Create file. This will fail if the logfile exists, so we don't check its return value. */ + fsFsCreateFile(sdmc_fs, path, 0, 0); + + /* Open file. */ + rc = fsFsOpenFile(sdmc_fs, path, FsOpenMode_Write | FsOpenMode_Append, &g_logFile); + if (R_SUCCEEDED(rc)) + { + /* Get file size. */ + rc = fsFileGetSize(&g_logFile, &g_logFileOffset); + if (R_SUCCEEDED(rc)) + { + /* Write UTF-8 BOM right away (if needed). */ + if (!g_logFileOffset) + { + size_t utf8_bom_len = strlen(g_utf8Bom); + fsFileWrite(&g_logFile, g_logFileOffset, g_utf8Bom, utf8_bom_len, FsWriteOption_Flush); + g_logFileOffset += (s64)utf8_bom_len; + } + } else { + fsFileClose(&g_logFile); + } + } + + return R_SUCCEEDED(rc); +} diff --git a/source/log.h b/source/log.h index 3f17bd9..9120aad 100644 --- a/source/log.h +++ b/source/log.h @@ -47,7 +47,8 @@ void logFlushLogFile(void); /// Closes the logfile. void logCloseLogFile(void); -/// (Un)locks the log mutex. Use with caution. +/// (Un)locks the log mutex. Can be used to block other threads and prevent them from writing data to the logfile. +/// Use with caution. void logControlMutex(bool lock); #endif /* __LOG_H__ */ diff --git a/source/romfs.c b/source/romfs.c index e817f55..ddd6aca 100644 --- a/source/romfs.c +++ b/source/romfs.c @@ -547,12 +547,24 @@ static RomFileSystemDirectoryEntry *romfsGetChildDirectoryEntryByName(RomFileSys size_t name_len = 0; RomFileSystemDirectoryEntry *child_dir_entry = NULL; - if (!ctx || !ctx->dir_table || !ctx->dir_table_size || !dir_entry || (dir_offset = dir_entry->directory_offset) == ROMFS_VOID_ENTRY || !name || !(name_len = strlen(name))) return NULL; + if (!ctx || !ctx->dir_table || !ctx->dir_table_size || !dir_entry || (dir_offset = dir_entry->directory_offset) == ROMFS_VOID_ENTRY || !name || !(name_len = strlen(name))) + { + LOG_MSG("Invalid parameters!"); + return NULL; + } while(dir_offset != ROMFS_VOID_ENTRY) { - if (!(child_dir_entry = romfsGetDirectoryEntryByOffset(ctx, dir_offset))) return NULL; - if (!strcmp(child_dir_entry->name, name)) return child_dir_entry; + if (!(child_dir_entry = romfsGetDirectoryEntryByOffset(ctx, dir_offset))) + { + LOG_MSG("Failed to retrieve directory entry at offset 0x%lX!", dir_offset); + break; + } + + /* strncmp() is used here instead of strcmp() because names stored in RomFS sections are not always NULL terminated. */ + /* If the name ends at a 4-byte boundary, the next entry starts immediately. */ + if (child_dir_entry->name_length == name_len && !strncmp(child_dir_entry->name, name, name_len)) return child_dir_entry; + dir_offset = child_dir_entry->next_offset; } @@ -565,13 +577,25 @@ static RomFileSystemFileEntry *romfsGetChildFileEntryByName(RomFileSystemContext size_t name_len = 0; RomFileSystemFileEntry *child_file_entry = NULL; - if (!ctx || !ctx->dir_table || !ctx->dir_table_size || !ctx->file_table || !ctx->file_table_size || !dir_entry || (file_offset = dir_entry->file_offset) == ROMFS_VOID_ENTRY || !name || \ - !(name_len = strlen(name))) return NULL; + if (!ctx || !ctx->dir_table || !ctx->dir_table_size || !ctx->file_table || !ctx->file_table_size || !dir_entry || (file_offset = dir_entry->file_offset) == ROMFS_VOID_ENTRY || \ + !name || !(name_len = strlen(name))) + { + LOG_MSG("Invalid parameters!"); + return NULL; + } while(file_offset != ROMFS_VOID_ENTRY) { - if (!(child_file_entry = romfsGetFileEntryByOffset(ctx, file_offset))) return NULL; - if (!strcmp(child_file_entry->name, name)) return child_file_entry; + if (!(child_file_entry = romfsGetFileEntryByOffset(ctx, file_offset))) + { + LOG_MSG("Failed to retrieve file entry at offset 0x%lX!", file_offset); + break; + } + + /* strncmp() is used here instead of strcmp() because names stored in RomFS sections are not always NULL terminated. */ + /* If the name ends at a 4-byte boundary, the next entry starts immediately. */ + if (child_file_entry->name_length == name_len && !strncmp(child_file_entry->name, name, name_len)) return child_file_entry; + file_offset = child_file_entry->next_offset; } diff --git a/source/usb.c b/source/usb.c index 73b309e..f854163 100644 --- a/source/usb.c +++ b/source/usb.c @@ -662,8 +662,7 @@ static bool usbSendCommand(void) UsbStatus *cmd_status = (UsbStatus*)g_usbTransferBuffer; u32 status = UsbStatusType_Success; - /* Log error message only if the USB session has been started, or if thread exit flag hasn't been enabled. */ - bool ret = false, zlt_required = false, cmd_block_written = false, log_rw_errors = (g_usbSessionStarted || !g_usbDetectionThreadExitFlag); + bool ret = false, zlt_required = false, cmd_block_written = false; if ((sizeof(UsbCommandHeader) + cmd_block_size) > USB_TRANSFER_BUFFER_SIZE) { @@ -675,7 +674,7 @@ static bool usbSendCommand(void) /* Write command header first. */ if (!usbWrite(cmd_header, sizeof(UsbCommandHeader))) { - if (log_rw_errors) LOG_MSG("Failed to write header for type 0x%X command!", cmd); + LOG_MSG("Failed to write header for type 0x%X command!", cmd); status = UsbStatusType_WriteCommandFailed; goto end; } @@ -694,7 +693,7 @@ static bool usbSendCommand(void) cmd_block_written = usbWrite(g_usbTransferBuffer, cmd_block_size); if (!cmd_block_written) { - if (log_rw_errors) LOG_MSG("Failed to write command block for type 0x%X command!", cmd); + LOG_MSG("Failed to write command block for type 0x%X command!", cmd); status = UsbStatusType_WriteCommandFailed; } @@ -708,7 +707,7 @@ static bool usbSendCommand(void) /* Read status block. */ if (!usbRead(cmd_status, sizeof(UsbStatus))) { - if (log_rw_errors) LOG_MSG("Failed to read 0x%lX bytes long status block for type 0x%X command!", sizeof(UsbStatus), cmd); + LOG_MSG("Failed to read 0x%lX bytes long status block for type 0x%X command!", sizeof(UsbStatus), cmd); status = UsbStatusType_ReadStatusFailed; goto end; } diff --git a/source/utils.c b/source/utils.c index c95770f..feee804 100644 --- a/source/utils.c +++ b/source/utils.c @@ -82,9 +82,26 @@ bool utilsInitializeResources(void) padConfigureInput(8, HidNpadStyleSet_NpadFullCtrl); padInitializeWithMask(&g_padState, 0x1000000FFUL); + /* Retrieve pointer to the application launch path. */ + if (g_argc && g_argv) + { + for(int i = 0; i < g_argc; i++) + { + if (g_argv[i] && !strncmp(g_argv[i], "sdmc:/", 6)) + { + g_appLaunchPath = (const char*)g_argv[i]; + break; + } + } + } + + /* Retrieve pointer to the SD card FsFileSystem element. */ + if (!(g_sdCardFileSystem = fsdevGetDeviceFileSystem("sdmc:"))) goto end; + /* Create logfile. */ logWriteStringToLogFile("________________________________________________________________\r\n"); LOG_MSG(APP_TITLE " v%u.%u.%u starting. Built on " __DATE__ " - " __TIME__ ".", VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO); + if (g_appLaunchPath) LOG_MSG("Launch path: \"%s\".", g_appLaunchPath); /* Log Horizon OS version. */ u32 hos_version = hosversionGet(); @@ -150,13 +167,6 @@ bool utilsInitializeResources(void) goto end; } - /* Retrieve pointer to the SD card FsFileSystem element. */ - if (!(g_sdCardFileSystem = fsdevGetDeviceFileSystem("sdmc:"))) - { - LOG_MSG("Failed to retrieve FsFileSystem from SD card!"); - goto end; - } - /* Mount eMMC BIS System partition. */ if (!utilsMountEmmcBisSystemPartitionStorage()) goto end; @@ -365,14 +375,15 @@ bool utilsAppendFormattedStringToBuffer(char **dst, size_t *dst_size, const char va_list args; - size_t formatted_str_len = 0; + int formatted_str_len = 0; + size_t formatted_str_len_cast = 0; char *dst_ptr = *dst, *tmp_str = NULL; size_t dst_cur_size = *dst_size, dst_str_len = (dst_ptr ? strlen(dst_ptr) : 0); bool success = false; - if (dst_str_len >= dst_cur_size) + if (dst_cur_size && dst_str_len >= dst_cur_size) { LOG_MSG("String length is equal to or greater than the provided buffer size! (0x%lX >= 0x%lX).", dst_str_len, dst_cur_size); return false; @@ -382,18 +393,18 @@ bool utilsAppendFormattedStringToBuffer(char **dst, size_t *dst_size, const char /* Get formatted string length. */ formatted_str_len = vsnprintf(NULL, 0, fmt, args); - if ((int)formatted_str_len <= 0) + if (formatted_str_len <= 0) { LOG_MSG("Failed to retrieve formatted string length!"); goto end; } - formatted_str_len++; + formatted_str_len_cast = (size_t)(formatted_str_len + 1); - if (!dst_cur_size || formatted_str_len > (dst_cur_size - dst_str_len)) + if (!dst_cur_size || formatted_str_len_cast > (dst_cur_size - dst_str_len)) { /* Update buffer size. */ - dst_cur_size = (dst_str_len + formatted_str_len); + dst_cur_size = (dst_str_len + formatted_str_len_cast); /* Reallocate buffer. */ tmp_str = realloc(dst_ptr, dst_cur_size); @@ -407,7 +418,7 @@ bool utilsAppendFormattedStringToBuffer(char **dst, size_t *dst_size, const char tmp_str = NULL; /* Clear allocated area. */ - memset(dst_ptr + dst_str_len, 0, formatted_str_len); + memset(dst_ptr + dst_str_len, 0, formatted_str_len_cast); /* Update pointers. */ *dst = dst_ptr;