From patchwork Thu Sep 3 13:56:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Selva Nair X-Patchwork-Id: 1413 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director11.mail.ord1d.rsapps.net ([172.28.255.1]) by backend30.mail.ord1d.rsapps.net with LMTP id eIJdFhiDUV+gLAAAIUCqbw (envelope-from ) for ; Thu, 03 Sep 2020 19:58:16 -0400 Received: from proxy4.mail.ord1c.rsapps.net ([172.28.255.1]) by director11.mail.ord1d.rsapps.net with LMTP id SLtAFhiDUV9yZgAAvGGmqA (envelope-from ) for ; Thu, 03 Sep 2020 19:58:16 -0400 Received: from smtp16.gate.ord1c ([172.28.255.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy4.mail.ord1c.rsapps.net with LMTPS id oKgeFhiDUV++JAAAjcXvpA (envelope-from ) for ; Thu, 03 Sep 2020 19:58:16 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp16.gate.ord1c.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dkim=fail (signature verification failed) header.d=gmail.com; dmarc=fail (p=none; dis=none) header.from=gmail.com X-Suspicious-Flag: YES X-Classification-ID: 550fceba-ee41-11ea-9310-bc305bf036a4-1-1 Received: from [216.105.38.7] ([216.105.38.7:49580] helo=lists.sourceforge.net) by smtp16.gate.ord1c.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 3E/E4-08817-713815F5; Thu, 03 Sep 2020 19:58:16 -0400 Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1kDz6G-0008Nu-GV; Thu, 03 Sep 2020 23:57:04 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kDz6F-0008Nm-2H for openvpn-devel@lists.sourceforge.net; Thu, 03 Sep 2020 23:57:03 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=pBdXA36S2L+G8fW4+v5UH74yAwFAfpvII6LXpWCWjJA=; b=ZA6FiGXVL0DJ45BaBZEhaArla1 /ps9MegKMwJobip3wnhurOyvfECqP4d8pp/hvs5Lmd/ccd+recf2KVSXESju+bpbjAHGOiga8NC/N 0VqG4WffcGa1FxeZBH991V8myLkj2Om2lCQAJytItoJwt3EQgIizyOiGIRd0jS2qACx8=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:MIME-Version: Content-Type:Content-Transfer-Encoding:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=pBdXA36S2L+G8fW4+v5UH74yAwFAfpvII6LXpWCWjJA=; b=e3n/XlK3fgXSsNm9AFBdh1CXHJ DXS8Da0YwbutaEwnQ7UvNMfQavY0jJcHiQiXUZfXIdbhOjebQzXMjKIswZbW7T1JlpVMJldwv0Mvi 6cpmtceOa8lyGsN7y41iC6kmSZbR9duQ04rh4xM9y57MQ6GZjbtJTLf6DmlEQFhvWnYo=; Received: from mail-qv1-f67.google.com ([209.85.219.67]) by sfi-mx-3.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.92.2) id 1kDz69-00BzIY-Kz for openvpn-devel@lists.sourceforge.net; Thu, 03 Sep 2020 23:57:03 +0000 Received: by mail-qv1-f67.google.com with SMTP id ef16so2219104qvb.8 for ; Thu, 03 Sep 2020 16:56:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=pBdXA36S2L+G8fW4+v5UH74yAwFAfpvII6LXpWCWjJA=; b=ou57eBgeRsk4tuToBLsykc3Bz1dsREWTPIBYWymnNmCVnjrE/4CanJmbFcFymoRAYt erNiwuhi3guY9bwV2qQ2wsoEQEgoUjfZgyexUxGrNLYm2Lz7Aj3L05J+jKzH/9YY/EmO 6SAKcp3sU7ljnBAd2cOypJPLymcu1TK2W/qzBQ2eRqQh08IvyEGKu30Ac+AI7U1G7PBB bUIbfBstZWhm4iPbkLyMR9a2wyG82Jzac0FosMGmnLdbFcIp82VD/FCxw/6LpRqZZPTO FTEAQtfUrnln59izQYJy1K6qWo0QSXc+w9czpv5F77s4XVOsM+mZeO1ir5pRGMsZk80a ukMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=pBdXA36S2L+G8fW4+v5UH74yAwFAfpvII6LXpWCWjJA=; b=P3J7ACnqzWVJ/TYvMx5i/vqG2+f33aqtrXXqoHze/HuNpKwOKmbaVhcHBK6Ftt3mP4 JvOfUi7y7RypuEVMnZnbBmBmS7nzEhCGIDN3rbo+hBtF+oEqQiS2qhvm0B+x4rXmAb9P jE4FORIuw9L9YhP38B7Gb8gtAh4lVSFOeNK7TtFYYqlG/r5JWVQO4vSmOI8pBN8U7Atb pGUnU15fUY6AZZueNpnQKUWNO0f7Gk35Jckzfl9lMt02CESxdI2OT1RhybiztcUsNOst mNXlNLmnzKS3FFOP3CD0jHrKfg9vv6sHdLf0nPOJ3jzqR1u3KEehbWzwxyYsymbIFBab bycA== X-Gm-Message-State: AOAM531aW6R46J8/F8OysJ0Nmi8v6YP7rCd5i8en5fXTbexhEPhQWZQX UQGr1Qs3bHw8ALVqp6NKWlG2coyETBg= X-Google-Smtp-Source: ABdhPJwd+gatx1A3ttoKwyFsVz97FOkJHHcdHSCftP5vSiYLC0NCPR9T2/hh4UT3h5wFTSbkk1omUg== X-Received: by 2002:a0c:e188:: with SMTP id p8mr4298190qvl.9.1599177411407; Thu, 03 Sep 2020 16:56:51 -0700 (PDT) Received: from saturn.home.sansel.ca (CPE40167ea0e1c2-CM788df74daaa0.cpe.net.cable.rogers.com. [99.228.34.11]) by smtp.gmail.com with ESMTPSA id m36sm1219428qtd.10.2020.09.03.16.56.50 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 03 Sep 2020 16:56:50 -0700 (PDT) From: selva.nair@gmail.com To: openvpn-devel@lists.sourceforge.net Date: Thu, 3 Sep 2020 19:56:44 -0400 Message-Id: <1599177404-29996-1-git-send-email-selva.nair@gmail.com> X-Mailer: git-send-email 2.1.4 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (selva.nair[at]gmail.com) -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.219.67 listed in wl.mailspike.net] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.219.67 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-Headers-End: 1kDz69-00BzIY-Kz Subject: [Openvpn-devel] [PATCH] In tap.c use DiInstallDevice to install the driver on a new adapter X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox From: Selva Nair As reported in Trac 1321, additional adapter instalaltion by tapctl.exe fails to fully setup the device node (some registry keys missing, error in setapi.dev.log etc.). Although the exact cause of this failure is unclear, letting the Plug and Play subsystem handle the instalaltion by calling DiInsatllDevice() avoids it. We let the system automatically choose the best driver by passing NULL for driverinfo to DiInstallDevice(). This also eliminates the need for enumerating all drivers in the Net class and selecting a matching one. Somehow mingw-w64 fails to find DiInstallDriver() in newdev.lib although the header does define it. Use LoadLibrary() to locate it at run time (available in Vista and above). Built using mingw and tested both the msi installer (code shared with libopenvpnmscia.dll) and tapctl.exe on Windows 10 64 bit. Fixes: Trac #1321 Signed-off-by: Selva Nair Acked-by: Lev Stipakov --- config-msvc.h | 1 + src/tapctl/tap.c | 231 +++++++++++++++++++------------------------------------ 2 files changed, 78 insertions(+), 154 deletions(-) diff --git a/config-msvc.h b/config-msvc.h index 8ef4897..f199bb2 100644 --- a/config-msvc.h +++ b/config-msvc.h @@ -112,6 +112,7 @@ #define HAVE_EC_GROUP_ORDER_BITS 1 #define OPENSSL_NO_EC 1 #define HAVE_EVP_CIPHER_CTX_RESET 1 +#define HAVE_DIINSTALLDEVICE 1 #define PATH_SEPARATOR '\\' #define PATH_SEPARATOR_STR "\\" diff --git a/src/tapctl/tap.c b/src/tapctl/tap.c index 7cb3ded..e36d132 100644 --- a/src/tapctl/tap.c +++ b/src/tapctl/tap.c @@ -33,18 +33,69 @@ #include #include #include +#include #ifdef _MSC_VER #pragma comment(lib, "advapi32.lib") #pragma comment(lib, "ole32.lib") #pragma comment(lib, "setupapi.lib") +#pragma comment(lib, "newdev.lib") #endif + const static GUID GUID_DEVCLASS_NET = { 0x4d36e972L, 0xe325, 0x11ce, { 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 } }; const static TCHAR szAdapterRegKeyPathTemplate[] = TEXT("SYSTEM\\CurrentControlSet\\Control\\Network\\%") TEXT(PRIsLPOLESTR) TEXT("\\%") TEXT(PRIsLPOLESTR) TEXT("\\Connection"); #define ADAPTER_REGKEY_PATH_MAX (_countof(TEXT("SYSTEM\\CurrentControlSet\\Control\\Network\\")) - 1 + 38 + _countof(TEXT("\\")) - 1 + 38 + _countof(TEXT("\\Connection"))) +/** + * Dynamically load a library and find a function in it + * + * @param libname Name of the library to load + * @param funcname Name of the function to find + * @param m Pointer to a module. On return this is set to the + * the handle to the loaded library. The caller must + * free it by calling FreeLibrary() if not NULL. + * + * @return Pointer to the function + * NULL on error -- use GetLastError() to find the error code. + * + **/ +static void * +find_function(const WCHAR *libname, const char *funcname, HMODULE *m) +{ + WCHAR libpath[MAX_PATH]; + void *fptr = NULL; + + /* Make sure the dll is loaded from the system32 folder */ + if (!GetSystemDirectoryW(libpath, _countof(libpath))) + { + return NULL; + } + + size_t len = _countof(libpath) - wcslen(libpath) - 1; + if (len < wcslen(libname) + 1) + { + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return NULL; + } + wcsncat(libpath, L"\\", len); + wcsncat(libpath, libname, len-1); + + *m = LoadLibraryW(libpath); + if (*m == NULL) + { + return NULL; + } + fptr = GetProcAddress(*m, funcname); + if (!fptr) + { + FreeLibrary(*m); + *m = NULL; + return NULL; + } + return fptr; +} /** * Returns length of string of strings @@ -678,6 +729,7 @@ tap_create_adapter( _Out_ LPGUID pguidAdapter) { DWORD dwResult; + HMODULE libnewdev = NULL; if (szHwId == NULL || pbRebootRequired == NULL @@ -746,129 +798,7 @@ tap_create_adapter( goto cleanup_hDevInfoList; } - /* Search for the driver. */ - if (!SetupDiBuildDriverInfoList( - hDevInfoList, - &devinfo_data, - SPDIT_CLASSDRIVER)) - { - dwResult = GetLastError(); - msg(M_NONFATAL, "%s: SetupDiBuildDriverInfoList failed", __FUNCTION__); - goto cleanup_hDevInfoList; - } - DWORDLONG dwlDriverVersion = 0; - DWORD drvinfo_detail_data_size = sizeof(SP_DRVINFO_DETAIL_DATA) + 0x100; - SP_DRVINFO_DETAIL_DATA *drvinfo_detail_data = (SP_DRVINFO_DETAIL_DATA *)malloc(drvinfo_detail_data_size); - if (drvinfo_detail_data == NULL) - { - msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, drvinfo_detail_data_size); - dwResult = ERROR_OUTOFMEMORY; goto cleanup_DriverInfoList; - } - - for (DWORD dwIndex = 0;; dwIndex++) - { - /* Get a driver from the list. */ - SP_DRVINFO_DATA drvinfo_data = { .cbSize = sizeof(SP_DRVINFO_DATA) }; - if (!SetupDiEnumDriverInfo( - hDevInfoList, - &devinfo_data, - SPDIT_CLASSDRIVER, - dwIndex, - &drvinfo_data)) - { - if (GetLastError() == ERROR_NO_MORE_ITEMS) - { - break; - } - else - { - /* Something is wrong with this driver. Skip it. */ - msg(M_WARN | M_ERRNO, "%s: SetupDiEnumDriverInfo(%u) failed", __FUNCTION__, dwIndex); - continue; - } - } - - /* Get driver info details. */ - DWORD dwSize; - drvinfo_detail_data->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA); - if (!SetupDiGetDriverInfoDetail( - hDevInfoList, - &devinfo_data, - &drvinfo_data, - drvinfo_detail_data, - drvinfo_detail_data_size, - &dwSize)) - { - if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) - { - /* (Re)allocate buffer. */ - if (drvinfo_detail_data) - { - free(drvinfo_detail_data); - } - - drvinfo_detail_data_size = dwSize; - drvinfo_detail_data = (SP_DRVINFO_DETAIL_DATA *)malloc(drvinfo_detail_data_size); - if (drvinfo_detail_data == NULL) - { - msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, drvinfo_detail_data_size); - dwResult = ERROR_OUTOFMEMORY; goto cleanup_DriverInfoList; - } - - /* Re-get driver info details. */ - drvinfo_detail_data->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA); - if (!SetupDiGetDriverInfoDetail( - hDevInfoList, - &devinfo_data, - &drvinfo_data, - drvinfo_detail_data, - drvinfo_detail_data_size, - &dwSize)) - { - /* Something is wrong with this driver. Skip it. */ - continue; - } - } - else - { - /* Something is wrong with this driver. Skip it. */ - msg(M_WARN | M_ERRNO, "%s: SetupDiGetDriverInfoDetail(\"%hs\") failed", __FUNCTION__, drvinfo_data.Description); - continue; - } - } - - /* Check the driver version and hardware ID. */ - if (dwlDriverVersion < drvinfo_data.DriverVersion - && drvinfo_detail_data->HardwareID - && _tcszistr(drvinfo_detail_data->HardwareID, szHwId)) - { - /* Newer version and matching hardware ID found. Select the driver. */ - if (!SetupDiSetSelectedDriver( - hDevInfoList, - &devinfo_data, - &drvinfo_data)) - { - /* Something is wrong with this driver. Skip it. */ - msg(M_WARN | M_ERRNO, "%s: SetupDiSetSelectedDriver(\"%hs\") failed", __FUNCTION__, drvinfo_data.Description); - continue; - } - - dwlDriverVersion = drvinfo_data.DriverVersion; - } - } - if (drvinfo_detail_data) - { - free(drvinfo_detail_data); - } - - if (dwlDriverVersion == 0) - { - dwResult = ERROR_NOT_FOUND; - msg(M_NONFATAL, "%s: No driver for device \"%" PRIsLPTSTR "\" installed.", __FUNCTION__, szHwId); - goto cleanup_DriverInfoList; - } - - /* Call appropriate class installer. */ + /* Register the device instance with the PnP Manager */ if (!SetupDiCallClassInstaller( DIF_REGISTERDEVICE, hDevInfoList, @@ -876,43 +806,38 @@ tap_create_adapter( { dwResult = GetLastError(); msg(M_NONFATAL, "%s: SetupDiCallClassInstaller(DIF_REGISTERDEVICE) failed", __FUNCTION__); - goto cleanup_DriverInfoList; + goto cleanup_hDevInfoList; } - /* Register device co-installers if any. */ - if (!SetupDiCallClassInstaller( - DIF_REGISTER_COINSTALLERS, - hDevInfoList, - &devinfo_data)) - { - dwResult = GetLastError(); - msg(M_WARN | M_ERRNO, "%s: SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS) failed", __FUNCTION__); - } + /* Install the device using DiInstallDevice() + * We instruct the system to use the best driver in the driver store + * by setting the drvinfo argument of DiInstallDevice as NULL. This + * assumes a driver is already installed in the driver store. + */ +#ifdef HAVE_DIINSTALLDEVICE + if (!DiInstallDevice(hwndParent, hDevInfoList, &devinfo_data, NULL, 0, pbRebootRequired)) +#else + /* mingw does not resolve DiInstallDevice, so load it at run time. */ + typedef BOOL (WINAPI *DiInstallDeviceFn) (HWND, HDEVINFO, SP_DEVINFO_DATA *, + SP_DRVINFO_DATA *, DWORD, BOOL *); + DiInstallDeviceFn installfn + = find_function (L"newdev.dll", "DiInstallDevice", &libnewdev); - /* Install adapters if any. */ - if (!SetupDiCallClassInstaller( - DIF_INSTALLINTERFACES, - hDevInfoList, - &devinfo_data)) + if (!installfn) { dwResult = GetLastError(); - msg(M_WARN | M_ERRNO, "%s: SetupDiCallClassInstaller(DIF_INSTALLINTERFACES) failed", __FUNCTION__); + msg(M_NONFATAL | M_ERRNO, "%s: Failed to locate DiInstallDevice()", __FUNCTION__); + goto cleanup_hDevInfoList; } - /* Install the device. */ - if (!SetupDiCallClassInstaller( - DIF_INSTALLDEVICE, - hDevInfoList, - &devinfo_data)) + if (!installfn(hwndParent, hDevInfoList, &devinfo_data, NULL, 0, pbRebootRequired)) +#endif { dwResult = GetLastError(); - msg(M_NONFATAL | M_ERRNO, "%s: SetupDiCallClassInstaller(DIF_INSTALLDEVICE) failed", __FUNCTION__); + msg(M_NONFATAL | M_ERRNO, "%s: DiInstallDevice failed", __FUNCTION__); goto cleanup_remove_device; } - /* Check if a system reboot is required. (Ignore errors) */ - check_reboot(hDevInfoList, &devinfo_data, pbRebootRequired); - /* Get network adapter ID from registry. Retry for max 30sec. */ dwResult = get_net_adapter_guid(hDevInfoList, &devinfo_data, 30, pguidAdapter); @@ -958,13 +883,11 @@ cleanup_remove_device: } } -cleanup_DriverInfoList: - SetupDiDestroyDriverInfoList( - hDevInfoList, - &devinfo_data, - SPDIT_CLASSDRIVER); - cleanup_hDevInfoList: + if (libnewdev) + { + FreeLibrary(libnewdev); + } SetupDiDestroyDeviceInfoList(hDevInfoList); return dwResult; }