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