示例#1
0
static void
fu_wac_module_constructed (GObject *object)
{
	FuWacModule *self = FU_WAC_MODULE (object);
	FuWacModulePrivate *priv = GET_PRIVATE (self);
	g_autofree gchar *devid = NULL;
	g_autofree gchar *vendor_id = NULL;

	/* 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);

	/* set USB physical and logical IDs */
	fu_device_set_physical_id (FU_DEVICE (self),
				   g_usb_device_get_platform_id (priv->usb_device));
	fu_device_set_logical_id (FU_DEVICE (self),
				  fu_wac_module_fw_type_to_string (priv->fw_type));

	/* append the firmware kind to the generated GUID */
	devid = g_strdup_printf ("USB\\VID_%04X&PID_%04X-%s",
				 g_usb_device_get_vid (priv->usb_device),
				 g_usb_device_get_pid (priv->usb_device),
				 fu_wac_module_fw_type_to_string (priv->fw_type));
	fu_device_add_instance_id (FU_DEVICE (self), devid);

	G_OBJECT_CLASS (fu_wac_module_parent_class)->constructed (object);
}
示例#2
0
static gboolean
fu_plugin_dell_dock_probe (FuPlugin *plugin,
			   FuDevice *symbiote,
			   GError **error)
{
	g_autoptr(FuDellDockEc) ec_device = NULL;

	/* create all static endpoints */
	ec_device = fu_dell_dock_ec_new (symbiote);
	if (!fu_plugin_dell_dock_create_node (plugin,
					      FU_DEVICE (ec_device),
					      error))
		return FALSE;

	/* create TBT endpoint if Thunderbolt SKU and Thunderbolt link inactive */
	if (fu_dell_dock_ec_needs_tbt (FU_DEVICE (ec_device))) {
		g_autoptr(FuDellDockTbt) tbt_device = fu_dell_dock_tbt_new ();
		fu_device_add_child (FU_DEVICE (ec_device), FU_DEVICE (tbt_device));
		if (!fu_plugin_dell_dock_create_node (plugin,
						      FU_DEVICE (tbt_device),
						      error))
			return FALSE;
	}

	return TRUE;
}
示例#3
0
/**
 * fu_usb_device_set_dev:
 * @device: A #FuUsbDevice
 * @usb_device: A #GUsbDevice, or %NULL
 *
 * Sets the #GUsbDevice to use.
 *
 * Since: 1.0.2
 **/
