mirror of
https://git.proxmox.com/git/fwupd
synced 2025-07-27 10:47:02 +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'
|
'attach'
|
||||||
'detach'
|
'detach'
|
||||||
'firmware-dump'
|
'firmware-dump'
|
||||||
|
'firmware-read'
|
||||||
'refresh'
|
'refresh'
|
||||||
'verify-update'
|
'verify-update'
|
||||||
'watch'
|
'watch'
|
||||||
|
@ -2954,6 +2954,30 @@ fu_engine_firmware_dump(FuEngine *self,
|
|||||||
return fu_device_dump_firmware(device, progress, error);
|
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
|
gboolean
|
||||||
fu_engine_install_blob(FuEngine *self,
|
fu_engine_install_blob(FuEngine *self,
|
||||||
FuDevice *device,
|
FuDevice *device,
|
||||||
|
@ -144,6 +144,12 @@ fu_engine_firmware_dump(FuEngine *self,
|
|||||||
FuProgress *progress,
|
FuProgress *progress,
|
||||||
FwupdInstallFlags flags,
|
FwupdInstallFlags flags,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
FuFirmware *
|
||||||
|
fu_engine_firmware_read(FuEngine *self,
|
||||||
|
FuDevice *device,
|
||||||
|
FuProgress *progress,
|
||||||
|
FwupdInstallFlags flags,
|
||||||
|
GError **error);
|
||||||
gboolean
|
gboolean
|
||||||
fu_engine_modify_remote(FuEngine *self,
|
fu_engine_modify_remote(FuEngine *self,
|
||||||
const gchar *remote_id,
|
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);
|
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
|
static gint
|
||||||
fu_util_release_sort_cb(gconstpointer a, gconstpointer b)
|
fu_util_release_sort_cb(gconstpointer a, gconstpointer b)
|
||||||
{
|
{
|
||||||
@ -3541,6 +3606,13 @@ main(int argc, char *argv[])
|
|||||||
/* TRANSLATORS: command description */
|
/* TRANSLATORS: command description */
|
||||||
_("Read a firmware blob from a device"),
|
_("Read a firmware blob from a device"),
|
||||||
fu_util_firmware_dump);
|
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,
|
fu_util_cmd_array_add(cmd_array,
|
||||||
"firmware-patch",
|
"firmware-patch",
|
||||||
/* TRANSLATORS: command argument: uppercase, spaces->dashes */
|
/* TRANSLATORS: command argument: uppercase, spaces->dashes */
|
||||||
|
Loading…
Reference in New Issue
Block a user