From patchwork Wed Jul 8 02:11:36 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Roth X-Patchwork-Id: 492682 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id D219A140D25 for ; Wed, 8 Jul 2015 12:16:49 +1000 (AEST) Received: from localhost ([::1]:32929 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZCeul-00061r-Uv for incoming@patchwork.ozlabs.org; Tue, 07 Jul 2015 22:16:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39440) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZCeq6-0006EZ-Iw for qemu-devel@nongnu.org; Tue, 07 Jul 2015 22:12:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZCeq2-0002rw-Fn for qemu-devel@nongnu.org; Tue, 07 Jul 2015 22:11:58 -0400 Received: from e18.ny.us.ibm.com ([129.33.205.208]:48517) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZCeq2-0002ro-Bk for qemu-devel@nongnu.org; Tue, 07 Jul 2015 22:11:54 -0400 Received: from /spool/local by e18.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 7 Jul 2015 22:11:54 -0400 Received: from d01dlp03.pok.ibm.com (9.56.250.168) by e18.ny.us.ibm.com (146.89.104.205) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 7 Jul 2015 22:11:51 -0400 X-Helo: d01dlp03.pok.ibm.com X-MailFrom: mdroth@linux.vnet.ibm.com X-RcptTo: qemu-devel@nongnu.org Received: from b01cxnp23033.gho.pok.ibm.com (b01cxnp23033.gho.pok.ibm.com [9.57.198.28]) by d01dlp03.pok.ibm.com (Postfix) with ESMTP id ED5ABC90045 for ; Tue, 7 Jul 2015 22:02:57 -0400 (EDT) Received: from d01av02.pok.ibm.com (d01av02.pok.ibm.com [9.56.224.216]) by b01cxnp23033.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t682Bpgj59375864 for ; Wed, 8 Jul 2015 02:11:51 GMT Received: from d01av02.pok.ibm.com (localhost [127.0.0.1]) by d01av02.pok.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t682Bo43024692 for ; Tue, 7 Jul 2015 22:11:50 -0400 Received: from localhost ([9.41.105.109]) by d01av02.pok.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id t682Bne7024672; Tue, 7 Jul 2015 22:11:50 -0400 From: Michael Roth To: qemu-devel@nongnu.org Date: Tue, 7 Jul 2015 21:11:36 -0500 Message-Id: <1436321496-26179-12-git-send-email-mdroth@linux.vnet.ibm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1436321496-26179-1-git-send-email-mdroth@linux.vnet.ibm.com> References: <1436321496-26179-1-git-send-email-mdroth@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15070802-0045-0000-0000-000000A7E4A2 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 129.33.205.208 Cc: "Denis V. Lunev" , peter.maydell@linaro.org, Olga Krishtal Subject: [Qemu-devel] [PATCH 11/11] qga: added GuestPCIAddress information X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 Signed-off-by: Denis V. Lunev CC: Eric Blake CC: Michael Roth * stub out get_pci_info if !CONFIG_QGA_NTDDSCSI Signed-off-by: Michael Roth --- configure | 1 + qga/commands-win32.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 62fa05d..c89b1ea 100755 --- a/configure +++ b/configure @@ -3836,6 +3836,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 #include +#include +#include #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)