void
fu_usb_device_set_dev (FuUsbDevice *device, GUsbDevice *usb_device)
{
	FuUsbDevicePrivate *priv = GET_PRIVATE (device);

	g_return_if_fail (FU_IS_USB_DEVICE (device));

	/* need to re-probe hardware */
	fu_device_probe_invalidate (FU_DEVICE (device));

	/* allow replacement */
	g_set_object (&priv->usb_device, usb_device);
	if (usb_device == NULL) {
		g_clear_object (&priv->usb_device_locker);
		return;
	}

	/* set device ID automatically */
	fu_device_set_physical_id (FU_DEVICE (device),
				   g_usb_device_get_platform_id (usb_device));
}
示例#4
0
gboolean
fu_plugin_usb_device_added (FuPlugin *plugin, FuUsbDevice *device, GError **error)
{
	g_autoptr(FuWacDevice) dev = NULL;
	g_autoptr(FuDeviceLocker) locker = NULL;
	dev = fu_wac_device_new (device);
	locker = fu_device_locker_new (dev, error);
	if (locker == NULL)
		return FALSE;
	fu_plugin_device_add (plugin, FU_DEVICE (dev));
	return TRUE;
}
示例#5
0
/* now with kind and usb_device set */
static void
fu_altos_device_init_real (FuAltosDevice *self)
{
	/* allowed, but requires manual bootloader step */
	fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);

	/* set default vendor */
	fu_device_set_vendor (FU_DEVICE (self), "altusmetrum.org");

	/* set name */
	switch (self->kind) {
	case FU_ALTOS_DEVICE_KIND_BOOTLOADER:
		fu_device_set_name (FU_DEVICE (self), "Altos [bootloader]");
		break;
	case FU_ALTOS_DEVICE_KIND_CHAOSKEY:
		fu_device_set_name (FU_DEVICE (self), "Altos ChaosKey");
		break;
	default:
		g_assert_not_reached ();
		break;
	}

	/* set one line summary */
	fu_device_set_summary (FU_DEVICE (self),
			       "A USB hardware random number generator");

	/* only the bootloader can do the update */
	if (self->kind != FU_ALTOS_DEVICE_KIND_BOOTLOADER) {
		fu_device_add_flag (FU_DEVICE (self),
				    FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER);
	}
}
示例#6
0
FuAltosDevice *
fu_altos_device_new (FuUsbDevice *device)
{
	const FuAltosDeviceVidPid vidpids[] = {
		{ 0xfffe, 0x000a, FU_ALTOS_DEVICE_KIND_BOOTLOADER },
		{ 0x1d50, 0x60c6, FU_ALTOS_DEVICE_KIND_CHAOSKEY },
		{ 0x0000, 0x0000, FU_ALTOS_DEVICE_KIND_UNKNOWN }
	};

	/* set kind */
	for (guint j = 0; vidpids[j].vid != 0x0000; j++) {
		if (fu_usb_device_get_vid (device) == vidpids[j].vid &&
		    fu_usb_device_get_pid (device) == vidpids[j].pid) {
			FuAltosDevice *self = g_object_new (FU_TYPE_ALTOS_DEVICE, NULL);
			fu_device_incorporate (FU_DEVICE (self), FU_DEVICE (device));
			self->kind = vidpids[j].kind;
			fu_altos_device_init_real (self);
			return self;
		}
	}
	return NULL;
}
示例#7
0
gboolean
fu_plugin_usb_device_added (FuPlugin *plugin, FuUsbDevice *device, GError **error)
{
	g_autoptr(FuDeviceLocker) locker = NULL;
	g_autoptr(FuRts54HubDevice) dev = NULL;

	/* open the device */
	dev = fu_rts54hub_device_new (device);
	locker = fu_device_locker_new (dev, error);
	if (locker == NULL)
		return FALSE;

	/* success */
	fu_plugin_device_add (plugin, FU_DEVICE (dev));
	return TRUE;
}
示例#8
0
gboolean
fu_plugin_usb_device_added (FuPlugin *plugin, GUsbDevice *usb_device, GError **error)
{
	g_autoptr(FuDeviceLocker) locker = NULL;
	g_autoptr(FuNitrokeyDevice) device = NULL;

	/* open the device */
	device = fu_nitrokey_device_new (usb_device);
	locker = fu_device_locker_new (device, error);
	if (locker == NULL)
		return FALSE;

	/* success */
	fu_plugin_device_add (plugin, FU_DEVICE (device));
	return TRUE;
}
示例#9
0
gboolean
fu_plugin_usb_device_added (FuPlugin *plugin, FuUsbDevice *device, GError **error)
{
	g_autoptr(FuDeviceLocker) locker = NULL;
	g_autoptr(FuColorhugDevice) dev = NULL;

	/* open the device */
	dev = fu_colorhug_device_new (device);
	locker = fu_device_locker_new (dev, error);
	if (locker == NULL)
		return FALSE;

	/* insert to hash */
	fu_plugin_device_add (plugin, FU_DEVICE (dev));
	return TRUE;
}
示例#10
0
static gboolean
fu_altos_device_probe (FuDevice *device, GError **error)
{
	FuAltosDevice *self = FU_ALTOS_DEVICE (device);
	GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (self));

	/* bootloader uses tty */
	if (self->kind == FU_ALTOS_DEVICE_KIND_BOOTLOADER)
		return fu_altos_device_probe_bootloader (self, error);

	/* get version */
	if (self->kind == FU_ALTOS_DEVICE_KIND_CHAOSKEY) {
		const gchar *version_prefix = "ChaosKey-hw-1.0-sw-";
		guint8 version_idx;
		g_autofree gchar *version = NULL;
		g_autoptr(FuDeviceLocker) locker = NULL;

		/* open */
		locker = fu_device_locker_new (usb_device, error);
		if (locker == NULL)
			return FALSE;

		/* get string */
		version_idx = g_usb_device_get_product_index (usb_device);
		version = g_usb_device_get_string_descriptor (usb_device,
							      version_idx,
							      error);
		if (version == NULL)
			return FALSE;
		if (!g_str_has_prefix (version, version_prefix)) {
			g_set_error (error,
				     FWUPD_ERROR,
				     FWUPD_ERROR_NOT_SUPPORTED,
				     "not a ChaosKey v1.0 device: %s",
				     version);
			return FALSE;
		}
		fu_device_set_version (FU_DEVICE (self), version + 19);
	}

	/* success */
	return TRUE;
}
示例#11
0
gboolean
fu_plugin_usb_device_added (FuPlugin *plugin,
			    FuUsbDevice *device,
			    GError **error)
{
	g_autoptr(FuDeviceLocker) locker = NULL;
	g_autoptr(FuDellDockHub) hub = fu_dell_dock_hub_new (device);
	FuDevice *fu_device = FU_DEVICE (hub);
	const gchar *key = NULL;

	locker = fu_device_locker_new (fu_device, error);
	if (locker == NULL)
		return FALSE;
	fu_plugin_device_add (plugin, fu_device);

	if (fu_device_has_custom_flag (fu_device, "has-bridge")) {
		g_autoptr(GError) error_local = NULL;

		/* only add the device with parent to cache */
		key = fu_device_get_id (fu_device);
		if (fu_plugin_cache_lookup (plugin, key) != NULL) {
			g_debug ("Ignoring already added device %s", key);
			return TRUE;
		}
		fu_plugin_cache_add (plugin, key, fu_device);

		/* probe for extended devices */
		if (!fu_plugin_dell_dock_probe (plugin,
						fu_device,
						&error_local)) {
			g_warning ("Failed to probe bridged devices for %s: %s",
				   key,
				   error_local->message);
		}
	}

	/* clear updatable flag if parent doesn't have it */
	fu_dell_dock_clone_updatable (fu_device);

	return TRUE;
}
示例#12
0
static gboolean
fu_wac_module_refresh (FuWacModule *self, GError **error)
{
	FuWacDevice *parent_device = FU_WAC_DEVICE (fu_device_get_parent (FU_DEVICE (self)));
	FuWacModulePrivate *priv = GET_PRIVATE (self);
	guint8 buf[] = { [0] = FU_WAC_REPORT_ID_MODULE,
			 [1 ... FU_WAC_PACKET_LEN - 1] = 0xff };

	/* get from hardware */
	if (!fu_wac_device_get_feature_report (parent_device, buf, sizeof(buf),
					       FU_WAC_DEVICE_FEATURE_FLAG_ALLOW_TRUNC |
					       FU_WAC_DEVICE_FEATURE_FLAG_NO_DEBUG,
					       error)) {
		g_prefix_error (error, "failed to refresh status: ");
		return FALSE;
	}

	/* check fw type */
	if (priv->fw_type != buf[1]) {
		g_set_error (error,
			     FWUPD_ERROR,
			     FWUPD_ERROR_INTERNAL,
			     "Submodule GetFeature fw_Type invalid "
			     "got 0x%02x expected 0x%02x",
			     (guint) buf[1], (guint) priv->fw_type);
		return FALSE;
	}

	/* current phase and status */
	if (priv->command != buf[2] || priv->status != buf[3]) {
		priv->command = buf[2];
		priv->status = buf[3];
		g_debug ("command: %s, status: %s",
			 fu_wac_module_command_to_string (priv->command),
			 fu_wac_module_status_to_string (priv->status));
	}

	/* success */
	return TRUE;
}
示例#13
0
gboolean
fu_plugin_update_detach (FuPlugin *plugin, FuDevice *device, GError **error)
{
	g_autoptr(FuDeviceLocker) locker = NULL;

	/* open device */
	locker = fu_device_locker_new (device, error);
	if (locker == NULL)
		return FALSE;

	/* switch to bootloader mode is not required */
	if (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER)) {
		g_debug ("already in bootloader mode, skipping");
		return TRUE;
	}

	/* reset */
	if (!fu_device_detach (FU_DEVICE (device), error))
		return FALSE;

	/* wait for replug */
	fu_device_add_flag (device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
	return TRUE;
}
示例#14
0
gboolean
fu_wac_module_set_feature (FuWacModule *self,
			   guint8 command,
			   GBytes *blob, /* optional */
			   GError **error)
{
	FuWacDevice *parent_device = FU_WAC_DEVICE (fu_device_get_parent (FU_DEVICE (self)));
	FuWacModulePrivate *priv = GET_PRIVATE (self);
	const guint8 *data;
	gsize len = 0;
	guint busy_poll_loops = 100; /* 1s */
	guint8 buf[] = { [0] = FU_WAC_REPORT_ID_MODULE,
			 [1] = priv->fw_type,
			 [2] = command,
			 [3 ... FU_WAC_PACKET_LEN - 1] = 0xff };

	/* verify the size of the blob */
	if (blob != NULL) {
		data = g_bytes_get_data (blob, &len);
		if (len > 509) {
			g_set_error (error,
				     FWUPD_ERROR,
				     FWUPD_ERROR_INTERNAL,
				     "Submodule SetFeature blob larger than "
				     "buffer %" G_GSIZE_FORMAT, len);
			return FALSE;
		}
	}

	/* build packet */
	if (len > 0)
		memcpy (&buf[3], data, len);

	/* tell the daemon the current status */
	switch (command) {
	case FU_WAC_MODULE_COMMAND_START:
		fu_device_set_status (FU_DEVICE (self), FWUPD_STATUS_DEVICE_ERASE);
		break;
	case FU_WAC_MODULE_COMMAND_DATA:
		fu_device_set_status (FU_DEVICE (self), FWUPD_STATUS_DEVICE_WRITE);
		break;
	case FU_WAC_MODULE_COMMAND_END:
		fu_device_set_status (FU_DEVICE (self), FWUPD_STATUS_DEVICE_VERIFY);
		break;
	default:
		break;
	}

	/* send to hardware */
	if (!fu_wac_device_set_feature_report (parent_device, buf, len + 3,
					       FU_WAC_DEVICE_FEATURE_FLAG_ALLOW_TRUNC,
					       error)) {
		g_prefix_error (error, "failed to set module feature: ");
		return FALSE;
	}

	/* special case StartProgram, as it can take much longer as it is
	 * erasing the blocks (15s) */
	if (command == FU_WAC_MODULE_COMMAND_START)
		busy_poll_loops *= 15;

	/* wait for hardware */
	for (guint i = 0; i < busy_poll_loops; i++) {
		if (!fu_wac_module_refresh (self, error))
			return FALSE;
		if (priv->status == FU_WAC_MODULE_STATUS_BUSY) {
			g_usleep (10000); /* 10ms */
			continue;
		}
		if (priv->status == FU_WAC_MODULE_STATUS_OK)
			break;
		g_set_error (error,
			     FWUPD_ERROR,
			     FWUPD_ERROR_INTERNAL,
			     "Failed to SetFeature: %s",
			     fu_wac_module_status_to_string (priv->status));
		return FALSE;
	}

	/* too many retries */
	if (priv->status != FU_WAC_MODULE_STATUS_OK) {
		g_set_error (error,
			     FWUPD_ERROR,
			     FWUPD_ERROR_INTERNAL,
			     "Timed out after %u loops with status %s",
			     busy_poll_loops,
			     fu_wac_module_status_to_string (priv->status));
		return FALSE;
	}

	/* success */
	return TRUE;
}
示例#15
0
int
main (int argc, char *argv[])
{
	gboolean action_enable = FALSE;
	gboolean action_info = FALSE;
	gboolean action_list = FALSE;
	gboolean action_log = FALSE;
	gboolean action_set_debug = FALSE;
	gboolean action_supported = FALSE;
	gboolean action_unset_debug = FALSE;
	gboolean action_version = FALSE;
	gboolean ret;
	gboolean verbose = FALSE;
	g_autofree gchar *apply = FALSE;
	g_autofree gchar *esp_path = NULL;
	g_autoptr(FuUtilPrivate) priv = g_new0 (FuUtilPrivate, 1);
	g_autoptr(GError) error = NULL;
	g_autoptr(GPtrArray) devices = NULL;
	const GOptionEntry options[] = {
		{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
			/* TRANSLATORS: command line option */
			_("Show extra debugging information"), NULL },
		{ "version", '\0', 0, G_OPTION_ARG_NONE, &action_version,
			/* TRANSLATORS: command line option */
			_("Display version"), NULL },
		{ "log", 'L', 0, G_OPTION_ARG_NONE, &action_log,
			/* TRANSLATORS: command line option */
			_("Show the debug log from the last attempted update"), NULL },
		{ "list", 'l', 0, G_OPTION_ARG_NONE, &action_list,
			/* TRANSLATORS: command line option */
			_("List supported firmware updates"), NULL },
		{ "supported", 's', 0, G_OPTION_ARG_NONE, &action_supported,
			/* TRANSLATORS: command line option */
			_("Query for firmware update support"), NULL },
		{ "info", 'i', 0, G_OPTION_ARG_NONE, &action_info,
			/* TRANSLATORS: command line option */
			_("Show the information of firmware update status"), NULL },
		{ "enable", 'e', 0, G_OPTION_ARG_NONE, &action_enable,
			/* TRANSLATORS: command line option */
			_("Enable firmware update support on supported systems"), NULL },
		{ "esp-path", 'p', 0, G_OPTION_ARG_STRING, &esp_path,
			/* TRANSLATORS: command line option */
			_("Override the default ESP path"), "PATH" },
		{ "set-debug", 'd', 0, G_OPTION_ARG_NONE, &action_set_debug,
			/* TRANSLATORS: command line option */
			_("Set the debugging flag during update"), NULL },
		{ "unset-debug", 'D', 0, G_OPTION_ARG_NONE, &action_unset_debug,
			/* TRANSLATORS: command line option */
			_("Unset the debugging flag during update"), NULL },
		{ "apply", 'a', 0, G_OPTION_ARG_STRING, &apply,
			/* TRANSLATORS: command line option */
			_("Apply firmware updates"), "GUID" },
		{ NULL}
	};

	setlocale (LC_ALL, "");

	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
	textdomain (GETTEXT_PACKAGE);

	/* ensure root user */
	if (getuid () != 0 || geteuid () != 0)
		/* TRANSLATORS: we're poking around as a power user */
		g_printerr ("%s\n", _("This program may only work correctly as root"));

	/* get a action_list of the commands */
	priv->context = g_option_context_new (NULL);
	g_option_context_set_description (priv->context,
		"This tool allows an administrator to debug UpdateCapsule operation.");

	/* TRANSLATORS: program name */
	g_set_application_name (_("UEFI Firmware Utility"));
	g_option_context_add_main_entries (priv->context, options, NULL);
	ret = g_option_context_parse (priv->context, &argc, &argv, &error);
	if (!ret) {
		/* TRANSLATORS: the user didn't read the man page */
		g_print ("%s: %s\n", _("Failed to parse arguments"),
			 error->message);
		return EXIT_FAILURE;
	}

	/* set verbose? */
	if (verbose) {
		g_setenv ("G_MESSAGES_DEBUG", "all", FALSE);
	} else {
		g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
				   fu_util_ignore_cb, NULL);
	}

	/* nothing specified */
	if (!action_enable && !action_info && !action_list && !action_log &&
	    !action_set_debug && !action_supported && !action_unset_debug &&
	    !action_version) {
		g_autofree gchar *tmp = NULL;
		tmp = g_option_context_get_help (priv->context, TRUE, NULL);
		g_printerr ("%s\n\n%s", _("No action specified!"), tmp);
		return EXIT_FAILURE;
	}

	/* action_version first */
	if (action_version)
		g_print ("fwupd version: %s\n", PACKAGE_VERSION);

	/* override the default ESP path */
	if (esp_path != NULL) {
		if (!fu_uefi_check_esp_path (esp_path, &error)) {
			/* TRANSLATORS: ESP is EFI System Partition */
			g_print ("%s: %s\n", _("ESP specified was not valid"),
				 error->message);
			return EXIT_FAILURE;
		}
	} else {
		esp_path = fu_uefi_guess_esp_path ();
		if (esp_path == NULL) {
			g_printerr ("Unable to determine EFI system partition "
				    "location, override using --esp-path\n");
			return EXIT_FAILURE;
		}
	}

	/* check free space */
	if (!fu_uefi_check_esp_free_space (esp_path,
					   FU_UEFI_COMMON_REQUIRED_ESP_FREE_SPACE,
					   &error)) {
		g_printerr ("Unable to use EFI system partition: %s\n", error->message);
		return EXIT_FAILURE;
	}
	g_debug ("ESP mountpoint set as %s", esp_path);

	/* show the debug action_log from the last attempted update */
	if (action_log) {
		gsize sz = 0;
		g_autofree guint8 *buf = NULL;
		g_autofree guint16 *buf_ucs2 = NULL;
		g_autofree gchar *str = NULL;
		g_autoptr(GError) error_local = NULL;
		if (!fu_uefi_vars_get_data (FU_UEFI_VARS_GUID_FWUPDATE,
					    "FWUPDATE_DEBUG_LOG",
					    &buf, &sz, NULL,
					    &error_local)) {
			g_printerr ("failed: %s\n", error_local->message);
			return EXIT_FAILURE;
		}
		buf_ucs2 = g_new0 (guint16, (sz / 2) + 1);
		memcpy (buf_ucs2, buf, sz);
		str = fu_ucs2_to_uft8 (buf_ucs2, sz / 2);
		g_print ("%s", str);
	}

	if (action_list || action_supported || action_info) {
		g_autoptr(GPtrArray) entries = NULL;
		g_autofree gchar *esrt_path = NULL;
		g_autofree gchar *sysfsfwdir = NULL;
		g_autoptr(GError) error_local = NULL;

		/* get the directory of ESRT entries */
		sysfsfwdir = fu_common_get_path (FU_PATH_KIND_SYSFSDIR_FW);
		esrt_path = g_build_filename (sysfsfwdir, "efi", "esrt", NULL);
		entries = fu_uefi_get_esrt_entry_paths (esrt_path, &error_local);
		if (entries == NULL) {
			g_printerr ("failed: %s\n", error_local->message);
			return EXIT_FAILURE;
		}

		/* add each device */
		devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
		for (guint i = 0; i < entries->len; i++) {
			const gchar *path = g_ptr_array_index (entries, i);
			g_autoptr(GError) error_parse = NULL;
			g_autoptr(FuUefiDevice) dev = fu_uefi_device_new_from_entry (path, &error_parse);
			if (dev == NULL) {
				g_warning ("failed to parse %s: %s",
					   path, error_parse->message);
				continue;
			}
			fu_device_set_metadata (FU_DEVICE (dev), "EspPath", esp_path);
			g_ptr_array_add (devices, g_object_ref (dev));
		}
	}

	/* action_list action_supported firmware updates */
	if (action_list) {
		for (guint i = 0; i < devices->len; i++) {
			FuUefiDevice *dev = g_ptr_array_index (devices, i);
			g_print ("%s type, {%s} action_version %" G_GUINT32_FORMAT " can be updated "
				 "to any action_version above %" G_GUINT32_FORMAT "\n",
				 fu_uefi_device_kind_to_string (fu_uefi_device_get_kind (dev)),
				 fu_uefi_device_get_guid (dev),
				 fu_uefi_device_get_version (dev),
				 fu_uefi_device_get_version_lowest (dev) - 1);
		}
	}

	/* query for firmware update support */
	if (action_supported) {
		if (devices->len > 0) {
			g_print ("%s\n", _("Firmware updates are supported on this machine."));
		} else {
			g_print ("%s\n", _("Firmware updates are not supported on this machine."));
		}
	}

	/* show the information of firmware update status */
	if (action_info) {
		for (guint i = 0; i < devices->len; i++) {
			FuUefiDevice *dev = g_ptr_array_index (devices, i);
			g_autoptr(FuUefiUpdateInfo) info = NULL;
			g_autoptr(GError) error_local = NULL;

			/* load any existing update info */
			info = fu_uefi_device_load_update_info (dev, &error_local);
			if (info == NULL) {
				g_printerr ("failed: %s\n", error_local->message);
				continue;
			}
			g_print ("Information for the update status entry %u:\n", i);
			g_print ("  Information Version: %" G_GUINT32_FORMAT "\n",
				 fu_uefi_update_info_get_version (info));
			g_print ("  Firmware GUID: {%s}\n",
				 fu_uefi_update_info_get_guid (info));
			g_print ("  Capsule Flags: 0x%08" G_GUINT32_FORMAT "x\n",
				 fu_uefi_update_info_get_capsule_flags (info));
			g_print ("  Hardware Instance: %" G_GUINT64_FORMAT "\n",
				 fu_uefi_update_info_get_hw_inst (info));
			g_print ("  Update Status: %s\n",
				 fu_uefi_update_info_status_to_string (fu_uefi_update_info_get_status (info)));
			g_print ("  Capsule File Path: %s\n\n",
				 fu_uefi_update_info_get_capsule_fn (info));
		}
	}

	/* action_enable firmware update support on action_supported systems */
	if (action_enable) {
		g_printerr ("Unsupported, use `fwupdmgr unlock`\n");
		return EXIT_FAILURE;
	}

	/* set the debugging flag during update */
	if (action_set_debug) {
		const guint8 data = 1;
		g_autoptr(GError) error_local = NULL;
		if (!fu_uefi_vars_set_data (FU_UEFI_VARS_GUID_FWUPDATE,
					    "FWUPDATE_VERBOSE",
					    &data, sizeof(data),
					    EFI_VARIABLE_NON_VOLATILE |
					    EFI_VARIABLE_BOOTSERVICE_ACCESS |
					    EFI_VARIABLE_RUNTIME_ACCESS,
					    &error_local)) {
			g_printerr ("failed: %s\n", error_local->message);
			return EXIT_FAILURE;
		}
		g_print ("%s\n", _("Enabled fwupdate debugging"));
	}

	/* unset the debugging flag during update */
	if (action_unset_debug) {
		g_autoptr(GError) error_local = NULL;
		if (!fu_uefi_vars_delete (FU_UEFI_VARS_GUID_FWUPDATE,
					  "FWUPDATE_VERBOSE",
					  &error_local)) {
			g_printerr ("failed: %s\n", error_local->message);
			return EXIT_FAILURE;
		}
		g_print ("%s\n", _("Disabled fwupdate debugging"));
	}

	/* apply firmware updates */
	if (apply != NULL) {
		g_autoptr(FuUefiDevice) dev = fu_uefi_device_new_from_guid (apply);
		g_autoptr(GError) error_local = NULL;
		g_autoptr(GBytes) fw = fu_common_get_contents_bytes (argv[1], &error_local);
		if (fw == NULL) {
			g_printerr ("failed: %s\n", error_local->message);
			return EXIT_FAILURE;
		}
		if (!fu_device_write_firmware (FU_DEVICE (dev), fw, &error_local)) {
			g_printerr ("failed: %s\n", error_local->message);
			return EXIT_FAILURE;
		}
	}

	/* success */
	return EXIT_SUCCESS;
}
示例#16
0
static gboolean
fu_altos_device_probe_bootloader (FuAltosDevice *self, GError **error)
{
	g_autoptr(FuDeviceLocker) locker  = NULL;
	g_auto(GStrv) lines = NULL;
	g_autoptr(GString) str = NULL;

	/* get tty for upload */
	if (!fu_altos_device_find_tty (self, error))
		return FALSE;
	locker = fu_device_locker_new_full (self,
					    (FuDeviceLockerFunc) fu_altos_device_tty_open,
					    (FuDeviceLockerFunc) fu_altos_device_tty_close,
					    error);
	if (locker == NULL)
		return FALSE;

	/* get the version information */
	if (!fu_altos_device_tty_write (self, "v\n", -1, error))
		return FALSE;
	str = fu_altos_device_tty_read (self, 100, -1, error);
	if (str == NULL)
		return FALSE;

	/* parse each line */
	lines = g_strsplit_set (str->str, "\n\r", -1);
	for (guint i = 0; lines[i] != NULL; i++) {

		/* ignore */
		if (lines[i][0] == '\0')
			continue;
		if (g_str_has_prefix (lines[i], "manufacturer     "))
			continue;
		if (g_str_has_prefix (lines[i], "product          "))
			continue;

		/* we can flash firmware */
		if (g_strcmp0 (lines[i], "altos-loader") == 0) {
			fu_device_remove_flag (FU_DEVICE (self),
					       FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER);
			continue;
		}

		/* version number */
		if (g_str_has_prefix (lines[i], "software-version ")) {
			fu_device_set_version (FU_DEVICE (self), lines[i] + 17);
			continue;
		}

		/* address base and bound */
		if (g_str_has_prefix (lines[i], "flash-range      ")) {
			g_auto(GStrv) addrs = g_strsplit (lines[i] + 17, " ", -1);
			self->addr_base = g_ascii_strtoull (addrs[0], NULL, 16);
			self->addr_bound = g_ascii_strtoull (addrs[1], NULL, 16);
			g_debug ("base: %x, bound: %x",
				 (guint) self->addr_base,
				 (guint) self->addr_bound);
			continue;
		}

		/* unknown line */
		g_debug ("unknown data: '%s'", lines[i]);
	}

	return TRUE;
}