]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-boot: Detect windows boot loader title from BCD 20438/head
authorJan Janssen <medhefgo@web.de>
Fri, 13 Aug 2021 17:03:35 +0000 (19:03 +0200)
committerJan Janssen <medhefgo@web.de>
Mon, 16 Aug 2021 08:51:02 +0000 (10:51 +0200)
src/boot/efi/boot.c

index 70f5a2ba52c0e009b1d3f594c4fbec5c50935627..82da9843253f60467af25d7d669e07564ae026eb 100644 (file)
@@ -1897,6 +1897,55 @@ static VOID config_entry_add_osx(Config *config) {
         }
 }
 
+static VOID config_entry_add_windows(Config *config, EFI_HANDLE *device, EFI_FILE *root_dir) {
+        _cleanup_freepool_ CHAR8 *bcd = NULL;
+        const CHAR16 *title = NULL;
+        EFI_STATUS err;
+        UINTN len;
+
+        assert(config);
+        assert(device);
+        assert(root_dir);
+
+        if (!config->auto_entries)
+                return;
+
+        /* Try to find a better title. */
+        err = file_read(root_dir, L"\\EFI\\Microsoft\\Boot\\BCD", 0, 100*1024, &bcd, &len);
+        if (!EFI_ERROR(err)) {
+                static const CHAR16 *versions[] = {
+                        L"Windows 11",
+                        L"Windows 10",
+                        L"Windows 8.1",
+                        L"Windows 8",
+                        L"Windows 7",
+                        L"Windows Vista",
+                };
+
+                CHAR8 *p = bcd;
+                while (!title) {
+                        CHAR8 *q = mempmem_safe(p, len, versions[0], STRLEN(L"Windows "));
+                        if (!q)
+                                break;
+
+                        len -= q - p;
+                        p = q;
+
+                        /* We found the prefix, now try all the version strings. */
+                        for (UINTN i = 0; i < ELEMENTSOF(versions); i++) {
+                                if (memory_startswith(p, len, versions[i] + STRLEN("Windows "))) {
+                                        title = versions[i];
+                                        break;
+                                }
+                        }
+                }
+        }
+
+        config_entry_add_loader_auto(config, device, root_dir, NULL,
+                                     L"auto-windows", 'w', title ?: L"Windows Boot Manager",
+                                     L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi");
+}
+
 static VOID config_entry_add_linux(
                 Config *config,
                 EFI_HANDLE *device,
@@ -2430,13 +2479,12 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
         config_sort_entries(&config);
 
         /* if we find some well-known loaders, add them to the end of the list */
-        config_entry_add_loader_auto(&config, loaded_image->DeviceHandle, root_dir, NULL,
-                                     L"auto-windows", 'w', L"Windows Boot Manager", L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi");
+        config_entry_add_osx(&config);
+        config_entry_add_windows(&config, loaded_image->DeviceHandle, root_dir);
         config_entry_add_loader_auto(&config, loaded_image->DeviceHandle, root_dir, NULL,
                                      L"auto-efi-shell", 's', L"EFI Shell", L"\\shell" EFI_MACHINE_TYPE_NAME ".efi");
         config_entry_add_loader_auto(&config, loaded_image->DeviceHandle, root_dir, loaded_image_path,
                                      L"auto-efi-default", '\0', L"EFI Default Loader", NULL);
-        config_entry_add_osx(&config);
 
         if (config.auto_firmware && efivar_get_uint64_le(EFI_GLOBAL_GUID, L"OsIndicationsSupported", &osind) == EFI_SUCCESS) {
                 if (osind & EFI_OS_INDICATIONS_BOOT_TO_FW_UI)