[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 10/10] qga: added GuestPCIAddress information
From: |
Denis V. Lunev |
Subject: |
[Qemu-devel] [PATCH 10/10] qga: added GuestPCIAddress information |
Date: |
Fri, 19 Jun 2015 19:57:55 +0300 |
From: Olga Krishtal <address@hidden>
PCIAddress inforfation is obtained via SetupApi, which provides the
information about address, bus, etc. We look throught entire device tree
in the system and try to find device object for given volume. For this PDO
SetupDiGetDeviceRegistryProperty is called, which reads PCI configuration
for a given devicei if it is possible.
This is the most convinient way for a userspace service. The lookup is
performed for every volume available. However, this information is
not mandatory for vss-provider.
In order to use SetupApi we need to notify linker about it. We do not need
to install additional libs, so we do not make separate configuration
option to use libsetupapi.su
SetupApi gives as the same information as kernel driver
with IRP_MN_QUERY_INTERFACE.
https://support.microsoft.com/en-us/kb/253232
Signed-off-by: Olga Krishtal <address@hidden>
Signed-off-by: Denis V. Lunev <address@hidden>
CC: Eric Blake <address@hidden>
CC: Michael Roth <address@hidden>
---
configure | 2 +-
qga/commands-win32.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 78 insertions(+), 1 deletion(-)
diff --git a/configure b/configure
index 222694f..bf84c5a 100755
--- a/configure
+++ b/configure
@@ -731,7 +731,7 @@ if test "$mingw32" = "yes" ; then
sysconfdir="\${prefix}"
local_statedir=
confsuffix=""
- libs_qga="-lws2_32 -lwinmm -lpowrprof $libs_qga"
+ libs_qga="-lsetupapi -lws2_32 -lwinmm -lpowrprof $libs_qga"
fi
werror=""
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 09f0e82..f33ba7c 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -18,6 +18,8 @@
#include <string.h>
#include <winioctl.h>
#include <ntddscsi.h>
+#include <setupapi.h>
+#include <initguid.h>
#include "qga/guest-agent-core.h"
#include "qga/vss-win32.h"
#include "qga-qmp-commands.h"
@@ -29,6 +31,10 @@
#define SHTDN_REASON_FLAG_PLANNED 0x80000000
#endif
+DEFINE_GUID(GUID_DEVINTERFACE_VOLUME,
+ 0x53f5630dL, 0xb6bf, 0x11d0, 0x94, 0xf2,
+ 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
+
/* multiple of 100 nanoseconds elapsed between windows baseline
* (1/1/1601) and Unix Epoch (1/1/1970), accounting for leap years */
#define W32_FT_OFFSET (10000000ULL * 60 * 60 * 24 * \
@@ -811,6 +817,77 @@ done:
static GuestPCIAddress *get_pci_info(char *guid, Error **errp)
{
+ HDEVINFO dev_info;
+ SP_DEVINFO_DATA dev_info_data;
+ int i;
+ char dev_name[MAX_PATH];
+ char *name = g_strdup(&guid[4]);
+ char *buffer = NULL;
+ if (!QueryDosDevice(name, dev_name, sizeof(dev_name)/sizeof(char))) {
+ error_setg_win32(errp, GetLastError(), "failed to get dos device
name");
+ g_free(name);
+ return NULL;
+ }
+ g_free(name);
+
+ dev_info = SetupDiGetClassDevs(&GUID_DEVINTERFACE_VOLUME, 0, 0,
+ DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
+ if (dev_info == INVALID_HANDLE_VALUE) {
+ error_setg_win32(errp, GetLastError(), "failed to get devices tree");
+ return NULL;
+ }
+ dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
+ for (i = 0; SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data); i++) {
+ DWORD data, addr, bus, slot, func;
+ GuestPCIAddress *pci;
+ DWORD size = 0;
+
+ while (!SetupDiGetDeviceRegistryProperty(dev_info, &dev_info_data,
+ SPDRP_PHYSICAL_DEVICE_OBJECT_NAME,
+ &data, (PBYTE)buffer, size, &size)) {
+ if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ if (buffer) {
+ g_free(buffer);
+ }
+ buffer = g_malloc0(sizeof(char)*(size*2));
+ } else {
+ error_setg_win32(errp, GetLastError(),
+ "failed to get device name");
+ goto out;
+ }
+ }
+
+ if (g_strcmp0(buffer, dev_name)) {
+ continue;
+ }
+
+ if (!SetupDiGetDeviceRegistryProperty(dev_info, &dev_info_data,
+ SPDRP_BUSNUMBER, &data, (PBYTE)&bus, size, &size)) {
+ goto out;
+ }
+
+ if (!SetupDiGetDeviceRegistryProperty(dev_info, &dev_info_data,
+ SPDRP_ADDRESS, &data, (PBYTE)&addr, size, &size)) {
+ goto out;
+ }
+
+ slot = (addr >> 16) & 0xFFFF;
+ func = addr & 0xFFFF;
+ pci = g_malloc0(sizeof(*pci));
+ pci->domain = addr;
+ pci->slot = slot;
+ pci->function = func;
+ pci->bus = bus;
+
+ if (buffer) {
+ g_free(buffer);
+ }
+ return pci;
+ }
+out:
+ if (buffer) {
+ g_free(buffer);
+ }
return NULL;
}
--
1.9.1
- Re: [Qemu-devel] [PATCH 02/10] qga: implement guest-pipe-open command, (continued)
- [Qemu-devel] [PATCH 04/10] qga: handle possible SIGPIPE in guest-file-write, Denis V. Lunev, 2015/06/19
- [Qemu-devel] [PATCH 05/10] qga: guest-pipe-open for Windows guest, Denis V. Lunev, 2015/06/19
- [Qemu-devel] [PATCH 06/10] qga: guest exec functionality for Windows guests, Denis V. Lunev, 2015/06/19
- [Qemu-devel] [PATCH 03/10] qga: guest exec functionality for Unix guests, Denis V. Lunev, 2015/06/19
- [Qemu-devel] [PATCH 07/10] qga: added empty qmp_quest_get_fsinfo functionality., Denis V. Lunev, 2015/06/19
- [Qemu-devel] [PATCH 08/10] qga: added mountpoint and filesystem type for single volume, Denis V. Lunev, 2015/06/19
- [Qemu-devel] [PATCH 09/10] qga: added bus type and disk location path, Denis V. Lunev, 2015/06/19
- [Qemu-devel] [PATCH 10/10] qga: added GuestPCIAddress information,
Denis V. Lunev <=