mirror of
https://git.proxmox.com/git/fwupd
synced 2025-07-27 11:09:28 +00:00
Add a way to read the device firmware in fwupdtool
In most cases 'fwupdtool firmware-dump' and 'fwupdtool firmware-read' are going to be the same. This isn't true in all cases, especially when dealing with composite firmware like archives. See https://github.com/fwupd/fwupd/pull/4623#issuecomment-1129227133
This commit is contained in:
parent
09c703638f
commit
a4906010d6
@ -36,6 +36,7 @@ _fwupdtool_cmd_list=(
|
||||
'attach'
|
||||
'detach'
|
||||
'firmware-dump'
|
||||
'firmware-read'
|
||||
'refresh'
|
||||
'verify-update'
|
||||
'watch'
|
||||
|
@ -2954,6 +2954,30 @@ fu_engine_firmware_dump(FuEngine *self,
|
||||
return fu_device_dump_firmware(device, progress, error);
|
||||
}
|
||||
|
||||
FuFirmware *
|
||||
fu_engine_firmware_read(FuEngine *self,
|
||||
FuDevice *device,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
g_autoptr(FuDeviceLocker) poll_locker = NULL;
|
||||
|
||||
/* pause the polling */
|
||||
poll_locker = fu_device_poll_locker_new(device, error);
|
||||
if (poll_locker == NULL)
|
||||
return NULL;
|
||||
|
||||
/* open, read, close */
|
||||
locker = fu_device_locker_new(device, error);
|
||||
if (locker == NULL) {
|
||||
g_prefix_error(error, "failed to open device for firmware read: ");
|
||||
return NULL;
|
||||
}
|
||||
return fu_device_read_firmware(device, progress, error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_engine_install_blob(FuEngine *self,
|
||||
FuDevice *device,
|
||||
|
@ -144,6 +144,12 @@ fu_engine_firmware_dump(FuEngine *self,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error);
|
||||
FuFirmware *
|
||||
fu_engine_firmware_read(FuEngine *self,
|
||||
FuDevice *device,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error);
|
||||
gboolean
|
||||
fu_engine_modify_remote(FuEngine *self,
|
||||
const gchar *remote_id,
|
||||
|
@ -1110,6 +1110,71 @@ fu_util_firmware_dump(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
return fu_common_set_contents_bytes(values[0], blob_fw, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_util_firmware_read(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
{
|
||||
g_autoptr(FuDevice) device = NULL;
|
||||
g_autoptr(FuFirmware) fw = NULL;
|
||||
g_autoptr(GBytes) blob_empty = g_bytes_new(NULL, 0);
|
||||
g_autoptr(GBytes) blob_fw = NULL;
|
||||
|
||||
/* invalid args */
|
||||
if (g_strv_length(values) == 0) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_ARGS,
|
||||
"Invalid arguments");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* file already exists */
|
||||
if ((priv->flags & FWUPD_INSTALL_FLAG_FORCE) == 0 &&
|
||||
g_file_test(values[0], G_FILE_TEST_EXISTS)) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_ARGS,
|
||||
"Filename already exists");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* write a zero length file to ensure the destination is writable to
|
||||
* avoid failing at the end of a potentially lengthy operation */
|
||||
if (!fu_common_set_contents_bytes(values[0], blob_empty, error))
|
||||
return FALSE;
|
||||
|
||||
/* load engine */
|
||||
if (!fu_util_start_engine(priv,
|
||||
FU_ENGINE_LOAD_FLAG_COLDPLUG | FU_ENGINE_LOAD_FLAG_HWINFO,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
/* get device */
|
||||
priv->filter_include |= FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE;
|
||||
if (g_strv_length(values) >= 2) {
|
||||
device = fu_util_get_device(priv, values[1], error);
|
||||
if (device == NULL)
|
||||
return FALSE;
|
||||
} else {
|
||||
device = fu_util_prompt_for_device(priv, NULL, error);
|
||||
if (device == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
priv->current_operation = FU_UTIL_OPERATION_READ;
|
||||
g_signal_connect(FU_ENGINE(priv->engine),
|
||||
"device-changed",
|
||||
G_CALLBACK(fu_util_update_device_changed_cb),
|
||||
priv);
|
||||
|
||||
/* read firmware into the container format */
|
||||
fw = fu_engine_firmware_read(priv->engine, device, priv->progress, priv->flags, error);
|
||||
if (fw == NULL)
|
||||
return FALSE;
|
||||
blob_fw = fu_firmware_write(fw, error);
|
||||
if (blob_fw == NULL)
|
||||
return FALSE;
|
||||
return fu_common_set_contents_bytes(values[0], blob_fw, error);
|
||||
}
|
||||
|
||||
static gint
|
||||
fu_util_release_sort_cb(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
@ -3541,6 +3606,13 @@ main(int argc, char *argv[])
|
||||
/* TRANSLATORS: command description */
|
||||
_("Read a firmware blob from a device"),
|
||||
fu_util_firmware_dump);
|
||||
fu_util_cmd_array_add(cmd_array,
|
||||
"firmware-read",
|
||||
/* TRANSLATORS: command argument: uppercase, spaces->dashes */
|
||||
_("FILENAME [DEVICE-ID|GUID]"),
|
||||
/* TRANSLATORS: command description */
|
||||
_("Read a firmware from a device"),
|
||||
fu_util_firmware_read);
|
||||
fu_util_cmd_array_add(cmd_array,
|
||||
"firmware-patch",
|
||||
/* TRANSLATORS: command argument: uppercase, spaces->dashes */
|
||||
|
Loading…
Reference in New Issue
Block a user