summaryrefslogtreecommitdiffstats
path: root/qga
diff options
context:
space:
mode:
authorTomáš Golembiovský2018-10-23 13:23:19 +0200
committerMichael Roth2018-10-31 15:04:20 +0100
commitfb08aa703f4c601155aa65943eb29c1ad3972386 (patch)
treef4a197d5799e2ed8a0b2a635f4ba2a7cde4e5498 /qga
parentqga-win: refactor disk properties (bus) (diff)
downloadqemu-fb08aa703f4c601155aa65943eb29c1ad3972386.tar.gz
qemu-fb08aa703f4c601155aa65943eb29c1ad3972386.tar.xz
qemu-fb08aa703f4c601155aa65943eb29c1ad3972386.zip
qga-win: report disk serial number
Signed-off-by: Tomáš Golembiovský <tgolembi@redhat.com> *coding style fix-ups (declarations at beginning of block) *improve readability for user-visible errors *cover additional edge-cases with debug statements Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Diffstat (limited to 'qga')
-rw-r--r--qga/commands-win32.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 1e91aa2343..2d7b56d538 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -634,6 +634,36 @@ static void get_disk_properties(HANDLE vol_h, GuestDiskAddress *disk,
disk->bus_type = find_bus_type(dev_desc->BusType);
g_debug("bus type %d", disk->bus_type);
+ /* Query once more. Now with long enough buffer. */
+ size = dev_desc->Size;
+ dev_desc = g_malloc0(size);
+ if (!DeviceIoControl(vol_h, IOCTL_STORAGE_QUERY_PROPERTY, &query,
+ sizeof(STORAGE_PROPERTY_QUERY), dev_desc,
+ size, &received, NULL)) {
+ error_setg_win32(errp, GetLastError(), "failed to get serial number");
+ g_debug("failed to get serial number");
+ goto out_free;
+ }
+ if (dev_desc->SerialNumberOffset > 0) {
+ const char *serial;
+ size_t len;
+
+ if (dev_desc->SerialNumberOffset >= received) {
+ error_setg(errp, "failed to get serial number: offset outside the buffer");
+ g_debug("serial number offset outside the buffer");
+ goto out_free;
+ }
+ serial = (char *)dev_desc + dev_desc->SerialNumberOffset;
+ len = received - dev_desc->SerialNumberOffset;
+ g_debug("serial number \"%s\"", serial);
+ if (*serial != 0) {
+ disk->serial = g_strndup(serial, len);
+ disk->has_serial = true;
+ }
+ }
+out_free:
+ g_free(dev_desc);
+
return;
}