From 0dfc49c800d313d2ddeb7922c1841f6327ba00bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauri=20Kentt=C3=A4?= Date: Mon, 20 Nov 2023 16:05:33 +0200 Subject: [PATCH] Re-implement string formatting (%s, %d, %x) --- src/config.c | 2 +- src/main.c | 18 +++++------ src/util.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++------ src/util.h | 7 +++-- 4 files changed, 93 insertions(+), 22 deletions(-) diff --git a/src/config.c b/src/config.c index e478436..90814dc 100644 --- a/src/config.c +++ b/src/config.c @@ -74,7 +74,7 @@ static void SetBMPWithRandom(struct HackBGRT_config* config, int weight, enum Ha config->image_weight_sum += weight; UINT32 random = Random(); UINT32 limit = 0xfffffffful / config->image_weight_sum * weight; - Log(config->debug, L"HackBGRT: n=%d, action=%d, x=%d, y=%d, o=%d, path=%s, random = %08x, limit = %08x\n", weight, action, x, y, o, path, random, limit); + Log(config->debug, L"HackBGRT: n=%d, action=%d, x=%d, y=%d, o=%d, path=%s, random = %x, limit = %x\n", weight, action, x, y, o, path, random, limit); if (!config->image_weight_sum || random <= limit) { config->action = action; config->image_path = path; diff --git a/src/main.c b/src/main.c index 9734f09..355f6e0 100644 --- a/src/main.c +++ b/src/main.c @@ -432,7 +432,7 @@ EFI_STATUS EFIAPI EfiMain(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *ST_) { ReadConfigLine(&config, root_dir, argv[i]); } if (config.debug) { - Print(L"HackBGRT version: %s\n", version); + Log(-1, L"HackBGRT version: %s\n", version); } SetResolution(config.resolution_x, config.resolution_y); @@ -461,14 +461,14 @@ EFI_STATUS EFIAPI EfiMain(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *ST_) { goto ready_to_boot; } Log(1, L"HackBGRT: Reverting to %s.\n", config.boot_path); - Print(L"Press escape to cancel or any other key (or wait 15 seconds) to boot.\n"); + Log(-1, L"Press escape to cancel or any other key (or wait 15 seconds) to boot.\n"); if (ReadKey(15000).ScanCode == SCAN_ESC) { goto fail; } } else ready_to_boot: if (config.debug) { - Print(L"HackBGRT: Ready to boot.\n"); - Print(L"If all goes well, you can set debug=0 and log=0 in config.txt.\n"); - Print(L"Press escape to cancel or any other key (or wait 15 seconds) to boot.\n"); + Log(-1, L"HackBGRT: Ready to boot.\n"); + Log(-1, L"If all goes well, you can set debug=0 and log=0 in config.txt.\n"); + Log(-1, L"Press escape to cancel or any other key (or wait 15 seconds) to boot.\n"); if (ReadKey(15000).ScanCode == SCAN_ESC) { return 0; } @@ -481,15 +481,15 @@ EFI_STATUS EFIAPI EfiMain(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *ST_) { goto fail; } Log(1, L"HackBGRT: Started %s. Why are we still here?!\n", config.boot_path); - Print(L"Please check that %s is not actually HackBGRT!\n", config.boot_path); + Log(-1, L"Please check that %s is not actually HackBGRT!\n", config.boot_path); goto fail; fail: { Log(1, L"HackBGRT has failed.\n"); - Print(L"Dumping log:\n\n"); + Log(-1, L"Dumping log:\n\n"); DumpLog(); - Print(L"If you can't boot into Windows, get install/recovery disk to fix your boot.\n"); - Print(L"Press any key (or wait 15 seconds) to exit.\n"); + Log(-1, L"If you can't boot into Windows, get install/recovery disk to fix your boot.\n"); + Log(-1, L"Press any key (or wait 15 seconds) to exit.\n"); ReadKey(15000); return 1; } diff --git a/src/util.c b/src/util.c index 286c37b..9368b6f 100644 --- a/src/util.c +++ b/src/util.c @@ -14,31 +14,99 @@ const CHAR16* TmpStr(CHAR8 *src, int length) { return dest; } +const CHAR16* TmpIntToStr(UINT32 x) { + static CHAR16 buf[20]; + int i = 20 - 1; + buf[i] = 0; + if (!x) { + buf[--i] = '0'; + } + while (x && i) { + buf[--i] = '0' + (x % 10); + x /= 10; + } + return &buf[i]; +} + #define log_buffer_size (65536) CHAR16 log_buffer[log_buffer_size] = {0}; CHAR16 LogVarName[] = L"HackBGRTLog"; EFI_GUID LogVarGuid = {0x03c64761, 0x075f, 0x4dba, {0xab, 0xfb, 0x2e, 0xd8, 0x9e, 0x18, 0xb2, 0x36}}; // self-made: 03c64761-075f-4dba-abfb-2ed89e18b236 -void Log(int print, IN CONST CHAR16 *fmt, ...) { +void Log(int mode, IN CONST CHAR16 *fmt, ...) { va_list args; - CHAR16 buf[256]; + CHAR16 buf[256] = {0}; + int buf_i = 0; + #define putchar(c) { if (buf_i < 255) { buf[buf_i++] = c; } } va_start(args, fmt); - VSPrint(buf, sizeof(buf), fmt, args); // size is in bytes, not CHAR16s - va_end(args); - if (print) { - Print(L"%s", buf); + for (int i = 0; fmt[i]; ++i) { + if (fmt[i] == '\n') { + putchar('\r'); + putchar('\n'); + continue; + } + if (fmt[i] != '%') { + putchar(fmt[i]); + continue; + } + ++i; + switch (fmt[i]) { + case '%': putchar('%'); continue; + case 'd': goto fmt_decimal; + case 'x': goto fmt_hex; + case 's': goto fmt_string; + case 0: goto fmt_end; + } + putchar('%'); + putchar(fmt[i]); + continue; + + if (0) fmt_decimal: { + INT32 x = va_arg(args, INT32); + if (x < 0) { + putchar('-'); + x = -x; + } + const CHAR16* s = TmpIntToStr(x); + while (*s) { + putchar(*s++); + } + } + if (0) fmt_hex: { + UINT32 x = va_arg(args, UINT32); + for (int pos = 8, started = 0; pos--;) { + int d = (x >> (4 * pos)) & 0xf; + if (d || started || pos == 0) { + putchar("0123456789abcdef"[d]); + started = 1; + } + } + } + if (0) fmt_string: { + CHAR16* s = va_arg(args, CHAR16*); + while (*s) { + putchar(*s++); + } + } + } + fmt_end: + va_end(args); + if (mode) { + ST->ConOut->OutputString(ST->ConOut, buf); + } + if (mode != -1) { + StrnCat(log_buffer, buf, log_buffer_size - StrLen(log_buffer) - 1); + RT->SetVariable(LogVarName, &LogVarGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, StrLen(log_buffer) * 2, log_buffer); } - StrnCat(log_buffer, buf, log_buffer_size - StrLen(log_buffer) - 1); - LibSetVariable(LogVarName, &LogVarGuid, StrLen(log_buffer) * 2, log_buffer); } void DumpLog(void) { - Print(L"%s", log_buffer); + ST->ConOut->OutputString(ST->ConOut, log_buffer); } void ClearLogVariable(void) { - LibDeleteVariable(LogVarName, &LogVarGuid); + RT->SetVariable(LogVarName, &LogVarGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 0, 0); } const CHAR16* TrimLeft(const CHAR16* s) { diff --git a/src/util.h b/src/util.h index 95b168c..8ed7847 100644 --- a/src/util.h +++ b/src/util.h @@ -12,9 +12,12 @@ extern const CHAR16* TmpStr(CHAR8 *src, int length); /** - * Empty function that has the same signature as Print. + * Print or log a string. + * + * @param mode -1 = print without logging, 0 = no, 1 = yes. + * @param fmt The format string. Supports %d, %x, %s. */ -extern void Log(int print, IN CONST CHAR16 *fmt, ...); +extern void Log(int mode, IN CONST CHAR16 *fmt, ...); /** * Dump the log buffer to the screen.