int boot_info_query(struct boot_info *info) { char str[64]; char buf[64]; char *loader_active = NULL; info->fw_secure_boot = is_efi_secure_boot(); info->fw_secure_boot_setup_mode = is_efi_secure_boot_setup_mode(); efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderInfo", &info->loader); get_boot_entries(info); if (info->fw_entries_count > 0) { get_boot_order(info); qsort(info->fw_entries, info->fw_entries_count, sizeof(struct boot_info_entry), entry_cmp); find_active_entry(info); } efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderFirmwareType", &info->fw_type); efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderFirmwareInfo", &info->fw_info); efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderImageIdentifier", &info->loader_image_path); tilt_slashes(info->loader_image_path); efi_loader_get_device_part_uuid(&info->loader_part_uuid); boot_loader_read_entries(info); efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderEntrySelected", &loader_active); if (loader_active) { boot_loader_find_active_entry(info, loader_active); free(loader_active); } snprintf(str, sizeof(str), "LoaderEntryOptions-%s", sd_id128_to_string(info->machine_id, buf)); efi_get_variable_string(EFI_VENDOR_LOADER, str, &info->loader_options_added); return 0; }
static int get_boot_entries(struct boot_info *info) { uint16_t *list; int i, n; int err = 0; n = efi_get_boot_options(&list); if (n < 0) return n; for (i = 0; i < n; i++) { struct boot_info_entry *e; e = realloc(info->fw_entries, (info->fw_entries_count+1) * sizeof(struct boot_info_entry)); if (!e) { err = -ENOMEM; break; } info->fw_entries = e; e = &info->fw_entries[info->fw_entries_count]; memzero(e, sizeof(struct boot_info_entry)); e->order = -1; err = efi_get_boot_option(list[i], &e->title, &e->part_uuid, &e->path); if (err < 0) continue; if (isempty(e->title)) { free(e->title); e->title = NULL; } tilt_slashes(e->path); e->id = list[i]; info->fw_entries_count++; } free(list); return err; }
ssize_t efi_va_generate_file_device_path_from_esp(uint8_t *buf, ssize_t size, const char *devpath, int partition, const char *relpath, uint32_t options, va_list ap) { int rc; ssize_t ret = -1, off=0, sz; struct disk_info info = { 0, }; int fd = -1; int saved_errno; fd = open(devpath, O_RDONLY); if (fd < 0) goto err; rc = eb_disk_info_from_fd(fd, &info); if (rc < 0 && errno != ENOSYS) goto err; if (partition > 0) info.part = partition; if (options & EFIBOOT_ABBREV_EDD10) { va_list aq; va_copy(aq, ap); info.edd10_devicenum = va_arg(aq, uint32_t); va_end(aq); } if ((options & EFIBOOT_ABBREV_EDD10) && (!(options & EFIBOOT_ABBREV_FILE) && !(options & EFIBOOT_ABBREV_HD))) { sz = efidp_make_edd10(buf, size, info.edd10_devicenum); if (sz < 0) return -1; off = sz; } else if (!(options & EFIBOOT_ABBREV_FILE) && !(options & EFIBOOT_ABBREV_HD)) { /* * We're probably on a modern kernel, so just parse the * symlink from /sys/dev/block/$major:$minor and get it * from there. */ sz = make_blockdev_path(buf, size, fd, &info); if (sz < 0) return -1; off += sz; } if (!(options & EFIBOOT_ABBREV_FILE)) { int disk_fd; int saved_errno; int rc; rc = set_disk_and_part_name(&info); if (rc < 0) goto err; disk_fd = open_disk(&info, (options& EFIBOOT_OPTIONS_WRITE_SIGNATURE)?O_RDWR:O_RDONLY); if (disk_fd < 0) goto err; sz = make_hd_dn(buf, size, off, disk_fd, info.part, options); saved_errno = errno; close(disk_fd); errno = saved_errno; if (sz < 0) goto err; off += sz; } char *filepath = strdupa(relpath); tilt_slashes(filepath); sz = efidp_make_file(buf+off, size?size-off:0, filepath); if (sz < 0) goto err; off += sz; sz = efidp_make_end_entire(buf+off, size?size-off:0); if (sz < 0) goto err; off += sz; ret = off; err: saved_errno = errno; if (info.disk_name) { free(info.disk_name); info.disk_name = NULL; } if (info.part_name) { free(info.part_name); info.part_name = NULL; } if (fd >= 0) close(fd); errno = saved_errno; return ret; }