From patchwork Tue Jul 7 04:40:20 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Roth X-Patchwork-Id: 492037 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 3AD341402BF for ; Tue, 7 Jul 2015 14:41:39 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=Z/neDVw5; dkim-atps=neutral Received: from localhost ([::1]:53952 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZCKhK-0001wT-93 for incoming@patchwork.ozlabs.org; Tue, 07 Jul 2015 00:41:34 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50263) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZCKgi-00011f-PA for qemu-devel@nongnu.org; Tue, 07 Jul 2015 00:40:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZCKgg-0006B0-DP for qemu-devel@nongnu.org; Tue, 07 Jul 2015 00:40:56 -0400 Received: from mail-ob0-x229.google.com ([2607:f8b0:4003:c01::229]:36512) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZCKgg-0006At-70 for qemu-devel@nongnu.org; Tue, 07 Jul 2015 00:40:54 -0400 Received: by obdbs4 with SMTP id bs4so121260246obd.3 for ; Mon, 06 Jul 2015 21:40:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=UmGW1AlvegV7g5HU86oXCuA/iNOOpmEXaNcid8ZFAa8=; b=Z/neDVw5zKi6JLESLY8gjNfrI7qWMsBE36PCfA6xfnzQCUukGsvlly/eHrBhWMkGmh qihLK5BUNEsa6CZ7O/H/BsV6Hlr5okZtvItdkftkjnBQxbtfDNYa270f8jKTwCYR5dCm k4qdHNm8FGdPtzY62vXE/BidtR6gk/FNdaXR033P51rsGSgkubcGMTMLz9CnLz/5eus8 DXRWmZ40rpIBk/ZMElBvazUCxAAeViTgAtB6yYGIk1NBhWTYNqVF8P4epI31raziRrl5 TL7dpSZ3jODvHn+wqGRZpQjACDvi+7fhjZkHLxQ04vTdIv8uRrfSxuhcn3PuHI5nD51e Ykyw== X-Received: by 10.202.49.212 with SMTP id x203mr2000900oix.81.1436244053760; Mon, 06 Jul 2015 21:40:53 -0700 (PDT) Received: from localhost (104-184-96-177.lightspeed.austtx.sbcglobal.net. [104.184.96.177]) by mx.google.com with ESMTPSA id d13sm11317192obs.12.2015.07.06.21.40.51 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Mon, 06 Jul 2015 21:40:52 -0700 (PDT) From: Michael Roth To: qemu-devel@nongnu.org Date: Mon, 6 Jul 2015 23:40:20 -0500 Message-Id: <1436244020-27822-11-git-send-email-mdroth@linux.vnet.ibm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1436244020-27822-1-git-send-email-mdroth@linux.vnet.ibm.com> References: <1436244020-27822-1-git-send-email-mdroth@linux.vnet.ibm.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4003:c01::229 Cc: "Denis V. Lunev" , peter.maydell@linaro.org, Olga Krishtal Subject: [Qemu-devel] [PATCH 10/10] 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 From: Olga Krishtal 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 Signed-off-by: Michael Roth --- configure | 2 +- qga/commands-win32.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 97 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 3bb5e55..5fb8919 100755 --- a/configure +++ b/configure @@ -732,7 +732,7 @@ if test "$mingw32" = "yes" ; then sysconfdir="\${prefix}" local_statedir= confsuffix="" - libs_qga="-lws2_32 -lwinmm -lpowrprof -liphlpapi $libs_qga" + libs_qga="-lsetupapi -lws2_32 -lwinmm -lpowrprof -liphlpapi $libs_qga" fi werror="" diff --git a/qga/commands-win32.c b/qga/commands-win32.c index bffa766..609f3c7 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include "qga/guest-agent-core.h" #include "qga/vss-win32.h" #include "qga-qmp-commands.h" @@ -34,6 +36,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 * \ @@ -423,7 +429,96 @@ static void guest_file_init(void) 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)