mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-07 12:25:38 +00:00
Support vendor-specific UEFI version encodings
This allows vendors such as Dell to use encodings such as AA.BB.CC.DD rather than the default of AA.BB.CCDD which is used by Intel and Microsoft. Existing metainfo.xml files with version numbers prefixed with '0x' are automatically converted to the new scheme. Based on a patch Mario Limonciello, many thanks.
This commit is contained in:
parent
92f903823d
commit
df7950b8f3
@ -436,6 +436,54 @@ fu_main_get_guids_from_store (AsStore *store)
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_main_vendor_quirk_release_version:
|
||||
**/
|
||||
static void
|
||||
fu_main_vendor_quirk_release_version (AsApp *app)
|
||||
{
|
||||
AsVersionParseFlag flags = AS_VERSION_PARSE_FLAG_USE_TRIPLET;
|
||||
GPtrArray *releases;
|
||||
guint i;
|
||||
|
||||
/* no quirk required */
|
||||
if (as_app_get_id_kind (app) != AS_ID_KIND_FIRMWARE)
|
||||
return;
|
||||
|
||||
/* Dell uses AA.BB.CC.DD rather than AA.BB.CCDD */
|
||||
if (g_str_has_prefix (as_app_get_id (app), "com.dell.uefi"))
|
||||
flags = AS_VERSION_PARSE_FLAG_NONE;
|
||||
|
||||
/* fix each release */
|
||||
releases = as_app_get_releases (app);
|
||||
for (i = 0; i < releases->len; i++) {
|
||||
AsRelease *rel;
|
||||
const gchar *version;
|
||||
guint64 ver_uint32;
|
||||
g_autofree gchar *version_new = NULL;
|
||||
|
||||
rel = g_ptr_array_index (releases, i);
|
||||
version = as_release_get_version (rel);
|
||||
if (version == NULL)
|
||||
continue;
|
||||
if (g_strstr_len (version, -1, ".") != NULL)
|
||||
continue;
|
||||
|
||||
/* metainfo files use hex and the LVFS uses decimal */
|
||||
if (g_str_has_prefix (version, "0x")) {
|
||||
ver_uint32 = g_ascii_strtoull (version + 2, NULL, 16);
|
||||
} else {
|
||||
ver_uint32 = g_ascii_strtoull (version, NULL, 10);
|
||||
}
|
||||
if (ver_uint32 == 0)
|
||||
continue;
|
||||
|
||||
/* convert to dotted decimal */
|
||||
version_new = as_utils_version_from_uint32 (ver_uint32, flags);
|
||||
as_release_set_version (rel, version_new);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_main_update_helper:
|
||||
**/
|
||||
@ -521,6 +569,9 @@ fu_main_update_helper (FuMainAuthHelper *helper, GError **error)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* possibly convert the version from 0x to dotted */
|
||||
fu_main_vendor_quirk_release_version (app);
|
||||
|
||||
version = as_release_get_version (rel);
|
||||
fu_device_set_metadata (helper->device, FU_DEVICE_KEY_UPDATE_VERSION, version);
|
||||
|
||||
@ -872,6 +923,9 @@ fu_main_get_updates (FuMainPrivate *priv, GError **error)
|
||||
if (app == NULL)
|
||||
continue;
|
||||
|
||||
/* possibly convert the version from 0x to dotted */
|
||||
fu_main_vendor_quirk_release_version (app);
|
||||
|
||||
/* get latest release */
|
||||
rel = as_app_get_release_default (app);
|
||||
if (rel == NULL) {
|
||||
@ -1409,6 +1463,9 @@ fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender,
|
||||
return;
|
||||
}
|
||||
|
||||
/* possibly convert the version from 0x to dotted */
|
||||
fu_main_vendor_quirk_release_version (app);
|
||||
|
||||
/* create an array with all the metadata in */
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
|
@ -248,12 +248,43 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_provider_uefi_get_version_format:
|
||||
**/
|
||||
static AsVersionParseFlag
|
||||
fu_provider_uefi_get_version_format (void)
|
||||
{
|
||||
guint i;
|
||||
g_autofree gchar *content = NULL;
|
||||
struct {
|
||||
const gchar *sys_vendor;
|
||||
AsVersionParseFlag flags;
|
||||
} version_flags[] = {
|
||||
{ "Dell Inc.", AS_VERSION_PARSE_FLAG_NONE },
|
||||
{ NULL, AS_VERSION_PARSE_FLAG_NONE }
|
||||
};
|
||||
|
||||
/* any vendors match */
|
||||
if (!g_file_get_contents ("/sys/class/dmi/id/sys_vendor",
|
||||
&content, NULL, NULL))
|
||||
return AS_VERSION_PARSE_FLAG_USE_TRIPLET;
|
||||
g_strchomp (content);
|
||||
for (i = 0; version_flags[i].sys_vendor != NULL; i++) {
|
||||
if (g_strcmp0 (content, version_flags[i].sys_vendor) == 0)
|
||||
return version_flags[i].flags;
|
||||
}
|
||||
|
||||
/* fall back */
|
||||
return AS_VERSION_PARSE_FLAG_USE_TRIPLET;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_provider_uefi_coldplug:
|
||||
**/
|
||||
static gboolean
|
||||
fu_provider_uefi_coldplug (FuProvider *provider, GError **error)
|
||||
{
|
||||
AsVersionParseFlag parse_flags;
|
||||
fwup_resource_iter *iter = NULL;
|
||||
fwup_resource *re;
|
||||
g_autofree gchar *guid = NULL;
|
||||
@ -279,6 +310,7 @@ fu_provider_uefi_coldplug (FuProvider *provider, GError **error)
|
||||
|
||||
/* add each device */
|
||||
guid = g_strdup ("00000000-0000-0000-0000-000000000000");
|
||||
parse_flags = fu_provider_uefi_get_version_format ();
|
||||
while (fwup_resource_iter_next (iter, &re) > 0) {
|
||||
efi_guid_t *guid_raw;
|
||||
guint32 version_raw;
|
||||
@ -295,7 +327,7 @@ fu_provider_uefi_coldplug (FuProvider *provider, GError **error)
|
||||
}
|
||||
fwup_get_fw_version(re, &version_raw);
|
||||
version = as_utils_version_from_uint32 (version_raw,
|
||||
AS_VERSION_PARSE_FLAG_USE_TRIPLET);
|
||||
parse_flags);
|
||||
id = g_strdup_printf ("UEFI-%s-dev%" G_GUINT64_FORMAT,
|
||||
guid, hardware_instance);
|
||||
|
||||
@ -306,7 +338,7 @@ fu_provider_uefi_coldplug (FuProvider *provider, GError **error)
|
||||
fwup_get_lowest_supported_fw_version (re, &version_raw);
|
||||
if (version_raw != 0) {
|
||||
version_lowest = as_utils_version_from_uint32 (version_raw,
|
||||
AS_VERSION_PARSE_FLAG_USE_TRIPLET);
|
||||
parse_flags);
|
||||
fu_device_set_metadata (dev, FU_DEVICE_KEY_VERSION_LOWEST,
|
||||
version_lowest);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user