Ejemplo n.º 1
0
/**
 * fu_provider_udev_verify:
 **/
static gboolean
fu_provider_udev_verify (FuProvider *provider,
			 FuDevice *device,
			 FuProviderVerifyFlags flags,
			 GError **error)
{
	const gchar *rom_fn;
	g_autoptr(GFile) file = NULL;
	g_autoptr(FuRom) rom = NULL;

	/* open the file */
	rom_fn = fu_device_get_metadata (device, "RomFilename");
	if (rom_fn == NULL) {
		g_set_error_literal (error,
				     FWUPD_ERROR,
				     FWUPD_ERROR_INTERNAL,
				     "Unable to read firmware from device");
		return FALSE;
	}
	file = g_file_new_for_path (rom_fn);
	rom = fu_rom_new ();
	if (!fu_rom_load_file (rom, file, FU_ROM_LOAD_FLAG_BLANK_PPID, NULL, error))
		return FALSE;
	fu_device_set_metadata (device, FU_DEVICE_KEY_FIRMWARE_HASH,
				fu_rom_get_checksum (rom));
	return TRUE;
}
Ejemplo n.º 2
0
/**
 * fu_util_dump_rom:
 **/
static gboolean
fu_util_dump_rom (FuUtilPrivate *priv, gchar **values, GError **error)
{
	guint i;

	if (g_strv_length (values) == 0) {
		g_set_error_literal (error,
				     FWUPD_ERROR,
				     FWUPD_ERROR_INTERNAL,
				     "Invalid arguments: expected 'filename.rom'");
		return FALSE;
	}
	for (i = 0; values[i] != NULL; i++) {
		_cleanup_object_unref_ FuRom *rom = NULL;
		_cleanup_object_unref_ GFile *file = NULL;
		_cleanup_error_free_ GError *error_local = NULL;

		file = g_file_new_for_path (values[i]);
		rom = fu_rom_new ();
		g_print ("%s:\n", values[i]);
		if (!fu_rom_load_file (rom, file, FU_ROM_LOAD_FLAG_BLANK_PPID,
				       NULL, &error_local)) {
			g_print ("%s\n", error_local->message);
			continue;
		}
		g_print ("0x%04x:0x%04x -> %s [%s]\n",
			 fu_rom_get_vendor (rom),
			 fu_rom_get_model (rom),
			 fu_rom_get_checksum (rom),
			 fu_rom_get_version (rom));
	}
	return TRUE;
}
Ejemplo n.º 3
0
static gboolean
fu_fuzzer_rom_parse (const gchar *fn, GError **error)
{
	GPtrArray *checksums;
	g_autoptr(FuRom) rom = NULL;
	g_autoptr(GFile) file = NULL;

	g_debug ("loading %s", fn);
	file = g_file_new_for_path (fn);
	rom = fu_rom_new ();
	if (!fu_rom_load_file (rom, file, FU_ROM_LOAD_FLAG_NONE, NULL, error))
		return FALSE;
	g_print ("filename:%s\n", fn);
	g_print ("kind:%s\n", fu_rom_kind_to_string (fu_rom_get_kind (rom)));
	g_print ("version:%s\n", fu_rom_get_version (rom));
	checksums = fu_rom_get_checksums (rom);
	for (guint i = 0; i < checksums->len; i++) {
		const gchar *checksum = g_ptr_array_index (checksums, i);
		g_autofree gchar *checksum_display = NULL;
		checksum_display = fwupd_checksum_format_for_display (checksum);
		g_print ("checksum:%s\n", checksum_display);
	}
	g_print ("guid:%s\n", fu_rom_get_guid (rom));
	g_print ("vendor:%u\n", fu_rom_get_vendor (rom));
	g_print ("model:%u\n\n", fu_rom_get_model (rom));
	return TRUE;
}
Ejemplo n.º 4
0
/**
 * fu_provider_udev_unlock:
 **/
