Always check the BDP partitions when getting all the possible ESPs

Fixes https://github.com/fwupd/fwupd/issues/5035
This commit is contained in:
Richard Hughes 2022-09-16 17:23:37 +01:00
parent 48beb87faf
commit e72ed08b56
5 changed files with 70 additions and 31 deletions

View File

@ -767,3 +767,60 @@ fu_volume_new_esp_for_path(const gchar *esp_path, GError **error)
esp_path);
return NULL;
}
/**
* fu_volume_new_by_esp:
* @error: (nullable): optional return location for an error
*
* Finds all volumes that could be an ESP.
*
* Returns: (transfer container) (element-type FuVolume): a #GPtrArray, or %NULL if no ESP was found
*
* Since: 1.8.5
**/
GPtrArray *
fu_volume_new_by_esp(GError **error)
{
g_autoptr(GError) error_bdp = NULL;
g_autoptr(GError) error_esp = NULL;
g_autoptr(GPtrArray) volumes_bdp = NULL;
g_autoptr(GPtrArray) volumes_esp = NULL;
g_autoptr(GPtrArray) volumes =
g_ptr_array_new_with_free_func((GDestroyNotify)g_object_unref);
/* ESP */
volumes_esp = fu_volume_new_by_kind(FU_VOLUME_KIND_ESP, &error_esp);
if (volumes_esp == NULL) {
g_debug("%s", error_esp->message);
} else {
for (guint i = 0; i < volumes_esp->len; i++) {
FuVolume *vol = g_ptr_array_index(volumes_esp, i);
g_ptr_array_add(volumes, g_object_ref(vol));
}
}
/* BDP */
volumes_bdp = fu_volume_new_by_kind(FU_VOLUME_KIND_BDP, &error_bdp);
if (volumes_bdp == NULL) {
g_debug("%s", error_bdp->message);
} else {
for (guint i = 0; i < volumes_bdp->len; i++) {
FuVolume *vol = g_ptr_array_index(volumes_bdp, i);
g_autofree gchar *type = fu_volume_get_id_type(vol);
if (g_strcmp0(type, "vfat") != 0)
continue;
if (!fu_volume_is_internal(vol))
continue;
g_ptr_array_add(volumes, g_object_ref(vol));
}
}
/* nothing found */
if (volumes->len == 0) {
g_set_error_literal(error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "No ESP or BDP found");
return NULL;
}
/* success */
return g_steal_pointer(&volumes);
}

View File

@ -62,3 +62,5 @@ FuVolume *
fu_volume_new_esp_for_path(const gchar *esp_path, GError **error) G_GNUC_WARN_UNUSED_RESULT;
FuVolume *
fu_volume_new_esp_default(GError **error) G_GNUC_WARN_UNUSED_RESULT;
GPtrArray *
fu_volume_new_by_esp(GError **error) G_GNUC_WARN_UNUSED_RESULT;

View File

@ -1125,5 +1125,6 @@ LIBFWUPDPLUGIN_1.8.5 {
fu_usb_device_fw_ds20_new;
fu_usb_device_ms_ds20_get_type;
fu_usb_device_ms_ds20_new;
fu_volume_new_by_esp;
local: *;
} LIBFWUPDPLUGIN_1.8.4;

View File

@ -83,7 +83,7 @@ gboolean
fu_uefi_dbx_signature_list_validate(FuEfiSignatureList *siglist, GError **error)
{
g_autoptr(GPtrArray) volumes = NULL;
volumes = fu_volume_new_by_kind(FU_VOLUME_KIND_ESP, error);
volumes = fu_volume_new_by_esp(error);
if (volumes == NULL)
return FALSE;
for (guint i = 0; i < volumes->len; i++) {

View File

@ -3000,35 +3000,14 @@ fu_util_prompt_for_volume(GError **error)
{
FuVolume *volume;
guint idx;
gboolean is_fallback = FALSE;
g_autoptr(GPtrArray) volumes = NULL;
g_autoptr(GPtrArray) volumes_vfat = g_ptr_array_new();
g_autoptr(GError) error_local = NULL;
/* exactly one */
volumes = fu_volume_new_by_kind(FU_VOLUME_KIND_ESP, &error_local);
if (volumes == NULL) {
is_fallback = TRUE;
g_debug("%s, falling back to %s", error_local->message, FU_VOLUME_KIND_BDP);
volumes = fu_volume_new_by_kind(FU_VOLUME_KIND_BDP, error);
if (volumes == NULL) {
g_prefix_error(error, "%s: ", error_local->message);
return NULL;
}
}
/* on fallback: only add internal vfat partitions */
for (guint i = 0; i < volumes->len; i++) {
FuVolume *vol = g_ptr_array_index(volumes, i);
g_autofree gchar *type = fu_volume_get_id_type(vol);
if (type == NULL)
continue;
if (is_fallback && !fu_volume_is_internal(vol))
continue;
if (g_strcmp0(type, "vfat") == 0)
g_ptr_array_add(volumes_vfat, vol);
}
if (volumes_vfat->len == 1) {
volume = g_ptr_array_index(volumes_vfat, 0);
volumes = fu_volume_new_by_esp(error);
if (volumes == NULL)
return NULL;
if (volumes->len == 1) {
volume = g_ptr_array_index(volumes, 0);
/* TRANSLATORS: Volume has been chosen by the user */
g_print("%s: %s\n", _("Selected volume"), fu_volume_get_id(volume));
return g_object_ref(volume);
@ -3038,11 +3017,11 @@ fu_util_prompt_for_volume(GError **error)
g_print("%s\n", _("Choose a volume:"));
/* TRANSLATORS: this is to abort the interactive prompt */
g_print("0.\t%s\n", _("Cancel"));
for (guint i = 0; i < volumes_vfat->len; i++) {
volume = g_ptr_array_index(volumes_vfat, i);
for (guint i = 0; i < volumes->len; i++) {
volume = g_ptr_array_index(volumes, i);
g_print("%u.\t%s\n", i + 1, fu_volume_get_id(volume));
}
idx = fu_util_prompt_for_number(volumes_vfat->len);
idx = fu_util_prompt_for_number(volumes->len);
if (idx == 0) {
g_set_error_literal(error,
FWUPD_ERROR,
@ -3050,7 +3029,7 @@ fu_util_prompt_for_volume(GError **error)
"Request canceled");
return NULL;
}
volume = g_ptr_array_index(volumes_vfat, idx - 1);
volume = g_ptr_array_index(volumes, idx - 1);
return g_object_ref(volume);
}