mirror of
https://github.com/qemu/qemu.git
synced 2024-11-29 06:43:37 +08:00
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user