static gboolean
fu_provider_udev_unlock (FuProvider *provider,
			 FuDevice *device,
			 GError **error)
{
	const gchar *rom_fn;
	g_autoptr(FuRom) rom = NULL;
	g_autoptr(GFile) file = NULL;

	/* get the FW version from the rom */
	g_debug ("unlocking UDev device %s", fu_device_get_id (device));
	rom_fn = fu_device_get_metadata (device, "RomFilename");
	if (rom_fn == NULL) {
		g_set_error_literal (error,
				     FWUPD_ERROR,
				     FWUPD_ERROR_INTERNAL,
				     "Unable to read firmware from device");
		return FALSE;
	}
	file = g_file_new_for_path (rom_fn);
	rom = fu_rom_new ();
	if (!fu_rom_load_file (rom, file, FU_ROM_LOAD_FLAG_BLANK_PPID, NULL, error))
		return FALSE;

	/* update version */
	if (g_strcmp0 (fu_device_get_version (device),
		       fu_rom_get_version (rom)) != 0) {
		g_debug ("changing version of %s from %s to %s",
			 fu_device_get_id (device),
			 fu_device_get_version (device),
			 fu_rom_get_version (rom));
		fu_device_set_version (device, fu_rom_get_version (rom));
	}

	/* prefer the GUID from the firmware rather than the
	 * hardware as the firmware may be more generic, which
	 * also allows us to match the GUID when doing 'verify'
	 * on a device with a different PID to the firmware */
	if (g_strcmp0 (fu_device_get_guid (device), fu_rom_get_guid (rom)) != 0) {
		fu_device_set_guid (device, fu_rom_get_guid (rom));
		g_debug ("changing GUID of %s from %s to %s",
			 fu_device_get_id (device),
			 fu_device_get_guid (device),
			 fu_rom_get_guid (rom));
	}
	return TRUE;
}
Ejemplo n.º 5
0
/**
 * fu_provider_udev_client_add:
 **/
static void
fu_provider_udev_client_add (FuProviderUdev *provider_udev, GUdevDevice *device)
{
	FuProviderUdevPrivate *priv = GET_PRIVATE (provider_udev);
	FuDevice *dev;
	const gchar *display_name;
	const gchar *guid;
	const gchar *product;
	const gchar *vendor;
	g_autofree gchar *guid_new = NULL;
	g_autofree gchar *id = NULL;
	g_autofree gchar *rom_fn = NULL;
	g_autofree gchar *version = NULL;
	g_auto(GStrv) split = NULL;

	/* interesting device? */
	guid = g_udev_device_get_property (device, "FWUPD_GUID");
	if (guid == NULL)
		return;

	/* get data */
	g_debug ("adding udev device: %s", g_udev_device_get_sysfs_path (device));
	if (0) {
		const gchar * const *keys;
		guint i;
		keys = g_udev_device_get_property_keys (device);
		for (i = 0; keys[i] != NULL; i++)
			g_debug ("KEY: %s=%s", keys[i],
				 g_udev_device_get_property (device, keys[i]));

		keys = g_udev_device_get_sysfs_attr_keys (device);
		for (i = 0; keys[i] != NULL; i++)
			g_debug ("SYS: %s=%s", keys[i],
				 g_udev_device_get_sysfs_attr (device, keys[i]));
	}

	/* is already in database */
	id = fu_provider_udev_get_id (device);
	dev = g_hash_table_lookup (priv->devices, id);
	if (dev != NULL) {
		g_debug ("ignoring duplicate %s", id);
		return;
	}

	/* get the FW version from the BCD device revision */
	product = g_udev_device_get_property (device, "PRODUCT");
	if (product != NULL) {
		split = g_strsplit (product, "/", -1);
		if (g_strv_length (split) != 3) {
			g_warning ("env{PRODUCT} is invalid: %s", product);
			return;
		}
		version = g_strdup (split[2]);
	}

	/* get the FW version from the rom */
	rom_fn = g_build_filename (g_udev_device_get_sysfs_path (device), "rom", NULL);
	if (g_file_test (rom_fn, G_FILE_TEST_EXISTS)) {
		g_autoptr(GError) error = NULL;
		g_autoptr(GFile) file = NULL;
		g_autoptr(FuRom) rom = NULL;
		file = g_file_new_for_path (rom_fn);
		rom = fu_rom_new ();
		if (!fu_rom_load_file (rom, file, FU_ROM_LOAD_FLAG_BLANK_PPID, NULL, &error)) {
			g_warning ("Failed to parse ROM from %s: %s",
				   rom_fn, error->message);
		}
		version = g_strdup (fu_rom_get_version (rom));

		/* prefer the GUID from the firmware rather than the
		 * hardware as the firmware may be more generic, which
		 * also allows us to match the GUID when doing 'verify'
		 * on a device with a different PID to the firmware */
		guid_new = g_strdup (fu_rom_get_guid (rom));
	}

	/* we failed */
	if (version == NULL)
		return;

	/* no GUID from the ROM, so fix up the VID:PID */
	if (guid_new == NULL) {
		if (!as_utils_guid_is_valid (guid)) {
			guid_new = as_utils_guid_from_string (guid);
			g_debug ("Fixing GUID %s->%s", guid, guid_new);
		} else {
			guid_new = g_strdup (guid);
		}
	}

	/* did we get enough data */
	dev = fu_device_new ();
	fu_device_add_flag (dev, FU_DEVICE_FLAG_INTERNAL);
	fu_device_set_id (dev, id);
	fu_device_set_guid (dev, guid_new);
	display_name = g_udev_device_get_property (device, "FWUPD_MODEL");
	if (display_name == NULL)
		display_name = g_udev_device_get_property (device, "ID_MODEL_FROM_DATABASE");
	if (display_name != NULL)
		fu_device_set_display_name (dev, display_name);
	vendor = g_udev_device_get_property (device, "FWUPD_VENDOR");
	if (vendor == NULL)
		vendor = g_udev_device_get_property (device, "ID_VENDOR_FROM_DATABASE");
	if (vendor != NULL)
		fu_device_set_metadata (dev, FU_DEVICE_KEY_VENDOR, vendor);
	fu_device_set_metadata (dev, FU_DEVICE_KEY_VERSION, version);
	if (g_file_test (rom_fn, G_FILE_TEST_EXISTS))
		fu_device_set_metadata (dev, "RomFilename", rom_fn);

	/* insert to hash */
	g_hash_table_insert (priv->devices, g_strdup (id), dev);
	fu_provider_device_add (FU_PROVIDER (provider_udev), dev);
}
Ejemplo n.º 6
0
/**
 * fu_util_verify_update:
 **/
