mirror of
https://github.com/Metabolix/HackBGRT.git
synced 2025-12-06 17:15:42 -08:00
Gather log during boot
This commit is contained in:
@@ -48,6 +48,7 @@ Instructions for enrolling the certificate (if it's possible at all) depend on y
|
||||
* `allow-bad-loader` – ignore bad boot loader configuration in subsequent commands.
|
||||
* `disable` – run all relevant `disable-*` commands.
|
||||
* `uninstall` – disable and remove completely.
|
||||
* `show-boot-log` – show the debug log collected during boot (if `log=1` is set in `config.txt`).
|
||||
* For example, run `setup.exe batch install allow-secure-boot enable-overwrite` to copy files and overwrite the MS boot loader regardless of Secure Boot status.
|
||||
|
||||
### Multi-boot configurations
|
||||
|
||||
@@ -38,6 +38,11 @@ image= y=-200 path=\EFI\HackBGRT\splash.bmp
|
||||
# Preferred resolution. Use 0x0 for maximum and -1x-1 for original.
|
||||
resolution=0x0
|
||||
|
||||
# Logging (0 for disabled, 1 for enabled).
|
||||
# When logging is enabled, setup.exe can show debug information about the current boot.
|
||||
# The log might occupy a few kilobytes of RAM.
|
||||
log=1
|
||||
|
||||
# Debug mode (0 for disabled, 1 for enabled).
|
||||
# Shows debug information and prompts for keypress before booting.
|
||||
debug=0
|
||||
|
||||
23
src/Efi.cs
23
src/Efi.cs
@@ -139,8 +139,19 @@ public class Efi {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GUID of the global EFI variables.
|
||||
*/
|
||||
public const string EFI_GLOBAL_GUID = "{8be4df61-93ca-11d2-aa0d-00e098032b8c}";
|
||||
|
||||
/**
|
||||
* GUID for HackBGRT EFI variables.
|
||||
*/
|
||||
public const string EFI_HACKBGRT_GUID = "{03c64761-075f-4dba-abfb-2ed89e18b236}";
|
||||
|
||||
/**
|
||||
* Directory containing EFI variables in Linux.
|
||||
*/
|
||||
public const string LinuxEfiDir = "/sys/firmware/efi/efivars";
|
||||
|
||||
/**
|
||||
@@ -471,6 +482,18 @@ public class Efi {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve HackBGRT log collected during boot.
|
||||
*/
|
||||
public static string GetHackBGRTLog() {
|
||||
try {
|
||||
var log = GetVariable("HackBGRTLog", EFI_HACKBGRT_GUID);
|
||||
return new string(BytesToUInt16s(log.Data).Select(i => (char)i).ToArray());
|
||||
} catch (Exception e) {
|
||||
return $"Log not found: {e.ToString()}";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log the BGRT table (for debugging).
|
||||
*/
|
||||
|
||||
10
src/Setup.cs
10
src/Setup.cs
@@ -69,6 +69,7 @@ public class Setup {
|
||||
"disable",
|
||||
"uninstall",
|
||||
"boot-to-fw",
|
||||
"show-boot-log",
|
||||
};
|
||||
|
||||
/** @var The target directory. */
|
||||
@@ -751,6 +752,7 @@ public class Setup {
|
||||
WriteLine(" B = boot to UEFI setup");
|
||||
WriteLine(" - lets you disable Secure Boot");
|
||||
WriteLine(" - lets you move HackBGRT before Windows in boot order");
|
||||
WriteLine(" L = show boot log (what HackBGRT did during boot)");
|
||||
WriteLine(" C = cancel");
|
||||
|
||||
var k = Console.ReadKey().Key;
|
||||
@@ -773,6 +775,8 @@ public class Setup {
|
||||
RunPrivilegedActions(new string[] { "uninstall" });
|
||||
} else if (k == ConsoleKey.B) {
|
||||
RunPrivilegedActions(new string[] { "boot-to-fw" });
|
||||
} else if (k == ConsoleKey.L) {
|
||||
RunPrivilegedActions(new string[] { "show-boot-log" });
|
||||
} else if (k == ConsoleKey.C) {
|
||||
throw new ExitSetup(1);
|
||||
} else {
|
||||
@@ -806,6 +810,8 @@ public class Setup {
|
||||
|
||||
InitEspPath();
|
||||
InitEspInfo();
|
||||
var bootLog = $"\n--- BOOT LOG START ---\n{Efi.GetHackBGRTLog()}\n--- BOOT LOG END ---";
|
||||
Setup.Log(bootLog);
|
||||
Efi.LogBGRT();
|
||||
Efi.LogBootEntries();
|
||||
if (GetBootTime() is DateTime bootTime) {
|
||||
@@ -869,6 +875,8 @@ public class Setup {
|
||||
Uninstall();
|
||||
} else if (arg == "boot-to-fw") {
|
||||
BootToFW();
|
||||
} else if (arg == "show-boot-log") {
|
||||
WriteLine(bootLog);
|
||||
} else {
|
||||
throw new SetupException($"Invalid action: '{arg}'!");
|
||||
}
|
||||
@@ -934,7 +942,7 @@ public class Setup {
|
||||
WriteLine("This was a dry run, your system was not actually modified.");
|
||||
}
|
||||
if (!Batch) {
|
||||
WriteLine("If you need to report a bug, please include the setup.log file.");
|
||||
WriteLine("If you need to report a bug,\n - run this setup again with menu option L (show-boot-log)\n - then include the setup.log file with your report.");
|
||||
WriteLine("Press any key to quit.");
|
||||
Console.ReadKey();
|
||||
}
|
||||
|
||||
16
src/config.c
16
src/config.c
@@ -8,7 +8,7 @@ BOOLEAN ReadConfigFile(struct HackBGRT_config* config, EFI_FILE_HANDLE root_dir,
|
||||
UINTN data_bytes = 0;
|
||||
data = LoadFileWithPadding(root_dir, path, &data_bytes, 4);
|
||||
if (!data) {
|
||||
Print(L"HackBGRT: Failed to load configuration (%s)!\n", path);
|
||||
Log(1, L"HackBGRT: Failed to load configuration (%s)!\n", path);
|
||||
return FALSE;
|
||||
}
|
||||
CHAR16* str;
|
||||
@@ -74,9 +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;
|
||||
if (config->debug) {
|
||||
Print(L"HackBGRT: weight %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 = %08x, limit = %08x\n", weight, action, x, y, o, path, random, limit);
|
||||
if (!config->image_weight_sum || random <= limit) {
|
||||
config->action = action;
|
||||
config->image_path = path;
|
||||
@@ -112,7 +110,7 @@ static void ReadConfigImage(struct HackBGRT_config* config, const CHAR16* line)
|
||||
} else if (StrStr(line, L"keep")) {
|
||||
action = HackBGRT_KEEP;
|
||||
} else {
|
||||
Print(L"HackBGRT: Invalid image line: %s\n", line);
|
||||
Log(1, L"HackBGRT: Invalid image line: %s\n", line);
|
||||
return;
|
||||
}
|
||||
int weight = n && (!f || n < f) ? Atoi(n) : 1;
|
||||
@@ -129,7 +127,7 @@ static void ReadConfigResolution(struct HackBGRT_config* config, const CHAR16* l
|
||||
config->resolution_x = *x == '-' ? -(int)Atoi(x+1) : (int)Atoi(x);
|
||||
config->resolution_y = *y == '-' ? -(int)Atoi(y+1) : (int)Atoi(y);
|
||||
} else {
|
||||
Print(L"HackBGRT: Invalid resolution line: %s\n", line);
|
||||
Log(1, L"HackBGRT: Invalid resolution line: %s\n", line);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,6 +141,10 @@ void ReadConfigLine(struct HackBGRT_config* config, EFI_FILE_HANDLE root_dir, co
|
||||
config->debug = (StrCmp(line, L"debug=1") == 0);
|
||||
return;
|
||||
}
|
||||
if (StrnCmp(line, L"log=", 4) == 0) {
|
||||
config->log = (StrCmp(line, L"log=1") == 0);
|
||||
return;
|
||||
}
|
||||
if (StrnCmp(line, L"image=", 6) == 0) {
|
||||
ReadConfigImage(config, line + 6);
|
||||
return;
|
||||
@@ -159,5 +161,5 @@ void ReadConfigLine(struct HackBGRT_config* config, EFI_FILE_HANDLE root_dir, co
|
||||
ReadConfigResolution(config, line + 11);
|
||||
return;
|
||||
}
|
||||
Print(L"Unknown configuration directive: %s\n", line);
|
||||
Log(1, L"Unknown configuration directive: %s\n", line);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ enum HackBGRT_coordinate {
|
||||
* The configuration.
|
||||
*/
|
||||
struct HackBGRT_config {
|
||||
int debug;
|
||||
int debug, log;
|
||||
enum HackBGRT_action action;
|
||||
const CHAR16* image_path;
|
||||
int image_x;
|
||||
|
||||
112
src/main.c
112
src/main.c
@@ -6,20 +6,20 @@
|
||||
#include "util.h"
|
||||
|
||||
/**
|
||||
* The Print function signature.
|
||||
* The version.
|
||||
*/
|
||||
typedef UINTN print_t(IN CONST CHAR16 *fmt, ...);
|
||||
|
||||
/**
|
||||
* The function for debug printing; either Print or NullPrint.
|
||||
*/
|
||||
print_t* Debug = NullPrint;
|
||||
#ifdef GIT_DESCRIBE_W
|
||||
const CHAR16 version[] = GIT_DESCRIBE_W;
|
||||
#else
|
||||
const CHAR16 version[] = L"unknown; not an official release?";
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The configuration.
|
||||
*/
|
||||
static struct HackBGRT_config config = {
|
||||
.action = HackBGRT_KEEP
|
||||
.log = 1,
|
||||
.action = HackBGRT_KEEP,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -45,7 +45,7 @@ static void SetResolution(int w, int h) {
|
||||
if (!gop) {
|
||||
config.old_resolution_x = config.resolution_x = 0;
|
||||
config.old_resolution_y = config.resolution_y = 0;
|
||||
Debug(L"GOP not found!\n");
|
||||
Log(config.debug, L"GOP not found!\n");
|
||||
return;
|
||||
}
|
||||
UINTN best_i = gop->Mode->Mode;
|
||||
@@ -54,7 +54,7 @@ static void SetResolution(int w, int h) {
|
||||
w = (w <= 0 ? w < 0 ? best_w : 999999 : w);
|
||||
h = (h <= 0 ? h < 0 ? best_h : 999999 : h);
|
||||
|
||||
Debug(L"Looking for resolution %dx%d...\n", w, h);
|
||||
Log(config.debug, L"Looking for resolution %dx%d...\n", w, h);
|
||||
for (UINT32 i = gop->Mode->MaxMode; i--;) {
|
||||
int new_w = 0, new_h = 0;
|
||||
|
||||
@@ -87,7 +87,7 @@ static void SetResolution(int w, int h) {
|
||||
best_h = new_h;
|
||||
best_i = i;
|
||||
}
|
||||
Debug(L"Found resolution %dx%d.\n", best_w, best_h);
|
||||
Log(config.debug, L"Found resolution %dx%d.\n", best_w, best_h);
|
||||
config.resolution_x = best_w;
|
||||
config.resolution_y = best_h;
|
||||
if (best_i != gop->Mode->Mode) {
|
||||
@@ -107,7 +107,7 @@ ACPI_SDT_HEADER* CreateXsdt(ACPI_SDT_HEADER* xsdt0, UINTN entries) {
|
||||
UINT32 xsdt_len = sizeof(ACPI_SDT_HEADER) + entries * sizeof(UINT64);
|
||||
BS->AllocatePool(EfiACPIReclaimMemory, xsdt_len, (void**)&xsdt);
|
||||
if (!xsdt) {
|
||||
Print(L"HackBGRT: Failed to allocate memory for XSDT.\n");
|
||||
Log(1, L"HackBGRT: Failed to allocate memory for XSDT.\n");
|
||||
return 0;
|
||||
}
|
||||
ZeroMem(xsdt, xsdt_len);
|
||||
@@ -139,17 +139,17 @@ static ACPI_BGRT* HandleAcpiTables(enum HackBGRT_action action, ACPI_BGRT* bgrt)
|
||||
if (CompareMem(rsdp->signature, "RSD PTR ", 8) != 0 || rsdp->revision < 2 || !VerifyAcpiRsdp2Checksums(rsdp)) {
|
||||
continue;
|
||||
}
|
||||
Debug(L"RSDP @%x: revision = %d, OEM ID = %s\n", (UINTN)rsdp, rsdp->revision, TmpStr(rsdp->oem_id, 6));
|
||||
Log(config.debug, L"RSDP @%x: revision = %d, OEM ID = %s\n", (UINTN)rsdp, rsdp->revision, TmpStr(rsdp->oem_id, 6));
|
||||
|
||||
ACPI_SDT_HEADER* xsdt = (ACPI_SDT_HEADER *) (UINTN) rsdp->xsdt_address;
|
||||
if (!xsdt || CompareMem(xsdt->signature, "XSDT", 4) != 0 || !VerifyAcpiSdtChecksum(xsdt)) {
|
||||
Debug(L"* XSDT: missing or invalid\n");
|
||||
Log(config.debug, L"* XSDT: missing or invalid\n");
|
||||
continue;
|
||||
}
|
||||
UINT64* entry_arr = (UINT64*)&xsdt[1];
|
||||
UINT32 entry_arr_length = (xsdt->length - sizeof(*xsdt)) / sizeof(UINT64);
|
||||
|
||||
Debug(L"* XSDT @%x: OEM ID = %s, entry count = %d\n", (UINTN)xsdt, TmpStr(xsdt->oem_id, 6), entry_arr_length);
|
||||
Log(config.debug, L"* XSDT @%x: OEM ID = %s, entry count = %d\n", (UINTN)xsdt, TmpStr(xsdt->oem_id, 6), entry_arr_length);
|
||||
|
||||
int bgrt_count = 0;
|
||||
for (int j = 0; j < entry_arr_length; j++) {
|
||||
@@ -157,16 +157,16 @@ static ACPI_BGRT* HandleAcpiTables(enum HackBGRT_action action, ACPI_BGRT* bgrt)
|
||||
if (CompareMem(entry->signature, "BGRT", 4) != 0) {
|
||||
continue;
|
||||
}
|
||||
Debug(L" - ACPI table @%x: %s, revision = %d, OEM ID = %s\n", (UINTN)entry, TmpStr(entry->signature, 4), entry->revision, TmpStr(entry->oem_id, 6));
|
||||
Log(config.debug, L" - ACPI table @%x: %s, revision = %d, OEM ID = %s\n", (UINTN)entry, TmpStr(entry->signature, 4), entry->revision, TmpStr(entry->oem_id, 6));
|
||||
switch (action) {
|
||||
case HackBGRT_KEEP:
|
||||
if (!bgrt) {
|
||||
Debug(L" -> Returning this one for later use.\n");
|
||||
Log(config.debug, L" -> Returning this one for later use.\n");
|
||||
bgrt = (ACPI_BGRT*) entry;
|
||||
}
|
||||
break;
|
||||
case HackBGRT_REMOVE:
|
||||
Debug(L" -> Deleting.\n");
|
||||
Log(config.debug, L" -> Deleting.\n");
|
||||
for (int k = j+1; k < entry_arr_length; ++k) {
|
||||
entry_arr[k-1] = entry_arr[k];
|
||||
}
|
||||
@@ -176,13 +176,13 @@ static ACPI_BGRT* HandleAcpiTables(enum HackBGRT_action action, ACPI_BGRT* bgrt)
|
||||
--j;
|
||||
break;
|
||||
case HackBGRT_REPLACE:
|
||||
Debug(L" -> Replacing.\n");
|
||||
Log(config.debug, L" -> Replacing.\n");
|
||||
entry_arr[j] = (UINTN) bgrt;
|
||||
}
|
||||
bgrt_count += 1;
|
||||
}
|
||||
if (!bgrt_count && action == HackBGRT_REPLACE && bgrt) {
|
||||
Debug(L" - Adding missing BGRT.\n");
|
||||
Log(config.debug, L" - Adding missing BGRT.\n");
|
||||
xsdt = CreateXsdt(xsdt, entry_arr_length + 1);
|
||||
entry_arr = (UINT64*)&xsdt[1];
|
||||
entry_arr[entry_arr_length++] = (UINTN) bgrt;
|
||||
@@ -208,7 +208,7 @@ static BMP* MakeBMP(int w, int h, UINT8 r, UINT8 g, UINT8 b) {
|
||||
BMP* bmp = 0;
|
||||
BS->AllocatePool(EfiBootServicesData, 54 + w * h * 4, (void**) &bmp);
|
||||
if (!bmp) {
|
||||
Print(L"HackBGRT: Failed to allocate a blank BMP!\n");
|
||||
Log(1, L"HackBGRT: Failed to allocate a blank BMP!\n");
|
||||
BS->Stall(1000000);
|
||||
return 0;
|
||||
}
|
||||
@@ -243,7 +243,7 @@ static BMP* LoadBMP(EFI_FILE_HANDLE root_dir, const CHAR16* path) {
|
||||
if (!path) {
|
||||
return MakeBMP(1, 1, 0, 0, 0); // empty path = black image
|
||||
}
|
||||
Debug(L"HackBGRT: Loading %s.\n", path);
|
||||
Log(config.debug, L"HackBGRT: Loading %s.\n", path);
|
||||
UINTN size = 0;
|
||||
BMP* bmp = LoadFile(root_dir, path, &size);
|
||||
if (bmp) {
|
||||
@@ -251,9 +251,9 @@ static BMP* LoadBMP(EFI_FILE_HANDLE root_dir, const CHAR16* path) {
|
||||
return bmp;
|
||||
}
|
||||
FreePool(bmp);
|
||||
Print(L"HackBGRT: Invalid BMP (%s)!\n", path);
|
||||
Log(1, L"HackBGRT: Invalid BMP (%s)!\n", path);
|
||||
} else {
|
||||
Print(L"HackBGRT: Failed to load BMP (%s)!\n", path);
|
||||
Log(1, L"HackBGRT: Failed to load BMP (%s)!\n", path);
|
||||
}
|
||||
BS->Stall(1000000);
|
||||
return MakeBMP(16, 16, 255, 0, 0); // error = red image
|
||||
@@ -321,7 +321,7 @@ void HackBgrt(EFI_FILE_HANDLE root_dir) {
|
||||
// Replace missing = allocate new.
|
||||
BS->AllocatePool(EfiACPIReclaimMemory, sizeof(*bgrt), (void**)&bgrt);
|
||||
if (!bgrt) {
|
||||
Print(L"HackBGRT: Failed to allocate memory for BGRT.\n");
|
||||
Log(1, L"HackBGRT: Failed to allocate memory for BGRT.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -373,8 +373,8 @@ void HackBgrt(EFI_FILE_HANDLE root_dir) {
|
||||
bgrt->image_offset_x = max(0, min(max_x, new_x + (new_reso_x - new_bmp->width) / 2));
|
||||
bgrt->image_offset_y = max(0, min(max_y, new_y + (new_reso_y - new_bmp->height) / 2));
|
||||
|
||||
Debug(
|
||||
L"HackBGRT: BMP at (%d, %d), center (%d, %d), resolution (%d, %d) with orientation %d applied.\n",
|
||||
Log(config.debug,
|
||||
L"HackBGRT: BMP at (%d, %d), center (%d, %d), resolution (%d, %d), orientation %d.\n",
|
||||
(int) bgrt->image_offset_x, (int) bgrt->image_offset_y,
|
||||
new_x, new_y, new_reso_x, new_reso_y,
|
||||
new_orientation * 90
|
||||
@@ -388,12 +388,12 @@ void HackBgrt(EFI_FILE_HANDLE root_dir) {
|
||||
/**
|
||||
* Load an application.
|
||||
*/
|
||||
static EFI_HANDLE LoadApp(print_t* print_failure, EFI_HANDLE image_handle, EFI_LOADED_IMAGE* image, const CHAR16* path) {
|
||||
static EFI_HANDLE LoadApp(int print_failure, EFI_HANDLE image_handle, EFI_LOADED_IMAGE* image, const CHAR16* path) {
|
||||
EFI_DEVICE_PATH* boot_dp = FileDevicePath(image->DeviceHandle, (CHAR16*) path);
|
||||
EFI_HANDLE result = 0;
|
||||
Debug(L"HackBGRT: Loading application %s.\n", path);
|
||||
Log(config.debug, L"HackBGRT: Loading application %s.\n", path);
|
||||
if (EFI_ERROR(BS->LoadImage(0, image_handle, boot_dp, 0, 0, &result))) {
|
||||
print_failure(L"HackBGRT: Failed to load application %s.\n", path);
|
||||
Log(config.debug || print_failure, L"HackBGRT: Failed to load application %s.\n", path);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -403,10 +403,11 @@ static EFI_HANDLE LoadApp(print_t* print_failure, EFI_HANDLE image_handle, EFI_L
|
||||
*/
|
||||
EFI_STATUS EFIAPI EfiMain(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *ST_) {
|
||||
InitializeLib(image_handle, ST_);
|
||||
Log(0, L"HackBGRT version: %s\n", version);
|
||||
|
||||
EFI_LOADED_IMAGE* image;
|
||||
if (EFI_ERROR(BS->HandleProtocol(image_handle, &LoadedImageProtocol, (void**) &image))) {
|
||||
Debug(L"HackBGRT: LOADED_IMAGE_PROTOCOL failed.\n");
|
||||
Log(config.debug, L"HackBGRT: LOADED_IMAGE_PROTOCOL failed.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -418,14 +419,16 @@ EFI_STATUS EFIAPI EfiMain(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *ST_) {
|
||||
if (argc <= 1) {
|
||||
const CHAR16* config_path = L"\\EFI\\HackBGRT\\config.txt";
|
||||
if (!ReadConfigFile(&config, root_dir, config_path)) {
|
||||
Print(L"HackBGRT: No config, no command line!\n", config_path);
|
||||
Log(1, L"HackBGRT: No config, no command line!\n", config_path);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
ReadConfigLine(&config, root_dir, argv[i]);
|
||||
}
|
||||
Debug = config.debug ? Print : NullPrint;
|
||||
if (config.debug) {
|
||||
Print(L"HackBGRT version: %s\n", version);
|
||||
}
|
||||
|
||||
SetResolution(config.resolution_x, config.resolution_y);
|
||||
HackBgrt(root_dir);
|
||||
@@ -433,55 +436,54 @@ EFI_STATUS EFIAPI EfiMain(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *ST_) {
|
||||
EFI_HANDLE next_image_handle = 0;
|
||||
static CHAR16 backup_boot_path[] = L"\\EFI\\HackBGRT\\bootmgfw-original.efi";
|
||||
static CHAR16 ms_boot_path[] = L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi";
|
||||
int try_ms_quietly = 1;
|
||||
|
||||
if (config.boot_path && StriCmp(config.boot_path, L"MS") != 0) {
|
||||
next_image_handle = LoadApp(Print, image_handle, image, config.boot_path);
|
||||
} else {
|
||||
config.boot_path = backup_boot_path;
|
||||
next_image_handle = LoadApp(Debug, image_handle, image, config.boot_path);
|
||||
if (!next_image_handle) {
|
||||
config.boot_path = ms_boot_path;
|
||||
next_image_handle = LoadApp(Debug, image_handle, image, config.boot_path);
|
||||
}
|
||||
next_image_handle = LoadApp(1, image_handle, image, config.boot_path);
|
||||
try_ms_quietly = 0;
|
||||
}
|
||||
if (!next_image_handle) {
|
||||
config.boot_path = backup_boot_path;
|
||||
next_image_handle = LoadApp(Print, image_handle, image, config.boot_path);
|
||||
next_image_handle = LoadApp(!try_ms_quietly, image_handle, image, config.boot_path);
|
||||
if (!next_image_handle) {
|
||||
config.boot_path = ms_boot_path;
|
||||
next_image_handle = LoadApp(Print, image_handle, image, config.boot_path);
|
||||
next_image_handle = LoadApp(!try_ms_quietly, image_handle, image, config.boot_path);
|
||||
if (!next_image_handle) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
Print(L"HackBGRT: Reverting to %s.\n", config.boot_path);
|
||||
if (try_ms_quietly) {
|
||||
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");
|
||||
if (ReadKey(15000).ScanCode == SCAN_ESC) {
|
||||
goto fail;
|
||||
}
|
||||
} else if (config.debug) {
|
||||
Print(L"HackBGRT: Ready to boot. Disable debug mode to skip this screen.\n");
|
||||
} 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");
|
||||
if (ReadKey(15000).ScanCode == SCAN_ESC) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (!config.log) {
|
||||
ClearLogVariable();
|
||||
}
|
||||
if (EFI_ERROR(BS->StartImage(next_image_handle, 0, 0))) {
|
||||
Print(L"HackBGRT: Failed to start %s.\n", config.boot_path);
|
||||
Log(1, L"HackBGRT: Failed to start %s.\n", config.boot_path);
|
||||
goto fail;
|
||||
}
|
||||
Print(L"HackBGRT: Started %s. Why are we still here?!\n", config.boot_path);
|
||||
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);
|
||||
goto fail;
|
||||
|
||||
fail: {
|
||||
Print(L"HackBGRT has failed. Use parameter debug=1 for details.\n");
|
||||
Print(L"Get a Windows install disk or a recovery disk to fix your boot.\n");
|
||||
#ifdef GIT_DESCRIBE_W
|
||||
Print(L"HackBGRT version: " GIT_DESCRIBE_W L"\n");
|
||||
#else
|
||||
Print(L"HackBGRT version: unknown; not an official release?\n");
|
||||
#endif
|
||||
Log(1, L"HackBGRT has failed.\n");
|
||||
Print(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");
|
||||
ReadKey(15000);
|
||||
return 1;
|
||||
|
||||
27
src/util.c
27
src/util.c
@@ -14,8 +14,31 @@ const CHAR16* TmpStr(CHAR8 *src, int length) {
|
||||
return dest;
|
||||
}
|
||||
|
||||
UINTN NullPrint(IN CONST CHAR16 *fmt, ...) {
|
||||
return 0;
|
||||
#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, ...) {
|
||||
va_list args;
|
||||
CHAR16 buf[256];
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
void ClearLogVariable(void) {
|
||||
LibDeleteVariable(LogVarName, &LogVarGuid);
|
||||
}
|
||||
|
||||
const CHAR16* TrimLeft(const CHAR16* s) {
|
||||
|
||||
12
src/util.h
12
src/util.h
@@ -14,7 +14,17 @@ extern const CHAR16* TmpStr(CHAR8 *src, int length);
|
||||
/**
|
||||
* Empty function that has the same signature as Print.
|
||||
*/
|
||||
extern UINTN NullPrint(IN CONST CHAR16 *fmt, ...);
|
||||
extern void Log(int print, IN CONST CHAR16 *fmt, ...);
|
||||
|
||||
/**
|
||||
* Dump the log buffer to the screen.
|
||||
*/
|
||||
extern void DumpLog(void);
|
||||
|
||||
/**
|
||||
* Clear the log EFI variable, for minor RAM savings.
|
||||
*/
|
||||
extern void ClearLogVariable(void);
|
||||
|
||||
/**
|
||||
* Return the greater of two numbers.
|
||||
|
||||
Reference in New Issue
Block a user