[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 07/12] qga: add implementation of guest-get-disks for Windows
From: |
Michael Roth |
Subject: |
[PULL 07/12] qga: add implementation of guest-get-disks for Windows |
Date: |
Tue, 27 Oct 2020 00:53:12 -0500 |
From: Tomáš Golembiovský <tgolembi@redhat.com>
The command lists all the physical disk drives. Unlike for Linux
partitions and virtual volumes are not listed.
Example output:
{
"return": [
{
"name": "\\\\.\\PhysicalDrive0",
"partition": false,
"address": {
"serial": "QM00001",
"bus-type": "sata",
...
},
"dependents": []
}
]
}
Signed-off-by: Tomáš Golembiovský <tgolembi@redhat.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
---
qga/commands-win32.c | 107 ++++++++++++++++++++++++++++++++++++++++---
1 file changed, 101 insertions(+), 6 deletions(-)
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index f7bdd5a8b5..300b87c859 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -979,6 +979,101 @@ out:
return list;
}
+GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
+{
+ ERRP_GUARD();
+ GuestDiskInfoList *new = NULL, *ret = NULL;
+ HDEVINFO dev_info;
+ SP_DEVICE_INTERFACE_DATA dev_iface_data;
+ int i;
+
+ dev_info = SetupDiGetClassDevs(&GUID_DEVINTERFACE_DISK, 0, 0,
+ DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
+ if (dev_info == INVALID_HANDLE_VALUE) {
+ error_setg_win32(errp, GetLastError(), "failed to get device tree");
+ return NULL;
+ }
+
+ g_debug("enumerating devices");
+ dev_iface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
+ for (i = 0;
+ SetupDiEnumDeviceInterfaces(dev_info, NULL, &GUID_DEVINTERFACE_DISK,
+ i, &dev_iface_data);
+ i++) {
+ GuestDiskAddress *address = NULL;
+ GuestDiskInfo *disk = NULL;
+ Error *local_err = NULL;
+ g_autofree PSP_DEVICE_INTERFACE_DETAIL_DATA
+ pdev_iface_detail_data = NULL;
+ STORAGE_DEVICE_NUMBER sdn;
+ HANDLE dev_file;
+ DWORD size = 0;
+ BOOL result;
+ int attempt;
+
+ g_debug(" getting device path");
+ for (attempt = 0, result = FALSE; attempt < 2 && !result; attempt++) {
+ result = SetupDiGetDeviceInterfaceDetail(dev_info,
+ &dev_iface_data, pdev_iface_detail_data, size, &size, NULL);
+ if (result) {
+ break;
+ }
+ if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ pdev_iface_detail_data = g_realloc(pdev_iface_detail_data,
+ size);
+ pdev_iface_detail_data->cbSize =
+ sizeof(*pdev_iface_detail_data);
+ } else {
+ g_debug("failed to get device interface details");
+ break;
+ }
+ }
+ if (!result) {
+ g_debug("skipping device");
+ continue;
+ }
+
+ g_debug(" device: %s", pdev_iface_detail_data->DevicePath);
+ dev_file = CreateFile(pdev_iface_detail_data->DevicePath, 0,
+ FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+ if (!DeviceIoControl(dev_file, IOCTL_STORAGE_GET_DEVICE_NUMBER,
+ NULL, 0, &sdn, sizeof(sdn), &size, NULL)) {
+ CloseHandle(dev_file);
+ debug_error("failed to get storage device number");
+ continue;
+ }
+ CloseHandle(dev_file);
+
+ disk = g_new0(GuestDiskInfo, 1);
+ disk->name = g_strdup_printf("\\\\.\\PhysicalDrive%lu",
+ sdn.DeviceNumber);
+
+ g_debug(" number: %lu", sdn.DeviceNumber);
+ address = g_malloc0(sizeof(GuestDiskAddress));
+ address->has_dev = true;
+ address->dev = g_strdup(disk->name);
+ get_single_disk_info(sdn.DeviceNumber, address, &local_err);
+ if (local_err) {
+ g_debug("failed to get disk info: %s",
+ error_get_pretty(local_err));
+ error_free(local_err);
+ qapi_free_GuestDiskAddress(address);
+ address = NULL;
+ } else {
+ disk->address = address;
+ disk->has_address = true;
+ }
+
+ new = g_malloc0(sizeof(GuestDiskInfoList));
+ new->value = disk;
+ new->next = ret;
+ ret = new;
+ }
+
+ SetupDiDestroyDeviceInfoList(dev_info);
+ return ret;
+}
+
#else
static GuestDiskAddressList *build_guest_disk_info(char *guid, Error **errp)
@@ -986,6 +1081,12 @@ static GuestDiskAddressList *build_guest_disk_info(char
*guid, Error **errp)
return NULL;
}
+GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
+{
+ error_setg(errp, QERR_UNSUPPORTED);
+ return NULL;
+}
+
#endif /* CONFIG_QGA_NTDDSCSI */
static GuestFilesystemInfo *build_guest_fsinfo(char *guid, Error **errp)
@@ -2458,9 +2559,3 @@ GuestDeviceInfoList *qmp_guest_get_devices(Error **errp)
}
return head;
}
-
-GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
-{
- error_setg(errp, QERR_UNSUPPORTED);
- return NULL;
-}
--
2.25.1
- [PULL 00/12] qemu-ga patch queue for soft-freeze, Michael Roth, 2020/10/27
- [PULL 10/12] qga: add *reset argument to ssh-add-authorized-keys, Michael Roth, 2020/10/27
- [PULL 11/12] meson: minor simplification, Michael Roth, 2020/10/27
- [PULL 12/12] qga: add ssh-get-authorized-keys, Michael Roth, 2020/10/27
- [PULL 01/12] qga: Rename guest-get-devices return member 'address' to 'id', Michael Roth, 2020/10/27
- [PULL 02/12] qga: Use common time encoding for guest-get-devices 'driver-date', Michael Roth, 2020/10/27
- [PULL 03/12] qga-win: Fix guest-get-devices error API violations, Michael Roth, 2020/10/27
- [PULL 05/12] qga: add command guest-get-disks, Michael Roth, 2020/10/27
- [PULL 04/12] qga: Flatten simple union GuestDeviceId, Michael Roth, 2020/10/27
- [PULL 06/12] qga: add implementation of guest-get-disks for Linux, Michael Roth, 2020/10/27
- [PULL 07/12] qga: add implementation of guest-get-disks for Windows,
Michael Roth <=
- [PULL 08/12] glib-compat: add g_unix_get_passwd_entry_qemu(), Michael Roth, 2020/10/27
- [PULL 09/12] qga: add ssh-{add,remove}-authorized-keys, Michael Roth, 2020/10/27
- Re: [PULL 00/12] qemu-ga patch queue for soft-freeze, no-reply, 2020/10/27
- Re: [PULL 00/12] qemu-ga patch queue for soft-freeze, Peter Maydell, 2020/10/28