diff --git a/plugins/uefi-capsule/fu-uefi-device.c b/plugins/uefi-capsule/fu-uefi-device.c index 4f5c3beb5..a58af5252 100644 --- a/plugins/uefi-capsule/fu-uefi-device.c +++ b/plugins/uefi-capsule/fu-uefi-device.c @@ -18,8 +18,7 @@ #include "fu-uefi-bootmgr.h" #include "fu-uefi-pcrs.h" -struct _FuUefiDevice { - FuDevice parent_instance; +typedef struct { FuVolume *esp; FuDeviceLocker *esp_locker; gchar *fw_class; @@ -33,9 +32,11 @@ struct _FuUefiDevice { gboolean missing_header; gboolean automounted_esp; gboolean requires_header; -}; +} FuUefiDevicePrivate; -G_DEFINE_TYPE (FuUefiDevice, fu_uefi_device, FU_TYPE_DEVICE) +G_DEFINE_TYPE_WITH_PRIVATE (FuUefiDevice, fu_uefi_device, FU_TYPE_DEVICE) + +#define GET_PRIVATE(o) (fu_uefi_device_get_instance_private (o)) enum { PROP_0, @@ -53,9 +54,10 @@ enum { void fu_uefi_device_set_esp (FuUefiDevice *self, FuVolume *esp) { + FuUefiDevicePrivate *priv = GET_PRIVATE (self); g_return_if_fail (FU_IS_UEFI_DEVICE (self)); g_return_if_fail (FU_IS_VOLUME (esp)); - g_set_object (&self->esp, esp); + g_set_object (&priv->esp, esp); } const gchar * @@ -118,17 +120,18 @@ static void fu_uefi_device_to_string (FuDevice *device, guint idt, GString *str) { FuUefiDevice *self = FU_UEFI_DEVICE (device); - fu_common_string_append_kv (str, idt, "Kind", fu_uefi_device_kind_to_string (self->kind)); - fu_common_string_append_kv (str, idt, "FwClass", self->fw_class); - fu_common_string_append_kx (str, idt, "CapsuleFlags", self->capsule_flags); - fu_common_string_append_kx (str, idt, "FwVersion", self->fw_version); - fu_common_string_append_kx (str, idt, "FwVersionLowest", self->fw_version_lowest); + FuUefiDevicePrivate *priv = GET_PRIVATE (self); + fu_common_string_append_kv (str, idt, "Kind", fu_uefi_device_kind_to_string (priv->kind)); + fu_common_string_append_kv (str, idt, "FwClass", priv->fw_class); + fu_common_string_append_kx (str, idt, "CapsuleFlags", priv->capsule_flags); + fu_common_string_append_kx (str, idt, "FwVersion", priv->fw_version); + fu_common_string_append_kx (str, idt, "FwVersionLowest", priv->fw_version_lowest); fu_common_string_append_kv (str, idt, "LastAttemptStatus", - fu_uefi_device_status_to_string (self->last_attempt_status)); - fu_common_string_append_kx (str, idt, "LastAttemptVersion", self->last_attempt_version); - if (self->esp != NULL) { + fu_uefi_device_status_to_string (priv->last_attempt_status)); + fu_common_string_append_kx (str, idt, "LastAttemptVersion", priv->last_attempt_version); + if (priv->esp != NULL) { fu_common_string_append_kv (str, idt, "EspId", - fu_volume_get_id (self->esp)); + fu_volume_get_id (priv->esp)); } fu_common_string_append_ku (str, idt, "RequireESPFreeSpace", fu_device_get_metadata_integer (device, "RequireESPFreeSpace")); @@ -140,94 +143,105 @@ static void fu_uefi_device_report_metadata_pre (FuDevice *device, GHashTable *metadata) { FuUefiDevice *self = FU_UEFI_DEVICE (device); + FuUefiDevicePrivate *priv = GET_PRIVATE (self); /* record if we had an invalid header during update */ g_hash_table_insert (metadata, g_strdup ("MissingCapsuleHeader"), - g_strdup (self->missing_header ? "True" : "False")); + g_strdup (priv->missing_header ? "True" : "False")); /* where the ESP was mounted during installation */ g_hash_table_insert (metadata, g_strdup ("EspPath"), - fu_volume_get_mount_point (self->esp)); + fu_volume_get_mount_point (priv->esp)); } static void fu_uefi_device_report_metadata_post (FuDevice *device, GHashTable *metadata) { FuUefiDevice *self = FU_UEFI_DEVICE (device); + FuUefiDevicePrivate *priv = GET_PRIVATE (self); /* the actual last_attempt values */ g_hash_table_insert (metadata, g_strdup ("LastAttemptStatus"), - g_strdup_printf ("0x%x", self->last_attempt_status)); + g_strdup_printf ("0x%x", priv->last_attempt_status)); g_hash_table_insert (metadata, g_strdup ("LastAttemptVersion"), - g_strdup_printf ("0x%x", self->last_attempt_version)); + g_strdup_printf ("0x%x", priv->last_attempt_version)); } FuUefiDeviceKind fu_uefi_device_get_kind (FuUefiDevice *self) { + FuUefiDevicePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FU_IS_UEFI_DEVICE (self), 0); - return self->kind; + return priv->kind; } guint32 fu_uefi_device_get_version (FuUefiDevice *self) { + FuUefiDevicePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FU_IS_UEFI_DEVICE (self), 0x0); - return self->fw_version; + return priv->fw_version; } guint32 fu_uefi_device_get_version_lowest (FuUefiDevice *self) { + FuUefiDevicePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FU_IS_UEFI_DEVICE (self), 0x0); - return self->fw_version_lowest; + return priv->fw_version_lowest; } guint32 fu_uefi_device_get_version_error (FuUefiDevice *self) { + FuUefiDevicePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FU_IS_UEFI_DEVICE (self), 0x0); - return self->last_attempt_version; + return priv->last_attempt_version; } guint64 fu_uefi_device_get_hardware_instance (FuUefiDevice *self) { + FuUefiDevicePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FU_IS_UEFI_DEVICE (self), 0x0); - return self->fmp_hardware_instance; + return priv->fmp_hardware_instance; } FuUefiDeviceStatus fu_uefi_device_get_status (FuUefiDevice *self) { + FuUefiDevicePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FU_IS_UEFI_DEVICE (self), 0); - return self->last_attempt_status; + return priv->last_attempt_status; } guint32 fu_uefi_device_get_capsule_flags (FuUefiDevice *self) { + FuUefiDevicePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FU_IS_UEFI_DEVICE (self), 0x0); - return self->capsule_flags; + return priv->capsule_flags; } const gchar * fu_uefi_device_get_guid (FuUefiDevice *self) { + FuUefiDevicePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FU_IS_UEFI_DEVICE (self), NULL); - return self->fw_class; + return priv->fw_class; } static gchar * fu_uefi_device_build_varname (FuUefiDevice *self) { + FuUefiDevicePrivate *priv = GET_PRIVATE (self); return g_strdup_printf ("fwupd-%s-%"G_GUINT64_FORMAT, - self->fw_class, - self->fmp_hardware_instance); + priv->fw_class, + priv->fmp_hardware_instance); } FuUefiUpdateInfo * @@ -348,11 +362,12 @@ static GBytes * fu_uefi_device_fixup_firmware (FuDevice *device, GBytes *fw, GError **error) { FuUefiDevice *self = FU_UEFI_DEVICE (device); + FuUefiDevicePrivate *priv = GET_PRIVATE (self); gsize fw_length; const guint8 *data = g_bytes_get_data (fw, &fw_length); g_autofree gchar *guid_new = NULL; - self->missing_header = FALSE; + priv->missing_header = FALSE; /* GUID is the first 16 bytes */ if (fw_length < sizeof(fwupd_guid_t)) { @@ -367,7 +382,7 @@ fu_uefi_device_fixup_firmware (FuDevice *device, GBytes *fw, GError **error) g_debug ("ESRT matches payload GUID"); return g_bytes_ref (fw); /* Type that doesn't require a header */ - } else if (!self->requires_header) { + } else if (!priv->requires_header) { return g_bytes_ref (fw); /* Missing, add a header */ } else { @@ -378,8 +393,8 @@ fu_uefi_device_fixup_firmware (FuDevice *device, GBytes *fw, GError **error) efi_capsule_header_t *header = (efi_capsule_header_t *) new_data; g_warning ("missing or invalid embedded capsule header"); - self->missing_header = TRUE; - header->flags = self->capsule_flags; + priv->missing_header = TRUE; + header->flags = priv->capsule_flags; header->header_size = header_size; header->capsule_image_size = fw_length + header_size; if (!fwupd_guid_from_string (fu_uefi_device_get_guid (self), &esrt_guid, @@ -401,6 +416,7 @@ fu_uefi_device_write_update_info (FuUefiDevice *self, const gchar *guid, GError **error) { + FuUefiDevicePrivate *priv = GET_PRIVATE (self); gsize datasz = 0; gsize dp_bufsz = 0; g_autofree guint8 *data = NULL; @@ -408,8 +424,8 @@ fu_uefi_device_write_update_info (FuUefiDevice *self, efi_update_info_t info = { .update_info_version = 0x7, .guid = { 0x0 }, - .capsule_flags = self->capsule_flags, - .hw_inst = self->fmp_hardware_instance, + .capsule_flags = priv->capsule_flags, + .hw_inst = priv->fmp_hardware_instance, .time_attempted = { 0x0 }, .status = FU_UEFI_UPDATE_INFO_STATUS_ATTEMPT_UPDATE, }; @@ -444,12 +460,13 @@ static gboolean fu_uefi_device_check_esp_free (FuDevice *device, GError **error) { FuUefiDevice *self = FU_UEFI_DEVICE (device); + FuUefiDevicePrivate *priv = GET_PRIVATE (self); guint64 sz_reqd = fu_device_get_metadata_integer (device, "RequireESPFreeSpace"); if (sz_reqd == G_MAXUINT) { g_debug ("maximum size is not configured"); return TRUE; } - return fu_volume_check_free_space (self->esp, sz_reqd, error); + return fu_volume_check_free_space (priv->esp, sz_reqd, error); } static gboolean @@ -469,7 +486,8 @@ static gboolean fu_uefi_device_cleanup_esp (FuDevice *device, GError **error) { FuUefiDevice *self = FU_UEFI_DEVICE (device); - g_autofree gchar *esp_path = fu_volume_get_mount_point (self->esp); + FuUefiDevicePrivate *priv = GET_PRIVATE (self); + g_autofree gchar *esp_path = fu_volume_get_mount_point (priv->esp); g_autofree gchar *pattern = NULL; g_autoptr(GPtrArray) files = NULL; @@ -505,10 +523,11 @@ fu_uefi_device_prepare (FuDevice *device, GError **error) { FuUefiDevice *self = FU_UEFI_DEVICE (device); + FuUefiDevicePrivate *priv = GET_PRIVATE (self); /* mount if required */ - self->esp_locker = fu_volume_locker (self->esp, error); - if (self->esp_locker == NULL) + priv->esp_locker = fu_volume_locker (priv->esp, error); + if (priv->esp_locker == NULL) return FALSE; /* sanity checks */ @@ -528,11 +547,12 @@ fu_uefi_device_cleanup (FuDevice *device, GError **error) { FuUefiDevice *self = FU_UEFI_DEVICE (device); + FuUefiDevicePrivate *priv = GET_PRIVATE (self); /* unmount ESP if we opened it */ - if (!fu_device_locker_close (self->esp_locker, error)) + if (!fu_device_locker_close (priv->esp_locker, error)) return FALSE; - g_clear_object (&self->esp_locker); + g_clear_object (&priv->esp_locker); return TRUE; } @@ -544,9 +564,10 @@ fu_uefi_device_write_firmware (FuDevice *device, GError **error) { FuUefiDevice *self = FU_UEFI_DEVICE (device); + FuUefiDevicePrivate *priv = GET_PRIVATE (self); FuUefiBootmgrFlags flags = FU_UEFI_BOOTMGR_FLAG_NONE; const gchar *bootmgr_desc = "Linux Firmware Updater"; - g_autofree gchar *esp_path = fu_volume_get_mount_point (self->esp); + g_autofree gchar *esp_path = fu_volume_get_mount_point (priv->esp); g_autoptr(GBytes) fixed_fw = NULL; g_autoptr(GBytes) fw = NULL; g_autofree gchar *basename = NULL; @@ -555,7 +576,7 @@ fu_uefi_device_write_firmware (FuDevice *device, g_autofree gchar *varname = fu_uefi_device_build_varname (self); /* ensure we have the existing state */ - if (self->fw_class == NULL) { + if (priv->fw_class == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, @@ -570,7 +591,7 @@ fu_uefi_device_write_firmware (FuDevice *device, /* save the blob to the ESP */ directory = fu_uefi_get_esp_path_for_os (device, esp_path); - basename = g_strdup_printf ("fwupd-%s.cap", self->fw_class); + basename = g_strdup_printf ("fwupd-%s.cap", priv->fw_class); fn = g_build_filename (directory, "fw", basename, NULL); if (!fu_common_mkdir_parent (fn, error)) return FALSE; @@ -593,7 +614,7 @@ fu_uefi_device_write_firmware (FuDevice *device, } /* set the blob header shared with fwupd.efi */ - if (!fu_uefi_device_write_update_info (self, fn, varname, self->fw_class, error)) + if (!fu_uefi_device_write_update_info (self, fn, varname, priv->fw_class, error)) return FALSE; /* update the firmware before the bootloader runs */ @@ -656,6 +677,7 @@ static gboolean fu_uefi_device_probe (FuDevice *device, GError **error) { FuUefiDevice *self = FU_UEFI_DEVICE (device); + FuUefiDevicePrivate *priv = GET_PRIVATE (self); FwupdVersionFormat version_format; g_autofree gchar *devid = NULL; g_autofree gchar *guid_strup = NULL; @@ -663,7 +685,7 @@ fu_uefi_device_probe (FuDevice *device, GError **error) g_autofree gchar *version = NULL; /* broken sysfs? */ - if (self->fw_class == NULL) { + if (priv->fw_class == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, @@ -672,27 +694,27 @@ fu_uefi_device_probe (FuDevice *device, GError **error) } /* this is invalid */ - if (!fwupd_guid_is_valid (self->fw_class)) { + if (!fwupd_guid_is_valid (priv->fw_class)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, - "ESRT GUID '%s' was not valid", self->fw_class); + "ESRT GUID '%s' was not valid", priv->fw_class); return FALSE; } /* add GUID first, as quirks may set the version format */ - fu_device_add_guid (device, self->fw_class); + fu_device_add_guid (device, priv->fw_class); /* set versions */ version_format = fu_device_get_version_format (device); - version = fu_common_version_from_uint32 (self->fw_version, version_format); + version = fu_common_version_from_uint32 (priv->fw_version, version_format); fu_device_set_version_format (device, version_format); - fu_device_set_version_raw (device, self->fw_version); + fu_device_set_version_raw (device, priv->fw_version); fu_device_set_version (device, version); - if (self->fw_version_lowest != 0) { - version_lowest = fu_common_version_from_uint32 (self->fw_version_lowest, + if (priv->fw_version_lowest != 0) { + version_lowest = fu_common_version_from_uint32 (priv->fw_version_lowest, version_format); - fu_device_set_version_lowest_raw (device, self->fw_version_lowest); + fu_device_set_version_lowest_raw (device, priv->fw_version_lowest); fu_device_set_version_lowest (device, version_lowest); } @@ -704,7 +726,7 @@ fu_uefi_device_probe (FuDevice *device, GError **error) fu_device_add_internal_flag (device, FU_DEVICE_INTERNAL_FLAG_MD_SET_ICON); /* add icons */ - if (self->kind == FU_UEFI_DEVICE_KIND_DEVICE_FIRMWARE) { + if (priv->kind == FU_UEFI_DEVICE_KIND_DEVICE_FIRMWARE) { /* nothing better in the icon naming spec */ fu_device_add_icon (device, "audio-card"); } else { @@ -714,7 +736,7 @@ fu_uefi_device_probe (FuDevice *device, GError **error) } /* set the PCR0 as the device checksum */ - if (self->kind == FU_UEFI_DEVICE_KIND_SYSTEM_FIRMWARE) { + if (priv->kind == FU_UEFI_DEVICE_KIND_SYSTEM_FIRMWARE) { g_autoptr(GError) error_local = NULL; fu_device_add_flag (device, FWUPD_DEVICE_FLAG_CAN_VERIFY); if (!fu_uefi_device_add_system_checksum (device, &error_local)) @@ -722,15 +744,15 @@ fu_uefi_device_probe (FuDevice *device, GError **error) } /* whether to create a missing header */ - if (self->kind == FU_UEFI_DEVICE_KIND_FMP || - self->kind == FU_UEFI_DEVICE_KIND_DELL_TPM_FIRMWARE) - self->requires_header = FALSE; + if (priv->kind == FU_UEFI_DEVICE_KIND_FMP || + priv->kind == FU_UEFI_DEVICE_KIND_DELL_TPM_FIRMWARE) + priv->requires_header = FALSE; else - self->requires_header = TRUE; + priv->requires_header = TRUE; /* Windows seems to be case insensitive, but for convenience we'll * match the upper case values typically specified in the .inf file */ - guid_strup = g_ascii_strup (self->fw_class, -1); + guid_strup = g_ascii_strup (priv->fw_class, -1); devid = g_strdup_printf ("UEFI\\RES_{%s}", guid_strup); fu_device_add_instance_id (device, devid); return TRUE; @@ -741,30 +763,31 @@ fu_uefi_device_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { FuUefiDevice *self = FU_UEFI_DEVICE (object); + FuUefiDevicePrivate *priv = GET_PRIVATE (self); switch (prop_id) { case PROP_FW_CLASS: - self->fw_class = g_value_dup_string (value); + priv->fw_class = g_value_dup_string (value); break; case PROP_KIND: - self->kind = g_value_get_uint (value); + priv->kind = g_value_get_uint (value); break; case PROP_CAPSULE_FLAGS: - self->capsule_flags = g_value_get_uint (value); + priv->capsule_flags = g_value_get_uint (value); break; case PROP_FW_VERSION: - self->fw_version = g_value_get_uint (value); + priv->fw_version = g_value_get_uint (value); break; case PROP_FW_VERSION_LOWEST: - self->fw_version_lowest = g_value_get_uint (value); + priv->fw_version_lowest = g_value_get_uint (value); break; case PROP_LAST_ATTEMPT_STATUS: - self->last_attempt_status = g_value_get_uint (value); + priv->last_attempt_status = g_value_get_uint (value); break; case PROP_LAST_ATTEMPT_VERSION: - self->last_attempt_version = g_value_get_uint (value); + priv->last_attempt_version = g_value_get_uint (value); break; case PROP_FMP_HARDWARE_INSTANCE: - self->fmp_hardware_instance = g_value_get_uint64 (value); + priv->fmp_hardware_instance = g_value_get_uint64 (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -792,12 +815,13 @@ static void fu_uefi_device_finalize (GObject *object) { FuUefiDevice *self = FU_UEFI_DEVICE (object); + FuUefiDevicePrivate *priv = GET_PRIVATE (self); - g_free (self->fw_class); - if (self->esp != NULL) - g_object_unref (self->esp); - if (self->esp_locker != NULL) - g_object_unref (self->esp_locker); + g_free (priv->fw_class); + if (priv->esp != NULL) + g_object_unref (priv->esp); + if (priv->esp_locker != NULL) + g_object_unref (priv->esp_locker); G_OBJECT_CLASS (fu_uefi_device_parent_class)->finalize (object); } @@ -877,18 +901,20 @@ fu_uefi_device_new_from_dev (FuDevice *dev) { const gchar *tmp; FuUefiDevice *self; + FuUefiDevicePrivate *priv; g_return_val_if_fail (fu_device_get_guid_default (dev) != NULL, NULL); /* create virtual object not backed by an ESRT entry */ self = g_object_new (FU_TYPE_UEFI_DEVICE, NULL); fu_device_incorporate (FU_DEVICE (self), dev); - self->fw_class = g_strdup (fu_device_get_guid_default (dev)); + priv = GET_PRIVATE (self); + priv->fw_class = g_strdup (fu_device_get_guid_default (dev)); tmp = fu_device_get_metadata (dev, FU_DEVICE_METADATA_UEFI_DEVICE_KIND); - self->kind = fu_uefi_device_kind_from_string (tmp); - self->capsule_flags = fu_device_get_metadata_integer (dev, FU_DEVICE_METADATA_UEFI_CAPSULE_FLAGS); - self->fw_version = fu_device_get_metadata_integer (dev, FU_DEVICE_METADATA_UEFI_FW_VERSION); - g_assert (self->fw_class != NULL); + priv->kind = fu_uefi_device_kind_from_string (tmp); + priv->capsule_flags = fu_device_get_metadata_integer (dev, FU_DEVICE_METADATA_UEFI_CAPSULE_FLAGS); + priv->fw_version = fu_device_get_metadata_integer (dev, FU_DEVICE_METADATA_UEFI_FW_VERSION); + g_assert (priv->fw_class != NULL); return self; } @@ -896,8 +922,10 @@ FuUefiDevice * fu_uefi_device_new_from_guid (const gchar *guid) { FuUefiDevice *self; + FuUefiDevicePrivate *priv; self = g_object_new (FU_TYPE_UEFI_DEVICE, NULL); - self->fw_class = g_strdup (guid); + priv = GET_PRIVATE (self); + priv->fw_class = g_strdup (guid); fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_NUMBER); return self; } diff --git a/plugins/uefi-capsule/fu-uefi-device.h b/plugins/uefi-capsule/fu-uefi-device.h index 9087ae6c7..cdc3c7d08 100644 --- a/plugins/uefi-capsule/fu-uefi-device.h +++ b/plugins/uefi-capsule/fu-uefi-device.h @@ -13,7 +13,12 @@ #include "fu-uefi-update-info.h" #define FU_TYPE_UEFI_DEVICE (fu_uefi_device_get_type ()) -G_DECLARE_FINAL_TYPE (FuUefiDevice, fu_uefi_device, FU, UEFI_DEVICE, FuDevice) +G_DECLARE_DERIVABLE_TYPE (FuUefiDevice, fu_uefi_device, FU, UEFI_DEVICE, FuDevice) + +struct _FuUefiDeviceClass +{ + FuDeviceClass parent_class; +}; typedef enum { FU_UEFI_DEVICE_KIND_UNKNOWN,