mirror of https://github.com/xemu-project/xemu.git
qga: add implementation of guest-get-disks for Windows
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>
This commit is contained in:
parent
fed3956429
commit
c67d2efd9d
|
@ -979,6 +979,101 @@ out:
|
||||||
return list;
|
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
|
#else
|
||||||
|
|
||||||
static GuestDiskAddressList *build_guest_disk_info(char *guid, Error **errp)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
|
||||||
|
{
|
||||||
|
error_setg(errp, QERR_UNSUPPORTED);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_QGA_NTDDSCSI */
|
#endif /* CONFIG_QGA_NTDDSCSI */
|
||||||
|
|
||||||
static GuestFilesystemInfo *build_guest_fsinfo(char *guid, Error **errp)
|
static GuestFilesystemInfo *build_guest_fsinfo(char *guid, Error **errp)
|
||||||
|
@ -2458,9 +2559,3 @@ GuestDeviceInfoList *qmp_guest_get_devices(Error **errp)
|
||||||
}
|
}
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
|
|
||||||
{
|
|
||||||
error_setg(errp, QERR_UNSUPPORTED);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue