mirror of
https://github.com/DarkMatterCore/nxdumptool.git
synced 2024-11-22 18:26:39 +00:00
Minor fixes.
* The new logfile handler should now work properly. * A UTF-8 BOM is now written at the start of every new logfile.
This commit is contained in:
parent
3bc14696ec
commit
43f744326f
15 changed files with 228 additions and 120 deletions
18
.gitignore
vendored
18
.gitignore
vendored
|
@ -1,15 +1,15 @@
|
||||||
build
|
build
|
||||||
/*.elf
|
*.elf
|
||||||
/*.nacp
|
*.nacp
|
||||||
/*.nro
|
*.nro
|
||||||
/*.nso
|
*.nso
|
||||||
/*.map
|
*.map
|
||||||
/*.pfs0
|
*.pfs0
|
||||||
/*.lst
|
*.lst
|
||||||
/*.tar.bz2
|
*.tar.bz2
|
||||||
/code_templates/tmp/*
|
/code_templates/tmp/*
|
||||||
/source/main.c
|
/source/main.c
|
||||||
/*.log
|
*.log
|
||||||
|
|
||||||
# Clion files
|
# Clion files
|
||||||
.idea
|
.idea
|
||||||
|
|
2
build.sh
2
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.nro ./code_templates/tmp/$filename/nxdumptool-rewrite.nro
|
||||||
#cp ./$filename.elf ./code_templates/tmp/$filename/nxdumptool-rewrite.elf
|
#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
|
done
|
||||||
|
|
||||||
make clean
|
make clean
|
||||||
|
|
|
@ -31,6 +31,10 @@
|
||||||
#define BLOCK_SIZE 0x800000
|
#define BLOCK_SIZE 0x800000
|
||||||
#define OUTPATH "/nsp/"
|
#define OUTPATH "/nsp/"
|
||||||
|
|
||||||
|
int g_argc = 0;
|
||||||
|
char **g_argv = NULL;
|
||||||
|
const char *g_appLaunchPath = NULL;
|
||||||
|
|
||||||
static const char *dump_type_strings[] = {
|
static const char *dump_type_strings[] = {
|
||||||
"dump base application",
|
"dump base application",
|
||||||
"dump update",
|
"dump update",
|
||||||
|
@ -748,8 +752,8 @@ end:
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
(void)argc;
|
g_argc = argc;
|
||||||
(void)argv;
|
g_argv = argv;
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,10 @@
|
||||||
|
|
||||||
#define BLOCK_SIZE 0x800000
|
#define BLOCK_SIZE 0x800000
|
||||||
|
|
||||||
|
int g_argc = 0;
|
||||||
|
char **g_argv = NULL;
|
||||||
|
const char *g_appLaunchPath = NULL;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
void *data;
|
void *data;
|
||||||
|
@ -906,8 +910,8 @@ static void nspDump(TitleInfo *title_info)
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
(void)argc;
|
g_argc = argc;
|
||||||
(void)argv;
|
g_argv = argv;
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,10 @@
|
||||||
|
|
||||||
#define BLOCK_SIZE 0x800000
|
#define BLOCK_SIZE 0x800000
|
||||||
|
|
||||||
|
int g_argc = 0;
|
||||||
|
char **g_argv = NULL;
|
||||||
|
const char *g_appLaunchPath = NULL;
|
||||||
|
|
||||||
static Mutex g_fileMutex = 0;
|
static Mutex g_fileMutex = 0;
|
||||||
static CondVar g_readCondvar = 0, g_writeCondvar = 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[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
(void)argc;
|
g_argc = argc;
|
||||||
(void)argv;
|
g_argv = argv;
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,10 @@
|
||||||
#define BLOCK_SIZE 0x800000
|
#define BLOCK_SIZE 0x800000
|
||||||
#define OUTPATH "sdmc:/systitle_dumps"
|
#define OUTPATH "sdmc:/systitle_dumps"
|
||||||
|
|
||||||
|
int g_argc = 0;
|
||||||
|
char **g_argv = NULL;
|
||||||
|
const char *g_appLaunchPath = NULL;
|
||||||
|
|
||||||
static u8 *buf = NULL;
|
static u8 *buf = NULL;
|
||||||
static FILE *filefd = NULL;
|
static FILE *filefd = NULL;
|
||||||
static char path[FS_MAX_PATH * 2] = {0};
|
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[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
(void)argc;
|
g_argc = argc;
|
||||||
(void)argv;
|
g_argv = argv;
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,10 @@
|
||||||
|
|
||||||
#define BLOCK_SIZE USB_TRANSFER_BUFFER_SIZE
|
#define BLOCK_SIZE USB_TRANSFER_BUFFER_SIZE
|
||||||
|
|
||||||
|
int g_argc = 0;
|
||||||
|
char **g_argv = NULL;
|
||||||
|
const char *g_appLaunchPath = NULL;
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
|
|
||||||
typedef void (*MenuElementOptionFunction)(u32 idx);
|
typedef void (*MenuElementOptionFunction)(u32 idx);
|
||||||
|
@ -180,8 +184,8 @@ static char path[FS_MAX_PATH] = {0};
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
(void)argc;
|
g_argc = argc;
|
||||||
(void)argv;
|
g_argv = argv;
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,10 @@
|
||||||
|
|
||||||
#define BLOCK_SIZE USB_TRANSFER_BUFFER_SIZE
|
#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 Mutex g_fileMutex = 0;
|
||||||
static CondVar g_readCondvar = 0, g_writeCondvar = 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[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
(void)argc;
|
g_argc = argc;
|
||||||
(void)argv;
|
g_argv = argv;
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,10 @@
|
||||||
#include "nacp.h"
|
#include "nacp.h"
|
||||||
#include "legal_info.h"
|
#include "legal_info.h"
|
||||||
|
|
||||||
|
int g_argc = 0;
|
||||||
|
char **g_argv = NULL;
|
||||||
|
const char *g_appLaunchPath = NULL;
|
||||||
|
|
||||||
static void consolePrint(const char *text, ...)
|
static void consolePrint(const char *text, ...)
|
||||||
{
|
{
|
||||||
va_list v;
|
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[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
(void)argc;
|
g_argc = argc;
|
||||||
(void)argv;
|
g_argv = argv;
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
|
|
@ -79,4 +79,11 @@ typedef struct {
|
||||||
};
|
};
|
||||||
} VersionType2;
|
} 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__ */
|
#endif /* __COMMON_H__ */
|
||||||
|
|
176
source/log.c
176
source/log.c
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
#include "utils.h"
|
#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_BUF_SIZE 0x400000 /* 4 MiB. */
|
||||||
#define LOG_FORCE_FLUSH 0 /* Forces a log buffer flush each time the logfile is written to. */
|
#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 char *g_logBuffer = NULL;
|
||||||
static size_t g_logBufferLength = 0;
|
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_logStrFormat = "[%d-%02d-%02d %02d:%02d:%02d.%lu] %s -> ";
|
||||||
static const char *g_logLineBreak = "\r\n";
|
static const char *g_logLineBreak = "\r\n";
|
||||||
|
|
||||||
/* Function prototypes. */
|
/* 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 _logWriteStringToLogFile(const char *src, bool lock);
|
||||||
static void _logWriteFormattedStringToLogFile(const char *func_name, const char *fmt, va_list args, 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)
|
void logWriteStringToLogFile(const char *src)
|
||||||
{
|
{
|
||||||
_logWriteStringToLogFile(src, true);
|
_logWriteStringToLogFile(src, true);
|
||||||
|
@ -66,7 +67,8 @@ void logWriteFormattedStringToBuffer(char **dst, size_t *dst_size, const char *f
|
||||||
|
|
||||||
va_list args;
|
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;
|
char *dst_ptr = *dst, *tmp_str = NULL;
|
||||||
size_t dst_cur_size = *dst_size, dst_str_len = (dst_ptr ? strlen(dst_ptr) : 0);
|
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. */
|
/* 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);
|
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);
|
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))
|
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. */
|
/* 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);
|
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);
|
strcat(dst_ptr, g_logLineBreak);
|
||||||
|
|
||||||
end:
|
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)
|
static void _logWriteStringToLogFile(const char *src, bool lock)
|
||||||
{
|
{
|
||||||
if (!src || !*src) return;
|
if (!src || !*src) return;
|
||||||
|
@ -315,7 +265,9 @@ static void _logWriteFormattedStringToLogFile(const char *func_name, const char
|
||||||
if (lock) mutexLock(&g_logMutex);
|
if (lock) mutexLock(&g_logMutex);
|
||||||
|
|
||||||
Result rc = 0;
|
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;
|
char *tmp_str = NULL;
|
||||||
size_t tmp_len = 0;
|
size_t tmp_len = 0;
|
||||||
|
@ -334,12 +286,12 @@ static void _logWriteFormattedStringToLogFile(const char *func_name, const char
|
||||||
|
|
||||||
/* Get formatted string length. */
|
/* 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);
|
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);
|
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. */
|
/* Check if the formatted string length is less than the log buffer size. */
|
||||||
if (log_str_len < LOG_BUF_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. */
|
/* 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);
|
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);
|
strcat(g_logBuffer, g_logLineBreak);
|
||||||
g_logBufferLength += log_str_len;
|
g_logBufferLength += log_str_len;
|
||||||
} else {
|
} else {
|
||||||
|
@ -367,7 +319,7 @@ static void _logWriteFormattedStringToLogFile(const char *func_name, const char
|
||||||
|
|
||||||
/* Generate formatted string. */
|
/* 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);
|
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);
|
strcat(tmp_str, g_logLineBreak);
|
||||||
|
|
||||||
/* Write formatted string data until it no longer exceeds the log buffer size. */
|
/* Write formatted string data until it no longer exceeds the log buffer size. */
|
||||||
|
@ -399,3 +351,89 @@ end:
|
||||||
|
|
||||||
if (lock) mutexUnlock(&g_logMutex);
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -47,7 +47,8 @@ void logFlushLogFile(void);
|
||||||
/// Closes the logfile.
|
/// Closes the logfile.
|
||||||
void logCloseLogFile(void);
|
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);
|
void logControlMutex(bool lock);
|
||||||
|
|
||||||
#endif /* __LOG_H__ */
|
#endif /* __LOG_H__ */
|
||||||
|
|
|
@ -547,12 +547,24 @@ static RomFileSystemDirectoryEntry *romfsGetChildDirectoryEntryByName(RomFileSys
|
||||||
size_t name_len = 0;
|
size_t name_len = 0;
|
||||||
RomFileSystemDirectoryEntry *child_dir_entry = NULL;
|
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)
|
while(dir_offset != ROMFS_VOID_ENTRY)
|
||||||
{
|
{
|
||||||
if (!(child_dir_entry = romfsGetDirectoryEntryByOffset(ctx, dir_offset))) return NULL;
|
if (!(child_dir_entry = romfsGetDirectoryEntryByOffset(ctx, dir_offset)))
|
||||||
if (!strcmp(child_dir_entry->name, name)) return child_dir_entry;
|
{
|
||||||
|
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;
|
dir_offset = child_dir_entry->next_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,13 +577,25 @@ static RomFileSystemFileEntry *romfsGetChildFileEntryByName(RomFileSystemContext
|
||||||
size_t name_len = 0;
|
size_t name_len = 0;
|
||||||
RomFileSystemFileEntry *child_file_entry = NULL;
|
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 || \
|
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_len = strlen(name))) return NULL;
|
!name || !(name_len = strlen(name)))
|
||||||
|
{
|
||||||
|
LOG_MSG("Invalid parameters!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
while(file_offset != ROMFS_VOID_ENTRY)
|
while(file_offset != ROMFS_VOID_ENTRY)
|
||||||
{
|
{
|
||||||
if (!(child_file_entry = romfsGetFileEntryByOffset(ctx, file_offset))) return NULL;
|
if (!(child_file_entry = romfsGetFileEntryByOffset(ctx, file_offset)))
|
||||||
if (!strcmp(child_file_entry->name, name)) return child_file_entry;
|
{
|
||||||
|
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;
|
file_offset = child_file_entry->next_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -662,8 +662,7 @@ static bool usbSendCommand(void)
|
||||||
UsbStatus *cmd_status = (UsbStatus*)g_usbTransferBuffer;
|
UsbStatus *cmd_status = (UsbStatus*)g_usbTransferBuffer;
|
||||||
u32 status = UsbStatusType_Success;
|
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;
|
||||||
bool ret = false, zlt_required = false, cmd_block_written = false, log_rw_errors = (g_usbSessionStarted || !g_usbDetectionThreadExitFlag);
|
|
||||||
|
|
||||||
if ((sizeof(UsbCommandHeader) + cmd_block_size) > USB_TRANSFER_BUFFER_SIZE)
|
if ((sizeof(UsbCommandHeader) + cmd_block_size) > USB_TRANSFER_BUFFER_SIZE)
|
||||||
{
|
{
|
||||||
|
@ -675,7 +674,7 @@ static bool usbSendCommand(void)
|
||||||
/* Write command header first. */
|
/* Write command header first. */
|
||||||
if (!usbWrite(cmd_header, sizeof(UsbCommandHeader)))
|
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;
|
status = UsbStatusType_WriteCommandFailed;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
@ -694,7 +693,7 @@ static bool usbSendCommand(void)
|
||||||
cmd_block_written = usbWrite(g_usbTransferBuffer, cmd_block_size);
|
cmd_block_written = usbWrite(g_usbTransferBuffer, cmd_block_size);
|
||||||
if (!cmd_block_written)
|
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;
|
status = UsbStatusType_WriteCommandFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -708,7 +707,7 @@ static bool usbSendCommand(void)
|
||||||
/* Read status block. */
|
/* Read status block. */
|
||||||
if (!usbRead(cmd_status, sizeof(UsbStatus)))
|
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;
|
status = UsbStatusType_ReadStatusFailed;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,9 +82,26 @@ bool utilsInitializeResources(void)
|
||||||
padConfigureInput(8, HidNpadStyleSet_NpadFullCtrl);
|
padConfigureInput(8, HidNpadStyleSet_NpadFullCtrl);
|
||||||
padInitializeWithMask(&g_padState, 0x1000000FFUL);
|
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. */
|
/* Create logfile. */
|
||||||
logWriteStringToLogFile("________________________________________________________________\r\n");
|
logWriteStringToLogFile("________________________________________________________________\r\n");
|
||||||
LOG_MSG(APP_TITLE " v%u.%u.%u starting. Built on " __DATE__ " - " __TIME__ ".", VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO);
|
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. */
|
/* Log Horizon OS version. */
|
||||||
u32 hos_version = hosversionGet();
|
u32 hos_version = hosversionGet();
|
||||||
|
@ -150,13 +167,6 @@ bool utilsInitializeResources(void)
|
||||||
goto end;
|
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. */
|
/* Mount eMMC BIS System partition. */
|
||||||
if (!utilsMountEmmcBisSystemPartitionStorage()) goto end;
|
if (!utilsMountEmmcBisSystemPartitionStorage()) goto end;
|
||||||
|
|
||||||
|
@ -365,14 +375,15 @@ bool utilsAppendFormattedStringToBuffer(char **dst, size_t *dst_size, const char
|
||||||
|
|
||||||
va_list args;
|
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;
|
char *dst_ptr = *dst, *tmp_str = NULL;
|
||||||
size_t dst_cur_size = *dst_size, dst_str_len = (dst_ptr ? strlen(dst_ptr) : 0);
|
size_t dst_cur_size = *dst_size, dst_str_len = (dst_ptr ? strlen(dst_ptr) : 0);
|
||||||
|
|
||||||
bool success = false;
|
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);
|
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;
|
return false;
|
||||||
|
@ -382,18 +393,18 @@ bool utilsAppendFormattedStringToBuffer(char **dst, size_t *dst_size, const char
|
||||||
|
|
||||||
/* Get formatted string length. */
|
/* Get formatted string length. */
|
||||||
formatted_str_len = vsnprintf(NULL, 0, fmt, args);
|
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!");
|
LOG_MSG("Failed to retrieve formatted string length!");
|
||||||
goto end;
|
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. */
|
/* Update buffer size. */
|
||||||
dst_cur_size = (dst_str_len + formatted_str_len);
|
dst_cur_size = (dst_str_len + formatted_str_len_cast);
|
||||||
|
|
||||||
/* Reallocate buffer. */
|
/* Reallocate buffer. */
|
||||||
tmp_str = realloc(dst_ptr, dst_cur_size);
|
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;
|
tmp_str = NULL;
|
||||||
|
|
||||||
/* Clear allocated area. */
|
/* 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. */
|
/* Update pointers. */
|
||||||
*dst = dst_ptr;
|
*dst = dst_ptr;
|
||||||
|
|
Loading…
Reference in a new issue