From patchwork Mon Mar 9 02:17:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Rozman X-Patchwork-Id: 1028 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director12.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id eJP3KVVCZl5PJgAAIUCqbw for ; Mon, 09 Mar 2020 09:19:17 -0400 Received: from proxy5.mail.ord1d.rsapps.net ([172.30.191.6]) by director12.mail.ord1d.rsapps.net with LMTP id AOrXKVVCZl6oTAAAIasKDg ; Mon, 09 Mar 2020 09:19:17 -0400 Received: from smtp19.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy5.mail.ord1d.rsapps.net with LMTP id 6MlgKVVCZl4TNgAA8Zzt7w ; Mon, 09 Mar 2020 09:19:17 -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: smtp19.gate.ord1d.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=rozman.si; dmarc=fail (p=none; dis=none) header.from=rozman.si X-Suspicious-Flag: YES X-Classification-ID: 93a7e0e2-6208-11ea-ac83-525400d67fa8-1-1 Received: from [216.105.38.7] ([216.105.38.7:49346] helo=lists.sourceforge.net) by smtp19.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id CE/2F-26733-452466E5; Mon, 09 Mar 2020 09:19:17 -0400 Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1jBIIS-00028p-Lr; Mon, 09 Mar 2020 13:18:16 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jBIIP-00027t-LC for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:13 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: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=5YTm2ijJlSE2wKxjBCIzwuLK2IPT4RAPTxWlLX3jmm4=; b=fS6vKmFUaAg4eTaGsJRx6gEoQL Ez4IL+/B7MkG9vZI503KrpFCQNfg/tWALOCW/fk74md7XwrLhodwlkPikQKdJep78PSrOzKiRq3DS 9JuGGuLek7IeCitVhXui6xBe3499IstQSuZLgnZmia3skmY/1QUW1yXlpXL9F4Bnvl2M=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:Message-Id:Date:Subject:Cc:To:From :Sender:Reply-To:Content-Type: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=5YTm2ijJlSE2wKxjBCIzwuLK2IPT4RAPTxWlLX3jmm4=; b=b 2xuSNAt/PCUsPthCUOrh9jtOcXLu4S09qbMdRogowjoqXtD3fwpRQBgX9SMgfkK8vEwR84c2MXJJT uEErsUeoVjkbb/1srFHCtNTBhobroL/JTQtmmlUpv4K24T0sGunTeGpdXfrLbO2vKYlllDboMBg5D OOjwgm0ueAXzEGQE=; Received: from pub5.amebis.si ([213.250.55.21]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1jBIIL-00DVna-5U for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:13 +0000 Received: by pub5.amebis.si (Postfix, from userid 1000) id 981F41002FEE; Mon, 9 Mar 2020 14:17:51 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rozman.si; s=default; t=1583759871; bh=5YTm2ijJlSE2wKxjBCIzwuLK2IPT4RAPTxWlLX3jmm4=; h=From:To:Cc:Subject:Date:From; b=b6AtvPDLcXrFJQyAiOFvfOtH+TdAG8M4Q2xKGMtS9SoIVK9RPQYwSjgwiAiVmlEn7 EeXh+wiU9JPMZWc1tNNnZY51hck7RYAm5sOhBTb7FY2ASQvwg2ExHA2ZjXSQ8qYiSe /9vHoknk0abMbrjsRU4ggBtytDwp0jMYkLZkLZaM= X-Spam-Checker-Version: SpamAssassin 3.4.3 (2019-12-06) on brana.amebis.doma X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,BAYES_20 autolearn=ham autolearn_force=no version=3.4.3 Received: from SR6.amebis.doma (unknown [IPv6:2a00:ee2:209:164:a5ae:e83c:b7b:725]) by pub5.amebis.si (Postfix) with ESMTP id CDFA71002F87; Mon, 9 Mar 2020 14:17:48 +0100 (CET) From: Simon Rozman To: openvpn-devel@lists.sourceforge.net Date: Mon, 9 Mar 2020 14:17:17 +0100 Message-Id: <20200309131728.380-1-simon@rozman.si> X-Mailer: git-send-email 2.24.1.windows.2 MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -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 0.0 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1jBIIL-00DVna-5U Subject: [Openvpn-devel] [PATCH 01/12] openvpnmsica: Remove required Windows driver certification detection 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: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox The MSI packages are switching to TAP-Windows6 and Wintun MSM modules to install the TAP/TUN driver. The MSM modules have built-in Windows version detection already. This commit is now-dead-code clean up with uncrustification. Signed-off-by: Simon Rozman Acked-by: Gert Doering --- src/openvpnmsica/openvpnmsica.c | 129 +------------------------------- 1 file changed, 3 insertions(+), 126 deletions(-) diff --git a/src/openvpnmsica/openvpnmsica.c b/src/openvpnmsica/openvpnmsica.c index 16381ea1..4236330a 100644 --- a/src/openvpnmsica/openvpnmsica.c +++ b/src/openvpnmsica/openvpnmsica.c @@ -203,128 +203,6 @@ _openvpnmsica_debug_popup(_In_z_ LPCTSTR szFunctionName) #endif /* ifdef _DEBUG */ -/** - * Detects Windows version and sets DRIVERCERTIFICATION property to "", "whql", or "attsgn" - * accordingly. - * - * @param hInstall Handle to the installation provided to the DLL custom action - * - * @return ERROR_SUCCESS on success; An error code otherwise - * See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa368072.aspx - */ -static UINT -openvpnmsica_set_driver_certification(_In_ MSIHANDLE hInstall) -{ - UINT uiResult; - - /* Get Windows version. */ -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4996) /* 'GetVersionExW': was declared deprecated. */ -#endif - OSVERSIONINFOEX ver_info = { .dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX) }; - if (!GetVersionEx((LPOSVERSIONINFO)&ver_info)) - { - uiResult = GetLastError(); - msg(M_NONFATAL | M_ERRNO, "%s: GetVersionEx() failed", __FUNCTION__); - return uiResult; - } -#ifdef _MSC_VER -#pragma warning(pop) -#endif - - /* The Windows version is usually spoofed, check using RtlGetVersion(). */ - TCHAR szDllPath[0x1000]; - ExpandEnvironmentStrings(TEXT("%SystemRoot%\\System32\\ntdll.dll"), szDllPath, -#ifdef UNICODE - _countof(szDllPath) -#else - _countof(szDllPath) - 1 -#endif - ); - HMODULE hNtDllModule = LoadLibrary(szDllPath); - if (hNtDllModule) - { - typedef NTSTATUS (WINAPI* fnRtlGetVersion)(PRTL_OSVERSIONINFOW); - fnRtlGetVersion RtlGetVersion = (fnRtlGetVersion)GetProcAddress(hNtDllModule, "RtlGetVersion"); - if (RtlGetVersion) - { - RTL_OSVERSIONINFOW rtl_ver_info = { .dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW) }; - if (RtlGetVersion(&rtl_ver_info) == 0) - { - if ( - rtl_ver_info.dwMajorVersion > ver_info.dwMajorVersion - || rtl_ver_info.dwMajorVersion == ver_info.dwMajorVersion && rtl_ver_info.dwMinorVersion > ver_info.dwMinorVersion - || rtl_ver_info.dwMajorVersion == ver_info.dwMajorVersion && rtl_ver_info.dwMinorVersion == ver_info.dwMinorVersion && rtl_ver_info.dwBuildNumber > ver_info.dwBuildNumber) - { - /* We got RtlGetVersion() and it reported newer version than GetVersionEx(). */ - ver_info.dwMajorVersion = rtl_ver_info.dwMajorVersion; - ver_info.dwMinorVersion = rtl_ver_info.dwMinorVersion; - ver_info.dwBuildNumber = rtl_ver_info.dwBuildNumber; - ver_info.dwPlatformId = rtl_ver_info.dwPlatformId; - } - } - } - - FreeLibrary(hNtDllModule); - } - - /* We don't trust RtlGetVersion() either. Check the version resource of kernel32.dll. */ - ExpandEnvironmentStrings(TEXT("%SystemRoot%\\System32\\kernel32.dll"), szDllPath, -#ifdef UNICODE - _countof(szDllPath) -#else - _countof(szDllPath) - 1 -#endif - ); - - DWORD dwHandle; - DWORD dwVerInfoSize = GetFileVersionInfoSize(szDllPath, &dwHandle); - if (dwVerInfoSize) - { - LPVOID pVersionInfo = malloc(dwVerInfoSize); - if (pVersionInfo) - { - /* Read version info. */ - if (GetFileVersionInfo(szDllPath, dwHandle, dwVerInfoSize, pVersionInfo)) - { - /* Get the value for the root block. */ - UINT uiSize = 0; - VS_FIXEDFILEINFO *pVSFixedFileInfo = NULL; - if (VerQueryValue(pVersionInfo, TEXT("\\"), &pVSFixedFileInfo, &uiSize) && uiSize && pVSFixedFileInfo) - { - if (HIWORD(pVSFixedFileInfo->dwProductVersionMS) > ver_info.dwMajorVersion - || HIWORD(pVSFixedFileInfo->dwProductVersionMS) == ver_info.dwMajorVersion && LOWORD(pVSFixedFileInfo->dwProductVersionMS) > ver_info.dwMinorVersion - || HIWORD(pVSFixedFileInfo->dwProductVersionMS) == ver_info.dwMajorVersion && LOWORD(pVSFixedFileInfo->dwProductVersionMS) == ver_info.dwMinorVersion && HIWORD(pVSFixedFileInfo->dwProductVersionLS) > ver_info.dwBuildNumber) - { - /* We got kernel32.dll version and it is newer. */ - ver_info.dwMajorVersion = HIWORD(pVSFixedFileInfo->dwProductVersionMS); - ver_info.dwMinorVersion = LOWORD(pVSFixedFileInfo->dwProductVersionMS); - ver_info.dwBuildNumber = HIWORD(pVSFixedFileInfo->dwProductVersionLS); - } - } - } - - free(pVersionInfo); - } - else - { - msg(M_NONFATAL, "%s: malloc(%u) failed", __FUNCTION__, dwVerInfoSize); - } - } - - uiResult = MsiSetProperty(hInstall, TEXT("DRIVERCERTIFICATION"), ver_info.dwMajorVersion >= 10 ? ver_info.wProductType > VER_NT_WORKSTATION ? TEXT("whql") : TEXT("attsgn") : TEXT("")); - if (uiResult != ERROR_SUCCESS) - { - SetLastError(uiResult); /* MSDN does not mention MsiSetProperty() to set GetLastError(). But we do have an error code. Set last error manually. */ - msg(M_NONFATAL | M_ERRNO, "%s: MsiSetProperty(\"DRIVERCERTIFICATION\") failed", __FUNCTION__); - return uiResult; - } - - return ERROR_SUCCESS; -} - - /** * Detects if the OpenVPNService service is in use (running or paused) and sets * OPENVPNSERVICE to the service process PID, or its path if it is set to @@ -451,7 +329,6 @@ FindSystemInfo(_In_ MSIHANDLE hInstall) OPENVPNMSICA_SAVE_MSI_SESSION(hInstall); - openvpnmsica_set_driver_certification(hInstall); openvpnmsica_set_openvpnserv_state(hInstall); if (bIsCoInitialized) @@ -829,7 +706,7 @@ EvaluateTAPInterfaces(_In_ MSIHANDLE hInstall) goto cleanup_hViewST_close; } - for (;;) + for (;; ) { /* Fetch one record from the view. */ MSIHANDLE hRecord = 0; @@ -998,7 +875,7 @@ cleanup_szSeqFilename: if (uiResult != ERROR_SUCCESS) { /* Clean-up sequence files. */ - for (size_t i = _countof(szActionNames); i--;) + for (size_t i = _countof(szActionNames); i--; ) { if (szSeqFilename[i][0]) { @@ -1186,7 +1063,7 @@ cleanup_session: uiResult = ERROR_SUCCESS; } - for (size_t i = MSICA_CLEANUP_ACTION_COUNT; i--;) + for (size_t i = MSICA_CLEANUP_ACTION_COUNT; i--; ) { msica_op_seq_free(&session.seq_cleanup[i]); } From patchwork Mon Mar 9 02:17:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Rozman X-Patchwork-Id: 1029 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director8.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id SPQaOlVCZl7BBwAAIUCqbw for ; Mon, 09 Mar 2020 09:19:17 -0400 Received: from proxy15.mail.ord1d.rsapps.net ([172.30.191.6]) by director8.mail.ord1d.rsapps.net with LMTP id eND1OVVCZl7zagAAfY0hYg ; Mon, 09 Mar 2020 09:19:17 -0400 Received: from smtp21.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy15.mail.ord1d.rsapps.net with LMTP id 4P6lOVVCZl7SKQAAAY1PeQ ; Mon, 09 Mar 2020 09:19:17 -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: smtp21.gate.ord1d.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=rozman.si; dmarc=fail (p=none; dis=none) header.from=rozman.si X-Suspicious-Flag: YES X-Classification-ID: 939bd45a-6208-11ea-b377-525400a98691-1-1 Received: from [216.105.38.7] ([216.105.38.7:35072] helo=lists.sourceforge.net) by smtp21.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 5C/A5-09068-452466E5; Mon, 09 Mar 2020 09:19:17 -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 1jBIIT-00009E-Hq; Mon, 09 Mar 2020 13:18:17 +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 1jBIIP-00008h-E3 for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:13 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=f56+O8QHGTla8sER8LZvvji7eRhlfsNwj2HTC31WNvI=; b=ioKuAFZLHd6+c/FE+SnBciUQZs vdSSZeqKzoz8ifFqZ95eQm9uPiU55k9i2iwEaLOQvGs8xp11e7uMY87SDiCIMinrSV8KmPG1ywq8V f0S9Q1a1bwjV8xvOM+CIus2e/Npw+2zWWR+Cunl9ycbG+ddb1LNImSjk5DBalQrteFSE=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=f56+O8QHGTla8sER8LZvvji7eRhlfsNwj2HTC31WNvI=; b=a7GPWgyjRZvDZUtJJ2Lb3TXRCg NYDn4zh4R7hf9nIJAXjyTjUuJ6JMTYDgRGO7zxjiWul3f2gw/owRV8T8+PI0T8Ixh6YpZXg74bUDS TqDLyk87RrZ9+nhaczxG5SBan5uUAT8S5GaEO96r44O9eZYEH9YMcDUzuuQQ68Fb2SHs=; Received: from pub5.amebis.si ([213.250.55.21]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1jBIIL-00DVnj-5Y for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:13 +0000 Received: by pub5.amebis.si (Postfix, from userid 1000) id 443831002F87; Mon, 9 Mar 2020 14:17:54 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rozman.si; s=default; t=1583759874; bh=f56+O8QHGTla8sER8LZvvji7eRhlfsNwj2HTC31WNvI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Mfo1+pxI32OGtzyG7vJW4ntNUO+ihLGO1xhPGbPuA4CwH3mY4WRAF2mDI6hTV/wGA BFmqTgNXyUezL0rniDC2AqCgGWsLZiJePa9R6OcjoUe4RSFyhNblzeMRugb+43hgZp rEqC7YeuLAttyQUBKtkcwQsm4vLxy8L/KqnclHYM= X-Spam-Checker-Version: SpamAssassin 3.4.3 (2019-12-06) on brana.amebis.doma X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00 autolearn=ham autolearn_force=no version=3.4.3 Received: from SR6.amebis.doma (unknown [IPv6:2a00:ee2:209:164:a5ae:e83c:b7b:725]) by pub5.amebis.si (Postfix) with ESMTP id DF3711002F94; Mon, 9 Mar 2020 14:17:48 +0100 (CET) From: Simon Rozman To: openvpn-devel@lists.sourceforge.net Date: Mon, 9 Mar 2020 14:17:18 +0100 Message-Id: <20200309131728.380-2-simon@rozman.si> X-Mailer: git-send-email 2.24.1.windows.2 In-Reply-To: <20200309131728.380-1-simon@rozman.si> References: <20200309131728.380-1-simon@rozman.si> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -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: 1jBIIL-00DVnj-5Y Subject: [Openvpn-devel] [PATCH 02/12] openvpnmsica: Fix TAPInterface.DisplayName field interpretation 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: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox The DisplayName field type is Filename in the MSI database. This means it must be authored as "8.3" filename, or "8.3|long filename". This issue does not appear until interface names grow longer than 8 characters, or contain characters invalid in 8.3 filename notation. Signed-off-by: Simon Rozman Acked-by: Gert Doering --- src/openvpnmsica/openvpnmsica.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/openvpnmsica/openvpnmsica.c b/src/openvpnmsica/openvpnmsica.c index 4236330a..e1f0b77d 100644 --- a/src/openvpnmsica/openvpnmsica.c +++ b/src/openvpnmsica/openvpnmsica.c @@ -2,7 +2,7 @@ * openvpnmsica -- Custom Action DLL to provide OpenVPN-specific support to MSI packages * https://community.openvpn.net/openvpn/wiki/OpenVPNMSICA * - * Copyright (C) 2018 Simon Rozman + * Copyright (C) 2018-2020 Simon Rozman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -752,6 +752,9 @@ EvaluateTAPInterfaces(_In_ MSIHANDLE hInstall) { goto cleanup_hRecord; } + /* `DisplayName` field type is [Filename](https://docs.microsoft.com/en-us/windows/win32/msi/filename), which is either "8.3|long name" or "8.3". */ + LPTSTR szDisplayNameEx = _tcschr(szDisplayName, TEXT('|')); + szDisplayNameEx = szDisplayNameEx != NULL ? szDisplayNameEx + 1 : szDisplayName; if (iAction > INSTALLSTATE_BROKEN) { @@ -796,7 +799,7 @@ EvaluateTAPInterfaces(_In_ MSIHANDLE hInstall) msica_op_tap_interface_create, MSICA_INTERFACE_TICK_SIZE, NULL, - szDisplayName)); + szDisplayNameEx)); } else { @@ -807,7 +810,7 @@ EvaluateTAPInterfaces(_In_ MSIHANDLE hInstall) msica_op_tap_interface_delete_by_name, MSICA_INTERFACE_TICK_SIZE, NULL, - szDisplayName)); + szDisplayNameEx)); } /* The amount of tick space to add for each interface to progress indicator. */ From patchwork Mon Mar 9 02:17:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Rozman X-Patchwork-Id: 1021 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director9.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id kEvxHkNCZl4SagAAIUCqbw for ; Mon, 09 Mar 2020 09:18:59 -0400 Received: from proxy4.mail.ord1d.rsapps.net ([172.30.191.6]) by director9.mail.ord1d.rsapps.net with LMTP id ECHEHkNCZl51VAAAalYnBA ; Mon, 09 Mar 2020 09:18:59 -0400 Received: from smtp10.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy4.mail.ord1d.rsapps.net with LMTP id 6AwGHkNCZl7TTgAAiYrejw ; Mon, 09 Mar 2020 09:18:59 -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: smtp10.gate.ord1d.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=rozman.si; dmarc=fail (p=none; dis=none) header.from=rozman.si X-Suspicious-Flag: YES X-Classification-ID: 88a34b14-6208-11ea-b5e7-52540013bccb-1-1 Received: from [216.105.38.7] ([216.105.38.7:49112] helo=lists.sourceforge.net) by smtp10.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id F6/FD-18907-242466E5; Mon, 09 Mar 2020 09:18:58 -0400 Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1jBIIT-000290-Gw; Mon, 09 Mar 2020 13:18:17 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jBIIQ-00028U-OS for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:14 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=dTX8U/YJLEYJ55FCghepX0XR3yPMcYLJUacJlJcaiZI=; b=Qc2xRX4FcCGOV7NkN2bZEuDlyd YmPFSLaYux2wrj5B1XMAgAh6mRnB1zlxHKu8ALCBZlkuGVxQT/DRW5Ht/CM7ujjhe715RcObX7ZzZ +/v6rGWa6tujFPbsNgGVuHyvOfcmTqlRIOck96ZnaMESaTyENz+mO7IiI0thxEz1lp30=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=dTX8U/YJLEYJ55FCghepX0XR3yPMcYLJUacJlJcaiZI=; b=NvO1JfWTCVK+DpQ7E0fg1nYUO4 3Ei1z4xH8vRbb5n+tAvhgvLqf8anso93+miZ6tIZIYJpWVze/GrG4J64+KvI0W99ioMJSR94DsT42 RXW9+n/YlyT5izxhs1PFy20xqEYP1DvsJ1pny95WrplLHeBx3Z4LMYRV4Oyrn+EuZOok=; Received: from pub5.amebis.si ([213.250.55.21]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1jBIIL-00DVnm-5r for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:14 +0000 Received: by pub5.amebis.si (Postfix, from userid 1000) id 4BE201002FB5; Mon, 9 Mar 2020 14:17:55 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rozman.si; s=default; t=1583759875; bh=dTX8U/YJLEYJ55FCghepX0XR3yPMcYLJUacJlJcaiZI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=o1nSmk/+cuO5xm0owapk9resS3v+izuz8rusMuZo5Wsb8SROX6c4N6STtZkL82kes 2b9sdOSPdb/HEBJcGFpLYrPpDHop5COJxajAopFYJkTpb6kAJkzHt9J+TqEqQrzI/A IxhqhpJeg0PWhtb5Cleqvi0F9f27oMEMYWHs58uo= X-Spam-Checker-Version: SpamAssassin 3.4.3 (2019-12-06) on brana.amebis.doma X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.3 Received: from SR6.amebis.doma (unknown [IPv6:2a00:ee2:209:164:a5ae:e83c:b7b:725]) by pub5.amebis.si (Postfix) with ESMTP id EDAF11002FB5; Mon, 9 Mar 2020 14:17:48 +0100 (CET) From: Simon Rozman To: openvpn-devel@lists.sourceforge.net Date: Mon, 9 Mar 2020 14:17:19 +0100 Message-Id: <20200309131728.380-3-simon@rozman.si> X-Mailer: git-send-email 2.24.1.windows.2 In-Reply-To: <20200309131728.380-1-simon@rozman.si> References: <20200309131728.380-1-simon@rozman.si> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -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: 1jBIIL-00DVnm-5r Subject: [Openvpn-devel] [PATCH 03/12] tapctl: Update documentation 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: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox Signed-off-by: Simon Rozman Acked-by: Gert Doering --- src/tapctl/tap.c | 17 ++++++++--------- src/tapctl/tap.h | 18 +++++++++--------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/tapctl/tap.c b/src/tapctl/tap.c index 464ce725..b8249919 100644 --- a/src/tapctl/tap.c +++ b/src/tapctl/tap.c @@ -2,7 +2,7 @@ * tapctl -- Utility to manipulate TUN/TAP interfaces on Windows * https://community.openvpn.net/openvpn/wiki/Tapctl * - * Copyright (C) 2018 Simon Rozman + * Copyright (C) 2018-2020 Simon Rozman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -51,15 +51,15 @@ const static TCHAR szInterfaceRegKeyPathTemplate[] = TEXT("SYSTEM\\CurrentContro * Checks device install parameters if a system reboot is required. * * @param hDeviceInfoSet A handle to a device information set that contains a device - * information element that represents the device for which to + * information element that represents the device. * * @param pDeviceInfoData A pointer to an SP_DEVINFO_DATA structure that specifies the * device information element in hDeviceInfoSet. * - * @param pbRebootRequired A pointer to a BOOL flag. If the interface installation requires - * a system restart, this flag is set to TRUE. Otherwise, the flag is - * left unmodified. This allows the flag to be globally initialized to - * FALSE and reused for multiple interface installations. + * @param pbRebootRequired A pointer to a BOOL flag. If the device requires a system restart, + * this flag is set to TRUE. Otherwise, the flag is left unmodified. This + * allows the flag to be globally initialized to FALSE and reused for multiple + * interface manipulations. * * @return ERROR_SUCCESS on success; Win32 error code otherwise **/ @@ -244,7 +244,7 @@ get_reg_string( * Returns network interface ID. * * @param hDeviceInfoSet A handle to a device information set that contains a device - * information element that represents the device for which to + * information element that represents the device. * * @param pDeviceInfoData A pointer to an SP_DEVINFO_DATA structure that specifies the * device information element in hDeviceInfoSet. @@ -330,8 +330,7 @@ get_net_interface_guid( * Returns a specified Plug and Play device property. * * @param hDeviceInfoSet A handle to a device information set that contains a device - * information element that represents the device for which to - * retrieve a Plug and Play property. + * information element that represents the device. * * @param pDeviceInfoData A pointer to an SP_DEVINFO_DATA structure that specifies the * device information element in hDeviceInfoSet. diff --git a/src/tapctl/tap.h b/src/tapctl/tap.h index f74a39df..ca66e5da 100644 --- a/src/tapctl/tap.h +++ b/src/tapctl/tap.h @@ -2,7 +2,7 @@ * tapctl -- Utility to manipulate TUN/TAP interfaces on Windows * https://community.openvpn.net/openvpn/wiki/Tapctl * - * Copyright (C) 2018 Simon Rozman + * Copyright (C) 2018-2020 Simon Rozman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -41,10 +41,10 @@ * of the device. This pointer is optional and can be NULL. Default value * is root\tap0901. * - * @param pbRebootRequired A pointer to a BOOL flag. If the interface installation requires - * a system restart, this flag is set to TRUE. Otherwise, the flag is - * left unmodified. This allows the flag to be globally initialized to - * FALSE and reused for multiple interface installations. + * @param pbRebootRequired A pointer to a BOOL flag. If the device requires a system restart, + * this flag is set to TRUE. Otherwise, the flag is left unmodified. This + * allows the flag to be globally initialized to FALSE and reused for multiple + * interface manipulations. * * @param pguidInterface A pointer to GUID that receives network interface ID. * @@ -70,10 +70,10 @@ tap_create_interface( * * @param pguidInterface A pointer to GUID that contains network interface ID. * - * @param pbRebootRequired A pointer to a BOOL flag. If the interface installation requires - * a system restart, this flag is set to TRUE. Otherwise, the flag is - * left unmodified. This allows the flag to be globally initialized to - * FALSE and reused for multiple interface installations. + * @param pbRebootRequired A pointer to a BOOL flag. If the device requires a system restart, + * this flag is set to TRUE. Otherwise, the flag is left unmodified. This + * allows the flag to be globally initialized to FALSE and reused for multiple + * interface manipulations. * * @return ERROR_SUCCESS on success; Win32 error code otherwise **/ From patchwork Mon Mar 9 02:17:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Rozman X-Patchwork-Id: 1022 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director8.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id iBOUEU1CZl4SagAAIUCqbw for ; Mon, 09 Mar 2020 09:19:09 -0400 Received: from proxy19.mail.ord1d.rsapps.net ([172.30.191.6]) by director8.mail.ord1d.rsapps.net with LMTP id sKRYEU1CZl7dagAAfY0hYg ; Mon, 09 Mar 2020 09:19:09 -0400 Received: from smtp33.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy19.mail.ord1d.rsapps.net with LMTP id CDsGEU1CZl4JRAAAyH2SIw ; Mon, 09 Mar 2020 09:19:09 -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: smtp33.gate.ord1d.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=rozman.si; dmarc=fail (p=none; dis=none) header.from=rozman.si X-Suspicious-Flag: YES X-Classification-ID: 8e8741e8-6208-11ea-aefc-525400041ef2-1-1 Received: from [216.105.38.7] ([216.105.38.7:46048] helo=lists.sourceforge.net) by smtp33.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id BE/CB-22814-C42466E5; Mon, 09 Mar 2020 09:19:08 -0400 Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1jBIIS-0005tk-O8; Mon, 09 Mar 2020 13:18:16 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jBIIP-0005ss-0m for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:13 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=sUByytGJzo4iZtTa6NCteCaGpg+TQgWLJ2QZ+2fxSP4=; b=i6ipSaitYd4uPr4hCLlmBCx0My QlLOtzimRk3DgrmOyXiEKUjoFBYU7LCz9ljPLO1fbSgcjhIGfsGCEYjDLZPNs8/rW2KOvP8uF0EVx k6N0p3O2D5BY6fO0IragXZT+4i8BUJSLqWRUk+FSOk5hAxQVhsJ3xCjPfJiTUKQgTFAk=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=sUByytGJzo4iZtTa6NCteCaGpg+TQgWLJ2QZ+2fxSP4=; b=O9EL49mJHaPUXTXlCMEe2JbLQS 6wr8rTO/6xR7Uc3CtgAScRZyUEx17sYi8ENFOJ0veLhWmMLpTyze9NZSqv4i8TDIrYo1OGIfOqf5x 8YYy4lhJ2s+mB+E6G9SE+JMxBgyeb+z3hSU3G5WIlZKZmrd0lj5iZoD6gu2S1rOBCR1k=; Received: from pub5.amebis.si ([213.250.55.21]) by sfi-mx-3.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1jBIIL-0033P4-05 for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:12 +0000 Received: by pub5.amebis.si (Postfix, from userid 1000) id 3F5AD1002F94; Mon, 9 Mar 2020 14:17:55 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rozman.si; s=default; t=1583759875; bh=sUByytGJzo4iZtTa6NCteCaGpg+TQgWLJ2QZ+2fxSP4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aT1zJFNnyuwD4j/UNT4DuTaYp3Yj1nPpnaVi54yhXs+2YszsZVrquj3XyS69lVzeV Zl7W5/ftyELWqMQtlkbYKua+cRDerUacyv3O0iYxlYuUD405f/Zo8DSI9T0ezFgIM/ FNG14EC6Z+W8odvlQYTMrRAaSZUL0rsJ0lZ4ncGg= X-Spam-Checker-Version: SpamAssassin 3.4.3 (2019-12-06) on brana.amebis.doma X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00 autolearn=ham autolearn_force=no version=3.4.3 Received: from SR6.amebis.doma (unknown [IPv6:2a00:ee2:209:164:a5ae:e83c:b7b:725]) by pub5.amebis.si (Postfix) with ESMTP id 08A1D1002FB6; Mon, 9 Mar 2020 14:17:49 +0100 (CET) From: Simon Rozman To: openvpn-devel@lists.sourceforge.net Date: Mon, 9 Mar 2020 14:17:20 +0100 Message-Id: <20200309131728.380-4-simon@rozman.si> X-Mailer: git-send-email 2.24.1.windows.2 In-Reply-To: <20200309131728.380-1-simon@rozman.si> References: <20200309131728.380-1-simon@rozman.si> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -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: 1jBIIL-0033P4-05 Subject: [Openvpn-devel] [PATCH 04/12] tapctl: Add functions for enabling/disabling adapters 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: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox Signed-off-by: Simon Rozman Acked-by: Lev Stipakov --- src/tapctl/tap.c | 287 ++++++++++++++++++++++++++++++++++++++++------- src/tapctl/tap.h | 28 +++++ 2 files changed, 275 insertions(+), 40 deletions(-) diff --git a/src/tapctl/tap.c b/src/tapctl/tap.c index b8249919..576f6740 100644 --- a/src/tapctl/tap.c +++ b/src/tapctl/tap.c @@ -47,6 +47,28 @@ const static TCHAR szInterfaceRegKeyPathTemplate[] = TEXT("SYSTEM\\CurrentContro #define INTERFACE_REGKEY_PATH_MAX (_countof(TEXT("SYSTEM\\CurrentControlSet\\Control\\Network\\")) - 1 + 38 + _countof(TEXT("\\")) - 1 + 38 + _countof(TEXT("\\Connection"))) +/** + * Function that performs a specific task on a device + * + * @param hDeviceInfoSet A handle to a device information set that contains a device + * information element that represents the device. + * + * @param pDeviceInfoData A pointer to an SP_DEVINFO_DATA structure that specifies the + * device information element in hDeviceInfoSet. + * + * @param pbRebootRequired A pointer to a BOOL flag. If the device requires a system restart, + * this flag is set to TRUE. Otherwise, the flag is left unmodified. This + * allows the flag to be globally initialized to FALSE and reused for multiple + * interface manipulations. + * + * @return ERROR_SUCCESS on success; Win32 error code otherwise + **/ +typedef DWORD (*devop_func_t)( + _In_ HDEVINFO hDeviceInfoSet, + _In_ PSP_DEVINFO_DATA pDeviceInfoData, + _Inout_ LPBOOL pbRebootRequired); + + /** * Checks device install parameters if a system reboot is required. * @@ -94,6 +116,186 @@ check_reboot( } +/** + * Deletes the device. + * + * @param hDeviceInfoSet A handle to a device information set that contains a device + * information element that represents the device. + * + * @param pDeviceInfoData A pointer to an SP_DEVINFO_DATA structure that specifies the + * device information element in hDeviceInfoSet. + * + * @param pbRebootRequired A pointer to a BOOL flag. If the device requires a system restart, + * this flag is set to TRUE. Otherwise, the flag is left unmodified. This + * allows the flag to be globally initialized to FALSE and reused for multiple + * interface manipulations. + * + * @return ERROR_SUCCESS on success; Win32 error code otherwise + **/ +static DWORD +delete_device( + _In_ HDEVINFO hDeviceInfoSet, + _In_ PSP_DEVINFO_DATA pDeviceInfoData, + _Inout_ LPBOOL pbRebootRequired) +{ + SP_REMOVEDEVICE_PARAMS params = + { + .ClassInstallHeader = + { + .cbSize = sizeof(SP_CLASSINSTALL_HEADER), + .InstallFunction = DIF_REMOVE, + }, + .Scope = DI_REMOVEDEVICE_GLOBAL, + .HwProfile = 0, + }; + + /* Set class installer parameters for DIF_REMOVE. */ + if (!SetupDiSetClassInstallParams( + hDeviceInfoSet, + pDeviceInfoData, + ¶ms.ClassInstallHeader, + sizeof(SP_REMOVEDEVICE_PARAMS))) + { + DWORD dwResult = GetLastError(); + msg(M_NONFATAL | M_ERRNO, "%s: SetupDiSetClassInstallParams failed", __FUNCTION__); + return dwResult; + } + + /* Call appropriate class installer. */ + if (!SetupDiCallClassInstaller( + DIF_REMOVE, + hDeviceInfoSet, + pDeviceInfoData)) + { + DWORD dwResult = GetLastError(); + msg(M_NONFATAL | M_ERRNO, "%s: SetupDiCallClassInstaller(DIF_REMOVE) failed", __FUNCTION__); + return dwResult; + } + + /* Check if a system reboot is required. */ + check_reboot(hDeviceInfoSet, pDeviceInfoData, pbRebootRequired); + return ERROR_SUCCESS; +} + + +/** + * Changes the device state. + * + * @param hDeviceInfoSet A handle to a device information set that contains a device + * information element that represents the device. + * + * @param pDeviceInfoData A pointer to an SP_DEVINFO_DATA structure that specifies the + * device information element in hDeviceInfoSet. + * + * @param bEnable TRUE to enable the device; FALSE to disable. + * + * @param pbRebootRequired A pointer to a BOOL flag. If the device requires a system restart, + * this flag is set to TRUE. Otherwise, the flag is left unmodified. This + * allows the flag to be globally initialized to FALSE and reused for multiple + * interface manipulations. + * + * @return ERROR_SUCCESS on success; Win32 error code otherwise + **/ +static DWORD +change_device_state( + _In_ HDEVINFO hDeviceInfoSet, + _In_ PSP_DEVINFO_DATA pDeviceInfoData, + _In_ BOOL bEnable, + _Inout_ LPBOOL pbRebootRequired) +{ + SP_PROPCHANGE_PARAMS params = + { + .ClassInstallHeader = + { + .cbSize = sizeof(SP_CLASSINSTALL_HEADER), + .InstallFunction = DIF_PROPERTYCHANGE, + }, + .StateChange = bEnable ? DICS_ENABLE : DICS_DISABLE, + .Scope = DICS_FLAG_GLOBAL, + .HwProfile = 0, + }; + + /* Set class installer parameters for DIF_PROPERTYCHANGE. */ + if (!SetupDiSetClassInstallParams( + hDeviceInfoSet, + pDeviceInfoData, + ¶ms.ClassInstallHeader, + sizeof(SP_PROPCHANGE_PARAMS))) + { + DWORD dwResult = GetLastError(); + msg(M_NONFATAL | M_ERRNO, "%s: SetupDiSetClassInstallParams failed", __FUNCTION__); + return dwResult; + } + + /* Call appropriate class installer. */ + if (!SetupDiCallClassInstaller( + DIF_PROPERTYCHANGE, + hDeviceInfoSet, + pDeviceInfoData)) + { + DWORD dwResult = GetLastError(); + msg(M_NONFATAL | M_ERRNO, "%s: SetupDiCallClassInstaller(DIF_PROPERTYCHANGE) failed", __FUNCTION__); + return dwResult; + } + + /* Check if a system reboot is required. */ + check_reboot(hDeviceInfoSet, pDeviceInfoData, pbRebootRequired); + return ERROR_SUCCESS; +} + + +/** + * Enables the device. + * + * @param hDeviceInfoSet A handle to a device information set that contains a device + * information element that represents the device. + * + * @param pDeviceInfoData A pointer to an SP_DEVINFO_DATA structure that specifies the + * device information element in hDeviceInfoSet. + * + * @param pbRebootRequired A pointer to a BOOL flag. If the device requires a system restart, + * this flag is set to TRUE. Otherwise, the flag is left unmodified. This + * allows the flag to be globally initialized to FALSE and reused for multiple + * interface manipulations. + * + * @return ERROR_SUCCESS on success; Win32 error code otherwise + **/ +static DWORD +enable_device( + _In_ HDEVINFO hDeviceInfoSet, + _In_ PSP_DEVINFO_DATA pDeviceInfoData, + _Inout_ LPBOOL pbRebootRequired) +{ + return change_device_state(hDeviceInfoSet, pDeviceInfoData, TRUE, pbRebootRequired); +} + + +/** + * Disables the device. + * + * @param hDeviceInfoSet A handle to a device information set that contains a device + * information element that represents the device. + * + * @param pDeviceInfoData A pointer to an SP_DEVINFO_DATA structure that specifies the + * device information element in hDeviceInfoSet. + * + * @param pbRebootRequired A pointer to a BOOL flag. If the device requires a system restart, + * this flag is set to TRUE. Otherwise, the flag is left unmodified. This + * allows the flag to be globally initialized to FALSE and reused for multiple + * interface manipulations. + * + * @return ERROR_SUCCESS on success; Win32 error code otherwise + **/ +static DWORD +disable_device( + _In_ HDEVINFO hDeviceInfoSet, + _In_ PSP_DEVINFO_DATA pDeviceInfoData, + _Inout_ LPBOOL pbRebootRequired) +{ + return change_device_state(hDeviceInfoSet, pDeviceInfoData, FALSE, pbRebootRequired); +} + + /** * Reads string value from registry key. * @@ -754,10 +956,31 @@ cleanup_hDevInfoList: } -DWORD -tap_delete_interface( +/** + * Performs a given task on an interface. + * + * @param hwndParent A handle to the top-level window to use for any user interface that is + * related to non-device-specific actions (such as a select-device dialog + * box that uses the global class driver list). This handle is optional + * and can be NULL. If a specific top-level window is not required, set + * hwndParent to NULL. + * + * @param pguidInterface A pointer to GUID that contains network interface ID. + * + * @param funcOperation A pointer for the function to perform specific task on the interface. + * + * @param pbRebootRequired A pointer to a BOOL flag. If the device requires a system restart, + * this flag is set to TRUE. Otherwise, the flag is left unmodified. This + * allows the flag to be globally initialized to FALSE and reused for multiple + * interface manipulations. + * + * @return ERROR_SUCCESS on success; Win32 error code otherwise + **/ +static DWORD +execute_on_first_interface( _In_opt_ HWND hwndParent, _In_ LPCGUID pguidInterface, + _In_ devop_func_t funcOperation, _Inout_ LPBOOL pbRebootRequired) { DWORD dwResult; @@ -831,44 +1054,7 @@ tap_delete_interface( /* Compare GUIDs. */ if (memcmp(pguidInterface, &guidInterface, sizeof(GUID)) == 0) { - /* Remove the device. */ - SP_REMOVEDEVICE_PARAMS removedevice_params = - { - .ClassInstallHeader = - { - .cbSize = sizeof(SP_CLASSINSTALL_HEADER), - .InstallFunction = DIF_REMOVE, - }, - .Scope = DI_REMOVEDEVICE_GLOBAL, - .HwProfile = 0, - }; - - /* Set class installer parameters for DIF_REMOVE. */ - if (!SetupDiSetClassInstallParams( - hDevInfoList, - &devinfo_data, - &removedevice_params.ClassInstallHeader, - sizeof(SP_REMOVEDEVICE_PARAMS))) - { - dwResult = GetLastError(); - msg(M_NONFATAL, "%s: SetupDiSetClassInstallParams failed", __FUNCTION__); - goto cleanup_hDevInfoList; - } - - /* Call appropriate class installer. */ - if (!SetupDiCallClassInstaller( - DIF_REMOVE, - hDevInfoList, - &devinfo_data)) - { - dwResult = GetLastError(); - msg(M_NONFATAL, "%s: SetupDiCallClassInstaller(DIF_REMOVE) failed", __FUNCTION__); - goto cleanup_hDevInfoList; - } - - /* Check if a system reboot is required. */ - check_reboot(hDevInfoList, &devinfo_data, pbRebootRequired); - dwResult = ERROR_SUCCESS; + dwResult = funcOperation(hDevInfoList, &devinfo_data, pbRebootRequired); break; } } @@ -879,6 +1065,27 @@ cleanup_hDevInfoList: } +DWORD +tap_delete_interface( + _In_opt_ HWND hwndParent, + _In_ LPCGUID pguidInterface, + _Inout_ LPBOOL pbRebootRequired) +{ + return execute_on_first_interface(hwndParent, pguidInterface, delete_device, pbRebootRequired); +} + + +DWORD +tap_enable_interface( + _In_opt_ HWND hwndParent, + _In_ LPCGUID pguidInterface, + _In_ BOOL bEnable, + _Inout_ LPBOOL pbRebootRequired) +{ + return execute_on_first_interface(hwndParent, pguidInterface, bEnable ? enable_device : disable_device, pbRebootRequired); +} + + DWORD tap_set_interface_name( _In_ LPCGUID pguidInterface, diff --git a/src/tapctl/tap.h b/src/tapctl/tap.h index ca66e5da..4c2d73ba 100644 --- a/src/tapctl/tap.h +++ b/src/tapctl/tap.h @@ -84,6 +84,34 @@ tap_delete_interface( _Inout_ LPBOOL pbRebootRequired); +/** + * Enables or disables an interface. + * + * @param hwndParent A handle to the top-level window to use for any user interface that is + * related to non-device-specific actions (such as a select-device dialog + * box that uses the global class driver list). This handle is optional + * and can be NULL. If a specific top-level window is not required, set + * hwndParent to NULL. + * + * @param pguidInterface A pointer to GUID that contains network interface ID. + * + * @param bEnable TRUE to enable; FALSE to disable + * + * @param pbRebootRequired A pointer to a BOOL flag. If the device requires a system restart, + * this flag is set to TRUE. Otherwise, the flag is left unmodified. This + * allows the flag to be globally initialized to FALSE and reused for multiple + * interface manipulations. + * + * @return ERROR_SUCCESS on success; Win32 error code otherwise + **/ +DWORD +tap_enable_interface( + _In_opt_ HWND hwndParent, + _In_ LPCGUID pguidInterface, + _In_ BOOL bEnable, + _Inout_ LPBOOL pbRebootRequired); + + /** * Sets interface name. * From patchwork Mon Mar 9 02:17:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Rozman X-Patchwork-Id: 1032 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director7.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id oPBBI2VCZl7TWQAAIUCqbw for ; Mon, 09 Mar 2020 09:19:33 -0400 Received: from proxy4.mail.ord1d.rsapps.net ([172.30.191.6]) by director7.mail.ord1d.rsapps.net with LMTP id eAUPI2VCZl6xKAAAovjBpQ ; Mon, 09 Mar 2020 09:19:33 -0400 Received: from smtp37.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy4.mail.ord1d.rsapps.net with LMTP id aH+MImVCZl4mTgAAiYrejw ; Mon, 09 Mar 2020 09:19:33 -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: smtp37.gate.ord1d.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=rozman.si; dmarc=fail (p=none; dis=none) header.from=rozman.si X-Suspicious-Flag: YES X-Classification-ID: 9d143f40-6208-11ea-a92f-525400a11cf3-1-1 Received: from [216.105.38.7] ([216.105.38.7:49554] helo=lists.sourceforge.net) by smtp37.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id DF/26-09856-462466E5; Mon, 09 Mar 2020 09:19:33 -0400 Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1jBIIe-0002B2-66; Mon, 09 Mar 2020 13:18:28 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jBIIc-0002Af-Gr for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:26 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=IYldVImLzSxCPSIN3DTe+iVNudX+dBlFXo7e5YAn4M8=; b=JxxfwZ+w8Wtb9duz+ESC9bX9pq h6ruxrxmvbAZR7zviOxvPNuu9ACc3o7FmqMYmD3NLgIIAkEt0R2I5n4iCTkKt8w1CF09EYce9lENT ylonK/JiIxQtq0afX9lqoQGiV4foAWD4639t7qWDr0fOIekr8rIT9Oa+DmjtaaDpgB+g=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=IYldVImLzSxCPSIN3DTe+iVNudX+dBlFXo7e5YAn4M8=; b=WIIFPMZjdTfnS01tMs3Uwp/hAZ 5UXg6hp7EYvL/6yARG6UwRYENg8J0r25+1CxXkeQeZXp2OB2/c3xLT3HldhBOLaxp3qPaQu0hP2BR 24juCCZwnXY4pLJAdyTW8t58dBneL2OKLsqaAZsnNVWZziQJ5anRjQQ7DRu/N0EYjJiI=; Received: from pub5.amebis.si ([213.250.55.21]) by sfi-mx-3.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1jBIIV-0033Qb-20 for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:26 +0000 Received: by pub5.amebis.si (Postfix, from userid 1000) id 14C6D1002B55; Mon, 9 Mar 2020 14:17:58 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rozman.si; s=default; t=1583759878; bh=IYldVImLzSxCPSIN3DTe+iVNudX+dBlFXo7e5YAn4M8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GHdtvzTHbNET02xUHySKzdu+6TzLx/GiUJbW4JGld2iwU8aCwqLb4e+DTeq3SWZXD 3kffV1pNUnRRVednvcbPAPdh7sMDl6yLeHMGG9LcZIlGUJmRjG8eeHdbydbmD11HFc Nvmkr6p0dHD9/Lb9a/SJ4QQTjJUXR87mQOFa/NOk= X-Spam-Checker-Version: SpamAssassin 3.4.3 (2019-12-06) on brana.amebis.doma X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00 autolearn=ham autolearn_force=no version=3.4.3 Received: from SR6.amebis.doma (unknown [IPv6:2a00:ee2:209:164:a5ae:e83c:b7b:725]) by pub5.amebis.si (Postfix) with ESMTP id 1BFFF1002FB7; Mon, 9 Mar 2020 14:17:49 +0100 (CET) From: Simon Rozman To: openvpn-devel@lists.sourceforge.net Date: Mon, 9 Mar 2020 14:17:21 +0100 Message-Id: <20200309131728.380-5-simon@rozman.si> X-Mailer: git-send-email 2.24.1.windows.2 In-Reply-To: <20200309131728.380-1-simon@rozman.si> References: <20200309131728.380-1-simon@rozman.si> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 WEIRD_QUOTING BODY: Weird repeated double-quotation marks -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 -0.0 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1jBIIV-0033Qb-20 Subject: [Openvpn-devel] [PATCH 05/12] openvpnmsica: Revise MSI custom actions interop 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: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox Sequence scripts in temporary files has been discontinued in favor of much simpler sequence strings passed to individual custom actions. Pros: no temporary files; less code Cons: the evaluation phase must make a complete plan what to perform in each deferred custom action Signed-off-by: Simon Rozman Acked-by: Lev Stipakov --- src/openvpnmsica/Makefile.am | 4 +- src/openvpnmsica/msica_arg.c | 139 +++ src/openvpnmsica/msica_arg.h | 112 ++ src/openvpnmsica/msica_op.c | 1043 ----------------- src/openvpnmsica/msica_op.h | 430 ------- src/openvpnmsica/openvpnmsica.c | 713 ++++++----- src/openvpnmsica/openvpnmsica.vcxproj | 4 +- src/openvpnmsica/openvpnmsica.vcxproj.filters | 4 +- src/tapctl/basic.h | 19 +- src/tapctl/tap.c | 1 + 10 files changed, 678 insertions(+), 1791 deletions(-) create mode 100644 src/openvpnmsica/msica_arg.c create mode 100644 src/openvpnmsica/msica_arg.h delete mode 100644 src/openvpnmsica/msica_op.c delete mode 100644 src/openvpnmsica/msica_op.h diff --git a/src/openvpnmsica/Makefile.am b/src/openvpnmsica/Makefile.am index db8502b8..9d18854a 100644 --- a/src/openvpnmsica/Makefile.am +++ b/src/openvpnmsica/Makefile.am @@ -2,7 +2,7 @@ # openvpnmsica -- Custom Action DLL to provide OpenVPN-specific support to MSI packages # # Copyright (C) 2002-2018 OpenVPN Inc -# Copyright (C) 2018-2019 Simon Rozman +# Copyright (C) 2018-2020 Simon Rozman # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 @@ -48,7 +48,7 @@ endif libopenvpnmsica_la_SOURCES = \ dllmain.c \ msiex.c msiex.h \ - msica_op.c msica_op.h \ + msica_arg.c msica_arg.h \ openvpnmsica.c openvpnmsica.h \ $(top_srcdir)/src/tapctl/basic.h \ $(top_srcdir)/src/tapctl/error.c $(top_srcdir)/src/tapctl/error.h \ diff --git a/src/openvpnmsica/msica_arg.c b/src/openvpnmsica/msica_arg.c new file mode 100644 index 00000000..0014537a --- /dev/null +++ b/src/openvpnmsica/msica_arg.c @@ -0,0 +1,139 @@ +/* + * openvpnmsica -- Custom Action DLL to provide OpenVPN-specific support to MSI packages + * https://community.openvpn.net/openvpn/wiki/OpenVPNMSICA + * + * Copyright (C) 2018-2020 Simon Rozman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#elif defined(_MSC_VER) +#include +#endif + +#include "msica_arg.h" +#include "../tapctl/error.h" +#include "../tapctl/tap.h" + +#include +#include + + +void +msica_arg_seq_init(_Inout_ struct msica_arg_seq *seq) +{ + seq->head = NULL; + seq->tail = NULL; +} + + +void +msica_arg_seq_free(_Inout_ struct msica_arg_seq *seq) +{ + while (seq->head) + { + struct msica_arg *p = seq->head; + seq->head = seq->head->next; + free(p); + } + seq->tail = NULL; +} + + +void +msica_arg_seq_add_head( + _Inout_ struct msica_arg_seq *seq, + _In_z_ LPCTSTR argument) +{ + size_t argument_size = (_tcslen(argument) + 1) * sizeof(TCHAR); + struct msica_arg *p = malloc(sizeof(struct msica_arg) + argument_size); + if (p == NULL) + { + msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct msica_arg) + argument_size); + } + memcpy(p->val, argument, argument_size); + p->next = seq->head; + seq->head = p; + if (seq->tail == NULL) + { + seq->tail = p; + } +} + + +void +msica_arg_seq_add_tail( + _Inout_ struct msica_arg_seq *seq, + _Inout_ LPCTSTR argument) +{ + size_t argument_size = (_tcslen(argument) + 1) * sizeof(TCHAR); + struct msica_arg *p = malloc(sizeof(struct msica_arg) + argument_size); + if (p == NULL) + { + msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct msica_arg) + argument_size); + } + memcpy(p->val, argument, argument_size); + p->next = NULL; + *(seq->tail ? &seq->tail->next : &seq->head) = p; + seq->tail = p; +} + + +LPTSTR +msica_arg_seq_join(_In_ const struct msica_arg_seq *seq) +{ + /* Count required space. */ + size_t size = 2 /*x + zero-terminator*/; + for (struct msica_arg *p = seq->head; p != NULL; p = p->next) + { + size += _tcslen(p->val) + 1 /*space delimiter|zero-terminator*/; + } + size *= sizeof(TCHAR); + + /* Allocate. */ + LPTSTR str = malloc(size); + if (str == NULL) + { + msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, size); + return NULL; + } + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4996) /* Using unsafe string functions: The space in s and termination of p->val has been implicitly verified at the beginning of this function. */ +#endif + + /* Dummy argv[0] (i.e. executable name), for CommandLineToArgvW to work correctly when parsing this string. */ + _tcscpy(str, TEXT("x")); + + /* Join. */ + LPTSTR s = str + 1 /*x*/; + for (struct msica_arg *p = seq->head; p != NULL; p = p->next) + { + /* Convert zero-terminator into space delimiter. */ + s[0] = TEXT(' '); + s++; + /* Append argument. */ + _tcscpy(s, p->val); + s += _tcslen(p->val); + } + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + return str; +} diff --git a/src/openvpnmsica/msica_arg.h b/src/openvpnmsica/msica_arg.h new file mode 100644 index 00000000..d2158e0f --- /dev/null +++ b/src/openvpnmsica/msica_arg.h @@ -0,0 +1,112 @@ +/* + * openvpnmsica -- Custom Action DLL to provide OpenVPN-specific support to MSI packages + * https://community.openvpn.net/openvpn/wiki/OpenVPNMSICA + * + * Copyright (C) 2018-2020 Simon Rozman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MSICA_ARG_H +#define MSICA_ARG_H + +#include +#include +#include "../tapctl/basic.h" + + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4200) /* Using zero-sized arrays in struct/union. */ +#endif + + +/** + * Argument list + */ +struct msica_arg +{ + struct msica_arg *next; /** Pointer to the next argument in the sequence */ + TCHAR val[]; /** Zero terminated argument string */ +}; + + +/** + * Argument sequence + */ +struct msica_arg_seq +{ + struct msica_arg *head; /** Pointer to the first argument in the sequence */ + struct msica_arg *tail; /** Pointer to the last argument in the sequence */ +}; + + +/** + * Initializes argument sequence + * + * @param seq Pointer to uninitialized argument sequence + */ +void +msica_arg_seq_init(_Inout_ struct msica_arg_seq *seq); + + +/** + * Frees argument sequence + * + * @param seq Pointer to the argument sequence + */ +void +msica_arg_seq_free(_Inout_ struct msica_arg_seq *seq); + + +/** + * Inserts argument to the beginning of the argument sequence + * + * @param seq Pointer to the argument sequence + * + * @param argument Zero-terminated argument string to insert. + */ +void +msica_arg_seq_add_head( + _Inout_ struct msica_arg_seq *seq, + _In_z_ LPCTSTR argument); + + +/** + * Appends argument to the end of the argument sequence + * + * @param seq Pointer to the argument sequence + * + * @param argument Zero-terminated argument string to append. + */ +void +msica_arg_seq_add_tail( + _Inout_ struct msica_arg_seq *seq, + _Inout_ LPCTSTR argument); + +/** + * Join arguments of the argument sequence into a space delimited string + * + * @param seq Pointer to the argument sequence + * + * @return Joined argument string. Must be released with free() after use. + */ +LPTSTR +msica_arg_seq_join(_In_ const struct msica_arg_seq *seq); + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif /* ifndef MSICA_ARG_H */ diff --git a/src/openvpnmsica/msica_op.c b/src/openvpnmsica/msica_op.c deleted file mode 100644 index 63aa6c83..00000000 --- a/src/openvpnmsica/msica_op.c +++ /dev/null @@ -1,1043 +0,0 @@ -/* - * openvpnmsica -- Custom Action DLL to provide OpenVPN-specific support to MSI packages - * https://community.openvpn.net/openvpn/wiki/OpenVPNMSICA - * - * Copyright (C) 2018 Simon Rozman - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include -#elif defined(_MSC_VER) -#include -#endif - -#include "msica_op.h" -#include "../tapctl/error.h" -#include "../tapctl/tap.h" - -#include -#include -#include -#include - -#ifdef _MSC_VER -#pragma comment(lib, "msi.lib") -#pragma comment(lib, "ole32.lib") -#endif - - -/** - * Operation data persist header - */ -struct msica_op_hdr -{ - enum msica_op_type type; /** Action type */ - int ticks; /** Number of ticks on the progress indicator this operation represents */ - DWORD size_data; /** Size of the operation data (DWORD to better align with Win32 API) */ -}; - - -void -msica_op_seq_init(_Inout_ struct msica_op_seq *seq) -{ - seq->head = NULL; - seq->tail = NULL; -} - - -void -msica_op_seq_free(_Inout_ struct msica_op_seq *seq) -{ - while (seq->head) - { - struct msica_op *op = seq->head; - seq->head = seq->head->next; - free(op); - } - seq->tail = NULL; -} - - -struct msica_op * -msica_op_create_bool( - _In_ enum msica_op_type type, - _In_ int ticks, - _In_opt_ struct msica_op *next, - _In_ bool value) -{ - if (MSICA_OP_TYPE_DATA(type) != 0x1) - { - msg(M_NONFATAL, "%s: Operation data type not bool (%x)", __FUNCTION__, MSICA_OP_TYPE_DATA(type)); - return NULL; - } - - /* Create and fill operation struct. */ - struct msica_op_bool *op = (struct msica_op_bool *)malloc(sizeof(struct msica_op_bool)); - if (op == NULL) - { - msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct msica_op_bool)); - return NULL; - } - - op->base.type = type; - op->base.ticks = ticks; - op->base.next = next; - op->value = value; - - return &op->base; -} - - -struct msica_op * -msica_op_create_string( - _In_ enum msica_op_type type, - _In_ int ticks, - _In_opt_ struct msica_op *next, - _In_z_ LPCTSTR value) -{ - if (MSICA_OP_TYPE_DATA(type) != 0x2) - { - msg(M_NONFATAL, "%s: Operation data type not string (%x)", __FUNCTION__, MSICA_OP_TYPE_DATA(type)); - return NULL; - } - - /* Create and fill operation struct. */ - size_t value_size = (_tcslen(value) + 1) * sizeof(TCHAR); - struct msica_op_string *op = (struct msica_op_string *)malloc(sizeof(struct msica_op_string) + value_size); - if (op == NULL) - { - msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct msica_op_string) + value_size); - return NULL; - } - - op->base.type = type; - op->base.ticks = ticks; - op->base.next = next; - memcpy(op->value, value, value_size); - - return &op->base; -} - - -struct msica_op * -msica_op_create_multistring_va( - _In_ enum msica_op_type type, - _In_ int ticks, - _In_opt_ struct msica_op *next, - _In_ va_list arglist) -{ - if (MSICA_OP_TYPE_DATA(type) != 0x3) - { - msg(M_NONFATAL, "%s: Operation data type not multi-string (%x)", __FUNCTION__, MSICA_OP_TYPE_DATA(type)); - return NULL; - } - - /* Calculate required space first. */ - LPCTSTR str; - size_t value_size = 1; - for (va_list a = arglist; (str = va_arg(a, LPCTSTR)) != NULL; value_size += _tcslen(str) + 1) - { - } - value_size *= sizeof(TCHAR); - - /* Create and fill operation struct. */ - struct msica_op_multistring *op = (struct msica_op_multistring *)malloc(sizeof(struct msica_op_multistring) + value_size); - if (op == NULL) - { - msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct msica_op_multistring) + value_size); - return NULL; - } - - op->base.type = type; - op->base.ticks = ticks; - op->base.next = next; - LPTSTR value = op->value; - for (va_list a = arglist; (str = va_arg(a, LPCTSTR)) != NULL;) - { - size_t size = _tcslen(str) + 1; - memcpy(value, str, size*sizeof(TCHAR)); - value += size; - } - value[0] = 0; - - return &op->base; -} - - -struct msica_op * -msica_op_create_guid( - _In_ enum msica_op_type type, - _In_ int ticks, - _In_opt_ struct msica_op *next, - _In_ const GUID *value) -{ - if (MSICA_OP_TYPE_DATA(type) != 0x4) - { - msg(M_NONFATAL, "%s: Operation data type not GUID (%x)", __FUNCTION__, MSICA_OP_TYPE_DATA(type)); - return NULL; - } - - /* Create and fill operation struct. */ - struct msica_op_guid *op = (struct msica_op_guid *)malloc(sizeof(struct msica_op_guid)); - if (op == NULL) - { - msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct msica_op_guid)); - return NULL; - } - - op->base.type = type; - op->base.ticks = ticks; - op->base.next = next; - memcpy(&op->value, value, sizeof(GUID)); - - return &op->base; -} - - -struct msica_op * -msica_op_create_guid_string( - _In_ enum msica_op_type type, - _In_ int ticks, - _In_opt_ struct msica_op *next, - _In_ const GUID *value_guid, - _In_z_ LPCTSTR value_str) -{ - if (MSICA_OP_TYPE_DATA(type) != 0x5) - { - msg(M_NONFATAL, "%s: Operation data type not GUID-string (%x)", __FUNCTION__, MSICA_OP_TYPE_DATA(type)); - return NULL; - } - - /* Create and fill operation struct. */ - size_t value_str_size = (_tcslen(value_str) + 1) * sizeof(TCHAR); - struct msica_op_guid_string *op = (struct msica_op_guid_string *)malloc(sizeof(struct msica_op_guid_string) + value_str_size); - if (op == NULL) - { - msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct msica_op_guid_string) + value_str_size); - return NULL; - } - - op->base.type = type; - op->base.ticks = ticks; - op->base.next = next; - memcpy(&op->value_guid, value_guid, sizeof(GUID)); - memcpy(op->value_str, value_str, value_str_size); - - return &op->base; -} - - -void -msica_op_seq_add_head( - _Inout_ struct msica_op_seq *seq, - _Inout_ struct msica_op *operation) -{ - if (seq == NULL || operation == NULL) - { - return; - } - - /* Insert list in the head. */ - struct msica_op *op; - for (op = operation; op->next; op = op->next) - { - } - op->next = seq->head; - - /* Update head (and tail). */ - seq->head = operation; - if (seq->tail == NULL) - { - seq->tail = op; - } -} - - -void -msica_op_seq_add_tail( - _Inout_ struct msica_op_seq *seq, - _Inout_ struct msica_op *operation) -{ - if (seq == NULL || operation == NULL) - { - return; - } - - /* Append list to the tail. */ - struct msica_op *op; - for (op = operation; op->next; op = op->next) - { - } - if (seq->tail) - { - seq->tail->next = operation; - } - else - { - seq->head = operation; - } - seq->tail = op; -} - - -DWORD -msica_op_seq_save( - _In_ const struct msica_op_seq *seq, - _In_ HANDLE hFile) -{ - DWORD dwWritten; - for (const struct msica_op *op = seq->head; op; op = op->next) - { - struct msica_op_hdr hdr; - hdr.type = op->type; - hdr.ticks = op->ticks; - - /* Calculate size of data. */ - switch (MSICA_OP_TYPE_DATA(op->type)) - { - case 0x1: /* msica_op_bool */ - hdr.size_data = sizeof(struct msica_op_bool) - sizeof(struct msica_op); - break; - - case 0x2: /* msica_op_string */ - hdr.size_data = - sizeof(struct msica_op_string) - sizeof(struct msica_op) - +(DWORD)(_tcslen(((struct msica_op_string *)op)->value) + 1) * sizeof(TCHAR); - break; - - case 0x3: /* msica_op_multistring */ - { - LPCTSTR str; - for (str = ((struct msica_op_multistring *)op)->value; str[0]; str += _tcslen(str) + 1) - { - } - hdr.size_data = - sizeof(struct msica_op_multistring) - sizeof(struct msica_op) - +(DWORD)(str + 1 - ((struct msica_op_multistring *)op)->value) * sizeof(TCHAR); - break; - } - - case 0x4: /* msica_op_guid */ - hdr.size_data = sizeof(struct msica_op_guid) - sizeof(struct msica_op); - break; - - case 0x5: /* msica_op_guid_string */ - hdr.size_data = - sizeof(struct msica_op_guid_string) - sizeof(struct msica_op) - +(DWORD)(_tcslen(((struct msica_op_guid_string *)op)->value_str) + 1) * sizeof(TCHAR); - break; - - default: - msg(M_NONFATAL, "%s: Unknown operation data type (%x)", __FUNCTION__, MSICA_OP_TYPE_DATA(op->type)); - return ERROR_BAD_ARGUMENTS; - } - - if (!WriteFile(hFile, &hdr, sizeof(struct msica_op_hdr), &dwWritten, NULL) - || !WriteFile(hFile, op + 1, hdr.size_data, &dwWritten, NULL)) - { - DWORD dwResult = GetLastError(); - msg(M_NONFATAL | M_ERRNO, "%s: WriteFile failed", __FUNCTION__); - return dwResult; - } - } - - return ERROR_SUCCESS; -} - - -DWORD -msica_op_seq_load( - _Inout_ struct msica_op_seq *seq, - _In_ HANDLE hFile) -{ - DWORD dwRead; - - if (seq == NULL) - { - return ERROR_BAD_ARGUMENTS; - } - - seq->head = seq->tail = NULL; - - for (;;) - { - struct msica_op_hdr hdr; - if (!ReadFile(hFile, &hdr, sizeof(struct msica_op_hdr), &dwRead, NULL)) - { - DWORD dwResult = GetLastError(); - msg(M_NONFATAL | M_ERRNO, "%s: ReadFile failed", __FUNCTION__); - return dwResult; - } - else if (dwRead == 0) - { - /* EOF */ - return ERROR_SUCCESS; - } - else if (dwRead < sizeof(struct msica_op_hdr)) - { - msg(M_NONFATAL, "%s: Incomplete ReadFile", __FUNCTION__); - return ERROR_INVALID_DATA; - } - - struct msica_op *op = (struct msica_op *)malloc(sizeof(struct msica_op) + hdr.size_data); - if (op == NULL) - { - msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct msica_op) + hdr.size_data); - return ERROR_OUTOFMEMORY; - } - - op->type = hdr.type; - op->ticks = hdr.ticks; - op->next = NULL; - - if (!ReadFile(hFile, op + 1, hdr.size_data, &dwRead, NULL)) - { - DWORD dwResult = GetLastError(); - msg(M_NONFATAL | M_ERRNO, "%s: ReadFile failed", __FUNCTION__); - free(op); - return dwResult; - } - else if (dwRead < hdr.size_data) - { - msg(M_NONFATAL, "%s: Incomplete ReadFile", __FUNCTION__); - return ERROR_INVALID_DATA; - } - - msica_op_seq_add_tail(seq, op); - } -} - - -static DWORD -msica_op_tap_interface_create_exec( - _Inout_ const struct msica_op_string *op, - _Inout_ struct msica_session *session) -{ - if (op == NULL || session == NULL) - { - return ERROR_BAD_ARGUMENTS; - } - - { - /* Report the name of the interface to installer. */ - MSIHANDLE hRecord = MsiCreateRecord(3); - MsiRecordSetString(hRecord, 1, TEXT("Creating TAP interface")); - MsiRecordSetString(hRecord, 2, op->value); - int iResult = MsiProcessMessage(session->hInstall, INSTALLMESSAGE_ACTIONDATA, hRecord); - MsiCloseHandle(hRecord); - if (iResult == IDCANCEL) - { - return ERROR_INSTALL_USEREXIT; - } - } - - /* Get all available network interfaces. */ - struct tap_interface_node *pInterfaceList = NULL; - DWORD dwResult = tap_list_interfaces(NULL, NULL, &pInterfaceList, TRUE); - if (dwResult == ERROR_SUCCESS) - { - /* Does interface exist? */ - for (struct tap_interface_node *pInterfaceOther = pInterfaceList;; pInterfaceOther = pInterfaceOther->pNext) - { - if (pInterfaceOther == NULL) - { - /* No interface with a same name found. Create one. */ - BOOL bRebootRequired = FALSE; - GUID guidInterface; - dwResult = tap_create_interface(NULL, NULL, NULL, &bRebootRequired, &guidInterface); - if (dwResult == ERROR_SUCCESS) - { - /* Set interface name. */ - dwResult = tap_set_interface_name(&guidInterface, op->value); - if (dwResult == ERROR_SUCCESS) - { - if (session->rollback_enabled) - { - /* Order rollback action to delete it. */ - msica_op_seq_add_head( - &session->seq_cleanup[MSICA_CLEANUP_ACTION_ROLLBACK], - msica_op_create_guid( - msica_op_tap_interface_delete_by_guid, - 0, - NULL, - &guidInterface)); - } - } - else - { - tap_delete_interface(NULL, &guidInterface, &bRebootRequired); - } - - if (bRebootRequired) - { - MsiSetMode(session->hInstall, MSIRUNMODE_REBOOTATEND, TRUE); - } - } - break; - } - else if (_tcsicmp(op->value, pInterfaceOther->szName) == 0) - { - /* Interface with a same name found. */ - for (LPCTSTR hwid = pInterfaceOther->szzHardwareIDs;; hwid += _tcslen(hwid) + 1) - { - if (hwid[0] == 0) - { - /* This is not a TAP interface. */ - msg(M_NONFATAL, "%s: Interface with name \"%" PRIsLPTSTR "\" already exists", __FUNCTION__, pInterfaceOther->szName); - dwResult = ERROR_ALREADY_EXISTS; - break; - } - else if ( - _tcsicmp(hwid, TEXT(TAP_WIN_COMPONENT_ID)) == 0 - || _tcsicmp(hwid, TEXT("root\\") TEXT(TAP_WIN_COMPONENT_ID)) == 0) - { - /* This is a TAP interface. We already got what we wanted! */ - dwResult = ERROR_SUCCESS; - break; - } - } - break; - } - } - - tap_free_interface_list(pInterfaceList); - } - - return dwResult; -} - - -static DWORD -msica_op_tap_interface_delete( - _In_ struct tap_interface_node *pInterfaceList, - _In_ struct tap_interface_node *pInterface, - _Inout_ struct msica_session *session) -{ - if (pInterfaceList == NULL || pInterface == NULL || session == NULL) - { - return ERROR_BAD_ARGUMENTS; - } - - DWORD dwResult; - - /* Delete the interface. */ - BOOL bRebootRequired = FALSE; - dwResult = tap_delete_interface(NULL, &pInterface->guid, &bRebootRequired); - if (bRebootRequired) - { - MsiSetMode(session->hInstall, MSIRUNMODE_REBOOTATEND, TRUE); - } - - if (session->rollback_enabled) - { - /* - * Schedule rollback action to create the interface back. Though it won't be exactly the same interface again. - * - * The previous version of this function did: - * - Execution Pass: rename the interface to some temporary name - * - Commit/Rollback Pass: delete the interface / rename the interface back to original name - * - * However, the WiX Toolset's Diffx extension to install and remove drivers removed the TAP driver between the - * execution and commit passes. TAP driver removal makes all TAP interfaces unavailable and our CA couldn't find - * the interface to delete any more. - * - * While the system where OpenVPN was uninstalled didn't have any TAP interfaces any more as expected behaviour, - * the problem appears after reinstalling the OpenVPN. Some residue TAP interface registry keys remain on the - * system, causing the TAP interface to reappear as "Ethernet NN" interface next time the TAP driver is - * installed. This causes TAP interfaces to accumulate over cyclic install-uninstall-install... - * - * Therefore, it is better to remove the TAP interfaces before the TAP driver is removed, and reinstall the TAP - * interface back should the rollback be required. I wonder if the WiX Diffx extension supports execute/commit/ - * rollback feature of MSI in the first place. - */ - msica_op_seq_add_head( - &session->seq_cleanup[MSICA_CLEANUP_ACTION_ROLLBACK], - msica_op_create_string( - msica_op_tap_interface_create, - 0, - NULL, - pInterface->szName)); - } - - return dwResult; -} - - -static DWORD -msica_op_tap_interface_delete_by_name_exec( - _Inout_ const struct msica_op_string *op, - _Inout_ struct msica_session *session) -{ - if (op == NULL || session == NULL) - { - return ERROR_BAD_ARGUMENTS; - } - - { - /* Report the name of the interface to installer. */ - MSIHANDLE hRecord = MsiCreateRecord(3); - MsiRecordSetString(hRecord, 1, TEXT("Deleting interface")); - MsiRecordSetString(hRecord, 2, op->value); - int iResult = MsiProcessMessage(session->hInstall, INSTALLMESSAGE_ACTIONDATA, hRecord); - MsiCloseHandle(hRecord); - if (iResult == IDCANCEL) - { - return ERROR_INSTALL_USEREXIT; - } - } - - /* Get available TUN/TAP interfaces. */ - struct tap_interface_node *pInterfaceList = NULL; - DWORD dwResult = tap_list_interfaces(NULL, NULL, &pInterfaceList, FALSE); - if (dwResult == ERROR_SUCCESS) - { - /* Does interface exist? */ - for (struct tap_interface_node *pInterface = pInterfaceList;; pInterface = pInterface->pNext) - { - if (pInterface == NULL) - { - /* Interface not found. We already got what we wanted! */ - dwResult = ERROR_SUCCESS; - break; - } - else if (_tcsicmp(op->value, pInterface->szName) == 0) - { - /* Interface found. */ - dwResult = msica_op_tap_interface_delete( - pInterfaceList, - pInterface, - session); - break; - } - } - - tap_free_interface_list(pInterfaceList); - } - - return dwResult; -} - - -static DWORD -msica_op_tap_interface_delete_by_guid_exec( - _Inout_ const struct msica_op_guid *op, - _Inout_ struct msica_session *session) -{ - if (op == NULL || session == NULL) - { - return ERROR_BAD_ARGUMENTS; - } - - { - /* Report the GUID of the interface to installer. */ - MSIHANDLE hRecord = MsiCreateRecord(3); - LPOLESTR szInterfaceId = NULL; - StringFromIID((REFIID)&op->value, &szInterfaceId); - MsiRecordSetString(hRecord, 1, TEXT("Deleting interface")); - MsiRecordSetString(hRecord, 2, szInterfaceId); - int iResult = MsiProcessMessage(session->hInstall, INSTALLMESSAGE_ACTIONDATA, hRecord); - CoTaskMemFree(szInterfaceId); - MsiCloseHandle(hRecord); - if (iResult == IDCANCEL) - { - return ERROR_INSTALL_USEREXIT; - } - } - - /* Get all available interfaces. */ - struct tap_interface_node *pInterfaceList = NULL; - DWORD dwResult = tap_list_interfaces(NULL, NULL, &pInterfaceList, TRUE); - if (dwResult == ERROR_SUCCESS) - { - /* Does interface exist? */ - for (struct tap_interface_node *pInterface = pInterfaceList;; pInterface = pInterface->pNext) - { - if (pInterface == NULL) - { - /* Interface not found. We already got what we wanted! */ - dwResult = ERROR_SUCCESS; - break; - } - else if (memcmp(&op->value, &pInterface->guid, sizeof(GUID)) == 0) - { - /* Interface found. */ - dwResult = msica_op_tap_interface_delete( - pInterfaceList, - pInterface, - session); - break; - } - } - - tap_free_interface_list(pInterfaceList); - } - - return dwResult; -} - - -static DWORD -msica_op_tap_interface_set_name_exec( - _Inout_ const struct msica_op_guid_string *op, - _Inout_ struct msica_session *session) -{ - if (op == NULL || session == NULL) - { - return ERROR_BAD_ARGUMENTS; - } - - { - /* Report the GUID of the interface to installer. */ - MSIHANDLE hRecord = MsiCreateRecord(3); - LPOLESTR szInterfaceId = NULL; - StringFromIID((REFIID)&op->value_guid, &szInterfaceId); - MsiRecordSetString(hRecord, 1, TEXT("Setting interface name")); - MsiRecordSetString(hRecord, 2, szInterfaceId); - MsiRecordSetString(hRecord, 3, op->value_str); - int iResult = MsiProcessMessage(session->hInstall, INSTALLMESSAGE_ACTIONDATA, hRecord); - CoTaskMemFree(szInterfaceId); - MsiCloseHandle(hRecord); - if (iResult == IDCANCEL) - { - return ERROR_INSTALL_USEREXIT; - } - } - - /* Get all available network interfaces. */ - struct tap_interface_node *pInterfaceList = NULL; - DWORD dwResult = tap_list_interfaces(NULL, NULL, &pInterfaceList, TRUE); - if (dwResult == ERROR_SUCCESS) - { - /* Does interface exist? */ - for (struct tap_interface_node *pInterface = pInterfaceList;; pInterface = pInterface->pNext) - { - if (pInterface == NULL) - { - /* Interface not found. */ - LPOLESTR szInterfaceId = NULL; - StringFromIID((REFIID)&op->value_guid, &szInterfaceId); - msg(M_NONFATAL, "%s: %" PRIsLPOLESTR " interface not found", __FUNCTION__, szInterfaceId); - CoTaskMemFree(szInterfaceId); - dwResult = ERROR_FILE_NOT_FOUND; - break; - } - else if (memcmp(&op->value_guid, &pInterface->guid, sizeof(GUID)) == 0) - { - /* Interface found. */ - for (struct tap_interface_node *pInterfaceOther = pInterfaceList;; pInterfaceOther = pInterfaceOther->pNext) - { - if (pInterfaceOther == NULL) - { - /* No other interface with a same name found. All clear to rename the interface. */ - dwResult = tap_set_interface_name(&pInterface->guid, op->value_str); - if (dwResult == ERROR_SUCCESS) - { - if (session->rollback_enabled) - { - /* Order rollback action to rename it back. */ - msica_op_seq_add_head( - &session->seq_cleanup[MSICA_CLEANUP_ACTION_ROLLBACK], - msica_op_create_guid_string( - msica_op_tap_interface_set_name, - 0, - NULL, - &pInterface->guid, - pInterface->szName)); - } - } - break; - } - else if (_tcsicmp(op->value_str, pInterfaceOther->szName) == 0) - { - /* Interface with a same name found. Duplicate interface names are not allowed. */ - msg(M_NONFATAL, "%s: Interface with name \"%" PRIsLPTSTR "\" already exists", __FUNCTION__, pInterfaceOther->szName); - dwResult = ERROR_ALREADY_EXISTS; - break; - } - } - break; - } - } - - tap_free_interface_list(pInterfaceList); - } - - return dwResult; -} - - -static DWORD -msica_op_file_delete_exec( - _Inout_ const struct msica_op_string *op, - _Inout_ struct msica_session *session) -{ - if (op == NULL || session == NULL) - { - return ERROR_BAD_ARGUMENTS; - } - - { - /* Report the name of the file to installer. */ - MSIHANDLE hRecord = MsiCreateRecord(3); - MsiRecordSetString(hRecord, 1, TEXT("Deleting file")); - MsiRecordSetString(hRecord, 2, op->value); - int iResult = MsiProcessMessage(session->hInstall, INSTALLMESSAGE_ACTIONDATA, hRecord); - MsiCloseHandle(hRecord); - if (iResult == IDCANCEL) - { - return ERROR_INSTALL_USEREXIT; - } - } - - DWORD dwResult; - - if (session->rollback_enabled) - { - size_t sizeNameBackupLenZ = _tcslen(op->value) + 7 /*" (orig "*/ + 10 /*maximum int*/ + 1 /*")"*/ + 1 /*terminator*/; - LPTSTR szNameBackup = (LPTSTR)malloc(sizeNameBackupLenZ * sizeof(TCHAR)); - if (szNameBackup == NULL) - { - msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeNameBackupLenZ * sizeof(TCHAR)); - return ERROR_OUTOFMEMORY; - } - - int count = 0; - - do - { - /* Rename the file to make a backup. */ - _stprintf_s( - szNameBackup, sizeNameBackupLenZ, - TEXT("%s (orig %i)"), - op->value, - ++count); - dwResult = MoveFile(op->value, szNameBackup) ? ERROR_SUCCESS : GetLastError(); - } while (dwResult == ERROR_ALREADY_EXISTS); - - if (dwResult == ERROR_SUCCESS) - { - /* Schedule rollback action to restore from backup. */ - msica_op_seq_add_head( - &session->seq_cleanup[MSICA_CLEANUP_ACTION_ROLLBACK], - msica_op_create_multistring( - msica_op_file_move, - 0, - NULL, - szNameBackup, - op->value, - NULL)); - - /* Schedule commit action to delete the backup. */ - msica_op_seq_add_tail( - &session->seq_cleanup[MSICA_CLEANUP_ACTION_COMMIT], - msica_op_create_string( - msica_op_file_delete, - 0, - NULL, - szNameBackup)); - } - else if (dwResult == ERROR_FILE_NOT_FOUND) /* File does not exist: We already got what we wanted! */ - { - dwResult = ERROR_SUCCESS; - } - else - { - msg(M_NONFATAL | M_ERRNO, "%s: MoveFile(\"%" PRIsLPTSTR "\", \"%" PRIsLPTSTR "\") failed", __FUNCTION__, op->value, szNameBackup); - } - - free(szNameBackup); - } - else - { - /* Delete the file. */ - dwResult = DeleteFile(op->value) ? ERROR_SUCCESS : GetLastError(); - if (dwResult == ERROR_FILE_NOT_FOUND) /* File does not exist: We already got what we wanted! */ - { - dwResult = ERROR_SUCCESS; - } - else if (dwResult != ERROR_SUCCESS) - { - msg(M_NONFATAL | M_ERRNO, "%s: DeleteFile(\"%" PRIsLPTSTR "\") failed", __FUNCTION__, op->value); - } - } - - return dwResult; -} - - -static DWORD -msica_op_file_move_exec( - _Inout_ const struct msica_op_multistring *op, - _Inout_ struct msica_session *session) -{ - if (op == NULL || session == NULL) - { - return ERROR_BAD_ARGUMENTS; - } - - /* Get source filename. */ - LPCTSTR szNameSrc = op->value; - if (szNameSrc[0] == 0) - { - return ERROR_BAD_ARGUMENTS; - } - - /* Get destination filename. */ - LPCTSTR szNameDst = szNameSrc + _tcslen(szNameSrc) + 1; - if (szNameDst[0] == 0) - { - return ERROR_BAD_ARGUMENTS; - } - - { - /* Report the name of the files to installer. */ - MSIHANDLE hRecord = MsiCreateRecord(3); - MsiRecordSetString(hRecord, 1, TEXT("Moving file")); - MsiRecordSetString(hRecord, 2, szNameSrc); - MsiRecordSetString(hRecord, 3, szNameDst); - int iResult = MsiProcessMessage(session->hInstall, INSTALLMESSAGE_ACTIONDATA, hRecord); - MsiCloseHandle(hRecord); - if (iResult == IDCANCEL) - { - return ERROR_INSTALL_USEREXIT; - } - } - - DWORD dwResult = MoveFile(szNameSrc, szNameDst) ? ERROR_SUCCESS : GetLastError(); - if (dwResult == ERROR_SUCCESS) - { - if (session->rollback_enabled) - { - /* Order rollback action to move it back. */ - msica_op_seq_add_head( - &session->seq_cleanup[MSICA_CLEANUP_ACTION_ROLLBACK], - msica_op_create_multistring( - msica_op_file_move, - 0, - NULL, - szNameDst, - szNameSrc, - NULL)); - } - } - else - { - msg(M_NONFATAL | M_ERRNO, "%s: MoveFile(\"%" PRIsLPTSTR "\", \"%" PRIsLPTSTR "\") failed", __FUNCTION__, szNameSrc, szNameDst); - } - - return dwResult; -} - - -void -openvpnmsica_session_init( - _Inout_ struct msica_session *session, - _In_ MSIHANDLE hInstall, - _In_ bool continue_on_error, - _In_ bool rollback_enabled) -{ - session->hInstall = hInstall; - session->continue_on_error = continue_on_error; - session->rollback_enabled = rollback_enabled; - for (size_t i = 0; i < MSICA_CLEANUP_ACTION_COUNT; i++) - { - msica_op_seq_init(&session->seq_cleanup[i]); - } -} - - -DWORD -msica_op_seq_process( - _Inout_ const struct msica_op_seq *seq, - _Inout_ struct msica_session *session) -{ - DWORD dwResult; - - if (seq == NULL || session == NULL) - { - return ERROR_BAD_ARGUMENTS; - } - - /* Tell the installer to use explicit progress messages. */ - MSIHANDLE hRecordProg = MsiCreateRecord(3); - MsiRecordSetInteger(hRecordProg, 1, 1); - MsiRecordSetInteger(hRecordProg, 2, 1); - MsiRecordSetInteger(hRecordProg, 3, 0); - MsiProcessMessage(session->hInstall, INSTALLMESSAGE_PROGRESS, hRecordProg); - - /* Prepare hRecordProg for progress messages. */ - MsiRecordSetInteger(hRecordProg, 1, 2); - MsiRecordSetInteger(hRecordProg, 3, 0); - - for (const struct msica_op *op = seq->head; op; op = op->next) - { - switch (op->type) - { - case msica_op_rollback_enable: - session->rollback_enabled = ((const struct msica_op_bool *)op)->value; - dwResult = ERROR_SUCCESS; - break; - - case msica_op_tap_interface_create: - dwResult = msica_op_tap_interface_create_exec((const struct msica_op_string *)op, session); - break; - - case msica_op_tap_interface_delete_by_name: - dwResult = msica_op_tap_interface_delete_by_name_exec((const struct msica_op_string *)op, session); - break; - - case msica_op_tap_interface_delete_by_guid: - dwResult = msica_op_tap_interface_delete_by_guid_exec((const struct msica_op_guid *)op, session); - break; - - case msica_op_tap_interface_set_name: - dwResult = msica_op_tap_interface_set_name_exec((const struct msica_op_guid_string *)op, session); - break; - - case msica_op_file_delete: - dwResult = msica_op_file_delete_exec((const struct msica_op_string *)op, session); - break; - - case msica_op_file_move: - dwResult = msica_op_file_move_exec((const struct msica_op_multistring *)op, session); - break; - - default: - msg(M_NONFATAL, "%s: Unknown operation type (%x)", __FUNCTION__, op->type); - dwResult = ERROR_FILE_NOT_FOUND; - } - - if (!session->continue_on_error && dwResult != ERROR_SUCCESS) - { - /* Operation failed. It should have sent error message to Installer. Therefore, just quit here. */ - goto cleanup_hRecordProg; - } - - /* Report progress and check for user cancellation. */ - MsiRecordSetInteger(hRecordProg, 2, op->ticks); - if (MsiProcessMessage(session->hInstall, INSTALLMESSAGE_PROGRESS, hRecordProg) == IDCANCEL) - { - dwResult = ERROR_INSTALL_USEREXIT; - goto cleanup_hRecordProg; - } - } - - dwResult = ERROR_SUCCESS; - -cleanup_hRecordProg: - MsiCloseHandle(hRecordProg); - return dwResult; -} diff --git a/src/openvpnmsica/msica_op.h b/src/openvpnmsica/msica_op.h deleted file mode 100644 index eaf7596c..00000000 --- a/src/openvpnmsica/msica_op.h +++ /dev/null @@ -1,430 +0,0 @@ -/* - * openvpnmsica -- Custom Action DLL to provide OpenVPN-specific support to MSI packages - * https://community.openvpn.net/openvpn/wiki/OpenVPNMSICA - * - * Copyright (C) 2018 Simon Rozman - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MSICA_OP_H -#define MSICA_OP_H - -#include -#include -#include -#include -#include -#include "../tapctl/basic.h" - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4200) /* Using zero-sized arrays in struct/union. */ -#endif - - -/** - * Operation type macros - */ -#define MSICA_MAKE_OP_TYPE(op, data) (((op)<<4)|((data)&0xf)) -#define MSICA_OP_TYPE_OP(type) ((unsigned int)(type)>>4) -#define MSICA_OP_TYPE_DATA(type) ((unsigned int)(type)&0xf) - - -/** - * Operation types - */ -enum msica_op_type -{ - msica_op_rollback_enable = MSICA_MAKE_OP_TYPE(0x1, 0x1), /** Enable/disable rollback | msica_op_bool */ - msica_op_tap_interface_create = MSICA_MAKE_OP_TYPE(0x2, 0x2), /** Create TAP/TUN interface | msica_op_string */ - msica_op_tap_interface_delete_by_name = MSICA_MAKE_OP_TYPE(0x3, 0x2), /** Delete TAP/TUN interface | msica_op_string */ - msica_op_tap_interface_delete_by_guid = MSICA_MAKE_OP_TYPE(0x3, 0x4), /** Delete TAP/TUN interface | msica_op_guid */ - msica_op_tap_interface_set_name = MSICA_MAKE_OP_TYPE(0x4, 0x5), /** Rename TAP/TUN interface | msica_op_guid_string */ - msica_op_file_delete = MSICA_MAKE_OP_TYPE(0x5, 0x2), /** Delete file | msica_op_string */ - msica_op_file_move = MSICA_MAKE_OP_TYPE(0x6, 0x3), /** Move file | msica_op_multistring (min 2 strings) */ -}; - - -/** - * Operation data - */ -struct msica_op -{ - enum msica_op_type type; /** Operation type */ - int ticks; /** Number of ticks on the progress indicator this operation represents */ - struct msica_op *next; /** Pointer to the next operation in the sequence */ -}; - - -/** - * Operation sequence - */ -struct msica_op_seq -{ - struct msica_op *head; /** Pointer to the first operation in the sequence */ - struct msica_op *tail; /** Pointer to the last operation in the sequence */ -}; - - -/** - * Initializes operation sequence - * - * @param seq Pointer to uninitialized operation sequence - */ -void -msica_op_seq_init(_Inout_ struct msica_op_seq *seq); - - -/** - * Frees operation sequence - * - * @param seq Pointer to operation sequence - */ -void -msica_op_seq_free(_Inout_ struct msica_op_seq *seq); - - -/** - * Operation data (bool, 0x1) - */ -struct msica_op_bool -{ - struct msica_op base; /** Common operation data */ - bool value; /** Operation data boolean value */ -}; - - -/** - * Allocates and fills a new msica_op_bool operation - * - * @param type Operation type - * - * @param ticks Number of ticks on the progress indicator this operation represents - * - * @param next Pointer to the next operation in the sequence - * - * @param value Boolean value - * - * @return A new msica_op_bool operation. Must be added to a sequence list or - * released using free() after use. The function returns a pointer to - * msica_op to reduce type-casting in code. - */ -struct msica_op * -msica_op_create_bool( - _In_ enum msica_op_type type, - _In_ int ticks, - _In_opt_ struct msica_op *next, - _In_ bool value); - - -/** - * Operation data (string, 0x2) - */ -struct msica_op_string -{ - struct msica_op base; /** Common operation data */ - TCHAR value[]; /** Operation data string - the string must always be zero terminated. */ -}; - - -/** - * Allocates and fills a new msica_op_string operation - * - * @param type Operation type - * - * @param ticks Number of ticks on the progress indicator this operation represents - * - * @param next Pointer to the next operation in the sequence - * - * @param value String value - * - * @return A new msica_op_string operation. Must be added to a sequence list or - * released using free() after use. The function returns a pointer to - * msica_op to reduce type-casting in code. - */ -struct msica_op * -msica_op_create_string( - _In_ enum msica_op_type type, - _In_ int ticks, - _In_opt_ struct msica_op *next, - _In_z_ LPCTSTR value); - - -/** - * Operation data (multi-string, 0x3) - */ -struct msica_op_multistring -{ - struct msica_op base; /** Common operation data */ - TCHAR value[]; /** Operation data strings - each string must always be zero terminated. The last string must be double terminated. */ -}; - - -/** - * Allocates and fills a new msica_op_multistring operation - * - * @param type Operation type - * - * @param ticks Number of ticks on the progress indicator this operation represents - * - * @param next Pointer to the next operation in the sequence - * - * @param arglist List of non-empty strings. The last string must be NULL. - * - * @return A new msica_op_string operation. Must be added to a sequence list or - * released using free() after use. The function returns a pointer to - * msica_op to reduce type-casting in code. - */ -struct msica_op * -msica_op_create_multistring_va( - _In_ enum msica_op_type type, - _In_ int ticks, - _In_opt_ struct msica_op *next, - _In_ va_list arglist); - - -/** - * Operation data (GUID, 0x4) - */ -struct msica_op_guid -{ - struct msica_op base; /** Common operation data */ - GUID value; /** Operation data GUID */ -}; - - -/** - * Allocates and fills a new msica_op_guid operation - * - * @param type Operation type - * - * @param ticks Number of ticks on the progress indicator this operation represents - * - * @param next Pointer to the next operation in the sequence - * - * @param value Pointer to GUID value - * - * @return A new msica_op_guid operation. Must be added to a sequence list or - * released using free() after use. The function returns a pointer to - * msica_op to reduce type-casting in code. - */ -struct msica_op * -msica_op_create_guid( - _In_ enum msica_op_type type, - _In_ int ticks, - _In_opt_ struct msica_op *next, - _In_ const GUID *value); - - -/** - * Operation data (guid-string, 0x5) - */ -struct msica_op_guid_string -{ - struct msica_op base; /** Common operation data */ - GUID value_guid; /** Operation data GUID */ - TCHAR value_str[]; /** Operation data string - the string must always be zero terminated. */ -}; - - -/** - * Allocates and fills a new msica_op_guid_string operation - * - * @param type Operation type - * - * @param ticks Number of ticks on the progress indicator this operation represents - * - * @param next Pointer to the next operation in the sequence - * - * @param value_guid Pointer to GUID value - * - * @param value_str String value - * - * @return A new msica_op_guid_string operation. Must be added to a sequence - * list or released using free() after use. The function returns a - * pointer to msica_op to reduce type-casting in code. - */ -struct msica_op * -msica_op_create_guid_string( - _In_ enum msica_op_type type, - _In_ int ticks, - _In_opt_ struct msica_op *next, - _In_ const GUID *value_guid, - _In_z_ LPCTSTR value_str); - - -/** - * Allocates and fills a new msica_op_multistring operation. Strings must be non-empty. The - * last string passed as the input parameter must be NULL. - * - * @param type Operation type - * - * @param ticks Number of ticks on the progress indicator this operation represents - * - * @param next Pointer to the next operation in the sequence - * - * @return A new msica_op_string operation. Must be added to a sequence list or - * released using free() after use. The function returns a pointer to - * msica_op to reduce type-casting in code. - */ -static inline struct msica_op * -msica_op_create_multistring( - _In_ enum msica_op_type type, - _In_ int ticks, - _In_opt_ struct msica_op *next, - ...) -{ - va_list arglist; - va_start(arglist, next); - struct msica_op *op = msica_op_create_multistring_va(type, ticks, next, arglist); - va_end(arglist); - return op; -} - - -/** - * Is operation sequence empty - * - * @param seq Pointer to operation sequence - * - * @return true if empty; false otherwise - */ -static inline bool -msica_op_seq_is_empty(_In_ const struct msica_op_seq *seq) -{ - return seq->head != NULL; -} - - -/** - * Inserts operation(s) to the beginning of the operation sequence - * - * @param seq Pointer to operation sequence - * - * @param operation Pointer to the operation to insert. All operations in the list are - * added until the list is terminated with msica_op.next field set to - * NULL. Operations must be allocated using malloc(). - */ -void -msica_op_seq_add_head( - _Inout_ struct msica_op_seq *seq, - _Inout_ struct msica_op *operation); - - -/** - * Appends operation(s) to the end of the operation sequence - * - * @param seq Pointer to operation sequence - * - * @param operation Pointer to the operation to append. All operations in the list are - * added until the list is terminated with msica_op.next field set to - * NULL. Operations must be allocated using malloc(). - */ -void -msica_op_seq_add_tail( - _Inout_ struct msica_op_seq *seq, - _Inout_ struct msica_op *operation); - - -/** - * Saves the operation sequence to the file - * - * @param seq Pointer to operation sequence - * - * @param hFile Handle of the file opened with GENERIC_WRITE access - * - * @return ERROR_SUCCESS on success; An error code otherwise - */ -DWORD -msica_op_seq_save( - _In_ const struct msica_op_seq *seq, - _In_ HANDLE hFile); - - -/** - * Loads the operation sequence from the file - * - * @param seq Pointer to uninitialized or empty operation sequence - * - * @param hFile Handle of the file opened with GENERIC_READ access - * - * @return ERROR_SUCCESS on success; An error code otherwise - */ -DWORD -msica_op_seq_load( - _Inout_ struct msica_op_seq *seq, - _In_ HANDLE hFile); - - -/** - * Execution session constants - */ -#define MSICA_CLEANUP_ACTION_COMMIT 0 -#define MSICA_CLEANUP_ACTION_ROLLBACK 1 -#define MSICA_CLEANUP_ACTION_COUNT 2 - - -/** - * Execution session - */ -struct msica_session -{ - MSIHANDLE hInstall; /** Installer handle */ - bool continue_on_error; /** Continue execution on operation error? */ - bool rollback_enabled; /** Is rollback enabled? */ - struct msica_op_seq seq_cleanup[MSICA_CLEANUP_ACTION_COUNT]; /** Commit/Rollback action operation sequence */ -}; - - -/** - * Initializes execution session - * - * @param session Pointer to an uninitialized execution session - * - * @param hInstall Installer handle - * - * @param continue_on_error Continue execution on operation error? - * - * @param rollback_enabled Is rollback enabled? - */ -void -openvpnmsica_session_init( - _Inout_ struct msica_session *session, - _In_ MSIHANDLE hInstall, - _In_ bool continue_on_error, - _In_ bool rollback_enabled); - - -/** - * Executes all operations in sequence - * - * @param seq Pointer to operation sequence - * - * @param session MSI session. The execution updates its members, most notably - * rollback_enabled and fills cleanup sequences with commit/rollback - * operations. - * - * @return ERROR_SUCCESS on success; An error code otherwise - */ -DWORD -msica_op_seq_process( - _Inout_ const struct msica_op_seq *seq, - _Inout_ struct msica_session *session); - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -#endif /* ifndef MSICA_OP_H */ diff --git a/src/openvpnmsica/openvpnmsica.c b/src/openvpnmsica/openvpnmsica.c index e1f0b77d..4c186b13 100644 --- a/src/openvpnmsica/openvpnmsica.c +++ b/src/openvpnmsica/openvpnmsica.c @@ -26,7 +26,7 @@ #include /* Must be included _before_ */ #include "openvpnmsica.h" -#include "msica_op.h" +#include "msica_arg.h" #include "msiex.h" #include "../tapctl/basic.h" @@ -61,100 +61,32 @@ /** - * Cleanup actions - */ -static const struct { - LPCTSTR szName; /** Name of the cleanup action. This name is appended to the deferred custom action name (e.g. "InstallTAPInterfaces" >> "InstallTAPInterfacesCommit"). */ - TCHAR szSuffix[3]; /** Two-character suffix to append to the cleanup operation sequence filename */ -} openvpnmsica_cleanup_action_seqs[MSICA_CLEANUP_ACTION_COUNT] = -{ - { TEXT("Commit" ), TEXT("cm") }, /* MSICA_CLEANUP_ACTION_COMMIT */ - { TEXT("Rollback"), TEXT("rb") }, /* MSICA_CLEANUP_ACTION_ROLLBACK */ -}; - - -/** - * Creates a new sequence file in the current user's temporary folder and sets MSI property - * to its absolute path. + * Joins an argument sequence and sets it to the MSI property. * * @param hInstall Handle to the installation provided to the DLL custom action * - * @param szProperty MSI property name to set to the absolute path of the sequence file. + * @param szProperty MSI property name to set to the joined argument sequence. * - * @param szFilename String of minimum MAXPATH+1 characters where the zero-terminated - * file absolute path is stored. + * @param seq The argument sequence. * * @return ERROR_SUCCESS on success; An error code otherwise */ -static DWORD -openvpnmsica_setup_sequence_filename( +static UINT +openvpnmsica_setup_sequence( _In_ MSIHANDLE hInstall, _In_z_ LPCTSTR szProperty, - _Out_z_cap_(MAXPATH + 1) LPTSTR szFilename) + _In_ struct msica_arg_seq *seq) { - DWORD dwResult; - - if (szFilename == NULL) - { - return ERROR_BAD_ARGUMENTS; - } - - /* Generate a random filename in the temporary folder. */ - if (GetTempPath(MAX_PATH + 1, szFilename) == 0) - { - dwResult = GetLastError(); - msg(M_NONFATAL | M_ERRNO, "%s: GetTempPath failed", __FUNCTION__); - return dwResult; - } - if (GetTempFileName(szFilename, szProperty, 0, szFilename) == 0) - { - dwResult = GetLastError(); - msg(M_NONFATAL | M_ERRNO, "%s: GetTempFileName failed", __FUNCTION__); - return dwResult; - } - - /* Store sequence filename to property for deferred custom action. */ - dwResult = MsiSetProperty(hInstall, szProperty, szFilename); - if (dwResult != ERROR_SUCCESS) + UINT uiResult; + LPTSTR szSequence = msica_arg_seq_join(seq); + uiResult = MsiSetProperty(hInstall, szProperty, szSequence); + free(szSequence); + if (uiResult != ERROR_SUCCESS) { - SetLastError(dwResult); /* MSDN does not mention MsiSetProperty() to set GetLastError(). But we do have an error code. Set last error manually. */ + SetLastError(uiResult); /* MSDN does not mention MsiSetProperty() to set GetLastError(). But we do have an error code. Set last error manually. */ msg(M_NONFATAL | M_ERRNO, "%s: MsiSetProperty(\"%" PRIsLPTSTR "\") failed", __FUNCTION__, szProperty); - return dwResult; - } - - /* Generate and store cleanup operation sequence filenames to properties. */ - LPTSTR szExtension = PathFindExtension(szFilename); - TCHAR szFilenameEx[MAX_PATH + 1 /*dash*/ + 2 /*suffix*/ + 1 /*terminator*/]; - size_t len_property_name = _tcslen(szProperty); - for (size_t i = 0; i < MSICA_CLEANUP_ACTION_COUNT; i++) - { - size_t len_action_name_z = _tcslen(openvpnmsica_cleanup_action_seqs[i].szName) + 1; - TCHAR *szPropertyEx = (TCHAR *)malloc((len_property_name + len_action_name_z) * sizeof(TCHAR)); - if (szPropertyEx == NULL) - { - msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, (len_property_name + len_action_name_z) * sizeof(TCHAR)); - return ERROR_OUTOFMEMORY; - } - - memcpy(szPropertyEx, szProperty, len_property_name * sizeof(TCHAR)); - memcpy(szPropertyEx + len_property_name, openvpnmsica_cleanup_action_seqs[i].szName, len_action_name_z * sizeof(TCHAR)); - _stprintf_s( - szFilenameEx, _countof(szFilenameEx), - TEXT("%.*s-%.2s%s"), - (int)(szExtension - szFilename), szFilename, - openvpnmsica_cleanup_action_seqs[i].szSuffix, - szExtension); - dwResult = MsiSetProperty(hInstall, szPropertyEx, szFilenameEx); - if (dwResult != ERROR_SUCCESS) - { - SetLastError(dwResult); /* MSDN does not mention MsiSetProperty() to set GetLastError(). But we do have an error code. Set last error manually. */ - msg(M_NONFATAL | M_ERRNO, "%s: MsiSetProperty(\"%" PRIsLPTSTR "\") failed", __FUNCTION__, szPropertyEx); - free(szPropertyEx); - return dwResult; - } - free(szPropertyEx); + return uiResult; } - return ERROR_SUCCESS; } @@ -613,6 +545,179 @@ cleanup_CoInitialize: } +/** + * Schedules interface creation. + * + * When the rollback is enabled, the interface deletition is scheduled on rollback. + * + * @param seq The argument sequence to pass to InstallTAPInterfaces custom action + * + * @param seqRollback The argument sequence to pass to InstallTAPInterfacesRollback custom + * action. NULL when rollback is disabled. + * + * @param szDisplayName Interface display name. + * + * @param iTicks Pointer to an integer that represents amount of work (on progress + * indicator) the InstallTAPInterfaces will take. This function increments it + * by MSICA_INTERFACE_TICK_SIZE for each interface to create. + * + * @return ERROR_SUCCESS on success; An error code otherwise + */ +static DWORD +openvpnmsica_schedule_interface_create(_Inout_ struct msica_arg_seq *seq, _Inout_opt_ struct msica_arg_seq *seqRollback, _In_z_ LPCTSTR szDisplayName, _Inout_ int *iTicks) +{ + /* Get all available network interfaces. */ + struct tap_interface_node *pInterfaceList = NULL; + DWORD dwResult = tap_list_interfaces(NULL, NULL, &pInterfaceList, TRUE); + if (dwResult != ERROR_SUCCESS) + { + return dwResult; + } + + /* Does interface exist? */ + for (struct tap_interface_node *pInterfaceOther = pInterfaceList;; pInterfaceOther = pInterfaceOther->pNext) + { + if (pInterfaceOther == NULL) + { + /* No interface with a same name found. */ + TCHAR szArgument[10 /*create=""|deleteN=""*/ + MAX_PATH /*szDisplayName*/ + 1 /*terminator*/]; + + /* InstallTAPInterfaces will create the interface. */ + _stprintf_s( + szArgument, _countof(szArgument), + TEXT("create=\"%.*s\""), + MAX_PATH, szDisplayName); + msica_arg_seq_add_tail(seq, szArgument); + + if (seqRollback) + { + /* InstallTAPInterfacesRollback will delete the interface. */ + _stprintf_s( + szArgument, _countof(szArgument), + TEXT("deleteN=\"%.*s\""), + MAX_PATH, szDisplayName); + msica_arg_seq_add_head(seqRollback, szArgument); + } + + *iTicks += MSICA_INTERFACE_TICK_SIZE; + break; + } + else if (_tcsicmp(szDisplayName, pInterfaceOther->szName) == 0) + { + /* Interface with a same name found. */ + for (LPCTSTR hwid = pInterfaceOther->szzHardwareIDs;; hwid += _tcslen(hwid) + 1) + { + if (hwid[0] == 0) + { + /* This is not a TAP interface. */ + msg(M_NONFATAL, "%s: Interface with name \"%" PRIsLPTSTR "\" already exists", __FUNCTION__, pInterfaceOther->szName); + dwResult = ERROR_ALREADY_EXISTS; + goto cleanup_pInterfaceList; + } + else if ( + _tcsicmp(hwid, TEXT(TAP_WIN_COMPONENT_ID)) == 0 + || _tcsicmp(hwid, TEXT("root\\") TEXT(TAP_WIN_COMPONENT_ID)) == 0) + { + /* This is a TAP-Windows6 interface. We already have what we want! */ + break; + } + } + break; /* Interface names are unique. There should be no other interface with this name. */ + } + } + +cleanup_pInterfaceList: + tap_free_interface_list(pInterfaceList); + return dwResult; +} + + +/** + * Schedules interface deletion. + * + * When the rollback is enabled, the interface deletition is scheduled as: disable in + * UninstallTAPInterfaces, enable on rollback, delete on commit. + * + * When rollback is disabled, the interface deletition is scheduled as delete in + * UninstallTAPInterfaces. + * + * @param seq The argument sequence to pass to UninstallTAPInterfaces custom action + * + * @param seqCommit The argument sequence to pass to UninstallTAPInterfacesCommit custom + * action. NULL when rollback is disabled. + * + * @param seqRollback The argument sequence to pass to UninstallTAPInterfacesRollback custom + * action. NULL when rollback is disabled. + * + * @param szDisplayName Interface display name. + * + * @param iTicks Pointer to an integer that represents amount of work (on progress + * indicator) the UninstallTAPInterfaces will take. This function increments + * it by MSICA_INTERFACE_TICK_SIZE for each interface to delete. + * + * @return ERROR_SUCCESS on success; An error code otherwise + */ +static DWORD +openvpnmsica_schedule_interface_delete(_Inout_ struct msica_arg_seq *seq, _Inout_opt_ struct msica_arg_seq *seqCommit, _Inout_opt_ struct msica_arg_seq *seqRollback, _In_z_ LPCTSTR szDisplayName, _Inout_ int *iTicks) +{ + /* Get available TUN/TAP interfaces. */ + struct tap_interface_node *pInterfaceList = NULL; + DWORD dwResult = tap_list_interfaces(NULL, NULL, &pInterfaceList, FALSE); + if (dwResult != ERROR_SUCCESS) + { + return dwResult; + } + + /* Does interface exist? */ + for (struct tap_interface_node *pInterface = pInterfaceList; pInterface != NULL; pInterface = pInterface->pNext) + { + if (_tcsicmp(szDisplayName, pInterface->szName) == 0) + { + /* Interface found. */ + TCHAR szArgument[8 /*disable=|enable=|delete=*/ + 38 /*{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}*/ + 1 /*terminator*/]; + if (seqCommit && seqRollback) + { + /* UninstallTAPInterfaces will disable the interface. */ + _stprintf_s( + szArgument, _countof(szArgument), + TEXT("disable=") TEXT(PRIXGUID), + PRIGUID_PARAM(pInterface->guid)); + msica_arg_seq_add_tail(seq, szArgument); + + /* UninstallTAPInterfacesRollback will re-enable the interface. */ + _stprintf_s( + szArgument, _countof(szArgument), + TEXT("enable=") TEXT(PRIXGUID), + PRIGUID_PARAM(pInterface->guid)); + msica_arg_seq_add_head(seqRollback, szArgument); + + /* UninstallTAPInterfacesCommit will delete the interface. */ + _stprintf_s( + szArgument, _countof(szArgument), + TEXT("delete=") TEXT(PRIXGUID), + PRIGUID_PARAM(pInterface->guid)); + msica_arg_seq_add_tail(seqCommit, szArgument); + } + else + { + /* UninstallTAPInterfaces will delete the interface. */ + _stprintf_s( + szArgument, _countof(szArgument), + TEXT("delete=") TEXT(PRIXGUID), + PRIGUID_PARAM(pInterface->guid)); + msica_arg_seq_add_tail(seq, szArgument); + } + + iTicks += MSICA_INTERFACE_TICK_SIZE; + break; /* Interface names are unique. There should be no other interface with this name. */ + } + } + + tap_free_interface_list(pInterfaceList); + return dwResult; +} + + UINT __stdcall EvaluateTAPInterfaces(_In_ MSIHANDLE hInstall) { @@ -627,43 +732,30 @@ EvaluateTAPInterfaces(_In_ MSIHANDLE hInstall) OPENVPNMSICA_SAVE_MSI_SESSION(hInstall); - /* List of deferred custom actions EvaluateTAPInterfaces prepares operation sequence for. */ - static const LPCTSTR szActionNames[] = - { - TEXT("InstallTAPInterfaces"), - TEXT("UninstallTAPInterfaces"), - }; - struct msica_op_seq exec_seq[_countof(szActionNames)]; - for (size_t i = 0; i < _countof(szActionNames); i++) - { - msica_op_seq_init(&exec_seq[i]); - } - - { - /* Check and store the rollback enabled state. */ - TCHAR szValue[128]; - DWORD dwLength = _countof(szValue); - bool enable_rollback = MsiGetProperty(hInstall, TEXT("RollbackDisabled"), szValue, &dwLength) == ERROR_SUCCESS ? - _ttoi(szValue) || _totlower(szValue[0]) == TEXT('y') ? false : true : - true; - for (size_t i = 0; i < _countof(szActionNames); i++) - { - msica_op_seq_add_tail( - &exec_seq[i], - msica_op_create_bool( - msica_op_rollback_enable, - 0, - NULL, - enable_rollback)); - } - } + struct msica_arg_seq + seqInstallTAPInterfaces, + seqInstallTAPInterfacesCommit, + seqInstallTAPInterfacesRollback, + seqUninstallTAPInterfaces, + seqUninstallTAPInterfacesCommit, + seqUninstallTAPInterfacesRollback; + msica_arg_seq_init(&seqInstallTAPInterfaces); + msica_arg_seq_init(&seqInstallTAPInterfacesCommit); + msica_arg_seq_init(&seqInstallTAPInterfacesRollback); + msica_arg_seq_init(&seqUninstallTAPInterfaces); + msica_arg_seq_init(&seqUninstallTAPInterfacesCommit); + msica_arg_seq_init(&seqUninstallTAPInterfacesRollback); + + /* Check rollback state. */ + bool bRollbackEnabled = MsiEvaluateCondition(hInstall, TEXT("RollbackDisabled")) != MSICONDITION_TRUE; /* Open MSI database. */ MSIHANDLE hDatabase = MsiGetActiveDatabase(hInstall); if (hDatabase == 0) { msg(M_NONFATAL, "%s: MsiGetActiveDatabase failed", __FUNCTION__); - uiResult = ERROR_INVALID_HANDLE; goto cleanup_exec_seq; + uiResult = ERROR_INVALID_HANDLE; + goto cleanup_exec_seq; } /* Check if TAPInterface table exists. If it doesn't exist, there's nothing to do. */ @@ -758,6 +850,8 @@ EvaluateTAPInterfaces(_In_ MSIHANDLE hInstall) if (iAction > INSTALLSTATE_BROKEN) { + int iTicks = 0; + if (iAction >= INSTALLSTATE_LOCAL) { /* Read and evaluate interface condition (`Condition` is field #3). */ @@ -793,29 +887,35 @@ EvaluateTAPInterfaces(_In_ MSIHANDLE hInstall) free(szValue); /* Component is or should be installed. Schedule interface creation. */ - msica_op_seq_add_tail( - &exec_seq[0], - msica_op_create_string( - msica_op_tap_interface_create, - MSICA_INTERFACE_TICK_SIZE, - NULL, - szDisplayNameEx)); + if (openvpnmsica_schedule_interface_create( + &seqInstallTAPInterfaces, + bRollbackEnabled ? &seqInstallTAPInterfacesRollback : NULL, + szDisplayNameEx, + &iTicks) != ERROR_SUCCESS) + { + uiResult = ERROR_INSTALL_FAILED; + goto cleanup_szDisplayName; + } } else { - /* Component is installed, but should be degraded to advertised/removed. Schedule interface deletition. */ - msica_op_seq_add_tail( - &exec_seq[1], - msica_op_create_string( - msica_op_tap_interface_delete_by_name, - MSICA_INTERFACE_TICK_SIZE, - NULL, - szDisplayNameEx)); + /* Component is installed, but should be degraded to advertised/removed. Schedule interface deletition. + * + * Note: On interface removal (product is being uninstalled), we tolerate dwResult error. + * Better a partial uninstallation than no uninstallation at all. + */ + openvpnmsica_schedule_interface_delete( + &seqUninstallTAPInterfaces, + bRollbackEnabled ? &seqUninstallTAPInterfacesCommit : NULL, + bRollbackEnabled ? &seqUninstallTAPInterfacesRollback : NULL, + szDisplayNameEx, + &iTicks); } - /* The amount of tick space to add for each interface to progress indicator. */ + /* Arrange the amount of tick space to add to the progress indicator. + * Do this within the loop to poll for user cancellation. */ MsiRecordSetInteger(hRecordProg, 1, 3 /* OP3 = Add ticks to the expected total number of progress of the progress bar */); - MsiRecordSetInteger(hRecordProg, 2, MSICA_INTERFACE_TICK_SIZE); + MsiRecordSetInteger(hRecordProg, 2, iTicks); if (MsiProcessMessage(hInstall, INSTALLMESSAGE_PROGRESS, hRecordProg) == IDCANCEL) { uiResult = ERROR_INSTALL_USEREXIT; @@ -833,59 +933,19 @@ cleanup_hRecord: } } - /* - * Write sequence files. - * The InstallTAPInterfaces and UninstallTAPInterfaces are deferred custom actions, thus all this information - * will be unavailable to them. Therefore save all required operations and their info to sequence files. - */ - TCHAR szSeqFilename[_countof(szActionNames)][MAX_PATH + 1]; - for (size_t i = 0; i < _countof(szActionNames); i++) + /* Store deferred custom action parameters. */ + if ((uiResult = openvpnmsica_setup_sequence(hInstall, TEXT("InstallTAPInterfaces" ), &seqInstallTAPInterfaces )) != ERROR_SUCCESS + || (uiResult = openvpnmsica_setup_sequence(hInstall, TEXT("InstallTAPInterfacesCommit" ), &seqInstallTAPInterfacesCommit )) != ERROR_SUCCESS + || (uiResult = openvpnmsica_setup_sequence(hInstall, TEXT("InstallTAPInterfacesRollback" ), &seqInstallTAPInterfacesRollback )) != ERROR_SUCCESS + || (uiResult = openvpnmsica_setup_sequence(hInstall, TEXT("UninstallTAPInterfaces" ), &seqUninstallTAPInterfaces )) != ERROR_SUCCESS + || (uiResult = openvpnmsica_setup_sequence(hInstall, TEXT("UninstallTAPInterfacesCommit" ), &seqUninstallTAPInterfacesCommit )) != ERROR_SUCCESS + || (uiResult = openvpnmsica_setup_sequence(hInstall, TEXT("UninstallTAPInterfacesRollback"), &seqUninstallTAPInterfacesRollback)) != ERROR_SUCCESS) { - szSeqFilename[i][0] = 0; - } - for (size_t i = 0; i < _countof(szActionNames); i++) - { - uiResult = openvpnmsica_setup_sequence_filename(hInstall, szActionNames[i], szSeqFilename[i]); - if (uiResult != ERROR_SUCCESS) - { - goto cleanup_szSeqFilename; - } - HANDLE hSeqFile = CreateFile( - szSeqFilename[i], - GENERIC_WRITE, - FILE_SHARE_READ, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, - NULL); - if (hSeqFile == INVALID_HANDLE_VALUE) - { - uiResult = GetLastError(); - msg(M_NONFATAL | M_ERRNO, "%s: CreateFile(\"%.*" PRIsLPTSTR "\") failed", __FUNCTION__, _countof(szSeqFilename[i]), szSeqFilename[i]); - goto cleanup_szSeqFilename; - } - uiResult = msica_op_seq_save(&exec_seq[i], hSeqFile); - CloseHandle(hSeqFile); - if (uiResult != ERROR_SUCCESS) - { - goto cleanup_szSeqFilename; - } + goto cleanup_hRecordProg; } uiResult = ERROR_SUCCESS; -cleanup_szSeqFilename: - if (uiResult != ERROR_SUCCESS) - { - /* Clean-up sequence files. */ - for (size_t i = _countof(szActionNames); i--; ) - { - if (szSeqFilename[i][0]) - { - DeleteFile(szSeqFilename[i]); - } - } - } cleanup_hRecordProg: MsiCloseHandle(hRecordProg); cleanup_hViewST_close: @@ -895,10 +955,12 @@ cleanup_hViewST: cleanup_hDatabase: MsiCloseHandle(hDatabase); cleanup_exec_seq: - for (size_t i = 0; i < _countof(szActionNames); i++) - { - msica_op_seq_free(&exec_seq[i]); - } + msica_arg_seq_free(&seqInstallTAPInterfaces); + msica_arg_seq_free(&seqInstallTAPInterfacesCommit); + msica_arg_seq_free(&seqInstallTAPInterfacesRollback); + msica_arg_seq_free(&seqUninstallTAPInterfaces); + msica_arg_seq_free(&seqUninstallTAPInterfacesCommit); + msica_arg_seq_free(&seqUninstallTAPInterfacesRollback); if (bIsCoInitialized) { CoUninitialize(); @@ -907,6 +969,27 @@ cleanup_exec_seq: } +/** + * Parses string encoded GUID. + * + * @param szArg Zero terminated string where the GUID string starts + * + * @param guid Pointer to GUID that receives parsed value + * + * @return TRUE on success; FALSE otherwise + */ +static BOOL +openvpnmsica_parse_guid(_In_z_ LPCWSTR szArg, _Out_ GUID *guid) +{ + if (swscanf_s(szArg, _L(PRIXGUID), PRIGUID_PARAM_REF(*guid)) != 11) + { + msg(M_NONFATAL | M_ERRNO, "%s: swscanf_s(\"%ls\") failed", __FUNCTION__, szArg); + return FALSE; + } + return TRUE; +} + + UINT __stdcall ProcessDeferredAction(_In_ MSIHANDLE hInstall) { @@ -923,158 +1006,172 @@ ProcessDeferredAction(_In_ MSIHANDLE hInstall) BOOL bIsCleanup = MsiGetMode(hInstall, MSIRUNMODE_COMMIT) || MsiGetMode(hInstall, MSIRUNMODE_ROLLBACK); - /* Get sequence filename and open the file. */ - LPTSTR szSeqFilename = NULL; - uiResult = msi_get_string(hInstall, TEXT("CustomActionData"), &szSeqFilename); + /* Get sequence arguments. Always Unicode as CommandLineToArgvW() is available as Unicode-only. */ + LPWSTR szSequence = NULL; + uiResult = msi_get_string(hInstall, L"CustomActionData", &szSequence); if (uiResult != ERROR_SUCCESS) { goto cleanup_CoInitialize; } - struct msica_op_seq seq = { .head = NULL, .tail = NULL }; + int nArgs; + LPWSTR *szArg = CommandLineToArgvW(szSequence, &nArgs); + if (szArg == NULL) { - HANDLE hSeqFile = CreateFile( - szSeqFilename, - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, - NULL); - if (hSeqFile == INVALID_HANDLE_VALUE) + uiResult = GetLastError(); + msg(M_NONFATAL | M_ERRNO, "%s: CommandLineToArgvW(\"%ls\") failed", __FUNCTION__, szSequence); + goto cleanup_szSequence; + } + + /* Tell the installer to use explicit progress messages. */ + MSIHANDLE hRecordProg = MsiCreateRecord(3); + MsiRecordSetInteger(hRecordProg, 1, 1); + MsiRecordSetInteger(hRecordProg, 2, 1); + MsiRecordSetInteger(hRecordProg, 3, 0); + MsiProcessMessage(hInstall, INSTALLMESSAGE_PROGRESS, hRecordProg); + + /* Prepare hRecordProg for progress messages. */ + MsiRecordSetInteger(hRecordProg, 1, 2); + MsiRecordSetInteger(hRecordProg, 3, 0); + + BOOL bRebootRequired = FALSE; + + for (int i = 1 /*CommandLineToArgvW injects msiexec.exe as szArg[0]*/; i < nArgs; ++i) + { + DWORD dwResult = ERROR_SUCCESS; + + if (wcsncmp(szArg[i], L"create=", 7) == 0) { - uiResult = GetLastError(); - if (uiResult == ERROR_FILE_NOT_FOUND && bIsCleanup) + /* Create an interface with a given name. */ + LPCWSTR szName = szArg[i] + 7; + { - /* - * Sequence file not found and this is rollback/commit action. Either of the following scenarios are possible: - * - The delayed action failed to save the rollback/commit sequence to file. The delayed action performed cleanup itself. No further operation is required. - * - Somebody removed the rollback/commit file between delayed action and rollback/commit action. No further operation is possible. - */ - uiResult = ERROR_SUCCESS; - goto cleanup_szSeqFilename; + /* Report the name of the interface to installer. */ + MSIHANDLE hRecord = MsiCreateRecord(3); + MsiRecordSetString(hRecord, 1, TEXT("Creating interface")); + MsiRecordSetString(hRecord, 2, szName); + int iResult = MsiProcessMessage(hInstall, INSTALLMESSAGE_ACTIONDATA, hRecord); + MsiCloseHandle(hRecord); + if (iResult == IDCANCEL) + { + uiResult = ERROR_INSTALL_USEREXIT; + goto cleanup; + } } - msg(M_NONFATAL | M_ERRNO, "%s: CreateFile(\"%" PRIsLPTSTR "\") failed", __FUNCTION__, szSeqFilename); - goto cleanup_szSeqFilename; - } - /* Load sequence. */ - uiResult = msica_op_seq_load(&seq, hSeqFile); - CloseHandle(hSeqFile); - if (uiResult != ERROR_SUCCESS) - { - goto cleanup_seq; + GUID guidInterface; + dwResult = tap_create_interface(NULL, NULL, NULL, &bRebootRequired, &guidInterface); + if (dwResult == ERROR_SUCCESS) + { + /* Set interface name. */ + dwResult = tap_set_interface_name(&guidInterface, szName); + if (dwResult != ERROR_SUCCESS) + { + tap_delete_interface(NULL, &guidInterface, &bRebootRequired); + } + } } - } - - /* Prepare session context. */ - struct msica_session session; - openvpnmsica_session_init( - &session, - hInstall, - bIsCleanup, /* In case of commit/rollback, continue sequence on error, to do as much cleanup as possible. */ - false); - - /* Execute sequence. */ - uiResult = msica_op_seq_process(&seq, &session); - if (!bIsCleanup) - { - /* - * Save cleanup scripts of delayed action regardless of action's execution status. - * Rollback action MUST be scheduled in InstallExecuteSequence before this action! Otherwise cleanup won't be performed in case this action execution failed. - */ - DWORD dwResultEx; /* Don't overwrite uiResult. */ - LPCTSTR szExtension = PathFindExtension(szSeqFilename); - TCHAR szFilenameEx[MAX_PATH + 1 /*dash*/ + 2 /*suffix*/ + 1 /*terminator*/]; - for (size_t i = 0; i < MSICA_CLEANUP_ACTION_COUNT; i++) + else if (wcsncmp(szArg[i], L"deleteN=", 8) == 0) { - _stprintf_s( - szFilenameEx, _countof(szFilenameEx), - TEXT("%.*s-%.2s%s"), - (int)(szExtension - szSeqFilename), szSeqFilename, - openvpnmsica_cleanup_action_seqs[i].szSuffix, - szExtension); - - /* After commit, delete rollback file. After rollback, delete commit file. */ - msica_op_seq_add_tail( - &session.seq_cleanup[MSICA_CLEANUP_ACTION_COUNT - 1 - i], - msica_op_create_string( - msica_op_file_delete, - 0, - NULL, - szFilenameEx)); + /* Delete the interface by name. */ + LPCWSTR szName = szArg[i] + 8; + + { + /* Report the name of the interface to installer. */ + MSIHANDLE hRecord = MsiCreateRecord(3); + MsiRecordSetString(hRecord, 1, TEXT("Deleting interface")); + MsiRecordSetString(hRecord, 2, szName); + int iResult = MsiProcessMessage(hInstall, INSTALLMESSAGE_ACTIONDATA, hRecord); + MsiCloseHandle(hRecord); + if (iResult == IDCANCEL) + { + uiResult = ERROR_INSTALL_USEREXIT; + goto cleanup; + } + } + + /* Get available TUN/TAP interfaces. */ + struct tap_interface_node *pInterfaceList = NULL; + dwResult = tap_list_interfaces(NULL, NULL, &pInterfaceList, FALSE); + if (dwResult == ERROR_SUCCESS) + { + /* Does the interface exist? */ + for (struct tap_interface_node *pInterface = pInterfaceList; pInterface != NULL; pInterface = pInterface->pNext) + { + if (_tcsicmp(szName, pInterface->szName) == 0) + { + /* Interface found. */ + dwResult = tap_delete_interface(NULL, &pInterface->guid, &bRebootRequired); + break; + } + } + + tap_free_interface_list(pInterfaceList); + } } - for (size_t i = 0; i < MSICA_CLEANUP_ACTION_COUNT; i++) + else if (wcsncmp(szArg[i], L"delete=", 7) == 0) { - _stprintf_s( - szFilenameEx, _countof(szFilenameEx), - TEXT("%.*s-%.2s%s"), - (int)(szExtension - szSeqFilename), szSeqFilename, - openvpnmsica_cleanup_action_seqs[i].szSuffix, - szExtension); - - /* Save the cleanup sequence file. */ - HANDLE hSeqFile = CreateFile( - szFilenameEx, - GENERIC_WRITE, - FILE_SHARE_READ, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, - NULL); - if (hSeqFile == INVALID_HANDLE_VALUE) + /* Delete the interface by GUID. */ + GUID guid; + if (!openvpnmsica_parse_guid(szArg[i] + 7, &guid)) { - dwResultEx = GetLastError(); - msg(M_NONFATAL | M_ERRNO, "%s: CreateFile(\"%.*" PRIsLPTSTR "\") failed", __FUNCTION__, _countof(szFilenameEx), szFilenameEx); - goto cleanup_session; + goto invalid_argument; } - dwResultEx = msica_op_seq_save(&session.seq_cleanup[i], hSeqFile); - CloseHandle(hSeqFile); - if (dwResultEx != ERROR_SUCCESS) + dwResult = tap_delete_interface(NULL, &guid, &bRebootRequired); + } + else if (wcsncmp(szArg[i], L"enable=", 7) == 0) + { + /* Enable the interface. */ + GUID guid; + if (!openvpnmsica_parse_guid(szArg[i] + 7, &guid)) { - goto cleanup_session; + goto invalid_argument; } + dwResult = tap_enable_interface(NULL, &guid, TRUE, &bRebootRequired); } - -cleanup_session: - if (dwResultEx != ERROR_SUCCESS) + else if (wcsncmp(szArg[i], L"disable=", 8) == 0) { - /* The commit and/or rollback scripts were not written to file successfully. Perform the cleanup immediately. */ - struct msica_session session_cleanup; - openvpnmsica_session_init( - &session_cleanup, - hInstall, - true, - false); - msica_op_seq_process(&session.seq_cleanup[MSICA_CLEANUP_ACTION_ROLLBACK], &session_cleanup); - - szExtension = PathFindExtension(szSeqFilename); - for (size_t i = 0; i < MSICA_CLEANUP_ACTION_COUNT; i++) + /* Disable the interface. */ + GUID guid; + if (!openvpnmsica_parse_guid(szArg[i] + 8, &guid)) { - _stprintf_s( - szFilenameEx, _countof(szFilenameEx), - TEXT("%.*s-%.2s%s"), - (int)(szExtension - szSeqFilename), szSeqFilename, - openvpnmsica_cleanup_action_seqs[i].szSuffix, - szExtension); - DeleteFile(szFilenameEx); + goto invalid_argument; } + dwResult = tap_enable_interface(NULL, &guid, FALSE, &bRebootRequired); } - } - else - { - /* No cleanup after cleanup support. */ - uiResult = ERROR_SUCCESS; + else + { + goto invalid_argument; + } + + if (dwResult != ERROR_SUCCESS && !bIsCleanup /* Ignore errors in case of commit/rollback to do as much work as possible. */) + { + uiResult = ERROR_INSTALL_FAILURE; + goto cleanup; + } + + /* Report progress and check for user cancellation. */ + MsiRecordSetInteger(hRecordProg, 2, MSICA_INTERFACE_TICK_SIZE); + if (MsiProcessMessage(hInstall, INSTALLMESSAGE_PROGRESS, hRecordProg) == IDCANCEL) + { + dwResult = ERROR_INSTALL_USEREXIT; + goto cleanup; + } + + continue; + +invalid_argument: + msg(M_NONFATAL, "%s: Ignoring invalid argument: %ls", __FUNCTION__, szArg[i]); } - for (size_t i = MSICA_CLEANUP_ACTION_COUNT; i--; ) +cleanup: + if (bRebootRequired) { - msica_op_seq_free(&session.seq_cleanup[i]); + MsiSetMode(hInstall, MSIRUNMODE_REBOOTATEND, TRUE); } - DeleteFile(szSeqFilename); -cleanup_seq: - msica_op_seq_free(&seq); -cleanup_szSeqFilename: - free(szSeqFilename); + MsiCloseHandle(hRecordProg); + LocalFree(szArg); +cleanup_szSequence: + free(szSequence); cleanup_CoInitialize: if (bIsCoInitialized) { diff --git a/src/openvpnmsica/openvpnmsica.vcxproj b/src/openvpnmsica/openvpnmsica.vcxproj index afa4faec..4b429806 100644 --- a/src/openvpnmsica/openvpnmsica.vcxproj +++ b/src/openvpnmsica/openvpnmsica.vcxproj @@ -116,7 +116,7 @@ - + @@ -124,7 +124,7 @@ - + diff --git a/src/openvpnmsica/openvpnmsica.vcxproj.filters b/src/openvpnmsica/openvpnmsica.vcxproj.filters index d0b6dcf0..cb050f97 100644 --- a/src/openvpnmsica/openvpnmsica.vcxproj.filters +++ b/src/openvpnmsica/openvpnmsica.vcxproj.filters @@ -27,7 +27,7 @@ Source Files - + Source Files @@ -41,7 +41,7 @@ Header Files - + Header Files diff --git a/src/tapctl/basic.h b/src/tapctl/basic.h index bfbcc30d..a0a88511 100644 --- a/src/tapctl/basic.h +++ b/src/tapctl/basic.h @@ -23,12 +23,20 @@ #define BASIC_H #ifdef _UNICODE -#define PRIsLPTSTR "ls" -#define PRIsLPOLESTR "ls" +#define PRIsLPTSTR "ls" +#define PRIsLPOLESTR "ls" #else -#define PRIsLPTSTR "s" -#define PRIsLPOLESTR "ls" +#define PRIsLPTSTR "s" +#define PRIsLPOLESTR "ls" #endif +#define PRIXGUID "{%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX}" +#define PRIGUID_PARAM(g) \ + (g).Data1, (g).Data2, (g).Data3, (g).Data4[0], (g).Data4[1], (g).Data4[2], (g).Data4[3], (g).Data4[4], (g).Data4[5], (g).Data4[6], (g).Data4[7] +#define PRIGUID_PARAM_REF(g) \ + &(g).Data1, &(g).Data2, &(g).Data3, &(g).Data4[0], &(g).Data4[1], &(g).Data4[2], &(g).Data4[3], &(g).Data4[4], &(g).Data4[5], &(g).Data4[6], &(g).Data4[7] + +#define __L(q) L ## q +#define _L(q) __L(q) #ifndef _In_ #define _In_ @@ -42,6 +50,9 @@ #ifndef _Inout_ #define _Inout_ #endif +#ifndef _Inout_opt_ +#define _Inout_opt_ +#endif #ifndef _Out_ #define _Out_ #endif diff --git a/src/tapctl/tap.c b/src/tapctl/tap.c index 576f6740..d4631679 100644 --- a/src/tapctl/tap.c +++ b/src/tapctl/tap.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #ifdef _MSC_VER From patchwork Mon Mar 9 02:17:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Rozman X-Patchwork-Id: 1027 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director8.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id aLPvF1VCZl6tHAAAIUCqbw for ; Mon, 09 Mar 2020 09:19:17 -0400 Received: from proxy19.mail.ord1d.rsapps.net ([172.30.191.6]) by director8.mail.ord1d.rsapps.net with LMTP id qFfFF1VCZl7cagAAfY0hYg ; Mon, 09 Mar 2020 09:19:17 -0400 Received: from smtp22.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy19.mail.ord1d.rsapps.net with LMTP id CHOpF1VCZl4HRAAAyH2SIw ; Mon, 09 Mar 2020 09:19:17 -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: smtp22.gate.ord1d.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=rozman.si; dmarc=fail (p=none; dis=none) header.from=rozman.si X-Suspicious-Flag: YES X-Classification-ID: 93a724d6-6208-11ea-940d-5254001a15c2-1-1 Received: from [216.105.38.7] ([216.105.38.7:49344] helo=lists.sourceforge.net) by smtp22.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 3B/2E-10879-452466E5; Mon, 09 Mar 2020 09:19:17 -0400 Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1jBIIQ-00028J-CX; Mon, 09 Mar 2020 13:18:14 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jBIIO-00027l-Dl for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:12 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=Uouv4Uj+M/7ncyneH03jNhbDyh4XS2AG3CpgPWkVTaE=; b=DxqaoT8i/eqO5Y5wOrTkrm0HBM w2Jzo+gkKMrV1AQJhZzlEHNHe4eHUdTPelBKqryOwPUsRQGBeNeARPz0xHgG5weTFJadsFobYtRPo npn8A0klyolC0T8SnGdgKjxpbg/0vckSuVW/AcBTcLyix7viilTRMLoD8sM1Y0qrUc9I=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=Uouv4Uj+M/7ncyneH03jNhbDyh4XS2AG3CpgPWkVTaE=; b=M03674bZB6dTDZv1UZGveeYQKi HhmBEcH28ZzWCgPpd1fpZ63KHovHVpCy23qJGFDa9dRBiaDHntoWlgeYEcqx5Yi0cacYoNW/dd/zy mB+4xTZsEkp+wVzHFf0HuZXpsDhie5ujvhJc5XLFOSlgmy0tSKh0LDc+30Ed0y2lcJd4=; Received: from pub5.amebis.si ([213.250.55.21]) by sfi-mx-3.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1jBIIL-0033PO-1z for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:12 +0000 Received: by pub5.amebis.si (Postfix, from userid 1000) id D46401002FB6; Mon, 9 Mar 2020 14:17:57 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rozman.si; s=default; t=1583759877; bh=Uouv4Uj+M/7ncyneH03jNhbDyh4XS2AG3CpgPWkVTaE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Zq+x9/sPMhXY0vYCdijg4IWebwaIkdZ0RxdZw+LU42XN78bMXFoDFmiGZ2Th6IUwM ANmYtX1iHgCJrTsUBw5DgDcTlcpWlc01BmJGtVJ7UBOsmQYBRlNocz3mfiAo6tbcHS Co+db0VxyQo66uSgtYfe2xxbPGuoPby/+oR0n328= X-Spam-Checker-Version: SpamAssassin 3.4.3 (2019-12-06) on brana.amebis.doma X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00 autolearn=ham autolearn_force=no version=3.4.3 Received: from SR6.amebis.doma (unknown [IPv6:2a00:ee2:209:164:a5ae:e83c:b7b:725]) by pub5.amebis.si (Postfix) with ESMTP id 487E91002FBE; Mon, 9 Mar 2020 14:17:49 +0100 (CET) From: Simon Rozman To: openvpn-devel@lists.sourceforge.net Date: Mon, 9 Mar 2020 14:17:22 +0100 Message-Id: <20200309131728.380-6-simon@rozman.si> X-Mailer: git-send-email 2.24.1.windows.2 In-Reply-To: <20200309131728.380-1-simon@rozman.si> References: <20200309131728.380-1-simon@rozman.si> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -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: 1jBIIL-0033PO-1z Subject: [Openvpn-devel] [PATCH 06/12] openvpnmsica: Simplify static function names 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: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox Signed-off-by: Simon Rozman Acked-by: Lev Stipakov --- src/openvpnmsica/openvpnmsica.c | 63 +++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/src/openvpnmsica/openvpnmsica.c b/src/openvpnmsica/openvpnmsica.c index 4c186b13..749dce56 100644 --- a/src/openvpnmsica/openvpnmsica.c +++ b/src/openvpnmsica/openvpnmsica.c @@ -72,7 +72,7 @@ * @return ERROR_SUCCESS on success; An error code otherwise */ static UINT -openvpnmsica_setup_sequence( +setup_sequence( _In_ MSIHANDLE hInstall, _In_z_ LPCTSTR szProperty, _In_ struct msica_arg_seq *seq) @@ -101,7 +101,7 @@ openvpnmsica_setup_sequence( * title. */ static void -_openvpnmsica_debug_popup(_In_z_ LPCTSTR szFunctionName) +_debug_popup(_In_z_ LPCTSTR szFunctionName) { TCHAR szTitle[0x100], szMessage[0x100+MAX_PATH], szProcessPath[MAX_PATH]; @@ -129,9 +129,9 @@ _openvpnmsica_debug_popup(_In_z_ LPCTSTR szFunctionName) MessageBox(NULL, szMessage, szTitle, MB_OK); } -#define openvpnmsica_debug_popup(f) _openvpnmsica_debug_popup(f) +#define debug_popup(f) _debug_popup(f) #else /* ifdef _DEBUG */ -#define openvpnmsica_debug_popup(f) +#define debug_popup(f) #endif /* ifdef _DEBUG */ @@ -146,7 +146,7 @@ _openvpnmsica_debug_popup(_In_z_ LPCTSTR szFunctionName) * See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa368072.aspx */ static UINT -openvpnmsica_set_openvpnserv_state(_In_ MSIHANDLE hInstall) +set_openvpnserv_state(_In_ MSIHANDLE hInstall) { UINT uiResult; @@ -255,13 +255,13 @@ FindSystemInfo(_In_ MSIHANDLE hInstall) #pragma comment(linker, DLLEXP_EXPORT) #endif - openvpnmsica_debug_popup(TEXT(__FUNCTION__)); + debug_popup(TEXT(__FUNCTION__)); BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL)); OPENVPNMSICA_SAVE_MSI_SESSION(hInstall); - openvpnmsica_set_openvpnserv_state(hInstall); + set_openvpnserv_state(hInstall); if (bIsCoInitialized) { @@ -278,7 +278,7 @@ FindTAPInterfaces(_In_ MSIHANDLE hInstall) #pragma comment(linker, DLLEXP_EXPORT) #endif - openvpnmsica_debug_popup(TEXT(__FUNCTION__)); + debug_popup(TEXT(__FUNCTION__)); UINT uiResult; BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL)); @@ -444,7 +444,7 @@ CloseOpenVPNGUI(_In_ MSIHANDLE hInstall) #endif UNREFERENCED_PARAMETER(hInstall); /* This CA is does not interact with MSI session (report errors, access properties, tables, etc.). */ - openvpnmsica_debug_popup(TEXT(__FUNCTION__)); + debug_popup(TEXT(__FUNCTION__)); /* Find OpenVPN GUI window. */ HWND hWnd = FindWindow(TEXT("OpenVPN-GUI"), NULL); @@ -466,7 +466,7 @@ StartOpenVPNGUI(_In_ MSIHANDLE hInstall) #pragma comment(linker, DLLEXP_EXPORT) #endif - openvpnmsica_debug_popup(TEXT(__FUNCTION__)); + debug_popup(TEXT(__FUNCTION__)); UINT uiResult; BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL)); @@ -564,7 +564,11 @@ cleanup_CoInitialize: * @return ERROR_SUCCESS on success; An error code otherwise */ static DWORD -openvpnmsica_schedule_interface_create(_Inout_ struct msica_arg_seq *seq, _Inout_opt_ struct msica_arg_seq *seqRollback, _In_z_ LPCTSTR szDisplayName, _Inout_ int *iTicks) +schedule_interface_create( + _Inout_ struct msica_arg_seq *seq, + _Inout_opt_ struct msica_arg_seq *seqRollback, + _In_z_ LPCTSTR szDisplayName, + _Inout_ int *iTicks) { /* Get all available network interfaces. */ struct tap_interface_node *pInterfaceList = NULL; @@ -658,7 +662,12 @@ cleanup_pInterfaceList: * @return ERROR_SUCCESS on success; An error code otherwise */ static DWORD -openvpnmsica_schedule_interface_delete(_Inout_ struct msica_arg_seq *seq, _Inout_opt_ struct msica_arg_seq *seqCommit, _Inout_opt_ struct msica_arg_seq *seqRollback, _In_z_ LPCTSTR szDisplayName, _Inout_ int *iTicks) +schedule_interface_delete( + _Inout_ struct msica_arg_seq *seq, + _Inout_opt_ struct msica_arg_seq *seqCommit, + _Inout_opt_ struct msica_arg_seq *seqRollback, + _In_z_ LPCTSTR szDisplayName, + _Inout_ int *iTicks) { /* Get available TUN/TAP interfaces. */ struct tap_interface_node *pInterfaceList = NULL; @@ -725,7 +734,7 @@ EvaluateTAPInterfaces(_In_ MSIHANDLE hInstall) #pragma comment(linker, DLLEXP_EXPORT) #endif - openvpnmsica_debug_popup(TEXT(__FUNCTION__)); + debug_popup(TEXT(__FUNCTION__)); UINT uiResult; BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL)); @@ -887,7 +896,7 @@ EvaluateTAPInterfaces(_In_ MSIHANDLE hInstall) free(szValue); /* Component is or should be installed. Schedule interface creation. */ - if (openvpnmsica_schedule_interface_create( + if (schedule_interface_create( &seqInstallTAPInterfaces, bRollbackEnabled ? &seqInstallTAPInterfacesRollback : NULL, szDisplayNameEx, @@ -904,7 +913,7 @@ EvaluateTAPInterfaces(_In_ MSIHANDLE hInstall) * Note: On interface removal (product is being uninstalled), we tolerate dwResult error. * Better a partial uninstallation than no uninstallation at all. */ - openvpnmsica_schedule_interface_delete( + schedule_interface_delete( &seqUninstallTAPInterfaces, bRollbackEnabled ? &seqUninstallTAPInterfacesCommit : NULL, bRollbackEnabled ? &seqUninstallTAPInterfacesRollback : NULL, @@ -934,12 +943,12 @@ cleanup_hRecord: } /* Store deferred custom action parameters. */ - if ((uiResult = openvpnmsica_setup_sequence(hInstall, TEXT("InstallTAPInterfaces" ), &seqInstallTAPInterfaces )) != ERROR_SUCCESS - || (uiResult = openvpnmsica_setup_sequence(hInstall, TEXT("InstallTAPInterfacesCommit" ), &seqInstallTAPInterfacesCommit )) != ERROR_SUCCESS - || (uiResult = openvpnmsica_setup_sequence(hInstall, TEXT("InstallTAPInterfacesRollback" ), &seqInstallTAPInterfacesRollback )) != ERROR_SUCCESS - || (uiResult = openvpnmsica_setup_sequence(hInstall, TEXT("UninstallTAPInterfaces" ), &seqUninstallTAPInterfaces )) != ERROR_SUCCESS - || (uiResult = openvpnmsica_setup_sequence(hInstall, TEXT("UninstallTAPInterfacesCommit" ), &seqUninstallTAPInterfacesCommit )) != ERROR_SUCCESS - || (uiResult = openvpnmsica_setup_sequence(hInstall, TEXT("UninstallTAPInterfacesRollback"), &seqUninstallTAPInterfacesRollback)) != ERROR_SUCCESS) + if ((uiResult = setup_sequence(hInstall, TEXT("InstallTAPInterfaces" ), &seqInstallTAPInterfaces )) != ERROR_SUCCESS + || (uiResult = setup_sequence(hInstall, TEXT("InstallTAPInterfacesCommit" ), &seqInstallTAPInterfacesCommit )) != ERROR_SUCCESS + || (uiResult = setup_sequence(hInstall, TEXT("InstallTAPInterfacesRollback" ), &seqInstallTAPInterfacesRollback )) != ERROR_SUCCESS + || (uiResult = setup_sequence(hInstall, TEXT("UninstallTAPInterfaces" ), &seqUninstallTAPInterfaces )) != ERROR_SUCCESS + || (uiResult = setup_sequence(hInstall, TEXT("UninstallTAPInterfacesCommit" ), &seqUninstallTAPInterfacesCommit )) != ERROR_SUCCESS + || (uiResult = setup_sequence(hInstall, TEXT("UninstallTAPInterfacesRollback"), &seqUninstallTAPInterfacesRollback)) != ERROR_SUCCESS) { goto cleanup_hRecordProg; } @@ -979,7 +988,9 @@ cleanup_exec_seq: * @return TRUE on success; FALSE otherwise */ static BOOL -openvpnmsica_parse_guid(_In_z_ LPCWSTR szArg, _Out_ GUID *guid) +parse_guid( + _In_z_ LPCWSTR szArg, + _Out_ GUID *guid) { if (swscanf_s(szArg, _L(PRIXGUID), PRIGUID_PARAM_REF(*guid)) != 11) { @@ -997,7 +1008,7 @@ ProcessDeferredAction(_In_ MSIHANDLE hInstall) #pragma comment(linker, DLLEXP_EXPORT) #endif - openvpnmsica_debug_popup(TEXT(__FUNCTION__)); + debug_popup(TEXT(__FUNCTION__)); UINT uiResult; BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL)); @@ -1112,7 +1123,7 @@ ProcessDeferredAction(_In_ MSIHANDLE hInstall) { /* Delete the interface by GUID. */ GUID guid; - if (!openvpnmsica_parse_guid(szArg[i] + 7, &guid)) + if (!parse_guid(szArg[i] + 7, &guid)) { goto invalid_argument; } @@ -1122,7 +1133,7 @@ ProcessDeferredAction(_In_ MSIHANDLE hInstall) { /* Enable the interface. */ GUID guid; - if (!openvpnmsica_parse_guid(szArg[i] + 7, &guid)) + if (!parse_guid(szArg[i] + 7, &guid)) { goto invalid_argument; } @@ -1132,7 +1143,7 @@ ProcessDeferredAction(_In_ MSIHANDLE hInstall) { /* Disable the interface. */ GUID guid; - if (!openvpnmsica_parse_guid(szArg[i] + 8, &guid)) + if (!parse_guid(szArg[i] + 8, &guid)) { goto invalid_argument; } From patchwork Mon Mar 9 02:17:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Simon Rozman X-Patchwork-Id: 1030 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director7.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id +MkGBVpCZl6YOwAAIUCqbw for ; Mon, 09 Mar 2020 09:19:22 -0400 Received: from proxy4.mail.ord1d.rsapps.net ([172.30.191.6]) by director7.mail.ord1d.rsapps.net with LMTP id CAzEBFpCZl4TKAAAovjBpQ ; Mon, 09 Mar 2020 09:19:22 -0400 Received: from smtp24.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy4.mail.ord1d.rsapps.net with LMTP id gE93BFpCZl7TTgAAiYrejw ; Mon, 09 Mar 2020 09:19:22 -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: smtp24.gate.ord1d.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=rozman.si; dmarc=fail (p=none; dis=none) header.from=rozman.si X-Suspicious-Flag: YES X-Classification-ID: 96537d10-6208-11ea-9b72-52540091a1c4-1-1 Received: from [216.105.38.7] ([216.105.38.7:49414] helo=lists.sourceforge.net) by smtp24.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id BD/B2-08450-952466E5; Mon, 09 Mar 2020 09:19:21 -0400 Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1jBIIb-0002AB-QV; Mon, 09 Mar 2020 13:18:25 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jBIIa-00029p-DX for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:24 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:Content-Type:MIME-Version :References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=2W8Q5JCGoRVkDaAbdGgMWCNcf2p8QBqUFP1VbKgZOpM=; b=aP2k2f5kFYSr/f/zm8MLS35mjx CC5Ek6ZX2F0fbSNvp4W2cfV76/yVscGK/gZtxQ0fzMjIjnrj4QWRN82DAyVDB+KTrqWW2+2P8O8pg p6EXlKIblYNUNHWKB4nWRJJnmN9ytDyTXfnhKEBXJ8rVrgy6ItrFUwKMycwMbu+limEY=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=2W8Q5JCGoRVkDaAbdGgMWCNcf2p8QBqUFP1VbKgZOpM=; b=T4BNCuyd/CFYgawGcxHJ/51nYz I4jIfmxoegJaLqRZnZIOruiteNrZZGmX4QLHcaFXNCSZatGsUtVVjd6E9nOIEPWPbL/d0tpqrGBkG OvnNbyMsUsf3bezgaAUhxbHsmC4ncMRrzbOUBWPgwUMUAj4+GTmzzVrj6MmQ2D2icbFo=; Received: from pub5.amebis.si ([213.250.55.21]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1jBIIV-00DVpN-21 for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:24 +0000 Received: by pub5.amebis.si (Postfix, from userid 1000) id 4F7791002FB7; Mon, 9 Mar 2020 14:17:58 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rozman.si; s=default; t=1583759878; bh=2W8Q5JCGoRVkDaAbdGgMWCNcf2p8QBqUFP1VbKgZOpM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QpAzsXc4BqosDgBlOHOuKNDZR8zow1CTu3a039tUCBC5VutvPYkvWQxlN26hZVuyU EB6vUyYZ6WmGNsOPvbeGxAxAXIXP3vlZ1xZzSp1DmfwwReKlNl4ZY+yDE9I3SZAGPC e719maPBqxhHYsD0PRPOgOv1t9S796Hfcvqr71ks= X-Spam-Checker-Version: SpamAssassin 3.4.3 (2019-12-06) on brana.amebis.doma X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00, WEIRD_QUOTING autolearn=ham autolearn_force=no version=3.4.3 Received: from SR6.amebis.doma (unknown [IPv6:2a00:ee2:209:164:a5ae:e83c:b7b:725]) by pub5.amebis.si (Postfix) with ESMTP id 58E1C1002FC0; Mon, 9 Mar 2020 14:17:49 +0100 (CET) From: Simon Rozman To: openvpn-devel@lists.sourceforge.net Date: Mon, 9 Mar 2020 14:17:23 +0100 Message-Id: <20200309131728.380-7-simon@rozman.si> X-Mailer: git-send-email 2.24.1.windows.2 In-Reply-To: <20200309131728.380-1-simon@rozman.si> References: <20200309131728.380-1-simon@rozman.si> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 WEIRD_QUOTING BODY: Weird repeated double-quotation marks -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 -0.0 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1jBIIV-00DVpN-21 Subject: [Openvpn-devel] [PATCH 07/12] openvpnmsica, tapctl: "interface" => "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: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox Interface is not equal to adapter. A quote from Microsoft documentation: > There is a one-to-one correspondence between the interfaces and > adapters on a given computer. An interface is an IP-level abstraction, > whereas an adapter is a datalink-level abstraction. As tapctl and openvpnmsica are all about managing network adapters on Windows computers, the terminology has been updated. Signed-off-by: Simon Rozman Acked-by: Lev Stipakov --- src/openvpnmsica/openvpnmsica.c | 366 ++++++++++++++++---------------- src/openvpnmsica/openvpnmsica.h | 13 +- src/tapctl/main.c | 150 ++++++------- src/tapctl/tap.c | 182 ++++++++-------- src/tapctl/tap.h | 82 +++---- src/tapctl/tapctl_resources.rc | 4 +- 6 files changed, 399 insertions(+), 398 deletions(-) diff --git a/src/openvpnmsica/openvpnmsica.c b/src/openvpnmsica/openvpnmsica.c index 749dce56..1438d3f7 100644 --- a/src/openvpnmsica/openvpnmsica.c +++ b/src/openvpnmsica/openvpnmsica.c @@ -57,7 +57,7 @@ * Local constants */ -#define MSICA_INTERFACE_TICK_SIZE (16*1024) /** Amount of tick space to reserve for one TAP/TUN interface creation/deletition. */ +#define MSICA_ADAPTER_TICK_SIZE (16*1024) /** Amount of tick space to reserve for one TAP/TUN adapter creation/deletition. */ /** @@ -272,7 +272,7 @@ FindSystemInfo(_In_ MSIHANDLE hInstall) UINT __stdcall -FindTAPInterfaces(_In_ MSIHANDLE hInstall) +FindTAPAdapters(_In_ MSIHANDLE hInstall) { #ifdef _MSC_VER #pragma comment(linker, DLLEXP_EXPORT) @@ -285,15 +285,15 @@ FindTAPInterfaces(_In_ MSIHANDLE hInstall) OPENVPNMSICA_SAVE_MSI_SESSION(hInstall); - /* Get all TUN/TAP network interfaces. */ - struct tap_interface_node *pInterfaceList = NULL; - uiResult = tap_list_interfaces(NULL, NULL, &pInterfaceList, FALSE); + /* Get all TUN/TAP network adapters. */ + struct tap_adapter_node *pAdapterList = NULL; + uiResult = tap_list_adapters(NULL, NULL, &pAdapterList, FALSE); if (uiResult != ERROR_SUCCESS) { goto cleanup_CoInitialize; } - /* Get IPv4/v6 info for all network interfaces. Actually, we're interested in link status only: up/down? */ + /* Get IPv4/v6 info for all network adapters. Actually, we're interested in link status only: up/down? */ PIP_ADAPTER_ADDRESSES pAdapterAdresses = NULL; ULONG ulAdapterAdressesSize = 16*1024; for (size_t iteration = 0; iteration < 2; iteration++) @@ -302,7 +302,7 @@ FindTAPInterfaces(_In_ MSIHANDLE hInstall) if (pAdapterAdresses == NULL) { msg(M_NONFATAL, "%s: malloc(%u) failed", __FUNCTION__, ulAdapterAdressesSize); - uiResult = ERROR_OUTOFMEMORY; goto cleanup_tap_list_interfaces; + uiResult = ERROR_OUTOFMEMORY; goto cleanup_tap_list_adapters; } ULONG ulResult = GetAdaptersAddresses( @@ -322,101 +322,101 @@ FindTAPInterfaces(_In_ MSIHANDLE hInstall) { SetLastError(ulResult); /* MSDN does not mention GetAdaptersAddresses() to set GetLastError(). But we do have an error code. Set last error manually. */ msg(M_NONFATAL | M_ERRNO, "%s: GetAdaptersAddresses() failed", __FUNCTION__); - uiResult = ulResult; goto cleanup_tap_list_interfaces; + uiResult = ulResult; goto cleanup_tap_list_adapters; } } - if (pInterfaceList != NULL) + if (pAdapterList != NULL) { - /* Count interfaces. */ - size_t interface_count = 0; - for (struct tap_interface_node *pInterface = pInterfaceList; pInterface; pInterface = pInterface->pNext) + /* Count adapters. */ + size_t adapter_count = 0; + for (struct tap_adapter_node *pAdapter = pAdapterList; pAdapter; pAdapter = pAdapter->pNext) { - interface_count++; + adapter_count++; } - /* Prepare semicolon delimited list of TAP interface ID(s) and active TAP interface ID(s). */ + /* Prepare semicolon delimited list of TAP adapter ID(s) and active TAP adapter ID(s). */ LPTSTR - szTAPInterfaces = (LPTSTR)malloc(interface_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)), - szTAPInterfacesTail = szTAPInterfaces; - if (szTAPInterfaces == NULL) + szTAPAdapters = (LPTSTR)malloc(adapter_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)), + szTAPAdaptersTail = szTAPAdapters; + if (szTAPAdapters == NULL) { - msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, interface_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)); + msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, adapter_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)); uiResult = ERROR_OUTOFMEMORY; goto cleanup_pAdapterAdresses; } LPTSTR - szTAPInterfacesActive = (LPTSTR)malloc(interface_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)), - szTAPInterfacesActiveTail = szTAPInterfacesActive; - if (szTAPInterfacesActive == NULL) + szTAPAdaptersActive = (LPTSTR)malloc(adapter_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)), + szTAPAdaptersActiveTail = szTAPAdaptersActive; + if (szTAPAdaptersActive == NULL) { - msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, interface_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)); - uiResult = ERROR_OUTOFMEMORY; goto cleanup_szTAPInterfaces; + msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, adapter_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)); + uiResult = ERROR_OUTOFMEMORY; goto cleanup_szTAPAdapters; } - for (struct tap_interface_node *pInterface = pInterfaceList; pInterface; pInterface = pInterface->pNext) + for (struct tap_adapter_node *pAdapter = pAdapterList; pAdapter; pAdapter = pAdapter->pNext) { - /* Convert interface GUID to UTF-16 string. (LPOLESTR defaults to LPWSTR) */ - LPOLESTR szInterfaceId = NULL; - StringFromIID((REFIID)&pInterface->guid, &szInterfaceId); + /* Convert adapter GUID to UTF-16 string. (LPOLESTR defaults to LPWSTR) */ + LPOLESTR szAdapterId = NULL; + StringFromIID((REFIID)&pAdapter->guid, &szAdapterId); - /* Append to the list of TAP interface ID(s). */ - if (szTAPInterfaces < szTAPInterfacesTail) + /* Append to the list of TAP adapter ID(s). */ + if (szTAPAdapters < szTAPAdaptersTail) { - *(szTAPInterfacesTail++) = TEXT(';'); + *(szTAPAdaptersTail++) = TEXT(';'); } - memcpy(szTAPInterfacesTail, szInterfaceId, 38 * sizeof(TCHAR)); - szTAPInterfacesTail += 38; + memcpy(szTAPAdaptersTail, szAdapterId, 38 * sizeof(TCHAR)); + szTAPAdaptersTail += 38; - /* If this interface is active (connected), add it to the list of active TAP interface ID(s). */ + /* If this adapter is active (connected), add it to the list of active TAP adapter ID(s). */ for (PIP_ADAPTER_ADDRESSES p = pAdapterAdresses; p; p = p->Next) { OLECHAR szId[38 /*GUID*/ + 1 /*terminator*/]; GUID guid; if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, p->AdapterName, -1, szId, _countof(szId)) > 0 && SUCCEEDED(IIDFromString(szId, &guid)) - && memcmp(&guid, &pInterface->guid, sizeof(GUID)) == 0) + && memcmp(&guid, &pAdapter->guid, sizeof(GUID)) == 0) { if (p->OperStatus == IfOperStatusUp) { - /* This TAP interface is active (connected). */ - if (szTAPInterfacesActive < szTAPInterfacesActiveTail) + /* This TAP adapter is active (connected). */ + if (szTAPAdaptersActive < szTAPAdaptersActiveTail) { - *(szTAPInterfacesActiveTail++) = TEXT(';'); + *(szTAPAdaptersActiveTail++) = TEXT(';'); } - memcpy(szTAPInterfacesActiveTail, szInterfaceId, 38 * sizeof(TCHAR)); - szTAPInterfacesActiveTail += 38; + memcpy(szTAPAdaptersActiveTail, szAdapterId, 38 * sizeof(TCHAR)); + szTAPAdaptersActiveTail += 38; } break; } } - CoTaskMemFree(szInterfaceId); + CoTaskMemFree(szAdapterId); } - szTAPInterfacesTail [0] = 0; - szTAPInterfacesActiveTail[0] = 0; + szTAPAdaptersTail [0] = 0; + szTAPAdaptersActiveTail[0] = 0; - /* Set Installer TAPINTERFACES property. */ - uiResult = MsiSetProperty(hInstall, TEXT("TAPINTERFACES"), szTAPInterfaces); + /* Set Installer TAPADAPTERS property. */ + uiResult = MsiSetProperty(hInstall, TEXT("TAPADAPTERS"), szTAPAdapters); if (uiResult != ERROR_SUCCESS) { SetLastError(uiResult); /* MSDN does not mention MsiSetProperty() to set GetLastError(). But we do have an error code. Set last error manually. */ - msg(M_NONFATAL | M_ERRNO, "%s: MsiSetProperty(\"TAPINTERFACES\") failed", __FUNCTION__); - goto cleanup_szTAPInterfacesActive; + msg(M_NONFATAL | M_ERRNO, "%s: MsiSetProperty(\"TAPADAPTERS\") failed", __FUNCTION__); + goto cleanup_szTAPAdaptersActive; } - /* Set Installer ACTIVETAPINTERFACES property. */ - uiResult = MsiSetProperty(hInstall, TEXT("ACTIVETAPINTERFACES"), szTAPInterfacesActive); + /* Set Installer ACTIVETAPADAPTERS property. */ + uiResult = MsiSetProperty(hInstall, TEXT("ACTIVETAPADAPTERS"), szTAPAdaptersActive); if (uiResult != ERROR_SUCCESS) { SetLastError(uiResult); /* MSDN does not mention MsiSetProperty() to set GetLastError(). But we do have an error code. Set last error manually. */ - msg(M_NONFATAL | M_ERRNO, "%s: MsiSetProperty(\"ACTIVETAPINTERFACES\") failed", __FUNCTION__); - goto cleanup_szTAPInterfacesActive; + msg(M_NONFATAL | M_ERRNO, "%s: MsiSetProperty(\"ACTIVETAPADAPTERS\") failed", __FUNCTION__); + goto cleanup_szTAPAdaptersActive; } -cleanup_szTAPInterfacesActive: - free(szTAPInterfacesActive); -cleanup_szTAPInterfaces: - free(szTAPInterfaces); +cleanup_szTAPAdaptersActive: + free(szTAPAdaptersActive); +cleanup_szTAPAdapters: + free(szTAPAdapters); } else { @@ -425,8 +425,8 @@ cleanup_szTAPInterfaces: cleanup_pAdapterAdresses: free(pAdapterAdresses); -cleanup_tap_list_interfaces: - tap_free_interface_list(pInterfaceList); +cleanup_tap_list_adapters: + tap_free_adapter_list(pAdapterList); cleanup_CoInitialize: if (bIsCoInitialized) { @@ -546,47 +546,47 @@ cleanup_CoInitialize: /** - * Schedules interface creation. + * Schedules adapter creation. * - * When the rollback is enabled, the interface deletition is scheduled on rollback. + * When the rollback is enabled, the adapter deletition is scheduled on rollback. * - * @param seq The argument sequence to pass to InstallTAPInterfaces custom action + * @param seq The argument sequence to pass to InstallTAPAdapters custom action * - * @param seqRollback The argument sequence to pass to InstallTAPInterfacesRollback custom + * @param seqRollback The argument sequence to pass to InstallTAPAdaptersRollback custom * action. NULL when rollback is disabled. * - * @param szDisplayName Interface display name. + * @param szDisplayName Adapter display name. * * @param iTicks Pointer to an integer that represents amount of work (on progress - * indicator) the InstallTAPInterfaces will take. This function increments it - * by MSICA_INTERFACE_TICK_SIZE for each interface to create. + * indicator) the InstallTAPAdapters will take. This function increments it + * by MSICA_ADAPTER_TICK_SIZE for each adapter to create. * * @return ERROR_SUCCESS on success; An error code otherwise */ static DWORD -schedule_interface_create( +schedule_adapter_create( _Inout_ struct msica_arg_seq *seq, _Inout_opt_ struct msica_arg_seq *seqRollback, _In_z_ LPCTSTR szDisplayName, _Inout_ int *iTicks) { - /* Get all available network interfaces. */ - struct tap_interface_node *pInterfaceList = NULL; - DWORD dwResult = tap_list_interfaces(NULL, NULL, &pInterfaceList, TRUE); + /* Get all available network adapters. */ + struct tap_adapter_node *pAdapterList = NULL; + DWORD dwResult = tap_list_adapters(NULL, NULL, &pAdapterList, TRUE); if (dwResult != ERROR_SUCCESS) { return dwResult; } - /* Does interface exist? */ - for (struct tap_interface_node *pInterfaceOther = pInterfaceList;; pInterfaceOther = pInterfaceOther->pNext) + /* Does adapter exist? */ + for (struct tap_adapter_node *pAdapterOther = pAdapterList;; pAdapterOther = pAdapterOther->pNext) { - if (pInterfaceOther == NULL) + if (pAdapterOther == NULL) { - /* No interface with a same name found. */ + /* No adapter with a same name found. */ TCHAR szArgument[10 /*create=""|deleteN=""*/ + MAX_PATH /*szDisplayName*/ + 1 /*terminator*/]; - /* InstallTAPInterfaces will create the interface. */ + /* InstallTAPAdapters will create the adapter. */ _stprintf_s( szArgument, _countof(szArgument), TEXT("create=\"%.*s\""), @@ -595,7 +595,7 @@ schedule_interface_create( if (seqRollback) { - /* InstallTAPInterfacesRollback will delete the interface. */ + /* InstallTAPAdaptersRollback will delete the adapter. */ _stprintf_s( szArgument, _countof(szArgument), TEXT("deleteN=\"%.*s\""), @@ -603,132 +603,132 @@ schedule_interface_create( msica_arg_seq_add_head(seqRollback, szArgument); } - *iTicks += MSICA_INTERFACE_TICK_SIZE; + *iTicks += MSICA_ADAPTER_TICK_SIZE; break; } - else if (_tcsicmp(szDisplayName, pInterfaceOther->szName) == 0) + else if (_tcsicmp(szDisplayName, pAdapterOther->szName) == 0) { - /* Interface with a same name found. */ - for (LPCTSTR hwid = pInterfaceOther->szzHardwareIDs;; hwid += _tcslen(hwid) + 1) + /* Adapter with a same name found. */ + for (LPCTSTR hwid = pAdapterOther->szzHardwareIDs;; hwid += _tcslen(hwid) + 1) { if (hwid[0] == 0) { - /* This is not a TAP interface. */ - msg(M_NONFATAL, "%s: Interface with name \"%" PRIsLPTSTR "\" already exists", __FUNCTION__, pInterfaceOther->szName); + /* This is not a TAP adapter. */ + msg(M_NONFATAL, "%s: Adapter with name \"%" PRIsLPTSTR "\" already exists", __FUNCTION__, pAdapterOther->szName); dwResult = ERROR_ALREADY_EXISTS; - goto cleanup_pInterfaceList; + goto cleanup_pAdapterList; } else if ( _tcsicmp(hwid, TEXT(TAP_WIN_COMPONENT_ID)) == 0 || _tcsicmp(hwid, TEXT("root\\") TEXT(TAP_WIN_COMPONENT_ID)) == 0) { - /* This is a TAP-Windows6 interface. We already have what we want! */ + /* This is a TAP-Windows6 adapter. We already have what we want! */ break; } } - break; /* Interface names are unique. There should be no other interface with this name. */ + break; /* Adapter names are unique. There should be no other adapter with this name. */ } } -cleanup_pInterfaceList: - tap_free_interface_list(pInterfaceList); +cleanup_pAdapterList: + tap_free_adapter_list(pAdapterList); return dwResult; } /** - * Schedules interface deletion. + * Schedules adapter deletion. * - * When the rollback is enabled, the interface deletition is scheduled as: disable in - * UninstallTAPInterfaces, enable on rollback, delete on commit. + * When the rollback is enabled, the adapter deletition is scheduled as: disable in + * UninstallTAPAdapters, enable on rollback, delete on commit. * - * When rollback is disabled, the interface deletition is scheduled as delete in - * UninstallTAPInterfaces. + * When rollback is disabled, the adapter deletition is scheduled as delete in + * UninstallTAPAdapters. * - * @param seq The argument sequence to pass to UninstallTAPInterfaces custom action + * @param seq The argument sequence to pass to UninstallTAPAdapters custom action * - * @param seqCommit The argument sequence to pass to UninstallTAPInterfacesCommit custom + * @param seqCommit The argument sequence to pass to UninstallTAPAdaptersCommit custom * action. NULL when rollback is disabled. * - * @param seqRollback The argument sequence to pass to UninstallTAPInterfacesRollback custom + * @param seqRollback The argument sequence to pass to UninstallTAPAdaptersRollback custom * action. NULL when rollback is disabled. * - * @param szDisplayName Interface display name. + * @param szDisplayName Adapter display name. * * @param iTicks Pointer to an integer that represents amount of work (on progress - * indicator) the UninstallTAPInterfaces will take. This function increments - * it by MSICA_INTERFACE_TICK_SIZE for each interface to delete. + * indicator) the UninstallTAPAdapters will take. This function increments + * it by MSICA_ADAPTER_TICK_SIZE for each adapter to delete. * * @return ERROR_SUCCESS on success; An error code otherwise */ static DWORD -schedule_interface_delete( +schedule_adapter_delete( _Inout_ struct msica_arg_seq *seq, _Inout_opt_ struct msica_arg_seq *seqCommit, _Inout_opt_ struct msica_arg_seq *seqRollback, _In_z_ LPCTSTR szDisplayName, _Inout_ int *iTicks) { - /* Get available TUN/TAP interfaces. */ - struct tap_interface_node *pInterfaceList = NULL; - DWORD dwResult = tap_list_interfaces(NULL, NULL, &pInterfaceList, FALSE); + /* Get available TUN/TAP adapters. */ + struct tap_adapter_node *pAdapterList = NULL; + DWORD dwResult = tap_list_adapters(NULL, NULL, &pAdapterList, FALSE); if (dwResult != ERROR_SUCCESS) { return dwResult; } - /* Does interface exist? */ - for (struct tap_interface_node *pInterface = pInterfaceList; pInterface != NULL; pInterface = pInterface->pNext) + /* Does adapter exist? */ + for (struct tap_adapter_node *pAdapter = pAdapterList; pAdapter != NULL; pAdapter = pAdapter->pNext) { - if (_tcsicmp(szDisplayName, pInterface->szName) == 0) + if (_tcsicmp(szDisplayName, pAdapter->szName) == 0) { - /* Interface found. */ + /* Adapter found. */ TCHAR szArgument[8 /*disable=|enable=|delete=*/ + 38 /*{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}*/ + 1 /*terminator*/]; if (seqCommit && seqRollback) { - /* UninstallTAPInterfaces will disable the interface. */ + /* UninstallTAPAdapters will disable the adapter. */ _stprintf_s( szArgument, _countof(szArgument), TEXT("disable=") TEXT(PRIXGUID), - PRIGUID_PARAM(pInterface->guid)); + PRIGUID_PARAM(pAdapter->guid)); msica_arg_seq_add_tail(seq, szArgument); - /* UninstallTAPInterfacesRollback will re-enable the interface. */ + /* UninstallTAPAdaptersRollback will re-enable the adapter. */ _stprintf_s( szArgument, _countof(szArgument), TEXT("enable=") TEXT(PRIXGUID), - PRIGUID_PARAM(pInterface->guid)); + PRIGUID_PARAM(pAdapter->guid)); msica_arg_seq_add_head(seqRollback, szArgument); - /* UninstallTAPInterfacesCommit will delete the interface. */ + /* UninstallTAPAdaptersCommit will delete the adapter. */ _stprintf_s( szArgument, _countof(szArgument), TEXT("delete=") TEXT(PRIXGUID), - PRIGUID_PARAM(pInterface->guid)); + PRIGUID_PARAM(pAdapter->guid)); msica_arg_seq_add_tail(seqCommit, szArgument); } else { - /* UninstallTAPInterfaces will delete the interface. */ + /* UninstallTAPAdapters will delete the adapter. */ _stprintf_s( szArgument, _countof(szArgument), TEXT("delete=") TEXT(PRIXGUID), - PRIGUID_PARAM(pInterface->guid)); + PRIGUID_PARAM(pAdapter->guid)); msica_arg_seq_add_tail(seq, szArgument); } - iTicks += MSICA_INTERFACE_TICK_SIZE; - break; /* Interface names are unique. There should be no other interface with this name. */ + iTicks += MSICA_ADAPTER_TICK_SIZE; + break; /* Adapter names are unique. There should be no other adapter with this name. */ } } - tap_free_interface_list(pInterfaceList); + tap_free_adapter_list(pAdapterList); return dwResult; } UINT __stdcall -EvaluateTAPInterfaces(_In_ MSIHANDLE hInstall) +EvaluateTAPAdapters(_In_ MSIHANDLE hInstall) { #ifdef _MSC_VER #pragma comment(linker, DLLEXP_EXPORT) @@ -742,18 +742,18 @@ EvaluateTAPInterfaces(_In_ MSIHANDLE hInstall) OPENVPNMSICA_SAVE_MSI_SESSION(hInstall); struct msica_arg_seq - seqInstallTAPInterfaces, - seqInstallTAPInterfacesCommit, - seqInstallTAPInterfacesRollback, - seqUninstallTAPInterfaces, - seqUninstallTAPInterfacesCommit, - seqUninstallTAPInterfacesRollback; - msica_arg_seq_init(&seqInstallTAPInterfaces); - msica_arg_seq_init(&seqInstallTAPInterfacesCommit); - msica_arg_seq_init(&seqInstallTAPInterfacesRollback); - msica_arg_seq_init(&seqUninstallTAPInterfaces); - msica_arg_seq_init(&seqUninstallTAPInterfacesCommit); - msica_arg_seq_init(&seqUninstallTAPInterfacesRollback); + seqInstallTAPAdapters, + seqInstallTAPAdaptersCommit, + seqInstallTAPAdaptersRollback, + seqUninstallTAPAdapters, + seqUninstallTAPAdaptersCommit, + seqUninstallTAPAdaptersRollback; + msica_arg_seq_init(&seqInstallTAPAdapters); + msica_arg_seq_init(&seqInstallTAPAdaptersCommit); + msica_arg_seq_init(&seqInstallTAPAdaptersRollback); + msica_arg_seq_init(&seqUninstallTAPAdapters); + msica_arg_seq_init(&seqUninstallTAPAdaptersCommit); + msica_arg_seq_init(&seqUninstallTAPAdaptersRollback); /* Check rollback state. */ bool bRollbackEnabled = MsiEvaluateCondition(hInstall, TEXT("RollbackDisabled")) != MSICONDITION_TRUE; @@ -767,8 +767,8 @@ EvaluateTAPInterfaces(_In_ MSIHANDLE hInstall) goto cleanup_exec_seq; } - /* Check if TAPInterface table exists. If it doesn't exist, there's nothing to do. */ - switch (MsiDatabaseIsTablePersistent(hDatabase, TEXT("TAPInterface"))) + /* Check if TAPAdapter table exists. If it doesn't exist, there's nothing to do. */ + switch (MsiDatabaseIsTablePersistent(hDatabase, TEXT("TAPAdapter"))) { case MSICONDITION_FALSE: case MSICONDITION_TRUE: break; @@ -778,9 +778,9 @@ EvaluateTAPInterfaces(_In_ MSIHANDLE hInstall) goto cleanup_hDatabase; } - /* Prepare a query to get a list/view of interfaces. */ + /* Prepare a query to get a list/view of adapters. */ MSIHANDLE hViewST = 0; - LPCTSTR szQuery = TEXT("SELECT `Interface`,`DisplayName`,`Condition`,`Component_` FROM `TAPInterface`"); + LPCTSTR szQuery = TEXT("SELECT `Adapter`,`DisplayName`,`Condition`,`Component_` FROM `TAPAdapter`"); uiResult = MsiDatabaseOpenView(hDatabase, szQuery, &hViewST); if (uiResult != ERROR_SUCCESS) { @@ -826,7 +826,7 @@ EvaluateTAPInterfaces(_In_ MSIHANDLE hInstall) INSTALLSTATE iInstalled, iAction; { - /* Read interface component ID (`Component_` is field #4). */ + /* Read adapter component ID (`Component_` is field #4). */ LPTSTR szValue = NULL; uiResult = msi_get_record_string(hRecord, 4, &szValue); if (uiResult != ERROR_SUCCESS) @@ -846,7 +846,7 @@ EvaluateTAPInterfaces(_In_ MSIHANDLE hInstall) free(szValue); } - /* Get interface display name (`DisplayName` is field #2). */ + /* Get adapter display name (`DisplayName` is field #2). */ LPTSTR szDisplayName = NULL; uiResult = msi_format_field(hInstall, hRecord, 2, &szDisplayName); if (uiResult != ERROR_SUCCESS) @@ -863,7 +863,7 @@ EvaluateTAPInterfaces(_In_ MSIHANDLE hInstall) if (iAction >= INSTALLSTATE_LOCAL) { - /* Read and evaluate interface condition (`Condition` is field #3). */ + /* Read and evaluate adapter condition (`Condition` is field #3). */ LPTSTR szValue = NULL; uiResult = msi_get_record_string(hRecord, 3, &szValue); if (uiResult != ERROR_SUCCESS) @@ -895,10 +895,10 @@ EvaluateTAPInterfaces(_In_ MSIHANDLE hInstall) #endif free(szValue); - /* Component is or should be installed. Schedule interface creation. */ - if (schedule_interface_create( - &seqInstallTAPInterfaces, - bRollbackEnabled ? &seqInstallTAPInterfacesRollback : NULL, + /* Component is or should be installed. Schedule adapter creation. */ + if (schedule_adapter_create( + &seqInstallTAPAdapters, + bRollbackEnabled ? &seqInstallTAPAdaptersRollback : NULL, szDisplayNameEx, &iTicks) != ERROR_SUCCESS) { @@ -908,15 +908,15 @@ EvaluateTAPInterfaces(_In_ MSIHANDLE hInstall) } else { - /* Component is installed, but should be degraded to advertised/removed. Schedule interface deletition. + /* Component is installed, but should be degraded to advertised/removed. Schedule adapter deletition. * - * Note: On interface removal (product is being uninstalled), we tolerate dwResult error. + * Note: On adapter removal (product is being uninstalled), we tolerate dwResult error. * Better a partial uninstallation than no uninstallation at all. */ - schedule_interface_delete( - &seqUninstallTAPInterfaces, - bRollbackEnabled ? &seqUninstallTAPInterfacesCommit : NULL, - bRollbackEnabled ? &seqUninstallTAPInterfacesRollback : NULL, + schedule_adapter_delete( + &seqUninstallTAPAdapters, + bRollbackEnabled ? &seqUninstallTAPAdaptersCommit : NULL, + bRollbackEnabled ? &seqUninstallTAPAdaptersRollback : NULL, szDisplayNameEx, &iTicks); } @@ -943,12 +943,12 @@ cleanup_hRecord: } /* Store deferred custom action parameters. */ - if ((uiResult = setup_sequence(hInstall, TEXT("InstallTAPInterfaces" ), &seqInstallTAPInterfaces )) != ERROR_SUCCESS - || (uiResult = setup_sequence(hInstall, TEXT("InstallTAPInterfacesCommit" ), &seqInstallTAPInterfacesCommit )) != ERROR_SUCCESS - || (uiResult = setup_sequence(hInstall, TEXT("InstallTAPInterfacesRollback" ), &seqInstallTAPInterfacesRollback )) != ERROR_SUCCESS - || (uiResult = setup_sequence(hInstall, TEXT("UninstallTAPInterfaces" ), &seqUninstallTAPInterfaces )) != ERROR_SUCCESS - || (uiResult = setup_sequence(hInstall, TEXT("UninstallTAPInterfacesCommit" ), &seqUninstallTAPInterfacesCommit )) != ERROR_SUCCESS - || (uiResult = setup_sequence(hInstall, TEXT("UninstallTAPInterfacesRollback"), &seqUninstallTAPInterfacesRollback)) != ERROR_SUCCESS) + if ((uiResult = setup_sequence(hInstall, TEXT("InstallTAPAdapters" ), &seqInstallTAPAdapters )) != ERROR_SUCCESS + || (uiResult = setup_sequence(hInstall, TEXT("InstallTAPAdaptersCommit" ), &seqInstallTAPAdaptersCommit )) != ERROR_SUCCESS + || (uiResult = setup_sequence(hInstall, TEXT("InstallTAPAdaptersRollback" ), &seqInstallTAPAdaptersRollback )) != ERROR_SUCCESS + || (uiResult = setup_sequence(hInstall, TEXT("UninstallTAPAdapters" ), &seqUninstallTAPAdapters )) != ERROR_SUCCESS + || (uiResult = setup_sequence(hInstall, TEXT("UninstallTAPAdaptersCommit" ), &seqUninstallTAPAdaptersCommit )) != ERROR_SUCCESS + || (uiResult = setup_sequence(hInstall, TEXT("UninstallTAPAdaptersRollback"), &seqUninstallTAPAdaptersRollback)) != ERROR_SUCCESS) { goto cleanup_hRecordProg; } @@ -964,12 +964,12 @@ cleanup_hViewST: cleanup_hDatabase: MsiCloseHandle(hDatabase); cleanup_exec_seq: - msica_arg_seq_free(&seqInstallTAPInterfaces); - msica_arg_seq_free(&seqInstallTAPInterfacesCommit); - msica_arg_seq_free(&seqInstallTAPInterfacesRollback); - msica_arg_seq_free(&seqUninstallTAPInterfaces); - msica_arg_seq_free(&seqUninstallTAPInterfacesCommit); - msica_arg_seq_free(&seqUninstallTAPInterfacesRollback); + msica_arg_seq_free(&seqInstallTAPAdapters); + msica_arg_seq_free(&seqInstallTAPAdaptersCommit); + msica_arg_seq_free(&seqInstallTAPAdaptersRollback); + msica_arg_seq_free(&seqUninstallTAPAdapters); + msica_arg_seq_free(&seqUninstallTAPAdaptersCommit); + msica_arg_seq_free(&seqUninstallTAPAdaptersRollback); if (bIsCoInitialized) { CoUninitialize(); @@ -1052,13 +1052,13 @@ ProcessDeferredAction(_In_ MSIHANDLE hInstall) if (wcsncmp(szArg[i], L"create=", 7) == 0) { - /* Create an interface with a given name. */ + /* Create an adapter with a given name. */ LPCWSTR szName = szArg[i] + 7; { - /* Report the name of the interface to installer. */ + /* Report the name of the adapter to installer. */ MSIHANDLE hRecord = MsiCreateRecord(3); - MsiRecordSetString(hRecord, 1, TEXT("Creating interface")); + MsiRecordSetString(hRecord, 1, TEXT("Creating adapter")); MsiRecordSetString(hRecord, 2, szName); int iResult = MsiProcessMessage(hInstall, INSTALLMESSAGE_ACTIONDATA, hRecord); MsiCloseHandle(hRecord); @@ -1069,27 +1069,27 @@ ProcessDeferredAction(_In_ MSIHANDLE hInstall) } } - GUID guidInterface; - dwResult = tap_create_interface(NULL, NULL, NULL, &bRebootRequired, &guidInterface); + GUID guidAdapter; + dwResult = tap_create_adapter(NULL, NULL, NULL, &bRebootRequired, &guidAdapter); if (dwResult == ERROR_SUCCESS) { - /* Set interface name. */ - dwResult = tap_set_interface_name(&guidInterface, szName); + /* Set adapter name. */ + dwResult = tap_set_adapter_name(&guidAdapter, szName); if (dwResult != ERROR_SUCCESS) { - tap_delete_interface(NULL, &guidInterface, &bRebootRequired); + tap_delete_adapter(NULL, &guidAdapter, &bRebootRequired); } } } else if (wcsncmp(szArg[i], L"deleteN=", 8) == 0) { - /* Delete the interface by name. */ + /* Delete the adapter by name. */ LPCWSTR szName = szArg[i] + 8; { - /* Report the name of the interface to installer. */ + /* Report the name of the adapter to installer. */ MSIHANDLE hRecord = MsiCreateRecord(3); - MsiRecordSetString(hRecord, 1, TEXT("Deleting interface")); + MsiRecordSetString(hRecord, 1, TEXT("Deleting adapter")); MsiRecordSetString(hRecord, 2, szName); int iResult = MsiProcessMessage(hInstall, INSTALLMESSAGE_ACTIONDATA, hRecord); MsiCloseHandle(hRecord); @@ -1100,54 +1100,54 @@ ProcessDeferredAction(_In_ MSIHANDLE hInstall) } } - /* Get available TUN/TAP interfaces. */ - struct tap_interface_node *pInterfaceList = NULL; - dwResult = tap_list_interfaces(NULL, NULL, &pInterfaceList, FALSE); + /* Get available TUN/TAP adapters. */ + struct tap_adapter_node *pAdapterList = NULL; + dwResult = tap_list_adapters(NULL, NULL, &pAdapterList, FALSE); if (dwResult == ERROR_SUCCESS) { - /* Does the interface exist? */ - for (struct tap_interface_node *pInterface = pInterfaceList; pInterface != NULL; pInterface = pInterface->pNext) + /* Does the adapter exist? */ + for (struct tap_adapter_node *pAdapter = pAdapterList; pAdapter != NULL; pAdapter = pAdapter->pNext) { - if (_tcsicmp(szName, pInterface->szName) == 0) + if (_tcsicmp(szName, pAdapter->szName) == 0) { - /* Interface found. */ - dwResult = tap_delete_interface(NULL, &pInterface->guid, &bRebootRequired); + /* Adapter found. */ + dwResult = tap_delete_adapter(NULL, &pAdapter->guid, &bRebootRequired); break; } } - tap_free_interface_list(pInterfaceList); + tap_free_adapter_list(pAdapterList); } } else if (wcsncmp(szArg[i], L"delete=", 7) == 0) { - /* Delete the interface by GUID. */ + /* Delete the adapter by GUID. */ GUID guid; if (!parse_guid(szArg[i] + 7, &guid)) { goto invalid_argument; } - dwResult = tap_delete_interface(NULL, &guid, &bRebootRequired); + dwResult = tap_delete_adapter(NULL, &guid, &bRebootRequired); } else if (wcsncmp(szArg[i], L"enable=", 7) == 0) { - /* Enable the interface. */ + /* Enable the adapter. */ GUID guid; if (!parse_guid(szArg[i] + 7, &guid)) { goto invalid_argument; } - dwResult = tap_enable_interface(NULL, &guid, TRUE, &bRebootRequired); + dwResult = tap_enable_adapter(NULL, &guid, TRUE, &bRebootRequired); } else if (wcsncmp(szArg[i], L"disable=", 8) == 0) { - /* Disable the interface. */ + /* Disable the adapter. */ GUID guid; if (!parse_guid(szArg[i] + 8, &guid)) { goto invalid_argument; } - dwResult = tap_enable_interface(NULL, &guid, FALSE, &bRebootRequired); + dwResult = tap_enable_adapter(NULL, &guid, FALSE, &bRebootRequired); } else { @@ -1161,7 +1161,7 @@ ProcessDeferredAction(_In_ MSIHANDLE hInstall) } /* Report progress and check for user cancellation. */ - MsiRecordSetInteger(hRecordProg, 2, MSICA_INTERFACE_TICK_SIZE); + MsiRecordSetInteger(hRecordProg, 2, MSICA_ADAPTER_TICK_SIZE); if (MsiProcessMessage(hInstall, INSTALLMESSAGE_PROGRESS, hRecordProg) == IDCANCEL) { dwResult = ERROR_INSTALL_USEREXIT; diff --git a/src/openvpnmsica/openvpnmsica.h b/src/openvpnmsica/openvpnmsica.h index 1486c043..14fb78a2 100644 --- a/src/openvpnmsica/openvpnmsica.h +++ b/src/openvpnmsica/openvpnmsica.h @@ -90,8 +90,9 @@ FindSystemInfo(_In_ MSIHANDLE hInstall); /** - * Find existing TAP interfaces and set TAPINTERFACES property with semicolon delimited list - * of installed TAP interface GUIDs. + * Find existing TAP adapters and set TAPADAPTERS and ACTIVETAPADAPTERS properties with + * semicolon delimited list of all installed TAP adapter GUIDs and active adapter GUIDs + * respectively. * * @param hInstall Handle to the installation provided to the DLL custom action * @@ -99,7 +100,7 @@ FindSystemInfo(_In_ MSIHANDLE hInstall); * See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa368072.aspx */ DLLEXP_DECL UINT __stdcall -FindTAPInterfaces(_In_ MSIHANDLE hInstall); +FindTAPAdapters(_In_ MSIHANDLE hInstall); /** @@ -128,8 +129,8 @@ StartOpenVPNGUI(_In_ MSIHANDLE hInstall); /** - * Evaluate the TAPInterface table of the MSI package database and prepare a list of TAP - * interfaces to install/remove. + * Evaluate the TAPAdapter table of the MSI package database and prepare a list of TAP + * adapters to install/remove. * * @param hInstall Handle to the installation provided to the DLL custom action * @@ -137,7 +138,7 @@ StartOpenVPNGUI(_In_ MSIHANDLE hInstall); * See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa368072.aspx */ DLLEXP_DECL UINT __stdcall -EvaluateTAPInterfaces(_In_ MSIHANDLE hInstall); +EvaluateTAPAdapters(_In_ MSIHANDLE hInstall); /** diff --git a/src/tapctl/main.c b/src/tapctl/main.c index bf215862..1cc86424 100644 --- a/src/tapctl/main.c +++ b/src/tapctl/main.c @@ -1,5 +1,5 @@ /* - * tapctl -- Utility to manipulate TUN/TAP interfaces on Windows + * tapctl -- Utility to manipulate TUN/TAP adapters on Windows * https://community.openvpn.net/openvpn/wiki/Tapctl * * Copyright (C) 2002-2018 OpenVPN Inc @@ -57,9 +57,9 @@ static const TCHAR usage_message[] = TEXT("\n") TEXT("Commands:\n") TEXT("\n") - TEXT("create Create a new TUN/TAP interface\n") - TEXT("list List TUN/TAP interfaces\n") - TEXT("delete Delete specified network interface\n") + TEXT("create Create a new TUN/TAP adapter\n") + TEXT("list List TUN/TAP adapters\n") + TEXT("delete Delete specified network adapter\n") TEXT("help Display this text\n") TEXT("\n") TEXT("Hint: Use \"tapctl help \" to display help for particular command.\n") @@ -68,7 +68,7 @@ static const TCHAR usage_message[] = static const TCHAR usage_message_create[] = TEXT("%s\n") TEXT("\n") - TEXT("Creates a new TUN/TAP interface\n") + TEXT("Creates a new TUN/TAP adapter\n") TEXT("\n") TEXT("Usage:\n") TEXT("\n") @@ -76,23 +76,23 @@ static const TCHAR usage_message_create[] = TEXT("\n") TEXT("Options:\n") TEXT("\n") - TEXT("--name Set TUN/TAP interface name. Should the interface with given name\n") + TEXT("--name Set TUN/TAP adapter name. Should the adapter with given name \n") TEXT(" already exist, an error is returned. If this option is not \n") - TEXT(" specified, a default interface name is chosen by Windows. \n") + TEXT(" specified, a default adapter name is chosen by Windows. \n") TEXT(" Note: This name can also be specified as OpenVPN's --dev-node \n") TEXT(" option. \n") - TEXT("--hwid Interface hardware id. Default value is root\\tap0901, which \n") + TEXT("--hwid Adapter hardware id. Default value is root\\tap0901, which \n") TEXT(" describes tap-windows6 driver. To work with wintun driver, \n") TEXT(" specify 'wintun'. \n") TEXT("Output:\n") TEXT("\n") - TEXT("This command prints newly created TUN/TAP interface's GUID to stdout. \n") + TEXT("This command prints newly created TUN/TAP adapter's GUID to stdout. \n") ; static const TCHAR usage_message_list[] = TEXT("%s\n") TEXT("\n") - TEXT("Lists TUN/TAP interfaces\n") + TEXT("Lists TUN/TAP adapters\n") TEXT("\n") TEXT("Usage:\n") TEXT("\n") @@ -100,22 +100,22 @@ static const TCHAR usage_message_list[] = TEXT("\n") TEXT("Options:\n") TEXT("\n") - TEXT("--hwid Interface hardware id. Default value is root\\tap0901, which \n") + TEXT("--hwid Adapter hardware id. Default value is root\\tap0901, which \n") TEXT(" describes tap-windows6 driver. To work with wintun driver, \n") TEXT(" specify 'wintun'. \n") TEXT("Output:\n") TEXT("\n") - TEXT("This command prints all TUN/TAP interfaces to stdout. \n") + TEXT("This command prints all TUN/TAP adapters to stdout. \n") ; static const TCHAR usage_message_delete[] = TEXT("%s\n") TEXT("\n") - TEXT("Deletes the specified network interface\n") + TEXT("Deletes the specified network adapter\n") TEXT("\n") TEXT("Usage:\n") TEXT("\n") - TEXT("tapctl delete \n") + TEXT("tapctl delete \n") ; @@ -197,75 +197,75 @@ _tmain(int argc, LPCTSTR argv[]) } } - /* Create TUN/TAP interface. */ - GUID guidInterface; - LPOLESTR szInterfaceId = NULL; - DWORD dwResult = tap_create_interface( + /* Create TUN/TAP adapter. */ + GUID guidAdapter; + LPOLESTR szAdapterId = NULL; + DWORD dwResult = tap_create_adapter( NULL, TEXT("Virtual Ethernet"), szHwId, &bRebootRequired, - &guidInterface); + &guidAdapter); if (dwResult != ERROR_SUCCESS) { - _ftprintf(stderr, TEXT("Creating TUN/TAP interface failed (error 0x%x).\n"), dwResult); + _ftprintf(stderr, TEXT("Creating TUN/TAP adapter failed (error 0x%x).\n"), dwResult); iResult = 1; goto quit; } if (szName) { - /* Get the list of all available interfaces. */ - struct tap_interface_node *pInterfaceList = NULL; - dwResult = tap_list_interfaces(NULL, szHwId, &pInterfaceList, TRUE); + /* Get the list of all available adapters. */ + struct tap_adapter_node *pAdapterList = NULL; + dwResult = tap_list_adapters(NULL, szHwId, &pAdapterList, TRUE); if (dwResult != ERROR_SUCCESS) { - _ftprintf(stderr, TEXT("Enumerating interfaces failed (error 0x%x).\n"), dwResult); - iResult = 1; goto create_delete_interface; + _ftprintf(stderr, TEXT("Enumerating adapters failed (error 0x%x).\n"), dwResult); + iResult = 1; goto create_delete_adapter; } /* Check for duplicates. */ - for (struct tap_interface_node *pInterface = pInterfaceList; pInterface; pInterface = pInterface->pNext) + for (struct tap_adapter_node *pAdapter = pAdapterList; pAdapter; pAdapter = pAdapter->pNext) { - if (_tcsicmp(szName, pInterface->szName) == 0) + if (_tcsicmp(szName, pAdapter->szName) == 0) { - StringFromIID((REFIID)&pInterface->guid, &szInterfaceId); - _ftprintf(stderr, TEXT("Interface \"%s\" already exists (GUID %") TEXT(PRIsLPOLESTR) TEXT(").\n"), pInterface->szName, szInterfaceId); - CoTaskMemFree(szInterfaceId); - iResult = 1; goto create_cleanup_pInterfaceList; + StringFromIID((REFIID)&pAdapter->guid, &szAdapterId); + _ftprintf(stderr, TEXT("Adapter \"%s\" already exists (GUID %") TEXT(PRIsLPOLESTR) TEXT(").\n"), pAdapter->szName, szAdapterId); + CoTaskMemFree(szAdapterId); + iResult = 1; goto create_cleanup_pAdapterList; } } - /* Rename the interface. */ - dwResult = tap_set_interface_name(&guidInterface, szName); + /* Rename the adapter. */ + dwResult = tap_set_adapter_name(&guidAdapter, szName); if (dwResult != ERROR_SUCCESS) { - StringFromIID((REFIID)&guidInterface, &szInterfaceId); - _ftprintf(stderr, TEXT("Renaming TUN/TAP interface %") TEXT(PRIsLPOLESTR) TEXT(" to \"%s\" failed (error 0x%x).\n"), szInterfaceId, szName, dwResult); - CoTaskMemFree(szInterfaceId); + StringFromIID((REFIID)&guidAdapter, &szAdapterId); + _ftprintf(stderr, TEXT("Renaming TUN/TAP adapter %") TEXT(PRIsLPOLESTR) TEXT(" to \"%s\" failed (error 0x%x).\n"), szAdapterId, szName, dwResult); + CoTaskMemFree(szAdapterId); iResult = 1; goto quit; } iResult = 0; -create_cleanup_pInterfaceList: - tap_free_interface_list(pInterfaceList); +create_cleanup_pAdapterList: + tap_free_adapter_list(pAdapterList); if (iResult) { - goto create_delete_interface; + goto create_delete_adapter; } } - /* Output interface GUID. */ - StringFromIID((REFIID)&guidInterface, &szInterfaceId); - _ftprintf(stdout, TEXT("%") TEXT(PRIsLPOLESTR) TEXT("\n"), szInterfaceId); - CoTaskMemFree(szInterfaceId); + /* Output adapter GUID. */ + StringFromIID((REFIID)&guidAdapter, &szAdapterId); + _ftprintf(stdout, TEXT("%") TEXT(PRIsLPOLESTR) TEXT("\n"), szAdapterId); + CoTaskMemFree(szAdapterId); iResult = 0; goto quit; -create_delete_interface: - tap_delete_interface( +create_delete_adapter: + tap_delete_adapter( NULL, - &guidInterface, + &guidAdapter, &bRebootRequired); iResult = 1; goto quit; } @@ -286,78 +286,78 @@ create_delete_interface: } } - /* Output list of TUN/TAP interfaces. */ - struct tap_interface_node *pInterfaceList = NULL; - DWORD dwResult = tap_list_interfaces(NULL, szHwId, &pInterfaceList, FALSE); + /* Output list of TUN/TAP adapters. */ + struct tap_adapter_node *pAdapterList = NULL; + DWORD dwResult = tap_list_adapters(NULL, szHwId, &pAdapterList, FALSE); if (dwResult != ERROR_SUCCESS) { - _ftprintf(stderr, TEXT("Enumerating TUN/TAP interfaces failed (error 0x%x).\n"), dwResult); + _ftprintf(stderr, TEXT("Enumerating TUN/TAP adapters failed (error 0x%x).\n"), dwResult); iResult = 1; goto quit; } - for (struct tap_interface_node *pInterface = pInterfaceList; pInterface; pInterface = pInterface->pNext) + for (struct tap_adapter_node *pAdapter = pAdapterList; pAdapter; pAdapter = pAdapter->pNext) { - LPOLESTR szInterfaceId = NULL; - StringFromIID((REFIID)&pInterface->guid, &szInterfaceId); - _ftprintf(stdout, TEXT("%") TEXT(PRIsLPOLESTR) TEXT("\t%") TEXT(PRIsLPTSTR) TEXT("\n"), szInterfaceId, pInterface->szName); - CoTaskMemFree(szInterfaceId); + LPOLESTR szAdapterId = NULL; + StringFromIID((REFIID)&pAdapter->guid, &szAdapterId); + _ftprintf(stdout, TEXT("%") TEXT(PRIsLPOLESTR) TEXT("\t%") TEXT(PRIsLPTSTR) TEXT("\n"), szAdapterId, pAdapter->szName); + CoTaskMemFree(szAdapterId); } iResult = 0; - tap_free_interface_list(pInterfaceList); + tap_free_adapter_list(pAdapterList); } else if (_tcsicmp(argv[1], TEXT("delete")) == 0) { if (argc < 3) { - _ftprintf(stderr, TEXT("Missing interface GUID or name. Please, use \"tapctl help delete\" for usage info.\n")); + _ftprintf(stderr, TEXT("Missing adapter GUID or name. Please, use \"tapctl help delete\" for usage info.\n")); return 1; } - GUID guidInterface; - if (FAILED(IIDFromString(argv[2], (LPIID)&guidInterface))) + GUID guidAdapter; + if (FAILED(IIDFromString(argv[2], (LPIID)&guidAdapter))) { - /* The argument failed to covert to GUID. Treat it as the interface name. */ - struct tap_interface_node *pInterfaceList = NULL; - DWORD dwResult = tap_list_interfaces(NULL, NULL, &pInterfaceList, FALSE); + /* The argument failed to covert to GUID. Treat it as the adapter name. */ + struct tap_adapter_node *pAdapterList = NULL; + DWORD dwResult = tap_list_adapters(NULL, NULL, &pAdapterList, FALSE); if (dwResult != ERROR_SUCCESS) { - _ftprintf(stderr, TEXT("Enumerating TUN/TAP interfaces failed (error 0x%x).\n"), dwResult); + _ftprintf(stderr, TEXT("Enumerating TUN/TAP adapters failed (error 0x%x).\n"), dwResult); iResult = 1; goto quit; } - for (struct tap_interface_node *pInterface = pInterfaceList;; pInterface = pInterface->pNext) + for (struct tap_adapter_node *pAdapter = pAdapterList;; pAdapter = pAdapter->pNext) { - if (pInterface == NULL) + if (pAdapter == NULL) { - _ftprintf(stderr, TEXT("\"%s\" interface not found.\n"), argv[2]); - iResult = 1; goto delete_cleanup_pInterfaceList; + _ftprintf(stderr, TEXT("\"%s\" adapter not found.\n"), argv[2]); + iResult = 1; goto delete_cleanup_pAdapterList; } - else if (_tcsicmp(argv[2], pInterface->szName) == 0) + else if (_tcsicmp(argv[2], pAdapter->szName) == 0) { - memcpy(&guidInterface, &pInterface->guid, sizeof(GUID)); + memcpy(&guidAdapter, &pAdapter->guid, sizeof(GUID)); break; } } iResult = 0; -delete_cleanup_pInterfaceList: - tap_free_interface_list(pInterfaceList); +delete_cleanup_pAdapterList: + tap_free_adapter_list(pAdapterList); if (iResult) { goto quit; } } - /* Delete the network interface. */ - DWORD dwResult = tap_delete_interface( + /* Delete the network adapter. */ + DWORD dwResult = tap_delete_adapter( NULL, - &guidInterface, + &guidAdapter, &bRebootRequired); if (dwResult != ERROR_SUCCESS) { - _ftprintf(stderr, TEXT("Deleting interface \"%s\" failed (error 0x%x).\n"), argv[2], dwResult); + _ftprintf(stderr, TEXT("Deleting adapter \"%s\" failed (error 0x%x).\n"), argv[2], dwResult); iResult = 1; goto quit; } diff --git a/src/tapctl/tap.c b/src/tapctl/tap.c index d4631679..d718d43e 100644 --- a/src/tapctl/tap.c +++ b/src/tapctl/tap.c @@ -1,5 +1,5 @@ /* - * tapctl -- Utility to manipulate TUN/TAP interfaces on Windows + * tapctl -- Utility to manipulate TUN/TAP adapters on Windows * https://community.openvpn.net/openvpn/wiki/Tapctl * * Copyright (C) 2018-2020 Simon Rozman @@ -44,8 +44,8 @@ const static GUID GUID_DEVCLASS_NET = { 0x4d36e972L, 0xe325, 0x11ce, { 0xbf, 0xc const static TCHAR szzDefaultHardwareIDs[] = TEXT("root\\") TEXT(TAP_WIN_COMPONENT_ID) TEXT("\0"); -const static TCHAR szInterfaceRegKeyPathTemplate[] = TEXT("SYSTEM\\CurrentControlSet\\Control\\Network\\%") TEXT(PRIsLPOLESTR) TEXT("\\%") TEXT(PRIsLPOLESTR) TEXT("\\Connection"); -#define INTERFACE_REGKEY_PATH_MAX (_countof(TEXT("SYSTEM\\CurrentControlSet\\Control\\Network\\")) - 1 + 38 + _countof(TEXT("\\")) - 1 + 38 + _countof(TEXT("\\Connection"))) +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"))) /** @@ -60,7 +60,7 @@ const static TCHAR szInterfaceRegKeyPathTemplate[] = TEXT("SYSTEM\\CurrentContro * @param pbRebootRequired A pointer to a BOOL flag. If the device requires a system restart, * this flag is set to TRUE. Otherwise, the flag is left unmodified. This * allows the flag to be globally initialized to FALSE and reused for multiple - * interface manipulations. + * adapter manipulations. * * @return ERROR_SUCCESS on success; Win32 error code otherwise **/ @@ -82,7 +82,7 @@ typedef DWORD (*devop_func_t)( * @param pbRebootRequired A pointer to a BOOL flag. If the device requires a system restart, * this flag is set to TRUE. Otherwise, the flag is left unmodified. This * allows the flag to be globally initialized to FALSE and reused for multiple - * interface manipulations. + * adapter manipulations. * * @return ERROR_SUCCESS on success; Win32 error code otherwise **/ @@ -129,7 +129,7 @@ check_reboot( * @param pbRebootRequired A pointer to a BOOL flag. If the device requires a system restart, * this flag is set to TRUE. Otherwise, the flag is left unmodified. This * allows the flag to be globally initialized to FALSE and reused for multiple - * interface manipulations. + * adapter manipulations. * * @return ERROR_SUCCESS on success; Win32 error code otherwise **/ @@ -193,7 +193,7 @@ delete_device( * @param pbRebootRequired A pointer to a BOOL flag. If the device requires a system restart, * this flag is set to TRUE. Otherwise, the flag is left unmodified. This * allows the flag to be globally initialized to FALSE and reused for multiple - * interface manipulations. + * adapter manipulations. * * @return ERROR_SUCCESS on success; Win32 error code otherwise **/ @@ -257,7 +257,7 @@ change_device_state( * @param pbRebootRequired A pointer to a BOOL flag. If the device requires a system restart, * this flag is set to TRUE. Otherwise, the flag is left unmodified. This * allows the flag to be globally initialized to FALSE and reused for multiple - * interface manipulations. + * adapter manipulations. * * @return ERROR_SUCCESS on success; Win32 error code otherwise **/ @@ -283,7 +283,7 @@ enable_device( * @param pbRebootRequired A pointer to a BOOL flag. If the device requires a system restart, * this flag is set to TRUE. Otherwise, the flag is left unmodified. This * allows the flag to be globally initialized to FALSE and reused for multiple - * interface manipulations. + * adapter manipulations. * * @return ERROR_SUCCESS on success; Win32 error code otherwise **/ @@ -444,7 +444,7 @@ get_reg_string( /** - * Returns network interface ID. + * Returns network adapter ID. * * @param hDeviceInfoSet A handle to a device information set that contains a device * information element that represents the device. @@ -457,20 +457,20 @@ get_reg_string( * attempts to read NetCfgInstanceId value from registry. A 1sec sleep * is inserted between retry attempts. * - * @param pguidInterface A pointer to GUID that receives network interface ID. + * @param pguidAdapter A pointer to GUID that receives network adapter ID. * * @return ERROR_SUCCESS on success; Win32 error code otherwise **/ static DWORD -get_net_interface_guid( +get_net_adapter_guid( _In_ HDEVINFO hDeviceInfoSet, _In_ PSP_DEVINFO_DATA pDeviceInfoData, _In_ int iNumAttempts, - _Out_ LPGUID pguidInterface) + _Out_ LPGUID pguidAdapter) { DWORD dwResult = ERROR_BAD_ARGUMENTS; - if (pguidInterface == NULL || iNumAttempts < 1) + if (pguidAdapter == NULL || iNumAttempts < 1) { return ERROR_BAD_ARGUMENTS; } @@ -519,7 +519,7 @@ get_net_interface_guid( break; } - dwResult = SUCCEEDED(CLSIDFromString(szCfgGuidString, (LPCLSID)pguidInterface)) ? ERROR_SUCCESS : ERROR_INVALID_DATA; + dwResult = SUCCEEDED(CLSIDFromString(szCfgGuidString, (LPCLSID)pguidAdapter)) ? ERROR_SUCCESS : ERROR_INVALID_DATA; free(szCfgGuidString); break; } @@ -647,17 +647,17 @@ _tcszlen(_In_ LPCTSTR str) DWORD -tap_create_interface( +tap_create_adapter( _In_opt_ HWND hwndParent, _In_opt_ LPCTSTR szDeviceDescription, _In_opt_ LPCTSTR szHwId, _Inout_ LPBOOL pbRebootRequired, - _Out_ LPGUID pguidInterface) + _Out_ LPGUID pguidAdapter) { DWORD dwResult; if (pbRebootRequired == NULL - || pguidInterface == NULL) + || pguidAdapter == NULL) { return ERROR_BAD_ARGUMENTS; } @@ -876,7 +876,7 @@ tap_create_interface( msg(M_WARN | M_ERRNO, "%s: SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS) failed", __FUNCTION__); } - /* Install interfaces if any. */ + /* Install adapters if any. */ if (!SetupDiCallClassInstaller( DIF_INSTALLINTERFACES, hDevInfoList, @@ -900,13 +900,13 @@ tap_create_interface( /* Check if a system reboot is required. (Ignore errors) */ check_reboot(hDevInfoList, &devinfo_data, pbRebootRequired); - /* Get network interface ID from registry. Retry for max 30sec. */ - dwResult = get_net_interface_guid(hDevInfoList, &devinfo_data, 30, pguidInterface); + /* Get network adapter ID from registry. Retry for max 30sec. */ + dwResult = get_net_adapter_guid(hDevInfoList, &devinfo_data, 30, pguidAdapter); cleanup_remove_device: if (dwResult != ERROR_SUCCESS) { - /* The interface was installed. But, the interface ID was unobtainable. Clean-up. */ + /* The adapter was installed. But, the adapter ID was unobtainable. Clean-up. */ SP_REMOVEDEVICE_PARAMS removedevice_params = { .ClassInstallHeader = @@ -958,35 +958,35 @@ cleanup_hDevInfoList: /** - * Performs a given task on an interface. + * Performs a given task on an adapter. * - * @param hwndParent A handle to the top-level window to use for any user interface that is + * @param hwndParent A handle to the top-level window to use for any user adapter that is * related to non-device-specific actions (such as a select-device dialog * box that uses the global class driver list). This handle is optional * and can be NULL. If a specific top-level window is not required, set * hwndParent to NULL. * - * @param pguidInterface A pointer to GUID that contains network interface ID. + * @param pguidAdapter A pointer to GUID that contains network adapter ID. * - * @param funcOperation A pointer for the function to perform specific task on the interface. + * @param funcOperation A pointer for the function to perform specific task on the adapter. * * @param pbRebootRequired A pointer to a BOOL flag. If the device requires a system restart, * this flag is set to TRUE. Otherwise, the flag is left unmodified. This * allows the flag to be globally initialized to FALSE and reused for multiple - * interface manipulations. + * adapter manipulations. * * @return ERROR_SUCCESS on success; Win32 error code otherwise **/ static DWORD -execute_on_first_interface( +execute_on_first_adapter( _In_opt_ HWND hwndParent, - _In_ LPCGUID pguidInterface, + _In_ LPCGUID pguidAdapter, _In_ devop_func_t funcOperation, _Inout_ LPBOOL pbRebootRequired) { DWORD dwResult; - if (pguidInterface == NULL) + if (pguidAdapter == NULL) { return ERROR_BAD_ARGUMENTS; } @@ -1028,10 +1028,10 @@ execute_on_first_interface( { if (GetLastError() == ERROR_NO_MORE_ITEMS) { - LPOLESTR szInterfaceId = NULL; - StringFromIID((REFIID)pguidInterface, &szInterfaceId); - msg(M_NONFATAL, "%s: Interface %" PRIsLPOLESTR " not found", __FUNCTION__, szInterfaceId); - CoTaskMemFree(szInterfaceId); + LPOLESTR szAdapterId = NULL; + StringFromIID((REFIID)pguidAdapter, &szAdapterId); + msg(M_NONFATAL, "%s: Adapter %" PRIsLPOLESTR " not found", __FUNCTION__, szAdapterId); + CoTaskMemFree(szAdapterId); dwResult = ERROR_FILE_NOT_FOUND; goto cleanup_hDevInfoList; } @@ -1043,9 +1043,9 @@ execute_on_first_interface( } } - /* Get interface GUID. */ - GUID guidInterface; - dwResult = get_net_interface_guid(hDevInfoList, &devinfo_data, 1, &guidInterface); + /* Get adapter GUID. */ + GUID guidAdapter; + dwResult = get_net_adapter_guid(hDevInfoList, &devinfo_data, 1, &guidAdapter); if (dwResult != ERROR_SUCCESS) { /* Something is wrong with this device. Skip it. */ @@ -1053,7 +1053,7 @@ execute_on_first_interface( } /* Compare GUIDs. */ - if (memcmp(pguidInterface, &guidInterface, sizeof(GUID)) == 0) + if (memcmp(pguidAdapter, &guidAdapter, sizeof(GUID)) == 0) { dwResult = funcOperation(hDevInfoList, &devinfo_data, pbRebootRequired); break; @@ -1067,34 +1067,34 @@ cleanup_hDevInfoList: DWORD -tap_delete_interface( +tap_delete_adapter( _In_opt_ HWND hwndParent, - _In_ LPCGUID pguidInterface, + _In_ LPCGUID pguidAdapter, _Inout_ LPBOOL pbRebootRequired) { - return execute_on_first_interface(hwndParent, pguidInterface, delete_device, pbRebootRequired); + return execute_on_first_adapter(hwndParent, pguidAdapter, delete_device, pbRebootRequired); } DWORD -tap_enable_interface( +tap_enable_adapter( _In_opt_ HWND hwndParent, - _In_ LPCGUID pguidInterface, + _In_ LPCGUID pguidAdapter, _In_ BOOL bEnable, _Inout_ LPBOOL pbRebootRequired) { - return execute_on_first_interface(hwndParent, pguidInterface, bEnable ? enable_device : disable_device, pbRebootRequired); + return execute_on_first_adapter(hwndParent, pguidAdapter, bEnable ? enable_device : disable_device, pbRebootRequired); } DWORD -tap_set_interface_name( - _In_ LPCGUID pguidInterface, +tap_set_adapter_name( + _In_ LPCGUID pguidAdapter, _In_ LPCTSTR szName) { DWORD dwResult; - if (pguidInterface == NULL || szName == NULL) + if (pguidAdapter == NULL || szName == NULL) { return ERROR_BAD_ARGUMENTS; } @@ -1103,19 +1103,19 @@ tap_set_interface_name( LPOLESTR szDevClassNetId = NULL; StringFromIID((REFIID)&GUID_DEVCLASS_NET, &szDevClassNetId); - /* Get the interface GUID as string. */ - LPOLESTR szInterfaceId = NULL; - StringFromIID((REFIID)pguidInterface, &szInterfaceId); + /* Get the adapter GUID as string. */ + LPOLESTR szAdapterId = NULL; + StringFromIID((REFIID)pguidAdapter, &szAdapterId); /* Render registry key path. */ - TCHAR szRegKey[INTERFACE_REGKEY_PATH_MAX]; + TCHAR szRegKey[ADAPTER_REGKEY_PATH_MAX]; _stprintf_s( szRegKey, _countof(szRegKey), - szInterfaceRegKeyPathTemplate, + szAdapterRegKeyPathTemplate, szDevClassNetId, - szInterfaceId); + szAdapterId); - /* Open network interface registry key. */ + /* Open network adapter registry key. */ HKEY hKey = NULL; dwResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE, @@ -1127,10 +1127,10 @@ tap_set_interface_name( { SetLastError(dwResult); /* MSDN does not mention RegOpenKeyEx() to set GetLastError(). But we do have an error code. Set last error manually. */ msg(M_NONFATAL | M_ERRNO, "%s: RegOpenKeyEx(HKLM, \"%" PRIsLPTSTR "\") failed", __FUNCTION__, szRegKey); - goto cleanup_szInterfaceId; + goto cleanup_szAdapterId; } - /* Set the interface name. */ + /* Set the adapter name. */ size_t sizeName = ((_tcslen(szName) + 1) * sizeof(TCHAR)); #ifdef _WIN64 if (sizeName > DWORD_MAX) @@ -1156,23 +1156,23 @@ tap_set_interface_name( cleanup_hKey: RegCloseKey(hKey); -cleanup_szInterfaceId: - CoTaskMemFree(szInterfaceId); +cleanup_szAdapterId: + CoTaskMemFree(szAdapterId); CoTaskMemFree(szDevClassNetId); return dwResult; } DWORD -tap_list_interfaces( +tap_list_adapters( _In_opt_ HWND hwndParent, _In_opt_ LPCTSTR szHwId, - _Out_ struct tap_interface_node **ppInterface, + _Out_ struct tap_adapter_node **ppAdapter, _In_ BOOL bAll) { DWORD dwResult; - if (ppInterface == NULL) + if (ppAdapter == NULL) { return ERROR_BAD_ARGUMENTS; } @@ -1212,8 +1212,8 @@ tap_list_interfaces( StringFromIID((REFIID)&GUID_DEVCLASS_NET, &szDevClassNetId); /* Iterate. */ - *ppInterface = NULL; - struct tap_interface_node *pInterfaceTail = NULL; + *ppAdapter = NULL; + struct tap_adapter_node *pAdapterTail = NULL; for (DWORD dwIndex = 0;; dwIndex++) { /* Get the device from the list. */ @@ -1284,28 +1284,28 @@ tap_list_interfaces( goto cleanup_szzDeviceHardwareIDs; } - /* Get interface GUID. */ - GUID guidInterface; - dwResult = get_net_interface_guid(hDevInfoList, &devinfo_data, 1, &guidInterface); + /* Get adapter GUID. */ + GUID guidAdapter; + dwResult = get_net_adapter_guid(hDevInfoList, &devinfo_data, 1, &guidAdapter); if (dwResult != ERROR_SUCCESS) { /* Something is wrong with this device. Skip it. */ goto cleanup_szzDeviceHardwareIDs; } - /* Get the interface GUID as string. */ - LPOLESTR szInterfaceId = NULL; - StringFromIID((REFIID)&guidInterface, &szInterfaceId); + /* Get the adapter GUID as string. */ + LPOLESTR szAdapterId = NULL; + StringFromIID((REFIID)&guidAdapter, &szAdapterId); /* Render registry key path. */ - TCHAR szRegKey[INTERFACE_REGKEY_PATH_MAX]; + TCHAR szRegKey[ADAPTER_REGKEY_PATH_MAX]; _stprintf_s( szRegKey, _countof(szRegKey), - szInterfaceRegKeyPathTemplate, + szAdapterRegKeyPathTemplate, szDevClassNetId, - szInterfaceId); + szAdapterId); - /* Open network interface registry key. */ + /* Open network adapter registry key. */ HKEY hKey = NULL; dwResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE, @@ -1317,10 +1317,10 @@ tap_list_interfaces( { SetLastError(dwResult); /* MSDN does not mention RegOpenKeyEx() to set GetLastError(). But we do have an error code. Set last error manually. */ msg(M_WARN | M_ERRNO, "%s: RegOpenKeyEx(HKLM, \"%" PRIsLPTSTR "\") failed", __FUNCTION__, szRegKey); - goto cleanup_szInterfaceId; + goto cleanup_szAdapterId; } - /* Read interface name. */ + /* Read adapter name. */ LPTSTR szName = NULL; dwResult = get_reg_string( hKey, @@ -1329,42 +1329,42 @@ tap_list_interfaces( if (dwResult != ERROR_SUCCESS) { SetLastError(dwResult); - msg(M_WARN | M_ERRNO, "%s: Cannot determine %" PRIsLPOLESTR " interface name", __FUNCTION__, szInterfaceId); + msg(M_WARN | M_ERRNO, "%s: Cannot determine %" PRIsLPOLESTR " adapter name", __FUNCTION__, szAdapterId); goto cleanup_hKey; } /* Append to the list. */ size_t hwid_size = (_tcszlen(szzDeviceHardwareIDs) + 1) * sizeof(TCHAR); size_t name_size = (_tcslen(szName) + 1) * sizeof(TCHAR); - struct tap_interface_node *node = (struct tap_interface_node *)malloc(sizeof(struct tap_interface_node) + hwid_size + name_size); + struct tap_adapter_node *node = (struct tap_adapter_node *)malloc(sizeof(struct tap_adapter_node) + hwid_size + name_size); if (node == NULL) { - msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct tap_interface_node) + hwid_size + name_size); + msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct tap_adapter_node) + hwid_size + name_size); dwResult = ERROR_OUTOFMEMORY; goto cleanup_szName; } - memcpy(&node->guid, &guidInterface, sizeof(GUID)); + memcpy(&node->guid, &guidAdapter, sizeof(GUID)); node->szzHardwareIDs = (LPTSTR)(node + 1); memcpy(node->szzHardwareIDs, szzDeviceHardwareIDs, hwid_size); node->szName = (LPTSTR)((LPBYTE)node->szzHardwareIDs + hwid_size); memcpy(node->szName, szName, name_size); node->pNext = NULL; - if (pInterfaceTail) + if (pAdapterTail) { - pInterfaceTail->pNext = node; - pInterfaceTail = node; + pAdapterTail->pNext = node; + pAdapterTail = node; } else { - *ppInterface = pInterfaceTail = node; + *ppAdapter = pAdapterTail = node; } cleanup_szName: free(szName); cleanup_hKey: RegCloseKey(hKey); -cleanup_szInterfaceId: - CoTaskMemFree(szInterfaceId); +cleanup_szAdapterId: + CoTaskMemFree(szAdapterId); cleanup_szzDeviceHardwareIDs: free(szzDeviceHardwareIDs); } @@ -1379,16 +1379,16 @@ cleanup_hDevInfoList: void -tap_free_interface_list( - _In_ struct tap_interface_node *pInterfaceList) +tap_free_adapter_list( + _In_ struct tap_adapter_node *pAdapterList) { /* Iterate over all nodes of the list. */ - while (pInterfaceList) + while (pAdapterList) { - struct tap_interface_node *node = pInterfaceList; - pInterfaceList = pInterfaceList->pNext; + struct tap_adapter_node *node = pAdapterList; + pAdapterList = pAdapterList->pNext; - /* Free the interface node. */ + /* Free the adapter node. */ free(node); } } diff --git a/src/tapctl/tap.h b/src/tapctl/tap.h index 4c2d73ba..aec44ec8 100644 --- a/src/tapctl/tap.h +++ b/src/tapctl/tap.h @@ -1,5 +1,5 @@ /* - * tapctl -- Utility to manipulate TUN/TAP interfaces on Windows + * tapctl -- Utility to manipulate TUN/TAP adapters on Windows * https://community.openvpn.net/openvpn/wiki/Tapctl * * Copyright (C) 2018-2020 Simon Rozman @@ -26,9 +26,9 @@ /** - * Creates a TUN/TAP interface. + * Creates a TUN/TAP adapter. * - * @param hwndParent A handle to the top-level window to use for any user interface that is + * @param hwndParent A handle to the top-level window to use for any user adapter that is * related to non-device-specific actions (such as a select-device dialog * box that uses the global class driver list). This handle is optional * and can be NULL. If a specific top-level window is not required, set @@ -44,106 +44,106 @@ * @param pbRebootRequired A pointer to a BOOL flag. If the device requires a system restart, * this flag is set to TRUE. Otherwise, the flag is left unmodified. This * allows the flag to be globally initialized to FALSE and reused for multiple - * interface manipulations. + * adapter manipulations. * - * @param pguidInterface A pointer to GUID that receives network interface ID. + * @param pguidAdapter A pointer to GUID that receives network adapter ID. * * @return ERROR_SUCCESS on success; Win32 error code otherwise **/ DWORD -tap_create_interface( +tap_create_adapter( _In_opt_ HWND hwndParent, _In_opt_ LPCTSTR szDeviceDescription, _In_opt_ LPCTSTR szHwId, _Inout_ LPBOOL pbRebootRequired, - _Out_ LPGUID pguidInterface); + _Out_ LPGUID pguidAdapter); /** - * Deletes an interface. + * Deletes an adapter. * - * @param hwndParent A handle to the top-level window to use for any user interface that is + * @param hwndParent A handle to the top-level window to use for any user adapter that is * related to non-device-specific actions (such as a select-device dialog * box that uses the global class driver list). This handle is optional * and can be NULL. If a specific top-level window is not required, set * hwndParent to NULL. * - * @param pguidInterface A pointer to GUID that contains network interface ID. + * @param pguidAdapter A pointer to GUID that contains network adapter ID. * * @param pbRebootRequired A pointer to a BOOL flag. If the device requires a system restart, * this flag is set to TRUE. Otherwise, the flag is left unmodified. This * allows the flag to be globally initialized to FALSE and reused for multiple - * interface manipulations. + * adapter manipulations. * * @return ERROR_SUCCESS on success; Win32 error code otherwise **/ DWORD -tap_delete_interface( +tap_delete_adapter( _In_opt_ HWND hwndParent, - _In_ LPCGUID pguidInterface, + _In_ LPCGUID pguidAdapter, _Inout_ LPBOOL pbRebootRequired); /** - * Enables or disables an interface. + * Enables or disables an adapter. * - * @param hwndParent A handle to the top-level window to use for any user interface that is + * @param hwndParent A handle to the top-level window to use for any user adapter that is * related to non-device-specific actions (such as a select-device dialog * box that uses the global class driver list). This handle is optional * and can be NULL. If a specific top-level window is not required, set * hwndParent to NULL. * - * @param pguidInterface A pointer to GUID that contains network interface ID. + * @param pguidAdapter A pointer to GUID that contains network adapter ID. * * @param bEnable TRUE to enable; FALSE to disable * * @param pbRebootRequired A pointer to a BOOL flag. If the device requires a system restart, * this flag is set to TRUE. Otherwise, the flag is left unmodified. This * allows the flag to be globally initialized to FALSE and reused for multiple - * interface manipulations. + * adapter manipulations. * * @return ERROR_SUCCESS on success; Win32 error code otherwise **/ DWORD -tap_enable_interface( +tap_enable_adapter( _In_opt_ HWND hwndParent, - _In_ LPCGUID pguidInterface, + _In_ LPCGUID pguidAdapter, _In_ BOOL bEnable, _Inout_ LPBOOL pbRebootRequired); /** - * Sets interface name. + * Sets adapter name. * - * @param pguidInterface A pointer to GUID that contains network interface ID. + * @param pguidAdapter A pointer to GUID that contains network adapter ID. * - * @param szName New interface name - must be unique + * @param szName New adapter name - must be unique * * @return ERROR_SUCCESS on success; Win32 error code otherwise **/ DWORD -tap_set_interface_name( - _In_ LPCGUID pguidInterface, +tap_set_adapter_name( + _In_ LPCGUID pguidAdapter, _In_ LPCTSTR szName); /** - * Network interface list node + * Network adapter list node */ -struct tap_interface_node +struct tap_adapter_node { - GUID guid; /** Interface GUID */ + GUID guid; /** Adapter GUID */ LPTSTR szzHardwareIDs; /** Device hardware ID(s) */ - LPTSTR szName; /** Interface name */ + LPTSTR szName; /** Adapter name */ - struct tap_interface_node *pNext; /** Pointer to next interface */ + struct tap_adapter_node *pNext; /** Pointer to next adapter */ }; /** - * Creates a list of available network interfaces. + * Creates a list of available network adapters. * - * @param hwndParent A handle to the top-level window to use for any user interface that is + * @param hwndParent A handle to the top-level window to use for any user adapter that is * related to non-device-specific actions (such as a select-device dialog * box that uses the global class driver list). This handle is optional * and can be NULL. If a specific top-level window is not required, set @@ -153,30 +153,30 @@ struct tap_interface_node * of the device. This pointer is optional and can be NULL. Default value * is root\tap0901. * - * @param ppInterfaceList A pointer to the list to receive pointer to the first interface in + * @param ppAdapterList A pointer to the list to receive pointer to the first adapter in * the list. After the list is no longer required, free it using - * tap_free_interface_list(). + * tap_free_adapter_list(). * - * @param bAll When TRUE, all network interfaces found are added to the list. When - * FALSE, only TUN/TAP interfaces found are added. + * @param bAll When TRUE, all network adapters found are added to the list. When + * FALSE, only TUN/TAP adapters found are added. * * @return ERROR_SUCCESS on success; Win32 error code otherwise */ DWORD -tap_list_interfaces( +tap_list_adapters( _In_opt_ HWND hwndParent, _In_opt_ LPCTSTR szHwId, - _Out_ struct tap_interface_node **ppInterfaceList, + _Out_ struct tap_adapter_node **ppAdapterList, _In_ BOOL bAll); /** - * Frees a list of network interfaces. + * Frees a list of network adapters. * - * @param pInterfaceList A pointer to the first interface in the list to free. + * @param pAdapterList A pointer to the first adapter in the list to free. */ void -tap_free_interface_list( - _In_ struct tap_interface_node *pInterfaceList); +tap_free_adapter_list( + _In_ struct tap_adapter_node *pAdapterList); #endif /* ifndef TAP_H */ diff --git a/src/tapctl/tapctl_resources.rc b/src/tapctl/tapctl_resources.rc index f6f3cb75..2b3ff238 100644 --- a/src/tapctl/tapctl_resources.rc +++ b/src/tapctl/tapctl_resources.rc @@ -1,5 +1,5 @@ /* - * tapctl -- Utility to manipulate TUN/TAP interfaces on Windows + * tapctl -- Utility to manipulate TUN/TAP adapters on Windows * * Copyright (C) 2018 Simon Rozman * @@ -46,7 +46,7 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "The OpenVPN Project" - VALUE "FileDescription", "Utility to manipulate TUN/TAP interfaces on Windows" + VALUE "FileDescription", "Utility to manipulate TUN/TAP adapters on Windows" VALUE "FileVersion", PACKAGE_VERSION ".0" VALUE "InternalName", "OpenVPN" VALUE "LegalCopyright", "Copyright © The OpenVPN Project" From patchwork Mon Mar 9 02:17:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Rozman X-Patchwork-Id: 1024 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director12.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id MJDCE1JCZl6tHAAAIUCqbw for ; Mon, 09 Mar 2020 09:19:14 -0400 Received: from proxy8.mail.ord1d.rsapps.net ([172.30.191.6]) by director12.mail.ord1d.rsapps.net with LMTP id UHuUE1JCZl7HUAAAIasKDg ; Mon, 09 Mar 2020 09:19:14 -0400 Received: from smtp7.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy8.mail.ord1d.rsapps.net with LMTP id uPDQElJCZl5TQQAAGdz6CA ; Mon, 09 Mar 2020 09:19:14 -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: smtp7.gate.ord1d.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=rozman.si; dmarc=fail (p=none; dis=none) header.from=rozman.si X-Suspicious-Flag: YES X-Classification-ID: 91a8bd3e-6208-11ea-81be-525400d0c497-1-1 Received: from [216.105.38.7] ([216.105.38.7:46194] helo=lists.sourceforge.net) by smtp7.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 1C/F1-11674-152466E5; Mon, 09 Mar 2020 09:19:13 -0400 Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1jBIIj-0005wt-Ba; Mon, 09 Mar 2020 13:18:33 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jBIIg-0005wK-Bg for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:30 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=CpwbTGZK9FtSSF4q6ca1+RxN0MS8IQl3jGQYu/k3cp4=; b=Y/otBFulDeWq3D9JelAjdI76/N e1+HUyvNrzSpuyPyN4CzJCixo0/QS1AfMvj+UBhDdiRAOpYkHi4KjZ9ecfFVrjK+ISZkQ84GjDtFW /pMQ4wLgLjobW6cGz//74OGml7V/RE2yzF5HZrQ8SFEQo2U8hQqJH3vSefT0maC4ffhM=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=CpwbTGZK9FtSSF4q6ca1+RxN0MS8IQl3jGQYu/k3cp4=; b=Aox7wL9khvES3eX41Vy370WQ79 5CFwe9LhJxX1Y3AQxpGYur3bF8OqZT1csQBsCQdEs/+hyA98Q1jFj6O/GyxQ9YYNe5+hq52X1IQse 8vw2KKPiLr6iSeXPg2jOtHnK0HT0kgIzZaIH5mfqBZVBA58ZflpxEWb12034KmCR1BgQ=; Received: from pub5.amebis.si ([213.250.55.21]) by sfi-mx-4.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1jBIIc-006jrl-QI for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:30 +0000 Received: by pub5.amebis.si (Postfix, from userid 1000) id CCAD01002B60; Mon, 9 Mar 2020 14:18:00 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rozman.si; s=default; t=1583759880; bh=CpwbTGZK9FtSSF4q6ca1+RxN0MS8IQl3jGQYu/k3cp4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hTgx3uyC5X4xC8XvBkhK+EexF1zlkzPjH2ZfV4HDhbqGd4aHs2XPSXG47BIANo6o+ dBiUmhs2oObGyq1/zps2tXz8zAHgXLqgnDcArjnID/G72MDAYo2IFrW+Bb7UumAIc0 WTR9nKczG8DSenSYyqGHtgJwUOOuINQLt8sV2HeA= X-Spam-Checker-Version: SpamAssassin 3.4.3 (2019-12-06) on brana.amebis.doma X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00, WEIRD_QUOTING autolearn=ham autolearn_force=no version=3.4.3 Received: from SR6.amebis.doma (unknown [IPv6:2a00:ee2:209:164:a5ae:e83c:b7b:725]) by pub5.amebis.si (Postfix) with ESMTP id 7EE1F1002FC7; Mon, 9 Mar 2020 14:17:49 +0100 (CET) From: Simon Rozman To: openvpn-devel@lists.sourceforge.net Date: Mon, 9 Mar 2020 14:17:24 +0100 Message-Id: <20200309131728.380-8-simon@rozman.si> X-Mailer: git-send-email 2.24.1.windows.2 In-Reply-To: <20200309131728.380-1-simon@rozman.si> References: <20200309131728.380-1-simon@rozman.si> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 WEIRD_QUOTING BODY: Weird repeated double-quotation marks -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 -0.0 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1jBIIc-006jrl-QI Subject: [Openvpn-devel] [PATCH 08/12] openvpnmsica: "TAP" => "TUN/TAP" 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: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox The function and property names that are common to TAP and TUN from TAP-Windows6 and TUN from Wintun were renamed not to make the now mainstream TUN sad. I would have go with just the "adapter". But, wouldn't that cause confusion when user sees "Deleting adapters" when uninstalling the OpenVPN? Internal variable names were simplified thou to omit the TUN/TAP referencing. Signed-off-by: Simon Rozman Acked-by: Lev Stipakov --- src/openvpnmsica/openvpnmsica.c | 156 ++++++++++++++++---------------- src/openvpnmsica/openvpnmsica.h | 8 +- 2 files changed, 82 insertions(+), 82 deletions(-) diff --git a/src/openvpnmsica/openvpnmsica.c b/src/openvpnmsica/openvpnmsica.c index 1438d3f7..4223b680 100644 --- a/src/openvpnmsica/openvpnmsica.c +++ b/src/openvpnmsica/openvpnmsica.c @@ -272,7 +272,7 @@ FindSystemInfo(_In_ MSIHANDLE hInstall) UINT __stdcall -FindTAPAdapters(_In_ MSIHANDLE hInstall) +FindTUNTAPAdapters(_In_ MSIHANDLE hInstall) { #ifdef _MSC_VER #pragma comment(linker, DLLEXP_EXPORT) @@ -337,21 +337,21 @@ FindTAPAdapters(_In_ MSIHANDLE hInstall) /* Prepare semicolon delimited list of TAP adapter ID(s) and active TAP adapter ID(s). */ LPTSTR - szTAPAdapters = (LPTSTR)malloc(adapter_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)), - szTAPAdaptersTail = szTAPAdapters; - if (szTAPAdapters == NULL) + szAdapters = (LPTSTR)malloc(adapter_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)), + szAdaptersTail = szAdapters; + if (szAdapters == NULL) { msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, adapter_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)); uiResult = ERROR_OUTOFMEMORY; goto cleanup_pAdapterAdresses; } LPTSTR - szTAPAdaptersActive = (LPTSTR)malloc(adapter_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)), - szTAPAdaptersActiveTail = szTAPAdaptersActive; - if (szTAPAdaptersActive == NULL) + szAdaptersActive = (LPTSTR)malloc(adapter_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)), + szAdaptersActiveTail = szAdaptersActive; + if (szAdaptersActive == NULL) { msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, adapter_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)); - uiResult = ERROR_OUTOFMEMORY; goto cleanup_szTAPAdapters; + uiResult = ERROR_OUTOFMEMORY; goto cleanup_szAdapters; } for (struct tap_adapter_node *pAdapter = pAdapterList; pAdapter; pAdapter = pAdapter->pNext) @@ -361,12 +361,12 @@ FindTAPAdapters(_In_ MSIHANDLE hInstall) StringFromIID((REFIID)&pAdapter->guid, &szAdapterId); /* Append to the list of TAP adapter ID(s). */ - if (szTAPAdapters < szTAPAdaptersTail) + if (szAdapters < szAdaptersTail) { - *(szTAPAdaptersTail++) = TEXT(';'); + *(szAdaptersTail++) = TEXT(';'); } - memcpy(szTAPAdaptersTail, szAdapterId, 38 * sizeof(TCHAR)); - szTAPAdaptersTail += 38; + memcpy(szAdaptersTail, szAdapterId, 38 * sizeof(TCHAR)); + szAdaptersTail += 38; /* If this adapter is active (connected), add it to the list of active TAP adapter ID(s). */ for (PIP_ADAPTER_ADDRESSES p = pAdapterAdresses; p; p = p->Next) @@ -380,43 +380,43 @@ FindTAPAdapters(_In_ MSIHANDLE hInstall) if (p->OperStatus == IfOperStatusUp) { /* This TAP adapter is active (connected). */ - if (szTAPAdaptersActive < szTAPAdaptersActiveTail) + if (szAdaptersActive < szAdaptersActiveTail) { - *(szTAPAdaptersActiveTail++) = TEXT(';'); + *(szAdaptersActiveTail++) = TEXT(';'); } - memcpy(szTAPAdaptersActiveTail, szAdapterId, 38 * sizeof(TCHAR)); - szTAPAdaptersActiveTail += 38; + memcpy(szAdaptersActiveTail, szAdapterId, 38 * sizeof(TCHAR)); + szAdaptersActiveTail += 38; } break; } } CoTaskMemFree(szAdapterId); } - szTAPAdaptersTail [0] = 0; - szTAPAdaptersActiveTail[0] = 0; + szAdaptersTail [0] = 0; + szAdaptersActiveTail[0] = 0; - /* Set Installer TAPADAPTERS property. */ - uiResult = MsiSetProperty(hInstall, TEXT("TAPADAPTERS"), szTAPAdapters); + /* Set Installer TUNTAPADAPTERS property. */ + uiResult = MsiSetProperty(hInstall, TEXT("TUNTAPADAPTERS"), szAdapters); if (uiResult != ERROR_SUCCESS) { SetLastError(uiResult); /* MSDN does not mention MsiSetProperty() to set GetLastError(). But we do have an error code. Set last error manually. */ - msg(M_NONFATAL | M_ERRNO, "%s: MsiSetProperty(\"TAPADAPTERS\") failed", __FUNCTION__); - goto cleanup_szTAPAdaptersActive; + msg(M_NONFATAL | M_ERRNO, "%s: MsiSetProperty(\"TUNTAPADAPTERS\") failed", __FUNCTION__); + goto cleanup_szAdaptersActive; } - /* Set Installer ACTIVETAPADAPTERS property. */ - uiResult = MsiSetProperty(hInstall, TEXT("ACTIVETAPADAPTERS"), szTAPAdaptersActive); + /* Set Installer ACTIVETUNTAPADAPTERS property. */ + uiResult = MsiSetProperty(hInstall, TEXT("ACTIVETUNTAPADAPTERS"), szAdaptersActive); if (uiResult != ERROR_SUCCESS) { SetLastError(uiResult); /* MSDN does not mention MsiSetProperty() to set GetLastError(). But we do have an error code. Set last error manually. */ - msg(M_NONFATAL | M_ERRNO, "%s: MsiSetProperty(\"ACTIVETAPADAPTERS\") failed", __FUNCTION__); - goto cleanup_szTAPAdaptersActive; + msg(M_NONFATAL | M_ERRNO, "%s: MsiSetProperty(\"ACTIVETUNTAPADAPTERS\") failed", __FUNCTION__); + goto cleanup_szAdaptersActive; } -cleanup_szTAPAdaptersActive: - free(szTAPAdaptersActive); -cleanup_szTAPAdapters: - free(szTAPAdapters); +cleanup_szAdaptersActive: + free(szAdaptersActive); +cleanup_szAdapters: + free(szAdapters); } else { @@ -550,15 +550,15 @@ cleanup_CoInitialize: * * When the rollback is enabled, the adapter deletition is scheduled on rollback. * - * @param seq The argument sequence to pass to InstallTAPAdapters custom action + * @param seq The argument sequence to pass to InstallTUNTAPAdapters custom action * - * @param seqRollback The argument sequence to pass to InstallTAPAdaptersRollback custom + * @param seqRollback The argument sequence to pass to InstallTUNTAPAdaptersRollback custom * action. NULL when rollback is disabled. * * @param szDisplayName Adapter display name. * * @param iTicks Pointer to an integer that represents amount of work (on progress - * indicator) the InstallTAPAdapters will take. This function increments it + * indicator) the InstallTUNTAPAdapters will take. This function increments it * by MSICA_ADAPTER_TICK_SIZE for each adapter to create. * * @return ERROR_SUCCESS on success; An error code otherwise @@ -586,7 +586,7 @@ schedule_adapter_create( /* No adapter with a same name found. */ TCHAR szArgument[10 /*create=""|deleteN=""*/ + MAX_PATH /*szDisplayName*/ + 1 /*terminator*/]; - /* InstallTAPAdapters will create the adapter. */ + /* InstallTUNTAPAdapters will create the adapter. */ _stprintf_s( szArgument, _countof(szArgument), TEXT("create=\"%.*s\""), @@ -595,7 +595,7 @@ schedule_adapter_create( if (seqRollback) { - /* InstallTAPAdaptersRollback will delete the adapter. */ + /* InstallTUNTAPAdaptersRollback will delete the adapter. */ _stprintf_s( szArgument, _countof(szArgument), TEXT("deleteN=\"%.*s\""), @@ -640,23 +640,23 @@ cleanup_pAdapterList: * Schedules adapter deletion. * * When the rollback is enabled, the adapter deletition is scheduled as: disable in - * UninstallTAPAdapters, enable on rollback, delete on commit. + * UninstallTUNTAPAdapters, enable on rollback, delete on commit. * * When rollback is disabled, the adapter deletition is scheduled as delete in - * UninstallTAPAdapters. + * UninstallTUNTAPAdapters. * - * @param seq The argument sequence to pass to UninstallTAPAdapters custom action + * @param seq The argument sequence to pass to UninstallTUNTAPAdapters custom action * - * @param seqCommit The argument sequence to pass to UninstallTAPAdaptersCommit custom + * @param seqCommit The argument sequence to pass to UninstallTUNTAPAdaptersCommit custom * action. NULL when rollback is disabled. * - * @param seqRollback The argument sequence to pass to UninstallTAPAdaptersRollback custom + * @param seqRollback The argument sequence to pass to UninstallTUNTAPAdaptersRollback custom * action. NULL when rollback is disabled. * * @param szDisplayName Adapter display name. * * @param iTicks Pointer to an integer that represents amount of work (on progress - * indicator) the UninstallTAPAdapters will take. This function increments + * indicator) the UninstallTUNTAPAdapters will take. This function increments * it by MSICA_ADAPTER_TICK_SIZE for each adapter to delete. * * @return ERROR_SUCCESS on success; An error code otherwise @@ -686,21 +686,21 @@ schedule_adapter_delete( TCHAR szArgument[8 /*disable=|enable=|delete=*/ + 38 /*{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}*/ + 1 /*terminator*/]; if (seqCommit && seqRollback) { - /* UninstallTAPAdapters will disable the adapter. */ + /* UninstallTUNTAPAdapters will disable the adapter. */ _stprintf_s( szArgument, _countof(szArgument), TEXT("disable=") TEXT(PRIXGUID), PRIGUID_PARAM(pAdapter->guid)); msica_arg_seq_add_tail(seq, szArgument); - /* UninstallTAPAdaptersRollback will re-enable the adapter. */ + /* UninstallTUNTAPAdaptersRollback will re-enable the adapter. */ _stprintf_s( szArgument, _countof(szArgument), TEXT("enable=") TEXT(PRIXGUID), PRIGUID_PARAM(pAdapter->guid)); msica_arg_seq_add_head(seqRollback, szArgument); - /* UninstallTAPAdaptersCommit will delete the adapter. */ + /* UninstallTUNTAPAdaptersCommit will delete the adapter. */ _stprintf_s( szArgument, _countof(szArgument), TEXT("delete=") TEXT(PRIXGUID), @@ -709,7 +709,7 @@ schedule_adapter_delete( } else { - /* UninstallTAPAdapters will delete the adapter. */ + /* UninstallTUNTAPAdapters will delete the adapter. */ _stprintf_s( szArgument, _countof(szArgument), TEXT("delete=") TEXT(PRIXGUID), @@ -728,7 +728,7 @@ schedule_adapter_delete( UINT __stdcall -EvaluateTAPAdapters(_In_ MSIHANDLE hInstall) +EvaluateTUNTAPAdapters(_In_ MSIHANDLE hInstall) { #ifdef _MSC_VER #pragma comment(linker, DLLEXP_EXPORT) @@ -742,18 +742,18 @@ EvaluateTAPAdapters(_In_ MSIHANDLE hInstall) OPENVPNMSICA_SAVE_MSI_SESSION(hInstall); struct msica_arg_seq - seqInstallTAPAdapters, - seqInstallTAPAdaptersCommit, - seqInstallTAPAdaptersRollback, - seqUninstallTAPAdapters, - seqUninstallTAPAdaptersCommit, - seqUninstallTAPAdaptersRollback; - msica_arg_seq_init(&seqInstallTAPAdapters); - msica_arg_seq_init(&seqInstallTAPAdaptersCommit); - msica_arg_seq_init(&seqInstallTAPAdaptersRollback); - msica_arg_seq_init(&seqUninstallTAPAdapters); - msica_arg_seq_init(&seqUninstallTAPAdaptersCommit); - msica_arg_seq_init(&seqUninstallTAPAdaptersRollback); + seqInstall, + seqInstallCommit, + seqInstallRollback, + seqUninstall, + seqUninstallCommit, + seqUninstallRollback; + msica_arg_seq_init(&seqInstall); + msica_arg_seq_init(&seqInstallCommit); + msica_arg_seq_init(&seqInstallRollback); + msica_arg_seq_init(&seqUninstall); + msica_arg_seq_init(&seqUninstallCommit); + msica_arg_seq_init(&seqUninstallRollback); /* Check rollback state. */ bool bRollbackEnabled = MsiEvaluateCondition(hInstall, TEXT("RollbackDisabled")) != MSICONDITION_TRUE; @@ -767,8 +767,8 @@ EvaluateTAPAdapters(_In_ MSIHANDLE hInstall) goto cleanup_exec_seq; } - /* Check if TAPAdapter table exists. If it doesn't exist, there's nothing to do. */ - switch (MsiDatabaseIsTablePersistent(hDatabase, TEXT("TAPAdapter"))) + /* Check if TUNTAPAdapter table exists. If it doesn't exist, there's nothing to do. */ + switch (MsiDatabaseIsTablePersistent(hDatabase, TEXT("TUNTAPAdapter"))) { case MSICONDITION_FALSE: case MSICONDITION_TRUE: break; @@ -780,7 +780,7 @@ EvaluateTAPAdapters(_In_ MSIHANDLE hInstall) /* Prepare a query to get a list/view of adapters. */ MSIHANDLE hViewST = 0; - LPCTSTR szQuery = TEXT("SELECT `Adapter`,`DisplayName`,`Condition`,`Component_` FROM `TAPAdapter`"); + LPCTSTR szQuery = TEXT("SELECT `Adapter`,`DisplayName`,`Condition`,`Component_` FROM `TUNTAPAdapter`"); uiResult = MsiDatabaseOpenView(hDatabase, szQuery, &hViewST); if (uiResult != ERROR_SUCCESS) { @@ -897,8 +897,8 @@ EvaluateTAPAdapters(_In_ MSIHANDLE hInstall) /* Component is or should be installed. Schedule adapter creation. */ if (schedule_adapter_create( - &seqInstallTAPAdapters, - bRollbackEnabled ? &seqInstallTAPAdaptersRollback : NULL, + &seqInstall, + bRollbackEnabled ? &seqInstallRollback : NULL, szDisplayNameEx, &iTicks) != ERROR_SUCCESS) { @@ -914,9 +914,9 @@ EvaluateTAPAdapters(_In_ MSIHANDLE hInstall) * Better a partial uninstallation than no uninstallation at all. */ schedule_adapter_delete( - &seqUninstallTAPAdapters, - bRollbackEnabled ? &seqUninstallTAPAdaptersCommit : NULL, - bRollbackEnabled ? &seqUninstallTAPAdaptersRollback : NULL, + &seqUninstall, + bRollbackEnabled ? &seqUninstallCommit : NULL, + bRollbackEnabled ? &seqUninstallRollback : NULL, szDisplayNameEx, &iTicks); } @@ -943,12 +943,12 @@ cleanup_hRecord: } /* Store deferred custom action parameters. */ - if ((uiResult = setup_sequence(hInstall, TEXT("InstallTAPAdapters" ), &seqInstallTAPAdapters )) != ERROR_SUCCESS - || (uiResult = setup_sequence(hInstall, TEXT("InstallTAPAdaptersCommit" ), &seqInstallTAPAdaptersCommit )) != ERROR_SUCCESS - || (uiResult = setup_sequence(hInstall, TEXT("InstallTAPAdaptersRollback" ), &seqInstallTAPAdaptersRollback )) != ERROR_SUCCESS - || (uiResult = setup_sequence(hInstall, TEXT("UninstallTAPAdapters" ), &seqUninstallTAPAdapters )) != ERROR_SUCCESS - || (uiResult = setup_sequence(hInstall, TEXT("UninstallTAPAdaptersCommit" ), &seqUninstallTAPAdaptersCommit )) != ERROR_SUCCESS - || (uiResult = setup_sequence(hInstall, TEXT("UninstallTAPAdaptersRollback"), &seqUninstallTAPAdaptersRollback)) != ERROR_SUCCESS) + if ((uiResult = setup_sequence(hInstall, TEXT("InstallTUNTAPAdapters" ), &seqInstall )) != ERROR_SUCCESS + || (uiResult = setup_sequence(hInstall, TEXT("InstallTUNTAPAdaptersCommit" ), &seqInstallCommit )) != ERROR_SUCCESS + || (uiResult = setup_sequence(hInstall, TEXT("InstallTUNTAPAdaptersRollback" ), &seqInstallRollback )) != ERROR_SUCCESS + || (uiResult = setup_sequence(hInstall, TEXT("UninstallTUNTAPAdapters" ), &seqUninstall )) != ERROR_SUCCESS + || (uiResult = setup_sequence(hInstall, TEXT("UninstallTUNTAPAdaptersCommit" ), &seqUninstallCommit )) != ERROR_SUCCESS + || (uiResult = setup_sequence(hInstall, TEXT("UninstallTUNTAPAdaptersRollback"), &seqUninstallRollback)) != ERROR_SUCCESS) { goto cleanup_hRecordProg; } @@ -964,12 +964,12 @@ cleanup_hViewST: cleanup_hDatabase: MsiCloseHandle(hDatabase); cleanup_exec_seq: - msica_arg_seq_free(&seqInstallTAPAdapters); - msica_arg_seq_free(&seqInstallTAPAdaptersCommit); - msica_arg_seq_free(&seqInstallTAPAdaptersRollback); - msica_arg_seq_free(&seqUninstallTAPAdapters); - msica_arg_seq_free(&seqUninstallTAPAdaptersCommit); - msica_arg_seq_free(&seqUninstallTAPAdaptersRollback); + msica_arg_seq_free(&seqInstall); + msica_arg_seq_free(&seqInstallCommit); + msica_arg_seq_free(&seqInstallRollback); + msica_arg_seq_free(&seqUninstall); + msica_arg_seq_free(&seqUninstallCommit); + msica_arg_seq_free(&seqUninstallRollback); if (bIsCoInitialized) { CoUninitialize(); diff --git a/src/openvpnmsica/openvpnmsica.h b/src/openvpnmsica/openvpnmsica.h index 14fb78a2..5d140930 100644 --- a/src/openvpnmsica/openvpnmsica.h +++ b/src/openvpnmsica/openvpnmsica.h @@ -90,7 +90,7 @@ FindSystemInfo(_In_ MSIHANDLE hInstall); /** - * Find existing TAP adapters and set TAPADAPTERS and ACTIVETAPADAPTERS properties with + * Find existing TAP adapters and set TUNTAPADAPTERS and ACTIVETUNTAPADAPTERS properties with * semicolon delimited list of all installed TAP adapter GUIDs and active adapter GUIDs * respectively. * @@ -100,7 +100,7 @@ FindSystemInfo(_In_ MSIHANDLE hInstall); * See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa368072.aspx */ DLLEXP_DECL UINT __stdcall -FindTAPAdapters(_In_ MSIHANDLE hInstall); +FindTUNTAPAdapters(_In_ MSIHANDLE hInstall); /** @@ -129,7 +129,7 @@ StartOpenVPNGUI(_In_ MSIHANDLE hInstall); /** - * Evaluate the TAPAdapter table of the MSI package database and prepare a list of TAP + * Evaluate the TUNTAPAdapter table of the MSI package database and prepare a list of TAP * adapters to install/remove. * * @param hInstall Handle to the installation provided to the DLL custom action @@ -138,7 +138,7 @@ StartOpenVPNGUI(_In_ MSIHANDLE hInstall); * See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa368072.aspx */ DLLEXP_DECL UINT __stdcall -EvaluateTAPAdapters(_In_ MSIHANDLE hInstall); +EvaluateTUNTAPAdapters(_In_ MSIHANDLE hInstall); /** From patchwork Mon Mar 9 02:17:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Rozman X-Patchwork-Id: 1026 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director8.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id IA/XElVCZl7BBwAAIUCqbw for ; Mon, 09 Mar 2020 09:19:17 -0400 Received: from proxy9.mail.ord1d.rsapps.net ([172.30.191.6]) by director8.mail.ord1d.rsapps.net with LMTP id QLizElVCZl7cagAAfY0hYg ; Mon, 09 Mar 2020 09:19:17 -0400 Received: from smtp13.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy9.mail.ord1d.rsapps.net with LMTP id GMJtElVCZl4YcAAA7h+8OQ ; Mon, 09 Mar 2020 09:19:17 -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: smtp13.gate.ord1d.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=rozman.si; dmarc=fail (p=none; dis=none) header.from=rozman.si X-Suspicious-Flag: YES X-Classification-ID: 939ae298-6208-11ea-a212-525400b197d9-1-1 Received: from [216.105.38.7] ([216.105.38.7:46282] helo=lists.sourceforge.net) by smtp13.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 4D/ED-16252-452466E5; Mon, 09 Mar 2020 09:19:17 -0400 Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1jBIIY-0005us-UU; Mon, 09 Mar 2020 13:18:22 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jBIIX-0005uc-Gy for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:21 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=Vgofggg50l9duIhL2fpTVoxkWybZxkPrNKOoobeM7zA=; b=YRvzlQzv1P6RmPwjL79VBh4Vri Zua19V5ho7U/Z3OfGpbDjFKjyZ9RnNiuFw0IqhGiVB3tWwVfmNtQ5hwCVJy9TerIBCo2gXHGo0otS ebl80HBthoyztYOphAS1KZPdi14bt/j5Yf+zmurbcVYDq44Gd5vv1C/bQNBrPoMWREsY=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=Vgofggg50l9duIhL2fpTVoxkWybZxkPrNKOoobeM7zA=; b=Yj7YFxeNrN2OOBw1hfXrSwMCxT o25oLhKPsePVuSYxMpO9CRasy3wmdL4wTZjwFlexBu8oFG+m7W+LJ8wZo4ywKxsA3qxDEHLqJsjzP SBCt3Bg6aux451dV6ZrHIigzBdvOTfalTG42Lj9UKqmQjKwDQjM/hbkpbFHKZZRjSJy4=; Received: from pub5.amebis.si ([213.250.55.21]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1jBIIV-00DVpS-M9 for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:21 +0000 Received: by pub5.amebis.si (Postfix, from userid 1000) id 7D5F71002FBE; Mon, 9 Mar 2020 14:18:00 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rozman.si; s=default; t=1583759880; bh=Vgofggg50l9duIhL2fpTVoxkWybZxkPrNKOoobeM7zA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LefAEj6YZ3E/Za6czinKgxm8UhYS4GQMwwJwjb5exBjVcz8twmatyqMjqsVyPL+EW jZcrgh0S+rhbCYitpITVeacv/OXiyy1LBp754FonuaFiu4qkLMmAuopuWDsM+QC6Zi 8PvMcnIv/iiYxrFgWkqEyJ2rTYgJh66+Z3QJFUF4= X-Spam-Checker-Version: SpamAssassin 3.4.3 (2019-12-06) on brana.amebis.doma X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00, WEIRD_QUOTING autolearn=ham autolearn_force=no version=3.4.3 Received: from SR6.amebis.doma (unknown [IPv6:2a00:ee2:209:164:a5ae:e83c:b7b:725]) by pub5.amebis.si (Postfix) with ESMTP id 942891002FCB; Mon, 9 Mar 2020 14:17:49 +0100 (CET) From: Simon Rozman To: openvpn-devel@lists.sourceforge.net Date: Mon, 9 Mar 2020 14:17:25 +0100 Message-Id: <20200309131728.380-9-simon@rozman.si> X-Mailer: git-send-email 2.24.1.windows.2 In-Reply-To: <20200309131728.380-1-simon@rozman.si> References: <20200309131728.380-1-simon@rozman.si> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 WEIRD_QUOTING BODY: Weird repeated double-quotation marks -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 -0.0 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1jBIIV-00DVpS-M9 Subject: [Openvpn-devel] [PATCH 09/12] openvpnmsica: Extend to support arbitrary HWID network adapters 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: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox Signed-off-by: Simon Rozman Acked-by: Lev Stipakov --- src/openvpnmsica/openvpnmsica.c | 73 ++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/src/openvpnmsica/openvpnmsica.c b/src/openvpnmsica/openvpnmsica.c index 4223b680..cfbda8da 100644 --- a/src/openvpnmsica/openvpnmsica.c +++ b/src/openvpnmsica/openvpnmsica.c @@ -555,7 +555,9 @@ cleanup_CoInitialize: * @param seqRollback The argument sequence to pass to InstallTUNTAPAdaptersRollback custom * action. NULL when rollback is disabled. * - * @param szDisplayName Adapter display name. + * @param szDisplayName Adapter display name + * + * @param szHardwareId Adapter hardware ID * * @param iTicks Pointer to an integer that represents amount of work (on progress * indicator) the InstallTUNTAPAdapters will take. This function increments it @@ -568,6 +570,7 @@ schedule_adapter_create( _Inout_ struct msica_arg_seq *seq, _Inout_opt_ struct msica_arg_seq *seqRollback, _In_z_ LPCTSTR szDisplayName, + _In_z_ LPCTSTR szHardwareId, _Inout_ int *iTicks) { /* Get all available network adapters. */ @@ -584,13 +587,14 @@ schedule_adapter_create( if (pAdapterOther == NULL) { /* No adapter with a same name found. */ - TCHAR szArgument[10 /*create=""|deleteN=""*/ + MAX_PATH /*szDisplayName*/ + 1 /*terminator*/]; + TCHAR szArgument[10 /*create=""|deleteN=""*/ + MAX_PATH /*szDisplayName*/ + 1 /*|*/ + MAX_PATH /*szHardwareId*/ + 1 /*terminator*/]; /* InstallTUNTAPAdapters will create the adapter. */ _stprintf_s( szArgument, _countof(szArgument), - TEXT("create=\"%.*s\""), - MAX_PATH, szDisplayName); + TEXT("create=\"%.*s|%.*s\""), + MAX_PATH, szDisplayName, + MAX_PATH, szHardwareId); msica_arg_seq_add_tail(seq, szArgument); if (seqRollback) @@ -613,16 +617,14 @@ schedule_adapter_create( { if (hwid[0] == 0) { - /* This is not a TAP adapter. */ + /* This adapter has a different hardware ID. */ msg(M_NONFATAL, "%s: Adapter with name \"%" PRIsLPTSTR "\" already exists", __FUNCTION__, pAdapterOther->szName); dwResult = ERROR_ALREADY_EXISTS; goto cleanup_pAdapterList; } - else if ( - _tcsicmp(hwid, TEXT(TAP_WIN_COMPONENT_ID)) == 0 - || _tcsicmp(hwid, TEXT("root\\") TEXT(TAP_WIN_COMPONENT_ID)) == 0) + else if (_tcsicmp(hwid, szHardwareId) == 0) { - /* This is a TAP-Windows6 adapter. We already have what we want! */ + /* This is an adapter with the requested hardware ID. We already have what we want! */ break; } } @@ -653,7 +655,9 @@ cleanup_pAdapterList: * @param seqRollback The argument sequence to pass to UninstallTUNTAPAdaptersRollback custom * action. NULL when rollback is disabled. * - * @param szDisplayName Adapter display name. + * @param szDisplayName Adapter display name + * + * @param szHardwareId Adapter hardware ID * * @param iTicks Pointer to an integer that represents amount of work (on progress * indicator) the UninstallTUNTAPAdapters will take. This function increments @@ -667,11 +671,12 @@ schedule_adapter_delete( _Inout_opt_ struct msica_arg_seq *seqCommit, _Inout_opt_ struct msica_arg_seq *seqRollback, _In_z_ LPCTSTR szDisplayName, + _In_z_ LPCTSTR szHardwareId, _Inout_ int *iTicks) { - /* Get available TUN/TAP adapters. */ + /* Get available adapters with given hardware ID. */ struct tap_adapter_node *pAdapterList = NULL; - DWORD dwResult = tap_list_adapters(NULL, NULL, &pAdapterList, FALSE); + DWORD dwResult = tap_list_adapters(NULL, szHardwareId, &pAdapterList, FALSE); if (dwResult != ERROR_SUCCESS) { return dwResult; @@ -780,7 +785,7 @@ EvaluateTUNTAPAdapters(_In_ MSIHANDLE hInstall) /* Prepare a query to get a list/view of adapters. */ MSIHANDLE hViewST = 0; - LPCTSTR szQuery = TEXT("SELECT `Adapter`,`DisplayName`,`Condition`,`Component_` FROM `TUNTAPAdapter`"); + LPCTSTR szQuery = TEXT("SELECT `Adapter`,`DisplayName`,`Condition`,`Component_`,`HardwareId` FROM `TUNTAPAdapter`"); uiResult = MsiDatabaseOpenView(hDatabase, szQuery, &hViewST); if (uiResult != ERROR_SUCCESS) { @@ -857,6 +862,14 @@ EvaluateTUNTAPAdapters(_In_ MSIHANDLE hInstall) LPTSTR szDisplayNameEx = _tcschr(szDisplayName, TEXT('|')); szDisplayNameEx = szDisplayNameEx != NULL ? szDisplayNameEx + 1 : szDisplayName; + /* Get adapter hardware ID (`HardwareId` is field #5). */ + LPTSTR szHardwareId = NULL; + uiResult = msi_get_record_string(hRecord, 5, &szHardwareId); + if (uiResult != ERROR_SUCCESS) + { + goto cleanup_szDisplayName; + } + if (iAction > INSTALLSTATE_BROKEN) { int iTicks = 0; @@ -868,7 +881,7 @@ EvaluateTUNTAPAdapters(_In_ MSIHANDLE hInstall) uiResult = msi_get_record_string(hRecord, 3, &szValue); if (uiResult != ERROR_SUCCESS) { - goto cleanup_szDisplayName; + goto cleanup_szHardwareId; } #ifdef __GNUC__ /* @@ -882,13 +895,13 @@ EvaluateTUNTAPAdapters(_In_ MSIHANDLE hInstall) { case MSICONDITION_FALSE: free(szValue); - goto cleanup_szDisplayName; + goto cleanup_szHardwareId; case MSICONDITION_ERROR: uiResult = ERROR_INVALID_FIELD; msg(M_NONFATAL | M_ERRNO, "%s: MsiEvaluateCondition(\"%" PRIsLPTSTR "\") failed", __FUNCTION__, szValue); free(szValue); - goto cleanup_szDisplayName; + goto cleanup_szHardwareId; } #ifdef __GNUC__ #pragma GCC diagnostic pop @@ -900,10 +913,11 @@ EvaluateTUNTAPAdapters(_In_ MSIHANDLE hInstall) &seqInstall, bRollbackEnabled ? &seqInstallRollback : NULL, szDisplayNameEx, + szHardwareId, &iTicks) != ERROR_SUCCESS) { uiResult = ERROR_INSTALL_FAILED; - goto cleanup_szDisplayName; + goto cleanup_szHardwareId; } } else @@ -918,6 +932,7 @@ EvaluateTUNTAPAdapters(_In_ MSIHANDLE hInstall) bRollbackEnabled ? &seqUninstallCommit : NULL, bRollbackEnabled ? &seqUninstallRollback : NULL, szDisplayNameEx, + szHardwareId, &iTicks); } @@ -928,10 +943,12 @@ EvaluateTUNTAPAdapters(_In_ MSIHANDLE hInstall) if (MsiProcessMessage(hInstall, INSTALLMESSAGE_PROGRESS, hRecordProg) == IDCANCEL) { uiResult = ERROR_INSTALL_USEREXIT; - goto cleanup_szDisplayName; + goto cleanup_szHardwareId; } } +cleanup_szHardwareId: + free(szHardwareId); cleanup_szDisplayName: free(szDisplayName); cleanup_hRecord: @@ -1052,14 +1069,22 @@ ProcessDeferredAction(_In_ MSIHANDLE hInstall) if (wcsncmp(szArg[i], L"create=", 7) == 0) { - /* Create an adapter with a given name. */ - LPCWSTR szName = szArg[i] + 7; + /* Create an adapter with a given name and hardware ID. */ + LPWSTR szName = szArg[i] + 7; + LPWSTR szHardwareId = wcschr(szName, L'|'); + if (szHardwareId == NULL) + { + goto invalid_argument; + } + szHardwareId[0] = 0; + ++szHardwareId; { /* Report the name of the adapter to installer. */ - MSIHANDLE hRecord = MsiCreateRecord(3); + MSIHANDLE hRecord = MsiCreateRecord(4); MsiRecordSetString(hRecord, 1, TEXT("Creating adapter")); MsiRecordSetString(hRecord, 2, szName); + MsiRecordSetString(hRecord, 3, szHardwareId); int iResult = MsiProcessMessage(hInstall, INSTALLMESSAGE_ACTIONDATA, hRecord); MsiCloseHandle(hRecord); if (iResult == IDCANCEL) @@ -1070,7 +1095,7 @@ ProcessDeferredAction(_In_ MSIHANDLE hInstall) } GUID guidAdapter; - dwResult = tap_create_adapter(NULL, NULL, NULL, &bRebootRequired, &guidAdapter); + dwResult = tap_create_adapter(NULL, NULL, szHardwareId, &bRebootRequired, &guidAdapter); if (dwResult == ERROR_SUCCESS) { /* Set adapter name. */ @@ -1100,9 +1125,9 @@ ProcessDeferredAction(_In_ MSIHANDLE hInstall) } } - /* Get available TUN/TAP adapters. */ + /* Get all available adapters. */ struct tap_adapter_node *pAdapterList = NULL; - dwResult = tap_list_adapters(NULL, NULL, &pAdapterList, FALSE); + dwResult = tap_list_adapters(NULL, NULL, &pAdapterList, TRUE); if (dwResult == ERROR_SUCCESS) { /* Does the adapter exist? */ From patchwork Mon Mar 9 02:17:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Rozman X-Patchwork-Id: 1023 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director11.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id mG0eBE5CZl4qagAAIUCqbw for ; Mon, 09 Mar 2020 09:19:10 -0400 Received: from proxy19.mail.ord1d.rsapps.net ([172.30.191.6]) by director11.mail.ord1d.rsapps.net with LMTP id WPHuA05CZl63TAAAvGGmqA ; Mon, 09 Mar 2020 09:19:10 -0400 Received: from smtp19.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy19.mail.ord1d.rsapps.net with LMTP id wFm/A05CZl78QwAAyH2SIw ; Mon, 09 Mar 2020 09:19:10 -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: smtp19.gate.ord1d.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=rozman.si; dmarc=fail (p=none; dis=none) header.from=rozman.si X-Suspicious-Flag: YES X-Classification-ID: 8f0d3082-6208-11ea-ac83-525400d67fa8-1-1 Received: from [216.105.38.7] ([216.105.38.7:35010] helo=lists.sourceforge.net) by smtp19.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 79/1F-26733-D42466E5; Mon, 09 Mar 2020 09:19:09 -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 1jBIIb-0000Ab-0W; Mon, 09 Mar 2020 13:18:25 +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 1jBIIY-00009s-Da for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=DSUftUY+u48z0j6rAhuxc+UMqnu9mv4OunO8lslEhoI=; b=lQ5laBIidDPTbDcBc4lNM5BZNz M7rfFvZ6kkTOX9uyY+h8Q+Ys7PEHLep4gOeK98jtS87JtBnZ5/9csUj2WWccnqtfWyERBOW/Q5wsN TRG6hp6lQDWwqtm/ii6o5omuTGrq/+zt6mepmmfotPFo4Twya9HctHpzeug/95Frf9tA=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=DSUftUY+u48z0j6rAhuxc+UMqnu9mv4OunO8lslEhoI=; b=TjwWwfLwqsezeABOcn1YnKe4Cd PQCXeuLybPajOhHdp6xJy+S/4u1JIlHv6o5c8vCwOn3XOz7QIrNkWHFmJKsgnmUTIeK4vjg3B/Ay0 KdHhQbugonHLBb1AQg+k4JNzoWhNvC7huOvq2zJb+WKqfUc+2uJztrdQ5LpDgCkktkHw=; Received: from pub5.amebis.si ([213.250.55.21]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1jBIIW-00DVpc-4K for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:22 +0000 Received: by pub5.amebis.si (Postfix, from userid 1000) id 33AFB1002FC0; Mon, 9 Mar 2020 14:18:03 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rozman.si; s=default; t=1583759883; bh=DSUftUY+u48z0j6rAhuxc+UMqnu9mv4OunO8lslEhoI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ea+H8crqYkdV2zXk9hx16lVh30i+wOyQ3MEiZ6F4tfRJdV2oidnNH3TSqteGt0ljo WvLVGORC96FtxMvXpvk5mmO+bgaYlZUwajNX+FFkylWKJlVKxuVDIkPwrWFJxOe9gM 0D0R85HsIsJBth6DP5Xyf/dQkR4cBUft9LIbVfbc= X-Spam-Checker-Version: SpamAssassin 3.4.3 (2019-12-06) on brana.amebis.doma X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.3 Received: from SR6.amebis.doma (unknown [IPv6:2a00:ee2:209:164:a5ae:e83c:b7b:725]) by pub5.amebis.si (Postfix) with ESMTP id A59EE1002FCD; Mon, 9 Mar 2020 14:17:49 +0100 (CET) From: Simon Rozman To: openvpn-devel@lists.sourceforge.net Date: Mon, 9 Mar 2020 14:17:26 +0100 Message-Id: <20200309131728.380-10-simon@rozman.si> X-Mailer: git-send-email 2.24.1.windows.2 In-Reply-To: <20200309131728.380-1-simon@rozman.si> References: <20200309131728.380-1-simon@rozman.si> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -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 0.0 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1jBIIW-00DVpc-4K Subject: [Openvpn-devel] [PATCH 10/12] openvpnmsica, tapctl: Revise default hardware ID management 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: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox tap_create_adapter() and tap_list_adapter() no longer default to "root\tap0901". Defining a default hardware ID value is at the responsibility of upper layers that process user desires. Since the tap_list_adapter() no longer defaults the hardware ID to anything, its behavior was simplified to return all existing adapters when a NULL hardware ID is specified. Signed-off-by: Simon Rozman Acked-by: Lev Stipakov --- src/openvpnmsica/openvpnmsica.c | 16 ++-- src/tapctl/main.c | 14 ++-- src/tapctl/tap.c | 134 ++++++++++++++++---------------- src/tapctl/tap.h | 17 ++-- 4 files changed, 86 insertions(+), 95 deletions(-) diff --git a/src/openvpnmsica/openvpnmsica.c b/src/openvpnmsica/openvpnmsica.c index cfbda8da..ae9b007f 100644 --- a/src/openvpnmsica/openvpnmsica.c +++ b/src/openvpnmsica/openvpnmsica.c @@ -285,9 +285,9 @@ FindTUNTAPAdapters(_In_ MSIHANDLE hInstall) OPENVPNMSICA_SAVE_MSI_SESSION(hInstall); - /* Get all TUN/TAP network adapters. */ + /* Get existing network adapters. */ struct tap_adapter_node *pAdapterList = NULL; - uiResult = tap_list_adapters(NULL, NULL, &pAdapterList, FALSE); + uiResult = tap_list_adapters(NULL, NULL, &pAdapterList); if (uiResult != ERROR_SUCCESS) { goto cleanup_CoInitialize; @@ -573,9 +573,9 @@ schedule_adapter_create( _In_z_ LPCTSTR szHardwareId, _Inout_ int *iTicks) { - /* Get all available network adapters. */ + /* Get existing network adapters. */ struct tap_adapter_node *pAdapterList = NULL; - DWORD dwResult = tap_list_adapters(NULL, NULL, &pAdapterList, TRUE); + DWORD dwResult = tap_list_adapters(NULL, NULL, &pAdapterList); if (dwResult != ERROR_SUCCESS) { return dwResult; @@ -674,9 +674,9 @@ schedule_adapter_delete( _In_z_ LPCTSTR szHardwareId, _Inout_ int *iTicks) { - /* Get available adapters with given hardware ID. */ + /* Get adapters with given hardware ID. */ struct tap_adapter_node *pAdapterList = NULL; - DWORD dwResult = tap_list_adapters(NULL, szHardwareId, &pAdapterList, FALSE); + DWORD dwResult = tap_list_adapters(NULL, szHardwareId, &pAdapterList); if (dwResult != ERROR_SUCCESS) { return dwResult; @@ -1125,9 +1125,9 @@ ProcessDeferredAction(_In_ MSIHANDLE hInstall) } } - /* Get all available adapters. */ + /* Get existing adapters. */ struct tap_adapter_node *pAdapterList = NULL; - dwResult = tap_list_adapters(NULL, NULL, &pAdapterList, TRUE); + dwResult = tap_list_adapters(NULL, NULL, &pAdapterList); if (dwResult == ERROR_SUCCESS) { /* Does the adapter exist? */ diff --git a/src/tapctl/main.c b/src/tapctl/main.c index 1cc86424..fdeda7bf 100644 --- a/src/tapctl/main.c +++ b/src/tapctl/main.c @@ -177,7 +177,7 @@ _tmain(int argc, LPCTSTR argv[]) else if (_tcsicmp(argv[1], TEXT("create")) == 0) { LPCTSTR szName = NULL; - LPCTSTR szHwId = NULL; + LPCTSTR szHwId = TEXT("root\\") TEXT(TAP_WIN_COMPONENT_ID); /* Parse options. */ for (int i = 2; i < argc; i++) @@ -214,9 +214,9 @@ _tmain(int argc, LPCTSTR argv[]) if (szName) { - /* Get the list of all available adapters. */ + /* Get existing network adapters. */ struct tap_adapter_node *pAdapterList = NULL; - dwResult = tap_list_adapters(NULL, szHwId, &pAdapterList, TRUE); + dwResult = tap_list_adapters(NULL, NULL, &pAdapterList); if (dwResult != ERROR_SUCCESS) { _ftprintf(stderr, TEXT("Enumerating adapters failed (error 0x%x).\n"), dwResult); @@ -271,7 +271,7 @@ create_delete_adapter: } else if (_tcsicmp(argv[1], TEXT("list")) == 0) { - LPCTSTR szHwId = NULL; + LPCTSTR szHwId = TEXT("root\\") TEXT(TAP_WIN_COMPONENT_ID); /* Parse options. */ for (int i = 2; i < argc; i++) @@ -286,9 +286,9 @@ create_delete_adapter: } } - /* Output list of TUN/TAP adapters. */ + /* Output list of adapters with given hardware ID. */ struct tap_adapter_node *pAdapterList = NULL; - DWORD dwResult = tap_list_adapters(NULL, szHwId, &pAdapterList, FALSE); + DWORD dwResult = tap_list_adapters(NULL, szHwId, &pAdapterList); if (dwResult != ERROR_SUCCESS) { _ftprintf(stderr, TEXT("Enumerating TUN/TAP adapters failed (error 0x%x).\n"), dwResult); @@ -319,7 +319,7 @@ create_delete_adapter: { /* The argument failed to covert to GUID. Treat it as the adapter name. */ struct tap_adapter_node *pAdapterList = NULL; - DWORD dwResult = tap_list_adapters(NULL, NULL, &pAdapterList, FALSE); + DWORD dwResult = tap_list_adapters(NULL, NULL, &pAdapterList); if (dwResult != ERROR_SUCCESS) { _ftprintf(stderr, TEXT("Enumerating TUN/TAP adapters failed (error 0x%x).\n"), dwResult); diff --git a/src/tapctl/tap.c b/src/tapctl/tap.c index d718d43e..bdef3fc1 100644 --- a/src/tapctl/tap.c +++ b/src/tapctl/tap.c @@ -42,12 +42,53 @@ const static GUID GUID_DEVCLASS_NET = { 0x4d36e972L, 0xe325, 0x11ce, { 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 } }; -const static TCHAR szzDefaultHardwareIDs[] = TEXT("root\\") TEXT(TAP_WIN_COMPONENT_ID) TEXT("\0"); - 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"))) +/** + * Returns length of string of strings + * + * @param szz Pointer to a string of strings (terminated by an empty string) + * + * @return Number of characters not counting the final zero terminator + **/ +static inline size_t +_tcszlen(_In_z_ LPCTSTR szz) +{ + LPCTSTR s; + for (s = szz; s[0]; s += _tcslen(s) + 1) + { + } + return s - szz; +} + + +/** + * Checks if string is contained in the string of strings. Comparison is made case-insensitive. + * + * @param szzHay Pointer to a string of strings (terminated by an empty string) we are + * looking in + * + * @param szNeedle The string we are searching for + * + * @return Pointer to the string in szzHay that matches szNeedle is found; NULL otherwise + */ +static LPCTSTR +_tcszistr(_In_z_ LPCTSTR szzHay, _In_z_ LPCTSTR szNeedle) +{ + for (LPCTSTR s = szzHay; s[0]; s += _tcslen(s) + 1) + { + if (_tcsicmp(s, szNeedle) == 0) + { + return s; + } + } + + return NULL; +} + + /** * Function that performs a specific task on a device * @@ -628,45 +669,23 @@ get_device_reg_property( } -/** - * Returns length of list of strings - * - * @param str Pointer to a list of strings terminated by an empty string. - * - * @return Number of characters not counting the final zero terminator - **/ -static inline size_t -_tcszlen(_In_ LPCTSTR str) -{ - LPCTSTR s; - for (s = str; s[0]; s += _tcslen(s) + 1) - { - } - return s - str; -} - - DWORD tap_create_adapter( _In_opt_ HWND hwndParent, _In_opt_ LPCTSTR szDeviceDescription, - _In_opt_ LPCTSTR szHwId, + _In_ LPCTSTR szHwId, _Inout_ LPBOOL pbRebootRequired, _Out_ LPGUID pguidAdapter) { DWORD dwResult; - if (pbRebootRequired == NULL + if (szHwId == NULL + || pbRebootRequired == NULL || pguidAdapter == NULL) { return ERROR_BAD_ARGUMENTS; } - if (szHwId == NULL) - { - szHwId = szzDefaultHardwareIDs; - } - /* Create an empty device info set for network adapter device class. */ HDEVINFO hDevInfoList = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_NET, hwndParent); if (hDevInfoList == INVALID_HANDLE_VALUE) @@ -818,29 +837,23 @@ tap_create_adapter( } } - /* Check the driver version first, since the check is trivial and will save us iterating over hardware IDs for any driver versioned prior our best match. */ - if (dwlDriverVersion < drvinfo_data.DriverVersion) + /* Check the driver version and hardware ID. */ + if (dwlDriverVersion < drvinfo_data.DriverVersion + && drvinfo_detail_data->HardwareID + && _tcszistr(drvinfo_detail_data->HardwareID, szHwId)) { - /* Search the list of hardware IDs. */ - for (LPTSTR szHwdID = drvinfo_detail_data->HardwareID; szHwdID && szHwdID[0]; szHwdID += _tcslen(szHwdID) + 1) + /* Newer version and matching hardware ID found. Select the driver. */ + if (!SetupDiSetSelectedDriver( + hDevInfoList, + &devinfo_data, + &drvinfo_data)) { - if (_tcsicmp(szHwdID, szHwId) == 0) - { - /* 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); - break; - } - - dwlDriverVersion = drvinfo_data.DriverVersion; - break; - } + /* 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) @@ -1167,8 +1180,7 @@ DWORD tap_list_adapters( _In_opt_ HWND hwndParent, _In_opt_ LPCTSTR szHwId, - _Out_ struct tap_adapter_node **ppAdapter, - _In_ BOOL bAll) + _Out_ struct tap_adapter_node **ppAdapter) { DWORD dwResult; @@ -1177,11 +1189,6 @@ tap_list_adapters( return ERROR_BAD_ARGUMENTS; } - if (szHwId == NULL) - { - szHwId = szzDefaultHardwareIDs; - } - /* Create a list of network devices. */ HDEVINFO hDevInfoList = SetupDiGetClassDevsEx( &GUID_DEVCLASS_NET, @@ -1253,7 +1260,7 @@ tap_list_adapters( /* Check that hardware ID is REG_SZ/REG_MULTI_SZ, and optionally if it matches ours. */ if (dwDataType == REG_SZ) { - if (!bAll && _tcsicmp(szzDeviceHardwareIDs, szHwId) != 0) + if (szHwId && _tcsicmp(szzDeviceHardwareIDs, szHwId) != 0) { /* This is not our device. Skip it. */ goto cleanup_szzDeviceHardwareIDs; @@ -1261,21 +1268,10 @@ tap_list_adapters( } else if (dwDataType == REG_MULTI_SZ) { - if (!bAll) + if (szHwId && _tcszistr(szzDeviceHardwareIDs, szHwId) == NULL) { - for (LPTSTR szHwdID = szzDeviceHardwareIDs;; szHwdID += _tcslen(szHwdID) + 1) - { - if (szHwdID[0] == 0) - { - /* This is not our device. Skip it. */ - goto cleanup_szzDeviceHardwareIDs; - } - else if (_tcsicmp(szHwdID, szHwId) == 0) - { - /* This is our device. */ - break; - } - } + /* This is not our device. Skip it. */ + goto cleanup_szzDeviceHardwareIDs; } } else diff --git a/src/tapctl/tap.h b/src/tapctl/tap.h index aec44ec8..68662c82 100644 --- a/src/tapctl/tap.h +++ b/src/tapctl/tap.h @@ -38,8 +38,7 @@ * description of the device. This pointer is optional and can be NULL. * * @param szHwId A pointer to a NULL-terminated string that supplies the hardware id - * of the device. This pointer is optional and can be NULL. Default value - * is root\tap0901. + * of the device (e.g. "root\\tap0901", "Wintun"). * * @param pbRebootRequired A pointer to a BOOL flag. If the device requires a system restart, * this flag is set to TRUE. Otherwise, the flag is left unmodified. This @@ -54,7 +53,7 @@ DWORD tap_create_adapter( _In_opt_ HWND hwndParent, _In_opt_ LPCTSTR szDeviceDescription, - _In_opt_ LPCTSTR szHwId, + _In_ LPCTSTR szHwId, _Inout_ LPBOOL pbRebootRequired, _Out_ LPGUID pguidAdapter); @@ -141,7 +140,7 @@ struct tap_adapter_node /** - * Creates a list of available network adapters. + * Creates a list of existing network adapters. * * @param hwndParent A handle to the top-level window to use for any user adapter that is * related to non-device-specific actions (such as a select-device dialog @@ -150,24 +149,20 @@ struct tap_adapter_node * hwndParent to NULL. * * @param szHwId A pointer to a NULL-terminated string that supplies the hardware id - * of the device. This pointer is optional and can be NULL. Default value - * is root\tap0901. + * of the device. This pointer is optional and can be NULL. When NULL, + * all network adapters found are added to the list. * * @param ppAdapterList A pointer to the list to receive pointer to the first adapter in * the list. After the list is no longer required, free it using * tap_free_adapter_list(). * - * @param bAll When TRUE, all network adapters found are added to the list. When - * FALSE, only TUN/TAP adapters found are added. - * * @return ERROR_SUCCESS on success; Win32 error code otherwise */ DWORD tap_list_adapters( _In_opt_ HWND hwndParent, _In_opt_ LPCTSTR szHwId, - _Out_ struct tap_adapter_node **ppAdapterList, - _In_ BOOL bAll); + _Out_ struct tap_adapter_node **ppAdapterList); /** From patchwork Mon Mar 9 02:17:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Rozman X-Patchwork-Id: 1031 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director12.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id QGl1IltCZl7gNgAAIUCqbw for ; Mon, 09 Mar 2020 09:19:23 -0400 Received: from proxy15.mail.ord1d.rsapps.net ([172.30.191.6]) by director12.mail.ord1d.rsapps.net with LMTP id eMFJIltCZl7FUAAAIasKDg ; Mon, 09 Mar 2020 09:19:23 -0400 Received: from smtp23.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy15.mail.ord1d.rsapps.net with LMTP id 2MUcIltCZl7GKQAAAY1PeQ ; Mon, 09 Mar 2020 09:19:23 -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: smtp23.gate.ord1d.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=rozman.si; dmarc=fail (p=none; dis=none) header.from=rozman.si X-Suspicious-Flag: YES X-Classification-ID: 975921b0-6208-11ea-acba-525400bfb165-1-1 Received: from [216.105.38.7] ([216.105.38.7:35112] helo=lists.sourceforge.net) by smtp23.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id F5/C7-17906-B52466E5; Mon, 09 Mar 2020 09:19:23 -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 1jBIIh-0000CX-K7; Mon, 09 Mar 2020 13:18:31 +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 1jBIIg-0000Ba-LZ for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:30 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=iFcTPhAWhB6xydh1cRYaVxuL/IIPu9qufsRrWZXlCgY=; b=hryMkkxihar6y/uhRXusoilY3o L4Z2PjZoYOxnqCvfGJwfxbG/0OMGIQijAP6B827I6KbzfDTPuDMOW7lWQc1Nnu/tiF3XqHjkCYnmE Q5OcTVsTgQST5gVapc5WcjPv/gciIDG1C2EgownnOlXAcDf/scrmi6i8dimxLOJcn5IQ=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=iFcTPhAWhB6xydh1cRYaVxuL/IIPu9qufsRrWZXlCgY=; b=DxomrIYdnOvYMR9tLeml6UfhnU Rh5Xp4PZi1i4zzQ05me+TPb+7o7GEKZ2TEOqztgx4VVWmmi/gPqJ1MLgjTsEicByN+C6IgIp87qwR SGXGmq6zEinjmdJxIxm5d3UZnrmPWDrWkkHop2T7H6/4DP2iZ1GFM26hgrQjopCBEIl0=; Received: from pub5.amebis.si ([213.250.55.21]) by sfi-mx-4.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1jBIIc-006jro-QN for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:30 +0000 Received: by pub5.amebis.si (Postfix, from userid 1000) id 85EA61002FCB; Mon, 9 Mar 2020 14:18:03 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rozman.si; s=default; t=1583759883; bh=iFcTPhAWhB6xydh1cRYaVxuL/IIPu9qufsRrWZXlCgY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mqy0RnxZDuzjuzj+zl5nMeBe0fu9Hu+GQm5BlJlKgRUsV/B4M77vvbB1PZ0gQod2S Rs08ER1/kTZ8GqVJcuY5avGniisH6vlbQ8LaO9rOKTpkz/Y5SbJSdARGs+Lilz07yQ v7NzkGKI8xJxXgOB0ptYup2PH22zyp9TgAJjdkGc= X-Spam-Checker-Version: SpamAssassin 3.4.3 (2019-12-06) on brana.amebis.doma X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.3 Received: from SR6.amebis.doma (unknown [IPv6:2a00:ee2:209:164:a5ae:e83c:b7b:725]) by pub5.amebis.si (Postfix) with ESMTP id B95D31002FCF; Mon, 9 Mar 2020 14:17:49 +0100 (CET) From: Simon Rozman To: openvpn-devel@lists.sourceforge.net Date: Mon, 9 Mar 2020 14:17:27 +0100 Message-Id: <20200309131728.380-11-simon@rozman.si> X-Mailer: git-send-email 2.24.1.windows.2 In-Reply-To: <20200309131728.380-1-simon@rozman.si> References: <20200309131728.380-1-simon@rozman.si> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -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 0.0 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1jBIIc-006jro-QN Subject: [Openvpn-devel] [PATCH 11/12] openvpnmsica: Merge FindTUNTAPAdapters into FindSystemInfo 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: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox 1. We don't need two custom actions to evaluate the system state, do we? 2. FindTUNTAPAdapters was actually broken. It enumerated all existing network adapters, rather than just the ones we are interested in: TAP-Windows6 and Wintun. 3. TUNTAPADAPTER and ACTIVETUNTAPADAPTERS were split into TAPWINDOWS6ADAPTERS, ACTIVETAPWINDOWS6ADAPTERS, WINTUNADAPTERS and ACTIVEWINTUNADAPTERS to allow finer control. Signed-off-by: Simon Rozman Acked-by: Lev Stipakov --- src/openvpnmsica/openvpnmsica.c | 235 ++++++++++++++++---------------- src/openvpnmsica/openvpnmsica.h | 26 ++-- 2 files changed, 125 insertions(+), 136 deletions(-) diff --git a/src/openvpnmsica/openvpnmsica.c b/src/openvpnmsica/openvpnmsica.c index ae9b007f..28cf16b5 100644 --- a/src/openvpnmsica/openvpnmsica.c +++ b/src/openvpnmsica/openvpnmsica.c @@ -248,49 +248,26 @@ cleanup_OpenSCManager: } -UINT __stdcall -FindSystemInfo(_In_ MSIHANDLE hInstall) -{ -#ifdef _MSC_VER -#pragma comment(linker, DLLEXP_EXPORT) -#endif - - debug_popup(TEXT(__FUNCTION__)); - - BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL)); - - OPENVPNMSICA_SAVE_MSI_SESSION(hInstall); - - set_openvpnserv_state(hInstall); - - if (bIsCoInitialized) - { - CoUninitialize(); - } - return ERROR_SUCCESS; -} - - -UINT __stdcall -FindTUNTAPAdapters(_In_ MSIHANDLE hInstall) +static UINT +find_adapters( + _In_ MSIHANDLE hInstall, + _In_z_ LPCTSTR szHardwareId, + _In_z_ LPCTSTR szAdaptersPropertyName, + _In_z_ LPCTSTR szActiveAdaptersPropertyName) { -#ifdef _MSC_VER -#pragma comment(linker, DLLEXP_EXPORT) -#endif - - debug_popup(TEXT(__FUNCTION__)); - UINT uiResult; - BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL)); - - OPENVPNMSICA_SAVE_MSI_SESSION(hInstall); - /* Get existing network adapters. */ + /* Get network adapters with given hardware ID. */ struct tap_adapter_node *pAdapterList = NULL; - uiResult = tap_list_adapters(NULL, NULL, &pAdapterList); + uiResult = tap_list_adapters(NULL, szHardwareId, &pAdapterList); if (uiResult != ERROR_SUCCESS) { - goto cleanup_CoInitialize; + return uiResult; + } + else if (pAdapterList == NULL) + { + /* No adapters - no fun. */ + return ERROR_SUCCESS; } /* Get IPv4/v6 info for all network adapters. Actually, we're interested in link status only: up/down? */ @@ -302,7 +279,7 @@ FindTUNTAPAdapters(_In_ MSIHANDLE hInstall) if (pAdapterAdresses == NULL) { msg(M_NONFATAL, "%s: malloc(%u) failed", __FUNCTION__, ulAdapterAdressesSize); - uiResult = ERROR_OUTOFMEMORY; goto cleanup_tap_list_adapters; + uiResult = ERROR_OUTOFMEMORY; goto cleanup_pAdapterList; } ULONG ulResult = GetAdaptersAddresses( @@ -322,117 +299,135 @@ FindTUNTAPAdapters(_In_ MSIHANDLE hInstall) { SetLastError(ulResult); /* MSDN does not mention GetAdaptersAddresses() to set GetLastError(). But we do have an error code. Set last error manually. */ msg(M_NONFATAL | M_ERRNO, "%s: GetAdaptersAddresses() failed", __FUNCTION__); - uiResult = ulResult; goto cleanup_tap_list_adapters; + uiResult = ulResult; goto cleanup_pAdapterList; } } - if (pAdapterList != NULL) + /* Count adapters. */ + size_t adapter_count = 0; + for (struct tap_adapter_node *pAdapter = pAdapterList; pAdapter; pAdapter = pAdapter->pNext) { - /* Count adapters. */ - size_t adapter_count = 0; - for (struct tap_adapter_node *pAdapter = pAdapterList; pAdapter; pAdapter = pAdapter->pNext) - { - adapter_count++; - } + adapter_count++; + } - /* Prepare semicolon delimited list of TAP adapter ID(s) and active TAP adapter ID(s). */ - LPTSTR - szAdapters = (LPTSTR)malloc(adapter_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)), - szAdaptersTail = szAdapters; - if (szAdapters == NULL) - { - msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, adapter_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)); - uiResult = ERROR_OUTOFMEMORY; goto cleanup_pAdapterAdresses; - } + /* Prepare semicolon delimited list of TAP adapter ID(s) and active TAP adapter ID(s). */ + LPTSTR + szAdapters = (LPTSTR)malloc(adapter_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)), + szAdaptersTail = szAdapters; + if (szAdapters == NULL) + { + msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, adapter_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)); + uiResult = ERROR_OUTOFMEMORY; goto cleanup_pAdapterAdresses; + } + + LPTSTR + szAdaptersActive = (LPTSTR)malloc(adapter_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)), + szAdaptersActiveTail = szAdaptersActive; + if (szAdaptersActive == NULL) + { + msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, adapter_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)); + uiResult = ERROR_OUTOFMEMORY; goto cleanup_szAdapters; + } - LPTSTR - szAdaptersActive = (LPTSTR)malloc(adapter_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)), - szAdaptersActiveTail = szAdaptersActive; - if (szAdaptersActive == NULL) + for (struct tap_adapter_node *pAdapter = pAdapterList; pAdapter; pAdapter = pAdapter->pNext) + { + /* Convert adapter GUID to UTF-16 string. (LPOLESTR defaults to LPWSTR) */ + LPOLESTR szAdapterId = NULL; + StringFromIID((REFIID)&pAdapter->guid, &szAdapterId); + + /* Append to the list of TAP adapter ID(s). */ + if (szAdapters < szAdaptersTail) { - msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, adapter_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)); - uiResult = ERROR_OUTOFMEMORY; goto cleanup_szAdapters; + *(szAdaptersTail++) = TEXT(';'); } + memcpy(szAdaptersTail, szAdapterId, 38 * sizeof(TCHAR)); + szAdaptersTail += 38; - for (struct tap_adapter_node *pAdapter = pAdapterList; pAdapter; pAdapter = pAdapter->pNext) + /* If this adapter is active (connected), add it to the list of active TAP adapter ID(s). */ + for (PIP_ADAPTER_ADDRESSES p = pAdapterAdresses; p; p = p->Next) { - /* Convert adapter GUID to UTF-16 string. (LPOLESTR defaults to LPWSTR) */ - LPOLESTR szAdapterId = NULL; - StringFromIID((REFIID)&pAdapter->guid, &szAdapterId); - - /* Append to the list of TAP adapter ID(s). */ - if (szAdapters < szAdaptersTail) - { - *(szAdaptersTail++) = TEXT(';'); - } - memcpy(szAdaptersTail, szAdapterId, 38 * sizeof(TCHAR)); - szAdaptersTail += 38; - - /* If this adapter is active (connected), add it to the list of active TAP adapter ID(s). */ - for (PIP_ADAPTER_ADDRESSES p = pAdapterAdresses; p; p = p->Next) + OLECHAR szId[38 /*GUID*/ + 1 /*terminator*/]; + GUID guid; + if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, p->AdapterName, -1, szId, _countof(szId)) > 0 + && SUCCEEDED(IIDFromString(szId, &guid)) + && memcmp(&guid, &pAdapter->guid, sizeof(GUID)) == 0) { - OLECHAR szId[38 /*GUID*/ + 1 /*terminator*/]; - GUID guid; - if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, p->AdapterName, -1, szId, _countof(szId)) > 0 - && SUCCEEDED(IIDFromString(szId, &guid)) - && memcmp(&guid, &pAdapter->guid, sizeof(GUID)) == 0) + if (p->OperStatus == IfOperStatusUp) { - if (p->OperStatus == IfOperStatusUp) + /* This TAP adapter is active (connected). */ + if (szAdaptersActive < szAdaptersActiveTail) { - /* This TAP adapter is active (connected). */ - if (szAdaptersActive < szAdaptersActiveTail) - { - *(szAdaptersActiveTail++) = TEXT(';'); - } - memcpy(szAdaptersActiveTail, szAdapterId, 38 * sizeof(TCHAR)); - szAdaptersActiveTail += 38; + *(szAdaptersActiveTail++) = TEXT(';'); } - break; + memcpy(szAdaptersActiveTail, szAdapterId, 38 * sizeof(TCHAR)); + szAdaptersActiveTail += 38; } + break; } - CoTaskMemFree(szAdapterId); - } - szAdaptersTail [0] = 0; - szAdaptersActiveTail[0] = 0; - - /* Set Installer TUNTAPADAPTERS property. */ - uiResult = MsiSetProperty(hInstall, TEXT("TUNTAPADAPTERS"), szAdapters); - if (uiResult != ERROR_SUCCESS) - { - SetLastError(uiResult); /* MSDN does not mention MsiSetProperty() to set GetLastError(). But we do have an error code. Set last error manually. */ - msg(M_NONFATAL | M_ERRNO, "%s: MsiSetProperty(\"TUNTAPADAPTERS\") failed", __FUNCTION__); - goto cleanup_szAdaptersActive; - } - - /* Set Installer ACTIVETUNTAPADAPTERS property. */ - uiResult = MsiSetProperty(hInstall, TEXT("ACTIVETUNTAPADAPTERS"), szAdaptersActive); - if (uiResult != ERROR_SUCCESS) - { - SetLastError(uiResult); /* MSDN does not mention MsiSetProperty() to set GetLastError(). But we do have an error code. Set last error manually. */ - msg(M_NONFATAL | M_ERRNO, "%s: MsiSetProperty(\"ACTIVETUNTAPADAPTERS\") failed", __FUNCTION__); - goto cleanup_szAdaptersActive; } + CoTaskMemFree(szAdapterId); + } + szAdaptersTail [0] = 0; + szAdaptersActiveTail[0] = 0; -cleanup_szAdaptersActive: - free(szAdaptersActive); -cleanup_szAdapters: - free(szAdapters); + /* Set Installer properties. */ + uiResult = MsiSetProperty(hInstall, szAdaptersPropertyName, szAdapters); + if (uiResult != ERROR_SUCCESS) + { + SetLastError(uiResult); /* MSDN does not mention MsiSetProperty() to set GetLastError(). But we do have an error code. Set last error manually. */ + msg(M_NONFATAL | M_ERRNO, "%s: MsiSetProperty(\"%s\") failed", __FUNCTION__, szAdaptersPropertyName); + goto cleanup_szAdaptersActive; } - else + uiResult = MsiSetProperty(hInstall, szActiveAdaptersPropertyName, szAdaptersActive); + if (uiResult != ERROR_SUCCESS) { - uiResult = ERROR_SUCCESS; + SetLastError(uiResult); /* MSDN does not mention MsiSetProperty() to set GetLastError(). But we do have an error code. Set last error manually. */ + msg(M_NONFATAL | M_ERRNO, "%s: MsiSetProperty(\"%s\") failed", __FUNCTION__, szActiveAdaptersPropertyName); + goto cleanup_szAdaptersActive; } +cleanup_szAdaptersActive: + free(szAdaptersActive); +cleanup_szAdapters: + free(szAdapters); cleanup_pAdapterAdresses: free(pAdapterAdresses); -cleanup_tap_list_adapters: +cleanup_pAdapterList: tap_free_adapter_list(pAdapterList); -cleanup_CoInitialize: + return uiResult; +} + + +UINT __stdcall +FindSystemInfo(_In_ MSIHANDLE hInstall) +{ +#ifdef _MSC_VER +#pragma comment(linker, DLLEXP_EXPORT) +#endif + + debug_popup(TEXT(__FUNCTION__)); + + BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL)); + + OPENVPNMSICA_SAVE_MSI_SESSION(hInstall); + + set_openvpnserv_state(hInstall); + find_adapters( + hInstall, + TEXT("root\\") TEXT(TAP_WIN_COMPONENT_ID), + TEXT("TAPWINDOWS6ADAPTERS"), + TEXT("ACTIVETAPWINDOWS6ADAPTERS")); + find_adapters( + hInstall, + TEXT("Wintun"), + TEXT("WINTUNADAPTERS"), + TEXT("ACTIVEWINTUNADAPTERS")); + if (bIsCoInitialized) { CoUninitialize(); } - return uiResult; + return ERROR_SUCCESS; } diff --git a/src/openvpnmsica/openvpnmsica.h b/src/openvpnmsica/openvpnmsica.h index 5d140930..221d03ca 100644 --- a/src/openvpnmsica/openvpnmsica.h +++ b/src/openvpnmsica/openvpnmsica.h @@ -76,23 +76,17 @@ extern "C" { /** * Determines Windows information: - * - Sets `DriverCertification` MSI property to "", "attsgn" or "whql" - * according to the driver certification required by the running version of - * Windows. * - * @param hInstall Handle to the installation provided to the DLL custom action + * - Sets `OPENVPNSERVICE` MSI property to PID of OpenVPN Service if running, or its EXE path if + * configured for auto-start. * - * @return ERROR_SUCCESS on success; An error code otherwise - * See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa368072.aspx - */ -DLLEXP_DECL UINT __stdcall -FindSystemInfo(_In_ MSIHANDLE hInstall); - - -/** - * Find existing TAP adapters and set TUNTAPADAPTERS and ACTIVETUNTAPADAPTERS properties with - * semicolon delimited list of all installed TAP adapter GUIDs and active adapter GUIDs - * respectively. + * - Finds existing TAP-Windows6 adapters and set TAPWINDOWS6ADAPTERS and + * ACTIVETAPWINDOWS6ADAPTERS properties with semicolon delimited list of all installed adapter + * GUIDs and active adapter GUIDs respectively. + * + * - Finds existing Wintun adapters and set WINTUNADAPTERS and ACTIVEWINTUNADAPTERS properties + * with semicolon delimited list of all installed adapter GUIDs and active adapter GUIDs + * respectively. * * @param hInstall Handle to the installation provided to the DLL custom action * @@ -100,7 +94,7 @@ FindSystemInfo(_In_ MSIHANDLE hInstall); * See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa368072.aspx */ DLLEXP_DECL UINT __stdcall -FindTUNTAPAdapters(_In_ MSIHANDLE hInstall); +FindSystemInfo(_In_ MSIHANDLE hInstall); /** From patchwork Mon Mar 9 02:17:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Rozman X-Patchwork-Id: 1025 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director9.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id mITVElVCZl5PJgAAIUCqbw for ; Mon, 09 Mar 2020 09:19:17 -0400 Received: from proxy8.mail.ord1d.rsapps.net ([172.30.191.6]) by director9.mail.ord1d.rsapps.net with LMTP id 0Pm5ElVCZl5lVgAAalYnBA ; Mon, 09 Mar 2020 09:19:17 -0400 Received: from smtp11.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy8.mail.ord1d.rsapps.net with LMTP id KJQTElVCZl77QQAAGdz6CA ; Mon, 09 Mar 2020 09:19:17 -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: smtp11.gate.ord1d.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=rozman.si; dmarc=fail (p=none; dis=none) header.from=rozman.si X-Suspicious-Flag: YES X-Classification-ID: 939c156e-6208-11ea-94e3-5254005f837b-1-1 Received: from [216.105.38.7] ([216.105.38.7:35074] helo=lists.sourceforge.net) by smtp11.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 42/6D-24136-452466E5; Mon, 09 Mar 2020 09:19:17 -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 1jBIIa-0000AJ-QU; Mon, 09 Mar 2020 13:18:24 +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 1jBIIY-00009m-B7 for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=ysCktyMK78Y08grw1KkbA6RgpuuBRb9q6F3zd2nXRN0=; b=DPIZEYUDXVMkgzyw/XiKON0hCz 7a7/BV83FDbys9/JO1eMUSyMw1h8hclTePFIimpngALp8KYDCwhRzsO1adZG0y2r40pJ6nvOzqA9b Vj06ikPa7aqxolwLg3ZMU3jhIRTvwcW7C0ls1HRRQ+M+dwD7HcnwFkczz0PGfsr4g/qk=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=ysCktyMK78Y08grw1KkbA6RgpuuBRb9q6F3zd2nXRN0=; b=VIxUrnKhXdddYlaVEULczhOeti jlpr0F34iv3cR1OZhPotyuvLoGWSjqUYMuMNesOvDNnx8EzRUNKmY5shndvvVu1/EUZ6KBhwAFM/R B38V5RuK4N8deuFH1rqJOy5RimOzyYgLBC9QVM2mpA6a2g2Wy0C5fLlx6IM20Gl93fog=; Received: from pub5.amebis.si ([213.250.55.21]) by sfi-mx-3.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1jBIIW-0033Qj-BJ for openvpn-devel@lists.sourceforge.net; Mon, 09 Mar 2020 13:18:22 +0000 Received: by pub5.amebis.si (Postfix, from userid 1000) id 96CFA1002FCD; Mon, 9 Mar 2020 14:18:03 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rozman.si; s=default; t=1583759883; bh=ysCktyMK78Y08grw1KkbA6RgpuuBRb9q6F3zd2nXRN0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BJy8Y+vIuveCkuSgJQJzo5FuotcDijtDhMFSIWRey2ZGOpCPZxfjHRjpaCU+Jn7Sl vPd3NfEJ6rlr1jK9fp96cADp6CDF6J+Ya17D+l0roGOZYYdZmLVeDsLN09zGIHHisA rffn8wkflf6SfUpfI0C2cTY6VY5K8d/Xr+LCnqYw= X-Spam-Checker-Version: SpamAssassin 3.4.3 (2019-12-06) on brana.amebis.doma X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00 autolearn=ham autolearn_force=no version=3.4.3 Received: from SR6.amebis.doma (unknown [IPv6:2a00:ee2:209:164:a5ae:e83c:b7b:725]) by pub5.amebis.si (Postfix) with ESMTP id CB19A1002FE8; Mon, 9 Mar 2020 14:17:49 +0100 (CET) From: Simon Rozman To: openvpn-devel@lists.sourceforge.net Date: Mon, 9 Mar 2020 14:17:28 +0100 Message-Id: <20200309131728.380-12-simon@rozman.si> X-Mailer: git-send-email 2.24.1.windows.2 In-Reply-To: <20200309131728.380-1-simon@rozman.si> References: <20200309131728.380-1-simon@rozman.si> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -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 0.0 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1jBIIW-0033Qj-BJ Subject: [Openvpn-devel] [PATCH 12/12] tapctl: Support multiple hardware IDs 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: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox TAP-Windows6 adapters created with tapinstall/devcon.exe have hardware ID "tap0901", where TAP-Windows6 adapters created with tapctl.exe have hardware ID "root\\tap0901". The enumeration of the network adapters have been extended to detect adapters using a list of acceptable hardware IDs. Signed-off-by: Simon Rozman --- src/openvpnmsica/openvpnmsica.c | 43 ++++++++++++++++++--------------- src/tapctl/main.c | 8 +++--- src/tapctl/tap.c | 21 ++++++++++++---- src/tapctl/tap.h | 8 +++--- 4 files changed, 48 insertions(+), 32 deletions(-) diff --git a/src/openvpnmsica/openvpnmsica.c b/src/openvpnmsica/openvpnmsica.c index 28cf16b5..31e90bd2 100644 --- a/src/openvpnmsica/openvpnmsica.c +++ b/src/openvpnmsica/openvpnmsica.c @@ -251,7 +251,7 @@ cleanup_OpenSCManager: static UINT find_adapters( _In_ MSIHANDLE hInstall, - _In_z_ LPCTSTR szHardwareId, + _In_z_ LPCTSTR szzHardwareIDs, _In_z_ LPCTSTR szAdaptersPropertyName, _In_z_ LPCTSTR szActiveAdaptersPropertyName) { @@ -259,7 +259,7 @@ find_adapters( /* Get network adapters with given hardware ID. */ struct tap_adapter_node *pAdapterList = NULL; - uiResult = tap_list_adapters(NULL, szHardwareId, &pAdapterList); + uiResult = tap_list_adapters(NULL, szzHardwareIDs, &pAdapterList); if (uiResult != ERROR_SUCCESS) { return uiResult; @@ -414,12 +414,12 @@ FindSystemInfo(_In_ MSIHANDLE hInstall) set_openvpnserv_state(hInstall); find_adapters( hInstall, - TEXT("root\\") TEXT(TAP_WIN_COMPONENT_ID), + TEXT("root\\") TEXT(TAP_WIN_COMPONENT_ID) TEXT("\0") TEXT(TAP_WIN_COMPONENT_ID) TEXT("\0"), TEXT("TAPWINDOWS6ADAPTERS"), TEXT("ACTIVETAPWINDOWS6ADAPTERS")); find_adapters( hInstall, - TEXT("Wintun"), + TEXT("Wintun") TEXT("\0"), TEXT("WINTUNADAPTERS"), TEXT("ACTIVEWINTUNADAPTERS")); @@ -652,7 +652,7 @@ cleanup_pAdapterList: * * @param szDisplayName Adapter display name * - * @param szHardwareId Adapter hardware ID + * @param szzHardwareIDs String of strings with acceptable adapter hardware IDs * * @param iTicks Pointer to an integer that represents amount of work (on progress * indicator) the UninstallTUNTAPAdapters will take. This function increments @@ -666,12 +666,12 @@ schedule_adapter_delete( _Inout_opt_ struct msica_arg_seq *seqCommit, _Inout_opt_ struct msica_arg_seq *seqRollback, _In_z_ LPCTSTR szDisplayName, - _In_z_ LPCTSTR szHardwareId, + _In_z_ LPCTSTR szzHardwareIDs, _Inout_ int *iTicks) { /* Get adapters with given hardware ID. */ struct tap_adapter_node *pAdapterList = NULL; - DWORD dwResult = tap_list_adapters(NULL, szHardwareId, &pAdapterList); + DWORD dwResult = tap_list_adapters(NULL, szzHardwareIDs, &pAdapterList); if (dwResult != ERROR_SUCCESS) { return dwResult; @@ -858,11 +858,16 @@ EvaluateTUNTAPAdapters(_In_ MSIHANDLE hInstall) szDisplayNameEx = szDisplayNameEx != NULL ? szDisplayNameEx + 1 : szDisplayName; /* Get adapter hardware ID (`HardwareId` is field #5). */ - LPTSTR szHardwareId = NULL; - uiResult = msi_get_record_string(hRecord, 5, &szHardwareId); - if (uiResult != ERROR_SUCCESS) + TCHAR szzHardwareIDs[0x100] = { 0 }; { - goto cleanup_szDisplayName; + LPTSTR szHwId = NULL; + uiResult = msi_get_record_string(hRecord, 5, &szHwId); + if (uiResult != ERROR_SUCCESS) + { + goto cleanup_szDisplayName; + } + memcpy_s(szzHardwareIDs, sizeof(szzHardwareIDs) - 2*sizeof(TCHAR) /*requires double zero termination*/, szHwId, _tcslen(szHwId)*sizeof(TCHAR)); + free(szHwId); } if (iAction > INSTALLSTATE_BROKEN) @@ -876,7 +881,7 @@ EvaluateTUNTAPAdapters(_In_ MSIHANDLE hInstall) uiResult = msi_get_record_string(hRecord, 3, &szValue); if (uiResult != ERROR_SUCCESS) { - goto cleanup_szHardwareId; + goto cleanup_szDisplayName; } #ifdef __GNUC__ /* @@ -890,13 +895,13 @@ EvaluateTUNTAPAdapters(_In_ MSIHANDLE hInstall) { case MSICONDITION_FALSE: free(szValue); - goto cleanup_szHardwareId; + goto cleanup_szDisplayName; case MSICONDITION_ERROR: uiResult = ERROR_INVALID_FIELD; msg(M_NONFATAL | M_ERRNO, "%s: MsiEvaluateCondition(\"%" PRIsLPTSTR "\") failed", __FUNCTION__, szValue); free(szValue); - goto cleanup_szHardwareId; + goto cleanup_szDisplayName; } #ifdef __GNUC__ #pragma GCC diagnostic pop @@ -908,11 +913,11 @@ EvaluateTUNTAPAdapters(_In_ MSIHANDLE hInstall) &seqInstall, bRollbackEnabled ? &seqInstallRollback : NULL, szDisplayNameEx, - szHardwareId, + szzHardwareIDs, &iTicks) != ERROR_SUCCESS) { uiResult = ERROR_INSTALL_FAILED; - goto cleanup_szHardwareId; + goto cleanup_szDisplayName; } } else @@ -927,7 +932,7 @@ EvaluateTUNTAPAdapters(_In_ MSIHANDLE hInstall) bRollbackEnabled ? &seqUninstallCommit : NULL, bRollbackEnabled ? &seqUninstallRollback : NULL, szDisplayNameEx, - szHardwareId, + szzHardwareIDs, &iTicks); } @@ -938,12 +943,10 @@ EvaluateTUNTAPAdapters(_In_ MSIHANDLE hInstall) if (MsiProcessMessage(hInstall, INSTALLMESSAGE_PROGRESS, hRecordProg) == IDCANCEL) { uiResult = ERROR_INSTALL_USEREXIT; - goto cleanup_szHardwareId; + goto cleanup_szDisplayName; } } -cleanup_szHardwareId: - free(szHardwareId); cleanup_szDisplayName: free(szDisplayName); cleanup_hRecord: diff --git a/src/tapctl/main.c b/src/tapctl/main.c index fdeda7bf..40164879 100644 --- a/src/tapctl/main.c +++ b/src/tapctl/main.c @@ -271,14 +271,16 @@ create_delete_adapter: } else if (_tcsicmp(argv[1], TEXT("list")) == 0) { - LPCTSTR szHwId = TEXT("root\\") TEXT(TAP_WIN_COMPONENT_ID); + TCHAR szzHwId[0x100] = TEXT("root\\") TEXT(TAP_WIN_COMPONENT_ID) TEXT("\0") TEXT(TAP_WIN_COMPONENT_ID) TEXT("\0"); /* Parse options. */ for (int i = 2; i < argc; i++) { if (_tcsicmp(argv[i], TEXT("--hwid")) == 0) { - szHwId = argv[++i]; + memset(szzHwId, 0, sizeof(szzHwId)); + memcpy_s(szzHwId, sizeof(szzHwId) - 2*sizeof(TCHAR) /*requires double zero termination*/, argv[i], _tcslen(argv[i])*sizeof(TCHAR)); + ++i; } else { @@ -288,7 +290,7 @@ create_delete_adapter: /* Output list of adapters with given hardware ID. */ struct tap_adapter_node *pAdapterList = NULL; - DWORD dwResult = tap_list_adapters(NULL, szHwId, &pAdapterList); + DWORD dwResult = tap_list_adapters(NULL, szzHwId, &pAdapterList); if (dwResult != ERROR_SUCCESS) { _ftprintf(stderr, TEXT("Enumerating TUN/TAP adapters failed (error 0x%x).\n"), dwResult); diff --git a/src/tapctl/tap.c b/src/tapctl/tap.c index bdef3fc1..8ece3fb9 100644 --- a/src/tapctl/tap.c +++ b/src/tapctl/tap.c @@ -1179,7 +1179,7 @@ cleanup_szAdapterId: DWORD tap_list_adapters( _In_opt_ HWND hwndParent, - _In_opt_ LPCTSTR szHwId, + _In_opt_ LPCTSTR szzHwIDs, _Out_ struct tap_adapter_node **ppAdapter) { DWORD dwResult; @@ -1260,7 +1260,7 @@ tap_list_adapters( /* Check that hardware ID is REG_SZ/REG_MULTI_SZ, and optionally if it matches ours. */ if (dwDataType == REG_SZ) { - if (szHwId && _tcsicmp(szzDeviceHardwareIDs, szHwId) != 0) + if (szzHwIDs && !_tcszistr(szzHwIDs, szzDeviceHardwareIDs)) { /* This is not our device. Skip it. */ goto cleanup_szzDeviceHardwareIDs; @@ -1268,10 +1268,21 @@ tap_list_adapters( } else if (dwDataType == REG_MULTI_SZ) { - if (szHwId && _tcszistr(szzDeviceHardwareIDs, szHwId) == NULL) + if (szzHwIDs) { - /* This is not our device. Skip it. */ - goto cleanup_szzDeviceHardwareIDs; + for (LPTSTR s = szzDeviceHardwareIDs;; s += _tcslen(s) + 1) + { + if (s[0] == 0) + { + /* This is not our device. Skip it. */ + goto cleanup_szzDeviceHardwareIDs; + } + else if (_tcszistr(szzHwIDs, s)) + { + /* This is our device. */ + break; + } + } } } else diff --git a/src/tapctl/tap.h b/src/tapctl/tap.h index 68662c82..102de32d 100644 --- a/src/tapctl/tap.h +++ b/src/tapctl/tap.h @@ -148,9 +148,9 @@ struct tap_adapter_node * and can be NULL. If a specific top-level window is not required, set * hwndParent to NULL. * - * @param szHwId A pointer to a NULL-terminated string that supplies the hardware id - * of the device. This pointer is optional and can be NULL. When NULL, - * all network adapters found are added to the list. + * @param szzHwIDs A string of strings that supplies the list of hardware IDs of the device. + * This pointer is optional and can be NULL. When NULL, all network adapters + * found are added to the list. * * @param ppAdapterList A pointer to the list to receive pointer to the first adapter in * the list. After the list is no longer required, free it using @@ -161,7 +161,7 @@ struct tap_adapter_node DWORD tap_list_adapters( _In_opt_ HWND hwndParent, - _In_opt_ LPCTSTR szHwId, + _In_opt_ LPCTSTR szzHwIDs, _Out_ struct tap_adapter_node **ppAdapterList);