From eddaed0c115518785b094009ff47844d630575db Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Sun, 3 Jan 2021 12:08:38 +0000 Subject: [PATCH] Allow specifying more than one VendorID for a device Asking the user for the UID mapping isn't working very well, as it requires lots of manual handholding. It also doesn't work very well when the device vendor does not actually have a PCI ID or if the vendor has split into two entities. Just use the OUI address as an additional VendorID and match any of the device IDs against any of the metadata-supplied values. --- contrib/fwupd.spec.in | 1 - libfwupd/README.md | 1 + libfwupd/fwupd-device.c | 137 ++++++++++++++++-- libfwupd/fwupd-device.h | 7 + libfwupd/fwupd.map | 8 + libfwupdplugin/fu-device.c | 11 +- libfwupdplugin/fu-device.h | 5 +- libfwupdplugin/fu-udev-device.c | 2 +- libfwupdplugin/fu-usb-device.c | 2 +- plugins/ata/ata.conf | 4 - plugins/ata/fu-ata-device.c | 32 +--- plugins/ata/fu-ata-device.h | 2 - plugins/ata/fu-plugin-ata.c | 8 - plugins/ata/fu-self-test.c | 1 - plugins/ata/meson.build | 4 - plugins/coreboot/fu-plugin-coreboot.c | 2 +- plugins/dell-esrt/fu-plugin-dell-esrt.c | 2 +- plugins/dell/fu-plugin-dell.c | 8 +- plugins/elantp/fu-elantp-i2c-device.c | 2 +- plugins/emmc/fu-emmc-device.c | 2 +- plugins/flashrom/fu-plugin-flashrom.c | 2 +- .../fu-logitech-hidpp-peripheral.c | 2 +- plugins/modem-manager/fu-mm-device.c | 4 +- plugins/pixart-rf/fu-pxi-device.c | 2 +- plugins/superio/fu-plugin-superio.c | 2 +- .../synaptics-mst/fu-synaptics-mst-device.c | 2 +- plugins/test/fu-plugin-test.c | 6 +- plugins/thunderbolt/fu-thunderbolt-device.c | 2 +- plugins/tpm/fu-tpm-device.c | 2 +- plugins/uefi-dbx/fu-uefi-dbx-device.c | 2 +- .../uefi-recovery/fu-plugin-uefi-recovery.c | 2 +- plugins/uefi/fu-plugin-uefi.c | 2 +- plugins/wacom-usb/fu-wac-module.c | 2 +- src/fu-device-list.c | 9 +- src/fu-engine.c | 75 ++++++++-- src/fu-self-test.c | 63 ++++---- 36 files changed, 281 insertions(+), 139 deletions(-) delete mode 100644 plugins/ata/ata.conf diff --git a/contrib/fwupd.spec.in b/contrib/fwupd.spec.in index 961aa433f..7c2142eb3 100644 --- a/contrib/fwupd.spec.in +++ b/contrib/fwupd.spec.in @@ -287,7 +287,6 @@ done %files -f %{name}.lang %doc README.md AUTHORS %license COPYING -%config(noreplace)%{_sysconfdir}/fwupd/ata.conf %config(noreplace)%{_sysconfdir}/fwupd/daemon.conf %config(noreplace)%{_sysconfdir}/fwupd/upower.conf %if 0%{?have_uefi} diff --git a/libfwupd/README.md b/libfwupd/README.md index 96ac10187..84a63450a 100644 --- a/libfwupd/README.md +++ b/libfwupd/README.md @@ -3,6 +3,7 @@ Planned API/ABI changes for next release * Typedef `FwupdFeatureFlags` to `guint64` so it's the same size on all platforms * Remove the `soup-session` fallback property in `FwupdClient`. + * Remove fwupd_device_set_vendor_id() and fwupd_device_get_vendor_id() Migration from Version 0.9.x ============================ diff --git a/libfwupd/fwupd-device.c b/libfwupd/fwupd-device.c index 502eca796..40598fb90 100644 --- a/libfwupd/fwupd-device.c +++ b/libfwupd/fwupd-device.c @@ -34,6 +34,7 @@ typedef struct { guint64 modified; guint64 flags; GPtrArray *guids; + GPtrArray *vendor_ids; GPtrArray *instance_ids; GPtrArray *icons; gchar *name; @@ -42,7 +43,7 @@ typedef struct { gchar *branch; gchar *description; gchar *vendor; - gchar *vendor_id; + gchar *vendor_id; /* for compat only */ gchar *homepage; gchar *plugin; gchar *protocol; @@ -659,11 +660,13 @@ fwupd_device_set_vendor (FwupdDevice *device, const gchar *vendor) * fwupd_device_get_vendor_id: * @device: A #FwupdDevice * - * Gets the device vendor ID. + * Gets the combined device vendor ID. * - * Returns: the device vendor, e.g. 'USB:0x1234', or %NULL if unset + * Returns: the device vendor, e.g. 'USB:0x1234|PCI:0x5678', or %NULL if unset * * Since: 0.9.4 + * + * Deprecated: 1.5.5: Use fwupd_device_get_vendor_ids() instead. **/ const gchar * fwupd_device_get_vendor_id (FwupdDevice *device) @@ -676,19 +679,103 @@ fwupd_device_get_vendor_id (FwupdDevice *device) /** * fwupd_device_set_vendor_id: * @device: A #FwupdDevice - * @vendor_id: the ID, e.g. 'USB:0x1234' + * @vendor_id: the ID, e.g. 'USB:0x1234' or 'USB:0x1234|PCI:0x5678' * * Sets the device vendor ID. * * Since: 0.9.4 + * + * Deprecated: 1.5.5: Use fwupd_device_add_vendor_id() instead. **/ void fwupd_device_set_vendor_id (FwupdDevice *device, const gchar *vendor_id) { - FwupdDevicePrivate *priv = GET_PRIVATE (device); + g_auto(GStrv) vendor_ids = NULL; + g_return_if_fail (FWUPD_IS_DEVICE (device)); + g_return_if_fail (vendor_id != NULL); + + /* add all */ + vendor_ids = g_strsplit (vendor_id, "|", -1); + for (guint i = 0; vendor_ids[i] != NULL; i++) + fwupd_device_add_vendor_id (device, vendor_ids[i]); +} + +/** + * fwupd_device_get_vendor_ids: + * @device: A #FwupdDevice + * + * Gets the device vendor ID. + * + * Returns: (element-type utf8) (transfer none): the device vendor ID + * + * Since: 1.5.5 + **/ +GPtrArray * +fwupd_device_get_vendor_ids (FwupdDevice *device) +{ + FwupdDevicePrivate *priv = GET_PRIVATE (device); + g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); + return priv->vendor_ids; +} + +/** + * fwupd_device_has_vendor_id: + * @device: A #FwupdDevice + * @vendor_id: the ID, e.g. 'USB:0x1234' + * + * Finds out if the device has this specific vendor ID. + * + * Returns: %TRUE if the ID is found + * + * Since: 1.5.5 + **/ +gboolean +fwupd_device_has_vendor_id (FwupdDevice *device, const gchar *vendor_id) +{ + FwupdDevicePrivate *priv = GET_PRIVATE (device); + + g_return_val_if_fail (FWUPD_IS_DEVICE (device), FALSE); + g_return_val_if_fail (vendor_id != NULL, FALSE); + + for (guint i = 0; i < priv->vendor_ids->len; i++) { + const gchar *vendor_id_tmp = g_ptr_array_index (priv->vendor_ids, i); + if (g_strcmp0 (vendor_id, vendor_id_tmp) == 0) + return TRUE; + } + return FALSE; +} + +/** + * fwupd_device_add_vendor_id: + * @device: A #FwupdDevice + * @vendor_id: the ID, e.g. 'USB:0x1234' + * + * Adds a device vendor ID. + * + * Since: 1.5.5 + **/ +void +fwupd_device_add_vendor_id (FwupdDevice *device, const gchar *vendor_id) +{ + FwupdDevicePrivate *priv = GET_PRIVATE (device); + g_auto(GStrv) vendor_ids_tmp = NULL; + + g_return_if_fail (FWUPD_IS_DEVICE (device)); + g_return_if_fail (vendor_id != NULL); + + if (fwupd_device_has_vendor_id (device, vendor_id)) + return; + g_ptr_array_add (priv->vendor_ids, g_strdup (vendor_id)); + + /* build for compatibility */ + vendor_ids_tmp = g_new0 (gchar *, priv->vendor_ids->len + 1); + for (guint i = 0; i < priv->vendor_ids->len; i++) { + const gchar *vendor_id_tmp = g_ptr_array_index (priv->vendor_ids, i); + vendor_ids_tmp[i] = g_strdup (vendor_id_tmp); + } g_free (priv->vendor_id); - priv->vendor_id = g_strdup (vendor_id); + priv->vendor_id = g_strjoinv ("|", vendor_ids_tmp); } /** @@ -1261,8 +1348,10 @@ fwupd_device_incorporate (FwupdDevice *self, FwupdDevice *donor) fwupd_device_set_branch (self, priv_donor->branch); if (priv->vendor == NULL) fwupd_device_set_vendor (self, priv_donor->vendor); - if (priv->vendor_id == NULL) - fwupd_device_set_vendor_id (self, priv_donor->vendor_id); + for (guint i = 0; i < priv_donor->vendor_ids->len; i++) { + const gchar *tmp = g_ptr_array_index (priv_donor->vendor_ids, i); + fwupd_device_add_vendor_id (self, tmp); + } if (priv->plugin == NULL) fwupd_device_set_plugin (self, priv_donor->plugin); if (priv->protocol == NULL) @@ -1363,10 +1452,17 @@ fwupd_device_to_variant_full (FwupdDevice *device, FwupdDeviceFlags flags) FWUPD_RESULT_KEY_VENDOR, g_variant_new_string (priv->vendor)); } - if (priv->vendor_id != NULL) { + if (priv->vendor_ids->len > 0) { + g_autoptr(GString) str = g_string_new (NULL); + for (guint i = 0; i < priv->vendor_ids->len; i++) { + const gchar *tmp = g_ptr_array_index (priv->vendor_ids, i); + g_string_append_printf (str, "%s|", tmp); + } + if (str->len > 0) + g_string_truncate (str, str->len - 1); g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_VENDOR_ID, - g_variant_new_string (priv->vendor_id)); + g_variant_new_string (str->str)); } if (priv->flags > 0) { g_variant_builder_add (&builder, "{sv}", @@ -1600,7 +1696,10 @@ fwupd_device_from_key_value (FwupdDevice *device, const gchar *key, GVariant *va return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_VENDOR_ID) == 0) { - fwupd_device_set_vendor_id (device, g_variant_get_string (value, NULL)); + g_auto(GStrv) vendor_ids = NULL; + vendor_ids = g_strsplit (g_variant_get_string (value, NULL), "|", -1); + for (guint i = 0; vendor_ids[i] != NULL; i++) + fwupd_device_add_vendor_id (device, vendor_ids[i]); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_SERIAL) == 0) { @@ -2141,6 +2240,15 @@ fwupd_device_to_json (FwupdDevice *device, JsonBuilder *builder) } fwupd_device_json_add_string (builder, FWUPD_RESULT_KEY_VENDOR, priv->vendor); fwupd_device_json_add_string (builder, FWUPD_RESULT_KEY_VENDOR_ID, priv->vendor_id); + if (priv->vendor_ids->len > 1) { /* --> 0 when bumping API */ + json_builder_set_member_name (builder, "VendorIds"); + json_builder_begin_array (builder); + for (guint i = 0; i < priv->vendor_ids->len; i++) { + const gchar *tmp = g_ptr_array_index (priv->vendor_ids, i); + json_builder_add_string_value (builder, tmp); + } + json_builder_end_array (builder); + } fwupd_device_json_add_string (builder, FWUPD_RESULT_KEY_VERSION, priv->version); fwupd_device_json_add_string (builder, FWUPD_RESULT_KEY_VERSION_LOWEST, priv->version_lowest); fwupd_device_json_add_string (builder, FWUPD_RESULT_KEY_VERSION_BOOTLOADER, priv->version_bootloader); @@ -2262,7 +2370,10 @@ fwupd_device_to_string (FwupdDevice *device) fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_CHECKSUM, checksum_display); } fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VENDOR, priv->vendor); - fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VENDOR_ID, priv->vendor_id); + for (guint i = 0; i < priv->vendor_ids->len; i++) { + const gchar *tmp = g_ptr_array_index (priv->vendor_ids, i); + fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VENDOR_ID, tmp); + } fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VERSION, priv->version); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VERSION_LOWEST, priv->version_lowest); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VERSION_BOOTLOADER, priv->version_bootloader); @@ -2419,6 +2530,7 @@ fwupd_device_init (FwupdDevice *device) priv->instance_ids = g_ptr_array_new_with_free_func (g_free); priv->icons = g_ptr_array_new_with_free_func (g_free); priv->checksums = g_ptr_array_new_with_free_func (g_free); + priv->vendor_ids = g_ptr_array_new_with_free_func (g_free); priv->children = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); priv->releases = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); } @@ -2449,6 +2561,7 @@ fwupd_device_finalize (GObject *object) g_free (priv->version_lowest); g_free (priv->version_bootloader); g_ptr_array_unref (priv->guids); + g_ptr_array_unref (priv->vendor_ids); g_ptr_array_unref (priv->instance_ids); g_ptr_array_unref (priv->icons); g_ptr_array_unref (priv->checksums); diff --git a/libfwupd/fwupd-device.h b/libfwupd/fwupd-device.h index 0744fd8a0..b29589bcf 100644 --- a/libfwupd/fwupd-device.h +++ b/libfwupd/fwupd-device.h @@ -113,9 +113,16 @@ void fwupd_device_set_protocol (FwupdDevice *device, const gchar *fwupd_device_get_vendor (FwupdDevice *device); void fwupd_device_set_vendor (FwupdDevice *device, const gchar *vendor); +G_DEPRECATED_FOR(fwupd_device_get_vendor_ids) const gchar *fwupd_device_get_vendor_id (FwupdDevice *device); +G_DEPRECATED_FOR(fwupd_device_add_vendor_id) void fwupd_device_set_vendor_id (FwupdDevice *device, const gchar *vendor_id); +void fwupd_device_add_vendor_id (FwupdDevice *device, + const gchar *vendor_id); +gboolean fwupd_device_has_vendor_id (FwupdDevice *device, + const gchar *vendor_id); +GPtrArray *fwupd_device_get_vendor_ids (FwupdDevice *device); void fwupd_device_add_guid (FwupdDevice *device, const gchar *guid); gboolean fwupd_device_has_guid (FwupdDevice *device, diff --git a/libfwupd/fwupd.map b/libfwupd/fwupd.map index 86310ccb5..1d73a2750 100644 --- a/libfwupd/fwupd.map +++ b/libfwupd/fwupd.map @@ -631,3 +631,11 @@ LIBFWUPD_1.5.3 { fwupd_remote_set_keyring_kind; local: *; } LIBFWUPD_1.5.2; + +LIBFWUPD_1.5.5 { + global: + fwupd_device_add_vendor_id; + fwupd_device_get_vendor_ids; + fwupd_device_has_vendor_id; + local: *; +} LIBFWUPD_1.5.3; diff --git a/libfwupdplugin/fu-device.c b/libfwupdplugin/fu-device.c index ea52eabc2..7d51f943d 100644 --- a/libfwupdplugin/fu-device.c +++ b/libfwupdplugin/fu-device.c @@ -808,8 +808,13 @@ fu_device_add_child (FuDevice *self, FuDevice *child) fu_device_set_physical_id (child, fu_device_get_physical_id (self)); if (fu_device_get_vendor (child) == NULL) fu_device_set_vendor (child, fu_device_get_vendor (self)); - if (fu_device_get_vendor_id (child) == NULL) - fu_device_set_vendor_id (child, fu_device_get_vendor_id (self)); + if (fu_device_get_vendor_ids(child)->len == 0) { + GPtrArray *vendor_ids = fu_device_get_vendor_ids (self); + for (guint i = 0; i < vendor_ids->len; i++) { + const gchar *vendor_id = g_ptr_array_index (vendor_ids, i); + fu_device_add_vendor_id (child, vendor_id); + } + } if (fu_device_get_icons(child)->len == 0) { GPtrArray *icons = fu_device_get_icons (self); for (guint i = 0; i < icons->len; i++) { @@ -1011,7 +1016,7 @@ fu_device_set_quirk_kv (FuDevice *self, return TRUE; } if (g_strcmp0 (key, FU_QUIRKS_VENDOR_ID) == 0) { - fu_device_set_vendor_id (self, value); + fu_device_add_vendor_id (self, value); return TRUE; } if (g_strcmp0 (key, FU_QUIRKS_PROTOCOL) == 0) { diff --git a/libfwupdplugin/fu-device.h b/libfwupdplugin/fu-device.h index 35e7b7343..c8a74edcb 100644 --- a/libfwupdplugin/fu-device.h +++ b/libfwupdplugin/fu-device.h @@ -142,6 +142,7 @@ FuDevice *fu_device_new (void); #define fu_device_remove_flag(d,v) fwupd_device_remove_flag(FWUPD_DEVICE(d),v) #define fu_device_has_flag(d,v) fwupd_device_has_flag(FWUPD_DEVICE(d),v) #define fu_device_has_instance_id(d,v) fwupd_device_has_instance_id(FWUPD_DEVICE(d),v) +#define fu_device_has_vendor_id(d,v) fwupd_device_has_vendor_id(FWUPD_DEVICE(d),v) #define fu_device_add_checksum(d,v) fwupd_device_add_checksum(FWUPD_DEVICE(d),v) #define fu_device_add_release(d,v) fwupd_device_add_release(FWUPD_DEVICE(d),v) #define fu_device_add_icon(d,v) fwupd_device_add_icon(FWUPD_DEVICE(d),v) @@ -158,7 +159,7 @@ FuDevice *fu_device_new (void); #define fu_device_set_update_error(d,v) fwupd_device_set_update_error(FWUPD_DEVICE(d),v) #define fu_device_set_update_state(d,v) fwupd_device_set_update_state(FWUPD_DEVICE(d),v) #define fu_device_set_vendor(d,v) fwupd_device_set_vendor(FWUPD_DEVICE(d),v) -#define fu_device_set_vendor_id(d,v) fwupd_device_set_vendor_id(FWUPD_DEVICE(d),v) +#define fu_device_add_vendor_id(d,v) fwupd_device_add_vendor_id(FWUPD_DEVICE(d),v) #define fu_device_set_version_raw(d,v) fwupd_device_set_version_raw(FWUPD_DEVICE(d),v) #define fu_device_set_version_lowest_raw(d,v) fwupd_device_set_version_lowest_raw(FWUPD_DEVICE(d),v) #define fu_device_set_version_bootloader_raw(d,v) fwupd_device_set_version_bootloader_raw(FWUPD_DEVICE(d),v) @@ -188,7 +189,7 @@ FuDevice *fu_device_new (void); #define fu_device_get_version_raw(d) fwupd_device_get_version_raw(FWUPD_DEVICE(d)) #define fu_device_get_version_lowest_raw(d) fwupd_device_get_version_lowest_raw(FWUPD_DEVICE(d)) #define fu_device_get_version_bootloader_raw(d) fwupd_device_get_version_bootloader_raw(FWUPD_DEVICE(d)) -#define fu_device_get_vendor_id(d) fwupd_device_get_vendor_id(FWUPD_DEVICE(d)) +#define fu_device_get_vendor_ids(d) fwupd_device_get_vendor_ids(FWUPD_DEVICE(d)) #define fu_device_get_flashes_left(d) fwupd_device_get_flashes_left(FWUPD_DEVICE(d)) #define fu_device_get_install_duration(d) fwupd_device_get_install_duration(FWUPD_DEVICE(d)) diff --git a/libfwupdplugin/fu-udev-device.c b/libfwupdplugin/fu-udev-device.c index 17abdb0c6..293a32c97 100644 --- a/libfwupdplugin/fu-udev-device.c +++ b/libfwupdplugin/fu-udev-device.c @@ -408,7 +408,7 @@ fu_udev_device_probe (FuDevice *device, GError **error) if (subsystem != NULL && priv->vendor != 0x0000) { g_autofree gchar *vendor_id = NULL; vendor_id = g_strdup_printf ("%s:0x%04X", subsystem, (guint) priv->vendor); - fu_device_set_vendor_id (device, vendor_id); + fu_device_add_vendor_id (device, vendor_id); } /* add GUIDs in order of priority */ diff --git a/libfwupdplugin/fu-usb-device.c b/libfwupdplugin/fu-usb-device.c index 41b38030d..d578f218d 100644 --- a/libfwupdplugin/fu-usb-device.c +++ b/libfwupdplugin/fu-usb-device.c @@ -309,7 +309,7 @@ fu_usb_device_probe (FuDevice *device, GError **error) /* set vendor ID */ vendor_id = g_strdup_printf ("USB:0x%04X", g_usb_device_get_vid (priv->usb_device)); - fu_device_set_vendor_id (device, vendor_id); + fu_device_add_vendor_id (device, vendor_id); /* set the version if the release has been set */ release = g_usb_device_get_release (priv->usb_device); diff --git a/plugins/ata/ata.conf b/plugins/ata/ata.conf deleted file mode 100644 index f76abdd8f..000000000 --- a/plugins/ata/ata.conf +++ /dev/null @@ -1,4 +0,0 @@ -[ata] - -# ask the user to report the missing OUI in the daemon logs -UnknownOuiReport=true diff --git a/plugins/ata/fu-ata-device.c b/plugins/ata/fu-ata-device.c index 070a454f0..328a0ae04 100644 --- a/plugins/ata/fu-ata-device.c +++ b/plugins/ata/fu-ata-device.c @@ -72,7 +72,6 @@ struct _FuAtaDevice { guint16 transfer_blocks; guint8 transfer_mode; guint32 oui; - gboolean unknown_oui_report; }; G_DEFINE_TYPE (FuAtaDevice, fu_ata_device, FU_TYPE_UDEV_DEVICE) @@ -89,12 +88,6 @@ fu_ata_device_get_transfer_blocks (FuAtaDevice *self) return self->transfer_blocks; } -void -fu_ata_device_set_unknown_oui_report (FuAtaDevice *self, gboolean enabled) -{ - self->unknown_oui_report = enabled; -} - static gchar * fu_ata_device_get_string (const guint16 *buf, guint start, guint end) { @@ -179,7 +172,7 @@ fu_ata_device_parse_id_maybe_dell (FuAtaDevice *self, const guint16 *buf) /* owned by Dell */ fu_device_set_vendor (FU_DEVICE (self), "Dell"); - fu_device_set_vendor_id (FU_DEVICE (self), "ATA:0x1028"); + fu_device_add_vendor_id (FU_DEVICE (self), "ATA:0x1028"); } static void @@ -303,7 +296,7 @@ fu_ata_device_parse_vendor_name (FuAtaDevice *self, const gchar *name) /* devices without a vendor ID will not be UPGRADABLE */ if (vendor_id != NULL) - fu_device_set_vendor_id (FU_DEVICE (self), vendor_id); + fu_device_add_vendor_id (FU_DEVICE (self), vendor_id); /* remove leading junk */ while (name[0] == ' ' || name[0] == '_' || name[0] == '-') @@ -394,28 +387,17 @@ fu_ata_device_parse_id (FuAtaDevice *self, const guint8 *buf, gsize sz, GError * fu_device_add_instance_id_full (device, tmp, FU_DEVICE_INSTANCE_FLAG_ONLY_QUIRKS); has_oui_quirk = fu_device_get_vendor (FU_DEVICE (self)) != NULL; } + if (self->oui > 0x0) { + g_autofree gchar *vendor_id = NULL; + vendor_id = g_strdup_printf ("OUI:%06x", self->oui); + fu_device_add_vendor_id (device, vendor_id); + } /* if not already set using the vendor block or a OUI quirk */ name = fu_ata_device_get_string (id, 27, 46); if (name != NULL && !has_oui_quirk) fu_ata_device_parse_vendor_name (self, name); - /* ask user to report data */ - if (self->oui != 0x0 && !has_oui_quirk && self->unknown_oui_report) { - const gchar *url = "https://github.com/fwupd/fwupd/wiki/ATA-Disk:-OUI-Quirk-Required"; - g_printerr ("\nOUI quirk required, please see %s!\n", url); - g_printerr ("---\n"); - g_printerr ("[DeviceInstanceId=OUI\\%06x]\n", self->oui); - if (fu_device_get_vendor_id (FU_DEVICE (self)) != NULL) { - g_printerr ("Vendor = %s\n", fu_device_get_vendor (FU_DEVICE (self))); - g_printerr ("VendorId = %s\n", fu_device_get_vendor_id (FU_DEVICE (self))); - } else { - g_printerr ("Vendor = FIXME\n"); - g_printerr ("VendorId = ATA:UNKNOWN\n"); - } - g_printerr ("---\n"); - } - /* 8 byte additional product identifier == SKU? */ sku = fu_ata_device_get_string (id, 170, 173); if (sku != NULL) diff --git a/plugins/ata/fu-ata-device.h b/plugins/ata/fu-ata-device.h index 54b639bdc..dffae46f6 100644 --- a/plugins/ata/fu-ata-device.h +++ b/plugins/ata/fu-ata-device.h @@ -18,5 +18,3 @@ FuAtaDevice *fu_ata_device_new_from_blob (const guint8 *buf, /* for self tests */ guint8 fu_ata_device_get_transfer_mode (FuAtaDevice *self); guint16 fu_ata_device_get_transfer_blocks (FuAtaDevice *self); -void fu_ata_device_set_unknown_oui_report (FuAtaDevice *self, - gboolean enabled); diff --git a/plugins/ata/fu-plugin-ata.c b/plugins/ata/fu-plugin-ata.c index b37260827..2675ae4d2 100644 --- a/plugins/ata/fu-plugin-ata.c +++ b/plugins/ata/fu-plugin-ata.c @@ -18,11 +18,3 @@ fu_plugin_init (FuPlugin *plugin) fu_plugin_add_udev_subsystem (plugin, "block"); fu_plugin_set_device_gtype (plugin, FU_TYPE_ATA_DEVICE); } - -gboolean -fu_plugin_device_created (FuPlugin *plugin, FuDevice *dev, GError **error) -{ - gboolean tmp = fu_plugin_get_config_value_boolean (plugin, "UnknownOuiReport"); - fu_ata_device_set_unknown_oui_report (FU_ATA_DEVICE (dev), tmp); - return TRUE; -} diff --git a/plugins/ata/fu-self-test.c b/plugins/ata/fu-self-test.c index bbc1b0f5f..a9c2da10a 100644 --- a/plugins/ata/fu-self-test.c +++ b/plugins/ata/fu-self-test.c @@ -63,7 +63,6 @@ fu_ata_oui_func (void) dev = fu_ata_device_new_from_blob ((guint8 *)data, sz, &error); g_assert_no_error (error); g_assert_nonnull (dev); - fu_ata_device_set_unknown_oui_report (dev, FALSE); fu_device_convert_instance_ids (FU_DEVICE (dev)); str = fu_device_to_string (FU_DEVICE (dev)); g_debug ("%s", str); diff --git a/plugins/ata/meson.build b/plugins/ata/meson.build index f32b97fe3..6c55a82b6 100644 --- a/plugins/ata/meson.build +++ b/plugins/ata/meson.build @@ -6,10 +6,6 @@ install_data([ install_dir: join_paths(datadir, 'fwupd', 'quirks.d') ) -install_data(['ata.conf'], - install_dir: join_paths(sysconfdir, 'fwupd') -) - shared_module('fu_plugin_ata', fu_hash, sources : [ diff --git a/plugins/coreboot/fu-plugin-coreboot.c b/plugins/coreboot/fu-plugin-coreboot.c index 0c7bad6a1..af030fec3 100644 --- a/plugins/coreboot/fu-plugin-coreboot.c +++ b/plugins/coreboot/fu-plugin-coreboot.c @@ -91,7 +91,7 @@ fu_plugin_coldplug (FuPlugin *plugin, GError **error) } fu_device_set_vendor (dev, fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_MANUFACTURER)); fu_device_add_instance_id (dev, "main-system-firmware"); - fu_device_set_vendor_id (dev, "DMI:coreboot"); + fu_device_add_vendor_id (dev, "DMI:coreboot"); for (guint i = 0; i < G_N_ELEMENTS (hwids); i++) { char *str; diff --git a/plugins/dell-esrt/fu-plugin-dell-esrt.c b/plugins/dell-esrt/fu-plugin-dell-esrt.c index a6c92fcce..47612e23d 100644 --- a/plugins/dell-esrt/fu-plugin-dell-esrt.c +++ b/plugins/dell-esrt/fu-plugin-dell-esrt.c @@ -163,7 +163,7 @@ fu_plugin_coldplug (FuPlugin *plugin, GError **error) fu_device_set_id (dev, "UEFI-dummy"); fu_device_set_name (dev, "Dell UEFI updates"); fu_device_set_summary (dev, "Enable UEFI Update Functionality"); - fu_device_set_vendor_id (dev, "PCI:0x1028"); + fu_device_add_vendor_id (dev, "PCI:0x1028"); fu_device_add_instance_id (dev, "main-system-firmware"); fu_device_add_guid (dev, "2d47f29b-83a2-4f31-a2e8-63474f4d4c2e"); fu_device_set_version_format (dev, FWUPD_VERSION_FORMAT_NUMBER); diff --git a/plugins/dell/fu-plugin-dell.c b/plugins/dell/fu-plugin-dell.c index efe6b1b19..2279cc3fa 100644 --- a/plugins/dell/fu-plugin-dell.c +++ b/plugins/dell/fu-plugin-dell.c @@ -269,7 +269,7 @@ fu_plugin_dock_node (FuPlugin *plugin, const gchar *platform, dock_name = g_strdup_printf ("Dell %s", dock_type); } fu_device_set_vendor (dev, "Dell Inc."); - fu_device_set_vendor_id (dev, "PCI:0x1028"); + fu_device_add_vendor_id (dev, "PCI:0x1028"); fu_device_set_name (dev, dock_name); fu_device_set_metadata (dev, FU_DEVICE_METADATA_UEFI_DEVICE_KIND, "device-firmware"); if (type == DOCK_TYPE_TB16) { @@ -719,7 +719,7 @@ fu_plugin_dell_detect_tpm (FuPlugin *plugin, GError **error) fu_device_add_instance_id (dev, tpm_guid_raw); fu_device_add_instance_id (dev, "system-tpm"); fu_device_set_vendor (dev, "Dell Inc."); - fu_device_set_vendor_id (dev, "PCI:0x1028"); + fu_device_add_vendor_id (dev, "PCI:0x1028"); fu_device_set_name (dev, pretty_tpm_name); fu_device_set_summary (dev, "Platform TPM device"); fu_device_set_version_format (dev, FWUPD_VERSION_FORMAT_QUAD); @@ -754,7 +754,7 @@ fu_plugin_dell_detect_tpm (FuPlugin *plugin, GError **error) fu_device_set_id (dev_alt, tpm_id_alt); fu_device_add_instance_id (dev_alt, tpm_guid_raw_alt); fu_device_set_vendor (dev, "Dell Inc."); - fu_device_set_vendor_id (dev, "PCI:0x1028"); + fu_device_add_vendor_id (dev, "PCI:0x1028"); fu_device_set_name (dev_alt, pretty_tpm_name_alt); fu_device_set_summary (dev_alt, "Alternate mode for platform TPM device"); fu_device_add_flag (dev_alt, FWUPD_DEVICE_FLAG_INTERNAL); @@ -805,7 +805,7 @@ fu_plugin_device_registered (FuPlugin *plugin, FuDevice *device) /* the kernel returns lowercase in sysfs, need to match it */ device_id = g_strdup_printf ("TBT-%04x%04x", 0x00d4u, (unsigned) system_id); - fu_device_set_vendor_id (device, vendor_id); + fu_device_add_vendor_id (device, vendor_id); fu_device_add_instance_id (device, device_id); fu_device_add_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE); } diff --git a/plugins/elantp/fu-elantp-i2c-device.c b/plugins/elantp/fu-elantp-i2c-device.c index 362f46136..7cab4d5e4 100644 --- a/plugins/elantp/fu-elantp-i2c-device.c +++ b/plugins/elantp/fu-elantp-i2c-device.c @@ -151,7 +151,7 @@ fu_elantp_i2c_device_setup (FuDevice *device, GError **error) if (vid != 0x0000) { g_autofree gchar *vendor_id = NULL; vendor_id = g_strdup_printf ("HIDRAW:0x%04X", vid); - fu_device_set_vendor_id (device, vendor_id); + fu_device_add_vendor_id (device, vendor_id); } /* add GUIDs in order of priority */ diff --git a/plugins/emmc/fu-emmc-device.c b/plugins/emmc/fu-emmc-device.c index 7eb7cf90a..80124069a 100644 --- a/plugins/emmc/fu-emmc-device.c +++ b/plugins/emmc/fu-emmc-device.c @@ -201,7 +201,7 @@ fu_emmc_device_probe (FuUdevDevice *device, GError **error) /* set the vendor */ tmp = g_udev_device_get_sysfs_attr (udev_parent, "manfid"); vendor_id = g_strdup_printf ("EMMC:%s", tmp); - fu_device_set_vendor_id (FU_DEVICE (device), vendor_id); + fu_device_add_vendor_id (FU_DEVICE (device), vendor_id); fu_device_set_vendor (FU_DEVICE (device), fu_emmc_device_get_manufacturer (manfid)); /* set the physical ID */ diff --git a/plugins/flashrom/fu-plugin-flashrom.c b/plugins/flashrom/fu-plugin-flashrom.c index b3b0dd9ac..685934cd4 100644 --- a/plugins/flashrom/fu-plugin-flashrom.c +++ b/plugins/flashrom/fu-plugin-flashrom.c @@ -112,7 +112,7 @@ fu_plugin_coldplug (FuPlugin *plugin, GError **error) fu_device_add_guid (dev, guid); if (dmi_vendor != NULL) { g_autofree gchar *vendor_id = g_strdup_printf ("DMI:%s", dmi_vendor); - fu_device_set_vendor_id (FU_DEVICE (dev), vendor_id); + fu_device_add_vendor_id (FU_DEVICE (dev), vendor_id); } g_ptr_array_add (devices, g_steal_pointer (&dev)); break; diff --git a/plugins/logitech-hidpp/fu-logitech-hidpp-peripheral.c b/plugins/logitech-hidpp/fu-logitech-hidpp-peripheral.c index 288e5100d..ba34eae0b 100644 --- a/plugins/logitech-hidpp/fu-logitech-hidpp-peripheral.c +++ b/plugins/logitech-hidpp/fu-logitech-hidpp-peripheral.c @@ -477,7 +477,7 @@ fu_logitech_hidpp_peripheral_probe (FuUdevDevice *device, GError **error) return FALSE; /* nearly... */ - fu_device_set_vendor_id (FU_DEVICE (device), "USB:0x046D"); + fu_device_add_vendor_id (FU_DEVICE (device), "USB:0x046D"); /* this is a non-standard extension */ devid = g_strdup_printf ("UFY\\VID_%04X&PID_%04X", diff --git a/plugins/modem-manager/fu-mm-device.c b/plugins/modem-manager/fu-mm-device.c index d6ed28a06..f89b2acdf 100644 --- a/plugins/modem-manager/fu-mm-device.c +++ b/plugins/modem-manager/fu-mm-device.c @@ -284,7 +284,7 @@ fu_mm_device_probe_default (FuDevice *device, GError **error) fu_device_set_version (device, version); for (guint i = 0; device_ids[i] != NULL; i++) fu_device_add_instance_id (device, device_ids[i]); - if (fu_device_get_vendor_id (device) == NULL) { + if (fu_device_get_vendor_ids (device) == NULL) { g_autofree gchar *path = g_build_filename (device_sysfs_path, "idVendor", NULL); g_autofree gchar *value = NULL; g_autoptr(GError) error_local = NULL; @@ -293,7 +293,7 @@ fu_mm_device_probe_default (FuDevice *device, GError **error) g_warning ("failed to set vendor ID: %s", error_local->message); } else { g_autofree gchar *vendor_id = g_strdup_printf ("USB:0x%s", g_strchomp (value)); - fu_device_set_vendor_id (device, vendor_id); + fu_device_add_vendor_id (device, vendor_id); } } diff --git a/plugins/pixart-rf/fu-pxi-device.c b/plugins/pixart-rf/fu-pxi-device.c index 73a5ce6e0..7603346ac 100644 --- a/plugins/pixart-rf/fu-pxi-device.c +++ b/plugins/pixart-rf/fu-pxi-device.c @@ -610,7 +610,7 @@ fu_pxi_device_init (FuPxiDevice *self) { fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE); fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_TRIPLET); - fu_device_set_vendor_id (FU_DEVICE (self), "USB:0x093A"); + fu_device_add_vendor_id (FU_DEVICE (self), "USB:0x093A"); fu_device_set_protocol (FU_DEVICE (self), "com.pixart.rf"); } diff --git a/plugins/superio/fu-plugin-superio.c b/plugins/superio/fu-plugin-superio.c index 8e6c7da58..c290053e7 100644 --- a/plugins/superio/fu-plugin-superio.c +++ b/plugins/superio/fu-plugin-superio.c @@ -71,7 +71,7 @@ fu_plugin_superio_coldplug_chipset (FuPlugin *plugin, const gchar *chipset, GErr dmi_vendor = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_BASEBOARD_MANUFACTURER); if (dmi_vendor != NULL) { g_autofree gchar *vendor_id = g_strdup_printf ("DMI:%s", dmi_vendor); - fu_device_set_vendor_id (FU_DEVICE (dev), vendor_id); + fu_device_add_vendor_id (FU_DEVICE (dev), vendor_id); } /* unlock */ diff --git a/plugins/synaptics-mst/fu-synaptics-mst-device.c b/plugins/synaptics-mst/fu-synaptics-mst-device.c index 3c3ece6a0..e5995463e 100644 --- a/plugins/synaptics-mst/fu-synaptics-mst-device.c +++ b/plugins/synaptics-mst/fu-synaptics-mst-device.c @@ -70,7 +70,7 @@ fu_synaptics_mst_device_init (FuSynapticsMstDevice *self) { fu_device_set_protocol (FU_DEVICE (self), "com.synaptics.mst"); fu_device_set_vendor (FU_DEVICE (self), "Synaptics"); - fu_device_set_vendor_id (FU_DEVICE (self), "DRM_DP_AUX_DEV:0x06CB"); + fu_device_add_vendor_id (FU_DEVICE (self), "DRM_DP_AUX_DEV:0x06CB"); fu_device_set_summary (FU_DEVICE (self), "Multi-Stream Transport Device"); fu_device_add_icon (FU_DEVICE (self), "video-display"); fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_TRIPLET); diff --git a/plugins/test/fu-plugin-test.c b/plugins/test/fu-plugin-test.c index 2380ecb56..fd1e7e6f1 100644 --- a/plugins/test/fu-plugin-test.c +++ b/plugins/test/fu-plugin-test.c @@ -42,7 +42,7 @@ fu_plugin_coldplug (FuPlugin *plugin, GError **error) fu_device_set_protocol (device, "com.acme.test"); fu_device_set_summary (device, "A fake webcam"); fu_device_set_vendor (device, "ACME Corp."); - fu_device_set_vendor_id (device, "USB:0x046D"); + fu_device_add_vendor_id (device, "USB:0x046D"); fu_device_set_version_format (device, FWUPD_VERSION_FORMAT_TRIPLET); fu_device_set_version_bootloader (device, "0.1.2"); fu_device_set_version (device, "1.2.2"); @@ -64,7 +64,7 @@ fu_plugin_coldplug (FuPlugin *plugin, GError **error) g_autoptr(FuDevice) child2 = NULL; child1 = fu_device_new (); - fu_device_set_vendor_id (child1, "USB:FFFF"); + fu_device_add_vendor_id (child1, "USB:FFFF"); fu_device_set_protocol (child1, "com.acme"); fu_device_set_physical_id (child1, "fake"); fu_device_set_logical_id (child1, "child1"); @@ -77,7 +77,7 @@ fu_plugin_coldplug (FuPlugin *plugin, GError **error) fu_plugin_device_add (plugin, child1); child2 = fu_device_new (); - fu_device_set_vendor_id (child2, "USB:FFFF"); + fu_device_add_vendor_id (child2, "USB:FFFF"); fu_device_set_protocol (child2, "com.acme"); fu_device_set_physical_id (child2, "fake"); fu_device_set_logical_id (child2, "child2"); diff --git a/plugins/thunderbolt/fu-thunderbolt-device.c b/plugins/thunderbolt/fu-thunderbolt-device.c index c17cf6f86..d86cc90d3 100644 --- a/plugins/thunderbolt/fu-thunderbolt-device.c +++ b/plugins/thunderbolt/fu-thunderbolt-device.c @@ -391,7 +391,7 @@ fu_thunderbolt_device_setup_controller (FuDevice *device, GError **error) domain); } vendor_id = g_strdup_printf ("TBT:0x%04X", (guint) vid); - fu_device_set_vendor_id (device, vendor_id); + fu_device_add_vendor_id (device, vendor_id); device_id = g_strdup_printf ("TBT-%04x%04x%s", (guint) vid, (guint) did, diff --git a/plugins/tpm/fu-tpm-device.c b/plugins/tpm/fu-tpm-device.c index 8e42dfe75..8e50b2c9b 100644 --- a/plugins/tpm/fu-tpm-device.c +++ b/plugins/tpm/fu-tpm-device.c @@ -216,7 +216,7 @@ fu_tpm_device_setup (FuDevice *device, GError **error) /* enforce vendors can only ship updates for their own hardware */ vendor_id = g_strdup_printf ("TPM:%s", manufacturer); - fu_device_set_vendor_id (device, vendor_id); + fu_device_add_vendor_id (device, vendor_id); tmp = fu_tpm_device_convert_manufacturer (manufacturer); fu_device_set_vendor (device, tmp != NULL ? tmp : manufacturer); diff --git a/plugins/uefi-dbx/fu-uefi-dbx-device.c b/plugins/uefi-dbx/fu-uefi-dbx-device.c index fad3a403b..b5064b0fa 100644 --- a/plugins/uefi-dbx/fu-uefi-dbx-device.c +++ b/plugins/uefi-dbx/fu-uefi-dbx-device.c @@ -153,7 +153,7 @@ fu_uefi_dbx_device_init (FuUefiDbxDevice *self) fu_device_set_physical_id (FU_DEVICE (self), "dbx"); fu_device_set_name (FU_DEVICE (self), "UEFI dbx"); fu_device_set_summary (FU_DEVICE (self), "UEFI Revocation Database"); - fu_device_set_vendor_id (FU_DEVICE (self), "UEFI:Linux Foundation"); + fu_device_add_vendor_id (FU_DEVICE (self), "UEFI:Linux Foundation"); fu_device_set_protocol (FU_DEVICE (self), "org.uefi.dbx"); fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_NUMBER); fu_device_set_install_duration (FU_DEVICE (self), 1); diff --git a/plugins/uefi-recovery/fu-plugin-uefi-recovery.c b/plugins/uefi-recovery/fu-plugin-uefi-recovery.c index 59e6d0b34..530eab38f 100644 --- a/plugins/uefi-recovery/fu-plugin-uefi-recovery.c +++ b/plugins/uefi-recovery/fu-plugin-uefi-recovery.c @@ -56,7 +56,7 @@ fu_plugin_coldplug (FuPlugin *plugin, GError **error) dmi_vendor = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_BIOS_VENDOR); if (dmi_vendor != NULL) { g_autofree gchar *vendor_id = g_strdup_printf ("DMI:%s", dmi_vendor); - fu_device_set_vendor_id (device, vendor_id); + fu_device_add_vendor_id (device, vendor_id); } fu_plugin_device_register (plugin, device); diff --git a/plugins/uefi/fu-plugin-uefi.c b/plugins/uefi/fu-plugin-uefi.c index 067e59d65..0871b2be4 100644 --- a/plugins/uefi/fu-plugin-uefi.c +++ b/plugins/uefi/fu-plugin-uefi.c @@ -553,7 +553,7 @@ fu_plugin_uefi_coldplug_device (FuPlugin *plugin, FuUefiDevice *dev, GError **er dmi_vendor = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_BIOS_VENDOR); if (dmi_vendor != NULL) { g_autofree gchar *vendor_id = g_strdup_printf ("DMI:%s", dmi_vendor); - fu_device_set_vendor_id (FU_DEVICE (dev), vendor_id); + fu_device_add_vendor_id (FU_DEVICE (dev), vendor_id); } } diff --git a/plugins/wacom-usb/fu-wac-module.c b/plugins/wacom-usb/fu-wac-module.c index da872ba4b..4633e0338 100644 --- a/plugins/wacom-usb/fu-wac-module.c +++ b/plugins/wacom-usb/fu-wac-module.c @@ -320,7 +320,7 @@ fu_wac_module_constructed (GObject *object) /* set vendor ID */ vendor_id = g_strdup_printf ("USB:0x%04X", g_usb_device_get_vid (priv->usb_device)); - fu_device_set_vendor_id (FU_DEVICE (self), vendor_id); + fu_device_add_vendor_id (FU_DEVICE (self), vendor_id); /* set USB physical and logical IDs */ fu_device_set_physical_id (FU_DEVICE (self), diff --git a/src/fu-device-list.c b/src/fu-device-list.c index 6f24ed8eb..355c50941 100644 --- a/src/fu-device-list.c +++ b/src/fu-device-list.c @@ -569,6 +569,7 @@ static void fu_device_list_replace (FuDeviceList *self, FuDeviceItem *item, FuDevice *device) { const gchar *custom_flags; + GPtrArray *vendor_ids; /* clear timeout if scheduled */ if (item->remove_id != 0) { @@ -580,11 +581,11 @@ fu_device_list_replace (FuDeviceList *self, FuDeviceItem *item, FuDevice *device fu_device_list_add_missing_guids (device, item->device); /* enforce the vendor ID if specified */ - if (fu_device_get_vendor_id (item->device) != NULL && - fu_device_get_vendor_id (device) == NULL) { - const gchar *vendor_id = fu_device_get_vendor_id (item->device); + vendor_ids = fu_device_get_vendor_ids (item->device); + for (guint i = 0; i < vendor_ids->len; i++) { + const gchar *vendor_id = g_ptr_array_index (vendor_ids, i); g_debug ("copying old vendor ID %s to new device", vendor_id); - fu_device_set_vendor_id (device, vendor_id); + fu_device_add_vendor_id (device, vendor_id); } /* copy over custom flags */ diff --git a/src/fu-engine.c b/src/fu-engine.c index 413dac20a..7b01c76d7 100644 --- a/src/fu-engine.c +++ b/src/fu-engine.c @@ -1152,6 +1152,59 @@ fu_engine_check_requirement_not_child (FuEngine *self, XbNode *req, return TRUE; } +static gboolean +fu_engine_check_requirement_vendor_id (FuEngine *self, XbNode *req, + FuDevice *device, GError **error) +{ + GPtrArray *vendor_ids; + const gchar *vendor_ids_metadata; + g_autofree gchar *vendor_ids_device = NULL; + g_auto(GStrv) vendor_ids_tmp = NULL; + + /* devices without vendor IDs should not exist! */ + vendor_ids = fu_device_get_vendor_ids (device); + if (vendor_ids->len == 0) { + g_set_error (error, + FWUPD_ERROR, + FWUPD_ERROR_NOT_SUPPORTED, + "device [%s] has no vendor ID", + fu_device_get_id (device)); + return FALSE; + } + + /* metadata with empty vendor IDs should not exist! */ + vendor_ids_metadata = xb_node_get_attr (req, "version"); + if (vendor_ids_metadata == NULL) { + g_set_error_literal (error, + FWUPD_ERROR, + FWUPD_ERROR_NOT_SUPPORTED, + "metadata has no vendor ID"); + return FALSE; + } + + /* just cat them together into a string */ + vendor_ids_tmp = g_new0 (gchar *, vendor_ids->len + 1); + for (guint i = 0; i < vendor_ids->len; i++) { + const gchar *vendor_id_tmp = g_ptr_array_index (vendor_ids, i); + vendor_ids_tmp[i] = g_strdup (vendor_id_tmp); + } + vendor_ids_device = g_strjoinv ("|", vendor_ids_tmp); + + /* it is always safe to use a regex, even for simple strings */ + if (!g_regex_match_simple (vendor_ids_metadata, vendor_ids_device, 0, 0)) { + g_set_error (error, + FWUPD_ERROR, + FWUPD_ERROR_INVALID_FILE, + "Not compatible with vendor %s: got %s", + vendor_ids_device, + vendor_ids_metadata); + return FALSE; + } + + /* success */ + return TRUE; +} + static gboolean fu_engine_check_requirement_firmware (FuEngine *self, XbNode *req, FuDevice *device, FwupdInstallFlags flags, GError **error) @@ -1228,20 +1281,10 @@ fu_engine_check_requirement_firmware (FuEngine *self, XbNode *req, FuDevice *dev } /* vendor ID */ - if (g_strcmp0 (xb_node_get_text (req), "vendor-id") == 0 && - fu_device_get_vendor_id (device_actual) != NULL) { - if ((flags & FWUPD_INSTALL_FLAG_IGNORE_VID_PID) == 0 && - !fu_engine_require_vercmp (req, fu_device_get_vendor_id (device_actual), - fu_device_get_version_format (device_actual), - &error_local)) { - g_set_error (error, - FWUPD_ERROR, - FWUPD_ERROR_INVALID_FILE, - "Not compatible with vendor: %s", - error_local->message); - return FALSE; - } - return TRUE; + if (g_strcmp0 (xb_node_get_text (req), "vendor-id") == 0) { + if (flags & FWUPD_INSTALL_FLAG_IGNORE_VID_PID) + return TRUE; + return fu_engine_check_requirement_vendor_id (self, req, device_actual, error); } /* child version */ @@ -5302,7 +5345,7 @@ fu_engine_add_device (FuEngine *self, FuDevice *device) /* no vendor-id, and so no way to lock it down! */ if (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE) && - fu_device_get_vendor_id (device) == NULL) { + fu_device_get_vendor_ids(device)->len == 0) { fu_device_remove_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE); fu_device_set_update_error (device, "No vendor ID set"); } @@ -5313,7 +5356,7 @@ fu_engine_add_device (FuEngine *self, FuDevice *device) /* does the device *still* not have a vendor ID? */ if (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE) && - fu_device_get_vendor_id (device) == NULL) { + fu_device_get_vendor_ids(device)->len == 0) { g_warning ("device %s [%s] does not define a vendor-id!", fu_device_get_id (device), fu_device_get_name (device)); diff --git a/src/fu-self-test.c b/src/fu-self-test.c index fb663b0e2..e968fdb7b 100644 --- a/src/fu-self-test.c +++ b/src/fu-self-test.c @@ -354,7 +354,7 @@ fu_engine_requirements_version_require_func (gconstpointer user_data) fu_device_set_version_format (device, FWUPD_VERSION_FORMAT_TRIPLET); fu_device_set_version (device, "1.2.3"); fu_device_set_version_bootloader (device, "4.5.6"); - fu_device_set_vendor_id (device, "FFFF"); + fu_device_add_vendor_id (device, "FFFF"); fu_device_add_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE); fu_device_add_flag (device, FWUPD_DEVICE_FLAG_VERSION_CHECK_REQUIRED); fu_device_add_guid (device, "12345678-1234-1234-1234-123456789012"); @@ -445,7 +445,7 @@ fu_engine_requirements_child_func (gconstpointer user_data) fu_device_set_version_format (device, FWUPD_VERSION_FORMAT_TRIPLET); fu_device_set_version (device, "1.2.3"); fu_device_set_version_bootloader (device, "4.5.6"); - fu_device_set_vendor_id (device, "FFFF"); + fu_device_add_vendor_id (device, "FFFF"); fu_device_add_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE); fu_device_add_guid (device, "12345678-1234-1234-1234-123456789012"); fu_device_set_version_format (child, FWUPD_VERSION_FORMAT_TRIPLET); @@ -501,7 +501,7 @@ fu_engine_requirements_child_fail_func (gconstpointer user_data) fu_device_set_version_format (device, FWUPD_VERSION_FORMAT_TRIPLET); fu_device_set_version (device, "1.2.3"); fu_device_set_version_bootloader (device, "4.5.6"); - fu_device_set_vendor_id (device, "FFFF"); + fu_device_add_vendor_id (device, "FFFF"); fu_device_add_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE); fu_device_add_guid (device, "12345678-1234-1234-1234-123456789012"); fu_device_set_version_format (child, FWUPD_VERSION_FORMAT_TRIPLET); @@ -582,7 +582,7 @@ fu_engine_requirements_device_func (gconstpointer user_data) " " " " " bootloader" - " vendor-id" + " vendor-id" #ifndef _WIN32 " org.kernel" #endif @@ -601,7 +601,8 @@ fu_engine_requirements_device_func (gconstpointer user_data) fu_device_set_version_format (device, FWUPD_VERSION_FORMAT_TRIPLET); fu_device_set_version (device, "1.2.3"); fu_device_set_version_bootloader (device, "4.5.6"); - fu_device_set_vendor_id (device, "FFFF"); + fu_device_add_vendor_id (device, "USB:0xFFFF"); + fu_device_add_vendor_id (device, "PCI:0x0000"); fu_device_add_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE); fu_device_add_flag (device, FWUPD_DEVICE_FLAG_VERSION_CHECK_REQUIRED); fu_device_add_guid (device, "12345678-1234-1234-1234-123456789012"); @@ -649,7 +650,7 @@ fu_engine_requirements_device_plain_func (gconstpointer user_data) /* set up a dummy device */ fu_device_set_version_format (device, FWUPD_VERSION_FORMAT_PLAIN); fu_device_set_version (device, "5101AALB"); - fu_device_set_vendor_id (device, "FFFF"); + fu_device_add_vendor_id (device, "FFFF"); fu_device_add_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE); fu_device_add_guid (device, "12345678-1234-1234-1234-123456789012"); @@ -760,12 +761,12 @@ fu_engine_requirements_other_device_func (gconstpointer user_data) /* set up a different device */ fu_device_set_id (device2, "id2"); - fu_device_set_vendor_id (device2, "USB:FFFF"); + fu_device_add_vendor_id (device2, "USB:FFFF"); fu_device_set_protocol (device2, "com.acme"); fu_device_set_name (device2, "Secondary firmware"); fu_device_set_version_format (device2, FWUPD_VERSION_FORMAT_TRIPLET); fu_device_set_version (device2, "4.5.6"); - fu_device_set_vendor_id (device2, "FFFF"); + fu_device_add_vendor_id (device2, "FFFF"); fu_device_add_guid (device2, "1ff60ab2-3905-06a1-b476-0371f00c9e9b"); fu_engine_add_device (engine, device2); @@ -824,7 +825,7 @@ fu_engine_requirements_protocol_check_func (gconstpointer user_data) fu_device_set_id (device1, "NVME"); fu_device_set_protocol (device1, "com.acme"); fu_device_set_name (device1, "NVME device"); - fu_device_set_vendor_id (device1, "ACME"); + fu_device_add_vendor_id (device1, "ACME"); fu_device_set_version_format (device1, FWUPD_VERSION_FORMAT_TRIPLET); fu_device_set_version (device1, "1.2.3"); fu_device_add_guid (device1, "12345678-1234-1234-1234-123456789012"); @@ -834,7 +835,7 @@ fu_engine_requirements_protocol_check_func (gconstpointer user_data) fu_device_set_id (device2, "UEFI"); fu_device_set_protocol (device2, "org.bar"); fu_device_set_name (device2, "UEFI device"); - fu_device_set_vendor_id (device2, "ACME"); + fu_device_add_vendor_id (device2, "ACME"); fu_device_set_version_format (device2, FWUPD_VERSION_FORMAT_TRIPLET); fu_device_set_version (device2, "1.2.3"); fu_device_add_guid (device2, "12345678-1234-1234-1234-123456789012"); @@ -916,7 +917,7 @@ fu_engine_requirements_parent_device_func (gconstpointer user_data) /* set up a parent device */ fu_device_set_id (device1, "parent"); - fu_device_set_vendor_id (device1, "USB:FFFF"); + fu_device_add_vendor_id (device1, "USB:FFFF"); fu_device_set_protocol (device1, "com.acme"); fu_device_set_name (device1, "parent"); fu_device_set_version_format (device1, FWUPD_VERSION_FORMAT_TRIPLET); @@ -961,7 +962,7 @@ fu_engine_device_priority_func (gconstpointer user_data) /* add low prio then high then low */ fu_device_set_id (device1, "id1"); - fu_device_set_vendor_id (device1, "USB:FFFF"); + fu_device_add_vendor_id (device1, "USB:FFFF"); fu_device_set_protocol (device1, "com.acme"); fu_device_set_priority (device1, 0); fu_device_set_plugin (device1, "udev"); @@ -969,7 +970,7 @@ fu_engine_device_priority_func (gconstpointer user_data) fu_device_convert_instance_ids (device1); fu_engine_add_device (engine, device1); fu_device_set_id (device2, "id2"); - fu_device_set_vendor_id (device2, "USB:FFFF"); + fu_device_add_vendor_id (device2, "USB:FFFF"); fu_device_set_protocol (device2, "com.acme"); fu_device_set_priority (device2, 1); fu_device_set_plugin (device2, "redfish"); @@ -978,7 +979,7 @@ fu_engine_device_priority_func (gconstpointer user_data) fu_device_convert_instance_ids (device2); fu_engine_add_device (engine, device2); fu_device_set_id (device3, "id3"); - fu_device_set_vendor_id (device3, "USB:FFFF"); + fu_device_add_vendor_id (device3, "USB:FFFF"); fu_device_set_protocol (device3, "com.acme"); fu_device_set_priority (device3, 0); fu_device_set_plugin (device3, "uefi"); @@ -1006,7 +1007,7 @@ fu_engine_device_priority_func (gconstpointer user_data) /* add extra devices that should sort */ fu_device_set_id (device4, "id4"); - fu_device_set_vendor_id (device4, "USB:FFFF"); + fu_device_add_vendor_id (device4, "USB:FFFF"); fu_device_set_protocol (device4, "com.acme"); fu_device_set_priority (device4, 0); fu_device_set_plugin (device4, "redfish"); @@ -1015,7 +1016,7 @@ fu_engine_device_priority_func (gconstpointer user_data) fu_device_convert_instance_ids (device4); fu_engine_add_device (engine, device4); fu_device_set_id (device5, "id5"); - fu_device_set_vendor_id (device5, "USB:FFFF"); + fu_device_add_vendor_id (device5, "USB:FFFF"); fu_device_set_protocol (device5, "com.acme"); fu_device_set_priority (device5, 0); fu_device_set_plugin (device5, "uefi"); @@ -1053,7 +1054,7 @@ fu_engine_device_parent_func (gconstpointer user_data) /* add child */ fu_device_set_id (device1, "child"); - fu_device_set_vendor_id (device2, "USB:FFFF"); + fu_device_add_vendor_id (device2, "USB:FFFF"); fu_device_set_protocol (device2, "com.acme"); fu_device_add_instance_id (device1, "child-GUID-1"); fu_device_add_parent_guid (device1, "parent-GUID"); @@ -1062,7 +1063,7 @@ fu_engine_device_parent_func (gconstpointer user_data) /* parent */ fu_device_set_id (device2, "parent"); - fu_device_set_vendor_id (device2, "USB:FFFF"); + fu_device_add_vendor_id (device2, "USB:FFFF"); fu_device_set_protocol (device2, "com.acme"); fu_device_add_instance_id (device2, "parent-GUID"); fu_device_set_vendor (device2, "oem"); @@ -1115,13 +1116,13 @@ fu_engine_partial_hash_func (gconstpointer user_data) /* add two dummy devices */ fu_device_set_id (device1, "device1"); - fu_device_set_vendor_id (device1, "USB:FFFF"); + fu_device_add_vendor_id (device1, "USB:FFFF"); fu_device_set_protocol (device1, "com.acme"); fu_device_set_plugin (device1, "test"); fu_device_add_guid (device1, "12345678-1234-1234-1234-123456789012"); fu_engine_add_device (engine, device1); fu_device_set_id (device2, "device21"); - fu_device_set_vendor_id (device2, "USB:FFFF"); + fu_device_add_vendor_id (device2, "USB:FFFF"); fu_device_set_protocol (device2, "com.acme"); fu_device_set_plugin (device2, "test"); fu_device_set_equivalent_id (device2, "b92f5b7560b84ca005a79f5a15de3c003ce494cf"); @@ -1194,7 +1195,7 @@ fu_engine_device_unlock_func (gconstpointer user_data) /* add a dummy device */ fu_device_set_id (device, "UEFI-dummy-dev0"); - fu_device_set_vendor_id (device, "USB:FFFF"); + fu_device_add_vendor_id (device, "USB:FFFF"); fu_device_set_protocol (device, "com.acme"); fu_device_add_guid (device, "2d47f29b-83a2-4f31-a2e8-63474f4d4c2e"); fu_device_add_flag (device, FWUPD_DEVICE_FLAG_LOCKED); @@ -1245,7 +1246,7 @@ fu_engine_require_hwid_func (gconstpointer user_data) /* add a dummy device */ fu_device_set_id (device, "test_device"); - fu_device_set_vendor_id (device, "USB:FFFF"); + fu_device_add_vendor_id (device, "USB:FFFF"); fu_device_set_protocol (device, "com.acme"); fu_device_set_version_format (device, FWUPD_VERSION_FORMAT_TRIPLET); fu_device_set_version (device, "1.2.2"); @@ -1382,7 +1383,7 @@ fu_engine_downgrade_func (gconstpointer user_data) fu_device_set_version_format (device, FWUPD_VERSION_FORMAT_TRIPLET); fu_device_set_version (device, "1.2.3"); fu_device_set_id (device, "test_device"); - fu_device_set_vendor_id (device, "USB:FFFF"); + fu_device_add_vendor_id (device, "USB:FFFF"); fu_device_set_protocol (device, "com.acme"); fu_device_set_name (device, "Test Device"); fu_device_add_guid (device, "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"); @@ -1497,7 +1498,7 @@ fu_engine_install_duration_func (gconstpointer user_data) fu_device_set_version_format (device, FWUPD_VERSION_FORMAT_TRIPLET); fu_device_set_version (device, "1.2.3"); fu_device_set_id (device, "test_device"); - fu_device_set_vendor_id (device, "USB:FFFF"); + fu_device_add_vendor_id (device, "USB:FFFF"); fu_device_set_protocol (device, "com.acme"); fu_device_add_guid (device, "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"); fu_device_set_install_duration (device, 999); @@ -1567,7 +1568,7 @@ fu_engine_history_func (gconstpointer user_data) fu_device_set_version_format (device, FWUPD_VERSION_FORMAT_TRIPLET); fu_device_set_version (device, "1.2.2"); fu_device_set_id (device, "test_device"); - fu_device_set_vendor_id (device, "USB:FFFF"); + fu_device_add_vendor_id (device, "USB:FFFF"); fu_device_set_protocol (device, "com.acme"); fu_device_set_name (device, "Test Device"); fu_device_set_plugin (device, "test"); @@ -1694,7 +1695,7 @@ fu_engine_multiple_rels_func (gconstpointer user_data) fu_device_set_version_format (device, FWUPD_VERSION_FORMAT_TRIPLET); fu_device_set_version (device, "1.2.2"); fu_device_set_id (device, "test_device"); - fu_device_set_vendor_id (device, "USB:FFFF"); + fu_device_add_vendor_id (device, "USB:FFFF"); fu_device_set_protocol (device, "com.acme"); fu_device_set_name (device, "Test Device"); fu_device_set_plugin (device, "test"); @@ -1765,7 +1766,7 @@ fu_engine_history_inherit (gconstpointer user_data) fu_device_set_version_format (device, FWUPD_VERSION_FORMAT_TRIPLET); fu_device_set_version (device, "1.2.2"); fu_device_set_id (device, "test_device"); - fu_device_set_vendor_id (device, "USB:FFFF"); + fu_device_add_vendor_id (device, "USB:FFFF"); fu_device_set_protocol (device, "com.acme"); fu_device_set_name (device, "Test Device"); fu_device_set_plugin (device, "test"); @@ -1827,7 +1828,7 @@ fu_engine_history_inherit (gconstpointer user_data) fu_engine_add_plugin (engine, self->plugin); device = fu_device_new (); fu_device_set_id (device, "test_device"); - fu_device_set_vendor_id (device, "USB:FFFF"); + fu_device_add_vendor_id (device, "USB:FFFF"); fu_device_set_protocol (device, "com.acme"); fu_device_set_name (device, "Test Device"); fu_device_add_guid (device, "12345678-1234-1234-1234-123456789012"); @@ -1876,7 +1877,7 @@ fu_engine_history_error_func (gconstpointer user_data) fu_device_set_version_format (device, FWUPD_VERSION_FORMAT_TRIPLET); fu_device_set_version (device, "1.2.2"); fu_device_set_id (device, "test_device"); - fu_device_set_vendor_id (device, "USB:FFFF"); + fu_device_add_vendor_id (device, "USB:FFFF"); fu_device_set_protocol (device, "com.acme"); fu_device_set_name (device, "Test Device"); fu_device_set_plugin (device, "test"); @@ -2169,7 +2170,7 @@ fu_device_list_compatible_func (gconstpointer user_data) /* add one device in runtime mode */ fu_device_set_id (device1, "device1"); fu_device_set_plugin (device1, "plugin-for-runtime"); - fu_device_set_vendor_id (device1, "USB:0x20A0"); + fu_device_add_vendor_id (device1, "USB:0x20A0"); fu_device_set_version_format (device1, FWUPD_VERSION_FORMAT_TRIPLET); fu_device_set_version (device1, "1.2.3"); fu_device_add_instance_id (device1, "foobar"); @@ -2196,7 +2197,7 @@ fu_device_list_compatible_func (gconstpointer user_data) g_assert_cmpint (changed_cnt, ==, 1); /* device2 should inherit the vendor ID and version from device1 */ - g_assert_cmpstr (fu_device_get_vendor_id (device2), ==, "USB:0x20A0"); + g_assert_true (fu_device_has_vendor_id (device2, "USB:0x20A0")); g_assert_cmpstr (fu_device_get_version (device2), ==, "1.2.3"); /* one device is active */