mirror of
https://github.com/Metabolix/HackBGRT.git
synced 2025-12-07 01:26:14 -08:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a5b1df064 | ||
|
|
ea70f3ce79 | ||
|
|
a44b929012 | ||
|
|
9948e5a306 | ||
|
|
518d7c8a97 | ||
|
|
c6108ffd62 | ||
|
|
6dc447a8ce | ||
|
|
5ec17a49e8 | ||
|
|
7b7309a255 | ||
|
|
a82646a822 | ||
|
|
294da9c069 | ||
|
|
4096002eb2 |
21
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
21
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report if you encounter a bug
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**What happens?**
|
||||
Describe the bug.
|
||||
|
||||
**How this happens?**
|
||||
Explain exactly the steps you did:
|
||||
1. Download HackBGRT-(version).zip and extract all files.
|
||||
2. Start setup.
|
||||
3. Select ...
|
||||
4. ...
|
||||
|
||||
**Log file**
|
||||
Run the setup again and select menu option `L` (or add parameter `show-boot-log` on command line). Attach the `setup.log` to this report.
|
||||
10
CHANGELOG.md
10
CHANGELOG.md
@@ -2,6 +2,16 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## 2.4.0 - 2023-12-31
|
||||
|
||||
### Fixed
|
||||
- Fix BCDEdit boot entries to avoid *shim* error messages.
|
||||
- Combine BCDEdit and own code to create boot entries more reliably.
|
||||
|
||||
### Changed
|
||||
- Clear the screen to wipe the vendor logo as soon as possible.
|
||||
- Image paths in `config.txt` may be relative (just file names).
|
||||
|
||||
## 2.3.1 - 2023-11-27
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -6,6 +6,8 @@ HackBGRT is intended as a boot logo changer for UEFI-based Windows systems.
|
||||
|
||||
When booting on a UEFI-based computer, Windows may show a vendor-defined logo which is stored on the UEFI firmware in a section called Boot Graphics Resource Table (BGRT). It's usually very difficult to change the image permanently, but a custom UEFI application may be used to overwrite it during the boot. HackBGRT does exactly that.
|
||||
|
||||
**Note:** The original logo is often visible for a moment before HackBGRT is started. This is expected, please do not report this "bug". This can't be changed without modifying computer firmware, which this project will not do.
|
||||
|
||||
## Usage
|
||||
|
||||
**Important:** If you mess up the installation, your system may become unbootable! Create a rescue disk before use. This software comes with no warranty. Use at your own risk.
|
||||
@@ -70,14 +72,12 @@ The configuration options are described in `config.txt`, which the installer cop
|
||||
|
||||
## Images
|
||||
|
||||
The image path can be changed in the configuration file. The default path is `[EFI System Partition]\EFI\HackBGRT\splash.bmp`.
|
||||
If you only need one image, just edit `splash.bmp` to your needs.
|
||||
|
||||
The installer copies and converts files whose `path` starts with `\EFI\HackBGRT\`. For example, to use a file named `my.jpg`, copy it in the installer folder (same folder as `setup.exe`) and set the image path in `config.txt` to `path=\EFI\HackBGFT\my.jpg`.
|
||||
Advanced users may edit the `config.txt` to define multiple images, in which case one is picked at random. The installer copies and converts the images. For example, to use a file named `my.jpg`, copy it in the installer folder (same folder as `setup.exe`) and set the image path in `config.txt` to `path=my.jpg` before running the installer.
|
||||
|
||||
If you copy an image file to ESP manually, note that the image must be a 24-bit BMP file with a 54-byte header. That's a TrueColor BMP3 in Imagemagick, or 24-bit BMP/DIB in Microsoft Paint.
|
||||
|
||||
Advanced users may edit the `config.txt` to define multiple images, in which case one is picked at random.
|
||||
|
||||
## Recovery
|
||||
|
||||
If something breaks and you can't boot to Windows, you need to use the Windows installation disk (or recovery disk) to fix boot issues.
|
||||
|
||||
14
config.txt
14
config.txt
@@ -16,16 +16,14 @@ boot=MS
|
||||
# - "keep" to keep the firmware logo. Also keeps coordinates by default.
|
||||
# - "remove" to remove the BGRT. Makes x and y meaningless.
|
||||
# - "black" to use only a black image. Makes x and y meaningless.
|
||||
# - "path=..." to read a BMP file.
|
||||
# * NOTE: For path=\EFI\HackBGRT\*, the installer will copy and convert the file if necessary.
|
||||
# * NOTE: For other paths, make sure that the file is a 24-bit BMP file with a 54-byte header.
|
||||
# * NOTE: The file must be on the EFI System Partition. Do not add a drive letter!
|
||||
# - "path=file.bmp" to read an image file.
|
||||
# * NOTE: The installer can copy and convert BMP, PNG, JPEG, GIF.
|
||||
# Examples:
|
||||
# - image=remove
|
||||
# - image=black
|
||||
# - image= x=0 y=-200 path=\EFI\HackBGRT\topimage.bmp
|
||||
# - image= n=1 o=90 path=\EFI\HackBGRT\sideways.bmp
|
||||
# - image= n=50 y=999999 o=keep path=\EFI\HackBGRT\probable.bmp
|
||||
# - image= x=0 y=-200 path=topimage.bmp
|
||||
# - image= n=1 o=90 path=sideways.bmp
|
||||
# - image= n=50 y=999999 o=keep path=probable.bmp
|
||||
# The above examples together would produce
|
||||
# - 1/54 chance for the default OS logo
|
||||
# - 1/54 chance for black screen
|
||||
@@ -33,7 +31,7 @@ boot=MS
|
||||
# - 1/54 chance for splash.bmp, centered, orientation set to 90 degrees
|
||||
# - 50/54 chance for probable.bmp, at the bottom edge, explicitly default orientation
|
||||
# Default: just one image.
|
||||
image= y=-200 path=\EFI\HackBGRT\splash.bmp
|
||||
image= y=-200 path=splash.bmp
|
||||
|
||||
# Preferred resolution. Use 0x0 for maximum and -1x-1 for original.
|
||||
resolution=0x0
|
||||
|
||||
29
src/Efi.cs
29
src/Efi.cs
@@ -93,6 +93,7 @@ public class Efi {
|
||||
var pos = 6 + 2 * (Label.Length + 1);
|
||||
var pathNodesEnd = pos + pathNodesLength;
|
||||
DevicePathNodes = new List<DevicePathNode>();
|
||||
Arguments = new byte[0];
|
||||
while (pos + 4 <= pathNodesEnd) {
|
||||
var len = BitConverter.ToUInt16(data, pos + 2);
|
||||
if (len < 4 || pos + len > pathNodesEnd) {
|
||||
@@ -378,9 +379,10 @@ public class Efi {
|
||||
*
|
||||
* @param label Label of the boot entry.
|
||||
* @param fileName File name of the boot entry.
|
||||
* @param alwaysCopyFromMS If true, do not preserve any existing data.
|
||||
* @param dryRun Don't actually create the entry.
|
||||
*/
|
||||
public static void MakeAndEnableBootEntry(string label, string fileName, bool dryRun = false) {
|
||||
public static void MakeAndEnableBootEntry(string label, string fileName, bool alwaysCopyFromMS, bool dryRun = false) {
|
||||
Variable msEntry = null, ownEntry = null;
|
||||
UInt16 msNum = 0, ownNum = 0;
|
||||
|
||||
@@ -435,12 +437,28 @@ public class Efi {
|
||||
throw new Exception("MakeBootEntry: Windows Boot Manager not found.");
|
||||
} else {
|
||||
Setup.Log($"Read EFI variable: {msEntry}");
|
||||
Setup.Log($"Read EFI variable: {ownEntry}");
|
||||
// Make a new boot entry using the MS entry as a starting point.
|
||||
var entryData = new BootEntryData(msEntry.Data);
|
||||
entryData.Arguments = Encoding.UTF8.GetBytes(label + "\0");
|
||||
if (!alwaysCopyFromMS && ownEntry.Data != null) {
|
||||
entryData = new BootEntryData(ownEntry.Data);
|
||||
// Shim expects the arguments to be a filename or nothing.
|
||||
// But BCDEdit expects some Microsoft-specific data.
|
||||
// Modify the entry so that BCDEdit still recognises it
|
||||
// but the data becomes a valid UCS-2 / UTF-16LE file name.
|
||||
var str = new string(entryData.Arguments.Take(12).Select(c => (char) c).ToArray());
|
||||
if (str == "WINDOWS\0\x01\0\0\0") {
|
||||
entryData.Arguments[8] = (byte) 'X';
|
||||
} else if (str != "WINDOWS\0\x58\0\0\0") {
|
||||
// Not recognized. Clear the arguments.
|
||||
entryData.Arguments = new byte[0];
|
||||
}
|
||||
} else {
|
||||
entryData.Arguments = new byte[0];
|
||||
entryData.Label = label;
|
||||
entryData.FileName = fileName;
|
||||
}
|
||||
entryData.Attributes = 1; // LOAD_OPTION_ACTIVE
|
||||
entryData.Label = label;
|
||||
entryData.FileName = fileName;
|
||||
ownEntry.Attributes = 7; // EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS
|
||||
ownEntry.Data = entryData.ToBytes();
|
||||
SetVariable(ownEntry, dryRun);
|
||||
@@ -494,6 +512,9 @@ public class Efi {
|
||||
public static string GetHackBGRTLog() {
|
||||
try {
|
||||
var log = GetVariable("HackBGRTLog", EFI_HACKBGRT_GUID);
|
||||
if (log.Data == null) {
|
||||
return "(null)";
|
||||
}
|
||||
return new string(BytesToUInt16s(log.Data).Select(i => (char)i).ToArray());
|
||||
} catch (Exception e) {
|
||||
return $"Log not found: {e.ToString()}";
|
||||
|
||||
66
src/Setup.cs
66
src/Setup.cs
@@ -239,6 +239,8 @@ public class Setup {
|
||||
0x0200 => "ia64",
|
||||
0x8664 => "x64",
|
||||
0xaa64 => "aa64",
|
||||
0x01c2 => "arm",
|
||||
0x01c4 => "arm",
|
||||
_ => $"unknown-{peArch:x4}"
|
||||
};
|
||||
} catch {
|
||||
@@ -352,10 +354,16 @@ public class Setup {
|
||||
var lines = File.ReadAllLines("config.txt");
|
||||
Log($"config.txt:\n{String.Join("\n", lines)}");
|
||||
foreach (var line in lines.Where(s => s.StartsWith("image="))) {
|
||||
var delim = "path=\\EFI\\HackBGRT\\";
|
||||
var delim = "path=";
|
||||
var i = line.IndexOf(delim);
|
||||
if (i > 0) {
|
||||
InstallImageFile(line.Substring(i + delim.Length));
|
||||
var dir = "\\EFI\\HackBGRT\\";
|
||||
if (line.Substring(i + delim.Length).StartsWith(dir)) {
|
||||
InstallImageFile(line.Substring(i + delim.Length + dir.Length));
|
||||
}
|
||||
if (!line.Substring(i + delim.Length).StartsWith("\\")) {
|
||||
InstallImageFile(line.Substring(i + delim.Length));
|
||||
}
|
||||
}
|
||||
}
|
||||
var loaderDest = "loader.efi";
|
||||
@@ -365,6 +373,7 @@ public class Setup {
|
||||
loaderDest = $"grub{EfiArch}.efi";
|
||||
}
|
||||
InstallFile(loaderSource, loaderDest);
|
||||
InstallFile(loaderSource, "\u4957\u444e\u574f\u0053\u0058"); // bytes "WINDOWS\0X\0" as UTF-16
|
||||
if (LoaderIsSigned) {
|
||||
InstallFile("certificate.cer");
|
||||
}
|
||||
@@ -390,6 +399,10 @@ public class Setup {
|
||||
* Enable HackBGRT with bcdedit.
|
||||
*/
|
||||
protected void EnableBCDEdit() {
|
||||
if (DryRun) {
|
||||
WriteLine("Dry run, skip enabling with BCDEdit.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
var re = new Regex("[{][0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}[}]");
|
||||
var guid = re.Match(Execute("bcdedit", "/copy {bootmgr} /d HackBGRT", true)).Value;
|
||||
@@ -400,9 +413,12 @@ public class Setup {
|
||||
}
|
||||
var fwbootmgr = "{fwbootmgr}";
|
||||
Execute("bcdedit", $"/set {fwbootmgr} displayorder {guid} /addfirst", true);
|
||||
WriteLine("Enabled NVRAM entry for HackBGRT with BCDEdit.");
|
||||
// Verify that the entry was created.
|
||||
Execute("bcdedit", "/enum firmware", true);
|
||||
Efi.MakeAndEnableBootEntry("HackBGRT", "\\EFI\\HackBGRT\\loader.efi", false, DryRun);
|
||||
Execute("bcdedit", $"/enum {guid}", true);
|
||||
Efi.LogBootEntries();
|
||||
} catch (Exception e) {
|
||||
Log($"EnableBCDEdit failed: {e.ToString()}");
|
||||
throw new SetupException("Failed to enable HackBGRT with BCDEdit!");
|
||||
@@ -427,14 +443,18 @@ public class Setup {
|
||||
} else if (entry.IndexOf("HackBGRT") >= 0) {
|
||||
found = true;
|
||||
Log($"Disabling HackBGRT entry {guid}.");
|
||||
if (Execute("bcdedit", $"/delete {guid}", true) == null) {
|
||||
if (!DryRun && Execute("bcdedit", $"/delete {guid}", true) == null) {
|
||||
Log($"DisableBCDEdit failed to delete {guid}.");
|
||||
} else {
|
||||
disabled = true;
|
||||
}
|
||||
disabled = true;
|
||||
}
|
||||
}
|
||||
if (found && !disabled) {
|
||||
throw new SetupException("Failed to disable HackBGRT with BCDEdit!");
|
||||
if (found) {
|
||||
if (!disabled) {
|
||||
throw new SetupException("Failed to disable HackBGRT with BCDEdit!");
|
||||
}
|
||||
WriteLine("Disabled NVRAM entry for HackBGRT with BCDEdit.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,10 +462,11 @@ public class Setup {
|
||||
* Enable HackBGRT boot entry.
|
||||
*/
|
||||
protected void EnableEntry() {
|
||||
Efi.MakeAndEnableBootEntry("HackBGRT", "\\EFI\\HackBGRT\\loader.efi", DryRun);
|
||||
Efi.MakeAndEnableBootEntry("HackBGRT", "\\EFI\\HackBGRT\\loader.efi", true, DryRun);
|
||||
WriteLine("Enabled NVRAM entry for HackBGRT.");
|
||||
// Verify that the entry was created.
|
||||
Efi.LogBootEntries();
|
||||
Execute("bcdedit", "/enum firmware", true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -511,7 +532,7 @@ public class Setup {
|
||||
*/
|
||||
protected void VerifyLoaderConfig() {
|
||||
var lines = File.ReadAllLines("config.txt");
|
||||
var loader = lines.Where(s => s.StartsWith("boot=")).Select(s => s.Substring(5)).Prepend("").Last();
|
||||
var loader = lines.Where(s => s.StartsWith("boot=")).Select(s => s.Substring(5)).LastOrDefault();
|
||||
if (loader == null) {
|
||||
throw new SetupException("config.txt does not contain a boot=... line!");
|
||||
}
|
||||
@@ -708,8 +729,13 @@ public class Setup {
|
||||
* @param arch The architecture.
|
||||
*/
|
||||
protected void SetArch(string arch) {
|
||||
var detectedArch = DetectArchFromOS();
|
||||
if (arch == "") {
|
||||
var detectedArch = Environment.Is64BitOperatingSystem ? "x64" : "ia32";
|
||||
try {
|
||||
detectedArch = DetectArchFromOS();
|
||||
} catch {
|
||||
WriteLine($"Failed to detect OS architecture, assuming {detectedArch}.");
|
||||
}
|
||||
if (arch == "" || arch == null) {
|
||||
EfiArch = detectedArch;
|
||||
WriteLine($"Your OS uses arch={EfiArch}. This will be checked again during installation.");
|
||||
} else {
|
||||
@@ -781,7 +807,7 @@ public class Setup {
|
||||
WriteLine(" I = install");
|
||||
WriteLine(" - creates a new EFI boot entry for HackBGRT");
|
||||
WriteLine(" J = install (alternative)");
|
||||
WriteLine(" - creates a new EFI boot entry with an alternative method (BCDEdit)");
|
||||
WriteLine(" - creates a new EFI boot entry with an alternative method");
|
||||
WriteLine(" - try this if the first option doesn't work");
|
||||
WriteLine(" O = install (legacy)");
|
||||
WriteLine(" - overwrites the MS boot loader; gets removed by Windows updates");
|
||||
@@ -801,15 +827,15 @@ public class Setup {
|
||||
var k = Console.ReadKey().Key;
|
||||
Log($"User input: {k}");
|
||||
WriteLine();
|
||||
if (k == ConsoleKey.I || k == ConsoleKey.O || k == ConsoleKey.F) {
|
||||
if (k == ConsoleKey.I || k == ConsoleKey.J || k == ConsoleKey.O || k == ConsoleKey.F) {
|
||||
Configure();
|
||||
}
|
||||
if (k == ConsoleKey.I) {
|
||||
RunPrivilegedActions(new string[] { "install", "enable-entry" });
|
||||
RunPrivilegedActions(new string[] { "install", "disable", "enable-bcdedit" });
|
||||
} else if (k == ConsoleKey.J) {
|
||||
RunPrivilegedActions(new string[] { "install", "enable-bcdedit" });
|
||||
RunPrivilegedActions(new string[] { "install", "disable", "enable-entry" });
|
||||
} else if (k == ConsoleKey.O) {
|
||||
RunPrivilegedActions(new string[] { "install", "enable-overwrite" });
|
||||
RunPrivilegedActions(new string[] { "install", "disable", "enable-overwrite" });
|
||||
} else if (k == ConsoleKey.F) {
|
||||
RunPrivilegedActions(new string[] { "install" });
|
||||
} else if (k == ConsoleKey.D) {
|
||||
@@ -955,7 +981,7 @@ public class Setup {
|
||||
Batch = args.Contains("batch");
|
||||
ForwardArguments = String.Join(" ", args.Where(s => s == "dry-run" || s == "batch" || s.StartsWith("arch=")));
|
||||
try {
|
||||
SetArch(args.Prepend("arch=").Last(s => s.StartsWith("arch=")).Substring(5));
|
||||
SetArch(args.Where(s => s.StartsWith("arch=")).Select(s => s.Substring(5)).LastOrDefault());
|
||||
if (args.Contains("is-elevated") && !HasPrivileges() && !DryRun) {
|
||||
WriteLine("This installer needs to be run as administrator!");
|
||||
return 1;
|
||||
@@ -983,7 +1009,13 @@ public class Setup {
|
||||
WriteLine();
|
||||
WriteLine($"Unexpected error: {e.Message}");
|
||||
Log(e.ToString());
|
||||
WriteLine("If this is the most current release, please report this bug.");
|
||||
if (e is MissingMemberException || e is TypeLoadException) {
|
||||
WriteLine("This installer requires a recent version of .Net Framework.");
|
||||
WriteLine("Use Windows Update or download manually:");
|
||||
WriteLine("https://dotnet.microsoft.com/en-us/download/dotnet-framework");
|
||||
} else {
|
||||
WriteLine("If this is the most current release, please report this bug.");
|
||||
}
|
||||
return 1;
|
||||
} finally {
|
||||
if (DryRun) {
|
||||
|
||||
10
src/config.c
10
src/config.c
@@ -1,10 +1,10 @@
|
||||
#include "config.h"
|
||||
#include "util.h"
|
||||
|
||||
BOOLEAN ReadConfigFile(struct HackBGRT_config* config, EFI_FILE_HANDLE root_dir, const CHAR16* path) {
|
||||
BOOLEAN ReadConfigFile(struct HackBGRT_config* config, EFI_FILE_HANDLE base_dir, const CHAR16* path) {
|
||||
void* data = 0;
|
||||
UINTN data_bytes = 0;
|
||||
data = LoadFileWithPadding(root_dir, path, &data_bytes, 4);
|
||||
data = LoadFileWithPadding(base_dir, path, &data_bytes, 4);
|
||||
if (!data) {
|
||||
Log(1, L"Failed to load configuration (%s)!\n", path);
|
||||
return FALSE;
|
||||
@@ -61,7 +61,7 @@ BOOLEAN ReadConfigFile(struct HackBGRT_config* config, EFI_FILE_HANDLE root_dir,
|
||||
str[j] = 0;
|
||||
++j;
|
||||
}
|
||||
ReadConfigLine(config, root_dir, &str[i]);
|
||||
ReadConfigLine(config, base_dir, &str[i]);
|
||||
i = j;
|
||||
}
|
||||
// NOTICE: string is not freed, because paths are not copied.
|
||||
@@ -129,7 +129,7 @@ static void ReadConfigResolution(struct HackBGRT_config* config, const CHAR16* l
|
||||
}
|
||||
}
|
||||
|
||||
void ReadConfigLine(struct HackBGRT_config* config, EFI_FILE_HANDLE root_dir, const CHAR16* line) {
|
||||
void ReadConfigLine(struct HackBGRT_config* config, EFI_FILE_HANDLE base_dir, const CHAR16* line) {
|
||||
line = TrimLeft(line);
|
||||
if (line[0] == L'#' || line[0] == 0) {
|
||||
return;
|
||||
@@ -152,7 +152,7 @@ void ReadConfigLine(struct HackBGRT_config* config, EFI_FILE_HANDLE root_dir, co
|
||||
return;
|
||||
}
|
||||
if (StrnCmp(line, L"config=", 7) == 0) {
|
||||
ReadConfigFile(config, root_dir, line + 7);
|
||||
ReadConfigFile(config, base_dir, line + 7);
|
||||
return;
|
||||
}
|
||||
if (StrnCmp(line, L"resolution=", 11) == 0) {
|
||||
|
||||
@@ -39,17 +39,17 @@ struct HackBGRT_config {
|
||||
* Read a configuration parameter. (May recursively read config files.)
|
||||
*
|
||||
* @param config The configuration to modify.
|
||||
* @param root_dir The root directory, in case the parameter contains an include.
|
||||
* @param base_dir The base directory, in case the parameter contains an include.
|
||||
* @param line The configuration line to parse.
|
||||
*/
|
||||
extern void ReadConfigLine(struct HackBGRT_config* config, EFI_FILE_HANDLE root_dir, const CHAR16* line);
|
||||
extern void ReadConfigLine(struct HackBGRT_config* config, EFI_FILE_HANDLE base_dir, const CHAR16* line);
|
||||
|
||||
/**
|
||||
* Read a configuration file. (May recursively read more files.)
|
||||
*
|
||||
* @param config The configuration to modify.
|
||||
* @param root_dir The root directory.
|
||||
* @param base_dir The base directory.
|
||||
* @param path The path to the file.
|
||||
* @return FALSE, if the file couldn't be read, TRUE otherwise.
|
||||
*/
|
||||
extern BOOLEAN ReadConfigFile(struct HackBGRT_config* config, EFI_FILE_HANDLE root_dir, const CHAR16* path);
|
||||
extern BOOLEAN ReadConfigFile(struct HackBGRT_config* config, EFI_FILE_HANDLE base_dir, const CHAR16* path);
|
||||
|
||||
32
src/main.c
32
src/main.c
@@ -239,17 +239,17 @@ static BMP* MakeBMP(int w, int h, UINT8 r, UINT8 g, UINT8 b) {
|
||||
/**
|
||||
* Load a bitmap or generate a black one.
|
||||
*
|
||||
* @param root_dir The root directory for loading a BMP.
|
||||
* @param path The BMP path within the root directory; NULL for a black BMP.
|
||||
* @param base_dir The directory for loading a BMP.
|
||||
* @param path The BMP path within the directory; NULL for a black BMP.
|
||||
* @return The loaded BMP, or 0 if not available.
|
||||
*/
|
||||
static BMP* LoadBMP(EFI_FILE_HANDLE root_dir, const CHAR16* path) {
|
||||
static BMP* LoadBMP(EFI_FILE_HANDLE base_dir, const CHAR16* path) {
|
||||
if (!path) {
|
||||
return MakeBMP(1, 1, 0, 0, 0); // empty path = black image
|
||||
}
|
||||
Log(config.debug, L"Loading %s.\n", path);
|
||||
UINTN size = 0;
|
||||
BMP* bmp = LoadFile(root_dir, path, &size);
|
||||
BMP* bmp = LoadFile(base_dir, path, &size);
|
||||
if (bmp) {
|
||||
if (size >= bmp->file_size
|
||||
&& CompareMem(bmp, "BM", 2) == 0
|
||||
@@ -299,9 +299,9 @@ static void CropBMP(BMP* bmp, int w, int h) {
|
||||
/**
|
||||
* The main logic for BGRT modification.
|
||||
*
|
||||
* @param root_dir The root directory for loading a BMP.
|
||||
* @param base_dir The directory for loading a BMP.
|
||||
*/
|
||||
void HackBgrt(EFI_FILE_HANDLE root_dir) {
|
||||
void HackBgrt(EFI_FILE_HANDLE base_dir) {
|
||||
// REMOVE: simply delete all BGRT entries.
|
||||
if (config.action == HackBGRT_REMOVE) {
|
||||
HandleAcpiTables(config.action, 0);
|
||||
@@ -352,7 +352,7 @@ void HackBgrt(EFI_FILE_HANDLE root_dir) {
|
||||
// Get the image (either old or new).
|
||||
BMP* new_bmp = old_bmp;
|
||||
if (config.action == HackBGRT_REPLACE) {
|
||||
new_bmp = LoadBMP(root_dir, config.image_path);
|
||||
new_bmp = LoadBMP(base_dir, config.image_path);
|
||||
}
|
||||
|
||||
// No image = no need for BGRT.
|
||||
@@ -415,6 +415,10 @@ EFI_STATUS EFIAPI efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *ST_) {
|
||||
BS = ST_->BootServices;
|
||||
RT = ST_->RuntimeServices;
|
||||
|
||||
// Clear the screen to wipe the vendor logo.
|
||||
ST->ConOut->EnableCursor(ST->ConOut, 0);
|
||||
ST->ConOut->ClearScreen(ST->ConOut);
|
||||
|
||||
Log(0, L"HackBGRT version: %s\n", version);
|
||||
|
||||
EFI_LOADED_IMAGE* image;
|
||||
@@ -435,10 +439,16 @@ EFI_STATUS EFIAPI efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *ST_) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
EFI_FILE_HANDLE base_dir;
|
||||
if (EFI_ERROR(root_dir->Open(root_dir, &base_dir, L"\\EFI\\HackBGRT", EFI_FILE_MODE_READ, 0))) {
|
||||
Log(config.debug, L"Failed to HackBGRT directory.\n");
|
||||
base_dir = root_dir;
|
||||
}
|
||||
|
||||
EFI_SHELL_PARAMETERS_PROTOCOL *shell_param_proto = NULL;
|
||||
if (EFI_ERROR(BS->OpenProtocol(image_handle, TmpGuidPtr((EFI_GUID) EFI_SHELL_PARAMETERS_PROTOCOL_GUID), (void**) &shell_param_proto, 0, 0, EFI_OPEN_PROTOCOL_GET_PROTOCOL)) || shell_param_proto->Argc <= 1) {
|
||||
const CHAR16* config_path = L"\\EFI\\HackBGRT\\config.txt";
|
||||
if (!ReadConfigFile(&config, root_dir, config_path)) {
|
||||
const CHAR16* config_path = L"config.txt";
|
||||
if (!ReadConfigFile(&config, base_dir, config_path)) {
|
||||
Log(1, L"No config, no command line!\n", config_path);
|
||||
goto fail;
|
||||
}
|
||||
@@ -446,7 +456,7 @@ EFI_STATUS EFIAPI efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *ST_) {
|
||||
CHAR16 **argv = shell_param_proto->Argv;
|
||||
int argc = shell_param_proto->Argc;
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
ReadConfigLine(&config, root_dir, argv[i]);
|
||||
ReadConfigLine(&config, base_dir, argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -455,7 +465,7 @@ EFI_STATUS EFIAPI efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *ST_) {
|
||||
}
|
||||
|
||||
SetResolution(config.resolution_x, config.resolution_y);
|
||||
HackBgrt(root_dir);
|
||||
HackBgrt(base_dir);
|
||||
|
||||
EFI_HANDLE next_image_handle = 0;
|
||||
static CHAR16 backup_boot_path[] = L"\\EFI\\HackBGRT\\bootmgfw-original.efi";
|
||||
|
||||
@@ -177,6 +177,7 @@ EFI_STATUS WaitKey(UINT64 timeout_ms) {
|
||||
|
||||
EFI_INPUT_KEY ReadKey(UINT64 timeout_ms) {
|
||||
EFI_INPUT_KEY key = {0};
|
||||
ST->ConOut->EnableCursor(ST->ConOut, 1);
|
||||
WaitKey(timeout_ms);
|
||||
ST->ConIn->ReadKeyStroke(ST->ConIn, &key);
|
||||
return key;
|
||||
|
||||
Reference in New Issue
Block a user