[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 11/11] qga: added GuestPCIAddress information
From: |
Michael Roth |
Subject: |
[Qemu-devel] [PATCH 11/11] qga: added GuestPCIAddress information |
Date: |
Tue, 7 Jul 2015 20:43:39 -0500 |
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>
* stub out get_pci_info if !CONFIG_QGA_NTDDSCSI
Signed-off-by: Michael Roth <address@hidden>
---
configure | 1 +
qga/commands-win32.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 97 insertions(+), 1 deletion(-)
diff --git a/configure b/configure
index f43db83..0004040 100755
--- a/configure
+++ b/configure
@@ -3835,6 +3835,7 @@ int main(void) {
EOF
if compile_prog "" "" ; then
guest_agent_ntddscsi=yes
+ libs_qga="-lsetupapi $libs_qga"
fi
fi
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 2bcc4a5..a7822d5 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -23,6 +23,8 @@
#ifdef CONFIG_QGA_NTDDSCSI
#include <winioctl.h>
#include <ntddscsi.h>
+#include <setupapi.h>
+#include <initguid.h>
#endif
#include "qga/guest-agent-core.h"
#include "qga/vss-win32.h"
@@ -424,9 +426,102 @@ static GuestDiskBusType find_bus_type(STORAGE_BUS_TYPE
bus)
return win2qemu[(int)bus];
}
+DEFINE_GUID(GUID_DEVINTERFACE_VOLUME,
+ 0x53f5630dL, 0xb6bf, 0x11d0, 0x94, 0xf2,
+ 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
+
static GuestPCIAddress *get_pci_info(char *guid, Error **errp)
{
- return NULL;
+ HDEVINFO dev_info;
+ SP_DEVINFO_DATA dev_info_data;
+ DWORD size = 0;
+ int i;
+ char dev_name[MAX_PATH];
+ char *buffer = NULL;
+ GuestPCIAddress *pci = NULL;
+ char *name = g_strdup(&guid[4]);
+
+ if (!QueryDosDevice(name, dev_name, ARRAY_SIZE(dev_name))) {
+ error_setg_win32(errp, GetLastError(), "failed to get dos device
name");
+ goto out;
+ }
+
+ 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");
+ goto out;
+ }
+
+ dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
+ for (i = 0; SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data); i++) {
+ DWORD addr, bus, slot, func, dev, data, size2;
+ while (!SetupDiGetDeviceRegistryProperty(dev_info, &dev_info_data,
+ SPDRP_PHYSICAL_DEVICE_OBJECT_NAME,
+ &data, (PBYTE)buffer, size,
+ &size2)) {
+ size = MAX(size, size2);
+ if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ g_free(buffer);
+ /* Double the size to avoid problems on
+ * W2k MBCS systems per KB 888609.
+ * https://support.microsoft.com/en-us/kb/259695 */
+ buffer = g_malloc(size * 2);
+ } else {
+ error_setg_win32(errp, GetLastError(),
+ "failed to get device name");
+ goto out;
+ }
+ }
+
+ if (g_strcmp0(buffer, dev_name)) {
+ continue;
+ }
+
+ /* There is no need to allocate buffer in the next functions. The size
+ * is known and ULONG according to
+ * https://support.microsoft.com/en-us/kb/253232
+ *
https://msdn.microsoft.com/en-us/library/windows/hardware/ff543095(v=vs.85).aspx
+ */
+ if (!SetupDiGetDeviceRegistryProperty(dev_info, &dev_info_data,
+ SPDRP_BUSNUMBER, &data, (PBYTE)&bus, size, NULL)) {
+ break;
+ }
+
+ /* The function retrieves the device's address. This value will be
+ * transformed into device function and number */
+ if (!SetupDiGetDeviceRegistryProperty(dev_info, &dev_info_data,
+ SPDRP_ADDRESS, &data, (PBYTE)&addr, size, NULL)) {
+ break;
+ }
+
+ /* This call returns UINumber of DEVICE_CAPABILITIES structure.
+ * This number is typically a user-perceived slot number. */
+ if (!SetupDiGetDeviceRegistryProperty(dev_info, &dev_info_data,
+ SPDRP_UI_NUMBER, &data, (PBYTE)&slot, size, NULL)) {
+ break;
+ }
+
+ /* SetupApi gives us the same information as driver with
+ * IoGetDeviceProperty. According to Microsoft
+ * https://support.microsoft.com/en-us/kb/253232
+ * FunctionNumber = (USHORT)((propertyAddress) & 0x0000FFFF);
+ * DeviceNumber = (USHORT)(((propertyAddress) >> 16) & 0x0000FFFF);
+ * SPDRP_ADDRESS is propertyAddress, so we do the same.*/
+
+ func = addr & 0x0000FFFF;
+ dev = (addr >> 16) & 0x0000FFFF;
+ pci = g_malloc0(sizeof(*pci));
+ pci->domain = dev;
+ pci->slot = slot;
+ pci->function = func;
+ pci->bus = bus;
+ break;
+ }
+out:
+ g_free(buffer);
+ g_free(name);
+ return pci;
}
static int get_disk_bus_type(HANDLE vol_h, Error **errp)
--
1.9.1
- [Qemu-devel] [PULL v2 00/11] qemu-ga patches for 2.4.0, Michael Roth, 2015/07/07
- [Qemu-devel] [PATCH 09/11] configure: add configure check for ntdddisk.h, Michael Roth, 2015/07/07
- [Qemu-devel] [PATCH 07/11] qga: added empty qmp_quest_get_fsinfo functionality., Michael Roth, 2015/07/07
- [Qemu-devel] [PATCH 01/11] qga/commands-posix: Fix bug in guest-fstrim, Michael Roth, 2015/07/07
- [Qemu-devel] [PATCH 04/11] qga: add win32 library iphlpapi, Michael Roth, 2015/07/07
- [Qemu-devel] [PATCH 10/11] qga: added bus type and disk location path, Michael Roth, 2015/07/07
- [Qemu-devel] [PATCH 11/11] qga: added GuestPCIAddress information,
Michael Roth <=
- [Qemu-devel] [PATCH 08/11] qga: added mountpoint and filesystem type for single volume, Michael Roth, 2015/07/07
- [Qemu-devel] [PATCH 02/11] qga/qmp_guest_fstrim: Return per path fstrim result, Michael Roth, 2015/07/07
- [Qemu-devel] [PATCH 03/11] Revert "guest agent: remove g_strcmp0 usage", Michael Roth, 2015/07/07
- [Qemu-devel] [PATCH 06/11] qga: fail early for invalid time, Michael Roth, 2015/07/07
- [Qemu-devel] [PATCH 05/11] qga: win32 qmp_guest_network_get_interfaces implementation, Michael Roth, 2015/07/07