static gboolean
fu_util_verify_update (FuUtilPrivate *priv, gchar **values, GError **error)
{
	guint i;
	_cleanup_object_unref_ AsStore *store = NULL;
	_cleanup_object_unref_ GFile *xml_file = NULL;

	if (g_strv_length (values) < 2) {
		g_set_error_literal (error,
				     FWUPD_ERROR,
				     FWUPD_ERROR_INTERNAL,
				     "Invalid arguments: expected 'filename.xml' 'filename.rom'");
		return FALSE;
	}
	store = as_store_new ();

	/* open existing file */
	xml_file = g_file_new_for_path (values[0]);
	if (g_file_query_exists (xml_file, NULL)) {
		if (!as_store_from_file (store, xml_file, NULL, NULL, error))
			return FALSE;
	}

	/* add new values */
	as_store_set_api_version (store, 0.9);
	for (i = 1; values[i] != NULL; i++) {
		_cleanup_free_ gchar *guid = NULL;
		_cleanup_free_ gchar *id = NULL;
		_cleanup_object_unref_ AsApp *app = NULL;
		_cleanup_object_unref_ AsRelease *rel = NULL;
		_cleanup_object_unref_ FuRom *rom = NULL;
		_cleanup_object_unref_ GFile *file = NULL;
		_cleanup_error_free_ GError *error_local = NULL;

		file = g_file_new_for_path (values[i]);
		rom = fu_rom_new ();
		g_print ("Processing %s...\n", values[i]);
		if (!fu_rom_load_file (rom, file, FU_ROM_LOAD_FLAG_BLANK_PPID,
				       NULL, &error_local)) {
			g_print ("%s\n", error_local->message);
			continue;
		}

		/* add app to store */
		app = as_app_new ();
		id = g_strdup_printf ("0x%04x:0x%04x",
				      fu_rom_get_vendor (rom),
				      fu_rom_get_model (rom));
		guid = fu_guid_generate_from_string (id);
		as_app_set_id (app, guid, -1);
		as_app_set_id_kind (app, AS_ID_KIND_FIRMWARE);
		as_app_set_source_kind (app, AS_APP_SOURCE_KIND_INF);
		rel = as_release_new ();
		as_release_set_version (rel, fu_rom_get_version (rom), -1);
		as_release_set_checksum (rel, G_CHECKSUM_SHA1,
					 fu_rom_get_checksum (rom), -1);
		as_app_add_release (app, rel);
		as_store_add_app (store, app);
	}
	if (!as_store_to_file (store, xml_file,
			       AS_NODE_TO_XML_FLAG_ADD_HEADER |
			       AS_NODE_TO_XML_FLAG_FORMAT_INDENT |
			       AS_NODE_TO_XML_FLAG_FORMAT_MULTILINE,
			       NULL, error))
		return FALSE;
	return TRUE;
}