Fix a shim error caused by bad load options data

Shim expects a filename or nothing in the load options.

To avoid an error message during boot, do several things:

When creating the NVRAM entry, use empty load options. The current
string ("HackBGRT\0") was just a decoration, and it's luckily ignored
by shim because the length is odd.

When creating the entry with BCDEdit, manually fix the load options.
The load options in BCDEdit entries start with "WINDOWS\0" followed
by UINT32 version, as seen in ReactOS struct BL_WINDOWS_LOAD_OPTIONS.
The version is 1, but BCDEdit seems to be happy with a higher number.
By setting this version to 'X' (0x58), the string becomes a valid
UCS-2 file name. Update the installer so that the HackBGRT loader is
installed with this weird file name.

The reason why the load options cannot be deleted completely is that
BCDEdit will recreate the entry on next boot if it doesn't find the
entry it just tried to create.

See: https://github.com/rhboot/shim/pull/621
See: https://github.com/reactos/reactos/blob/v0.4.7/boot/environ/include/bl.h#L911
This commit is contained in:
Lauri Kenttä
2023-12-17 14:26:21 +02:00
parent 9948e5a306
commit a44b929012
2 changed files with 25 additions and 5 deletions

View File

@@ -373,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");
}
@@ -415,6 +416,7 @@ public class Setup {
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) {
@@ -460,7 +462,7 @@ 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();