diff --git a/libfwupdplugin/fu-volume.c b/libfwupdplugin/fu-volume.c index ac0c2ce93..6d21a00a7 100644 --- a/libfwupdplugin/fu-volume.c +++ b/libfwupdplugin/fu-volume.c @@ -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); +} diff --git a/libfwupdplugin/fu-volume.h b/libfwupdplugin/fu-volume.h index a49ea4b1a..9b46c5b74 100644 --- a/libfwupdplugin/fu-volume.h +++ b/libfwupdplugin/fu-volume.h @@ -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; diff --git a/libfwupdplugin/fwupdplugin.map b/libfwupdplugin/fwupdplugin.map index 79ae1e9d6..c7f318294 100644 --- a/libfwupdplugin/fwupdplugin.map +++ b/libfwupdplugin/fwupdplugin.map @@ -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; diff --git a/plugins/uefi-dbx/fu-uefi-dbx-common.c b/plugins/uefi-dbx/fu-uefi-dbx-common.c index 7db61dade..731b4a36f 100644 --- a/plugins/uefi-dbx/fu-uefi-dbx-common.c +++ b/plugins/uefi-dbx/fu-uefi-dbx-common.c @@ -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++) { diff --git a/src/fu-tool.c b/src/fu-tool.c index 992e64c45..275297252 100644 --- a/src/fu-tool.c +++ b/src/fu-tool.c @@ -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); }