From patchwork Fri Nov 14 21:21:07 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gert Doering X-Patchwork-Id: 4600 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:6d04:b0:7b1:439f:bdf with SMTP id e4csp1834409may; Fri, 14 Nov 2025 13:21:25 -0800 (PST) X-Forwarded-Encrypted: i=2; AJvYcCV2Y3CgkuNDlTe0IL8iYZglo3jMiZGmJqjqfxw8QkiGxL5Wmu5B/7qeB25iG3eSKFYU9RLJvfMgkOQ=@openvpn.net X-Google-Smtp-Source: AGHT+IGyRuvkKVXLwo8uNhXFlU0b1jgv/BantC9d+f6QE9Bd7DXkfyqFP0hllRoys5haYtF1mDay X-Received: by 2002:a05:6830:2aab:b0:7c6:e92f:41df with SMTP id 46e09a7af769-7c74446b276mr3775426a34.12.1763155284881; Fri, 14 Nov 2025 13:21:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1763155284; cv=none; d=google.com; s=arc-20240605; b=Hxa54jEvOcgbvaUnmKgJBAQNvjH9wpAShNacJrOawfeNN7D5UM0HPjJIpQHhTbCvUx wFhOKxjfaDTEX8KLEVfJoFlJGHhVFJFixsme/uZSoM23fIbfGDrHSAwY/8TyZQ+1R1pg 9QMOls9wCq0Z3KRYzk/O2qb3fPsSC4DHHL8vW3pL+IR2ltNRg1BK8alVYYxZngO4JL4h MrQUKpOscfrPCyzQMQW9w6qwNF4cnyPG0QBejzJSHTZhDwk6X0dCbs5TfL4ooR1gc05v hgC3ZXI2SosXkHJSCBg1O8vWBb3bnveBmyw1qHfZRCyd3TCU1sQwmLqyStkByl0k477d 1YLA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature:dkim-signature:dkim-signature; bh=etVgBC8pQ3YHPQqXsvV2R0lukatwgjwA+y5oXCqMiiE=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=MDqAnXvTzXxmzkf91Bv4Zt1miUaed8BIxb6UkLidGapjqSAIfVfijX8VBcRU2BnKI2 6+X4y8D2EHrEIpr1bmiv7sIkJSamn0H1gS4Q8EDxZ2AjgO9nygvdD7HAjUJ5y/mwcCwy xn21mgsenjdePe8G5ryzPAW3S+HCRa+bdvCYOSSyNmiqIkqGICR+Wqll3Ef1Ys8uK3JE dgsAcMSZ594+sFc6NQSgpKZ3TYEkEkrAFypSTAsGgwfADHUR/wt7gWlBO6nl7eYc1CRx bhg8Hcy5N4rLRfd6ofV0WjKsLff7/JJXgh7M/Dj3CXf0riJDue9fMZYDpr45zi1+iywm pRwA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=VdGM7ceG; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=cQgdDI7G; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=OPVmwwAM; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 46e09a7af769-7c73a3ded3fsi2436106a34.472.2025.11.14.13.21.24 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 14 Nov 2025 13:21:24 -0800 (PST) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=VdGM7ceG; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=cQgdDI7G; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=OPVmwwAM; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: Subject:MIME-Version:References:In-Reply-To:Message-ID:Date:To:From:Sender: Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=etVgBC8pQ3YHPQqXsvV2R0lukatwgjwA+y5oXCqMiiE=; b=VdGM7ceGkjaq7loYM0YCBcFPj3 CjU/JnFJPNE4ubhHwoiZGdww3jfTXvKgyTAqF5ukjMIMWyItELNovtJQ/aIC92aKnr1s/yPHOQvyI GxLuQ4KKAPdGTYr9tXfjPXy6I30heEgqvLlUv+stzyPULy7EkoBJJ+9pCF9aVQuFx5Gw=; 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.95) (envelope-from ) id 1vK1EP-0004iP-PC; Fri, 14 Nov 2025 21:21:22 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1vK1EO-0004iC-M4 for openvpn-devel@lists.sourceforge.net; Fri, 14 Nov 2025 21:21: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:To:From:Sender:Reply-To:Cc: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=a8Zc1bJg4iAXSko79KOzDE06K6ceHRAnETdjOkn4Xv4=; b=cQgdDI7GqCsxHqXQbWAWDyCw/W PVUYofakYSF1DTTm6+51XaW+KMpnDet3re9MSf2bspnRs8j2vTiPMp7cgd/zYeoqbxgDEjQevcW4c hHj6kt08m6KsArYiJfw8/K4x5XPEScO23UOdpZAk/Z4vg/QAxSQQuzC1sWMMne8LmyZs=; 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:To:From:Sender:Reply-To:Cc: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=a8Zc1bJg4iAXSko79KOzDE06K6ceHRAnETdjOkn4Xv4=; b=OPVmwwAMC+0r30/fGj+8egpdqv WlMXLSWjGr1CoLeFIghO31yC1sDLPPC914bamewk2wTi645fkhdmt0fA/6eK0bAngPy3SqSMVXZsO PGTEec+fUTSuYQcknJ2T94Jtr7zNMfC8zrjJ4+7EoSb17l1TmC6VfrHYte2FL5FWExY8=; Received: from [193.149.48.134] (helo=blue.greenie.muc.de) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1vK1EO-0006dj-5f for openvpn-devel@lists.sourceforge.net; Fri, 14 Nov 2025 21:21:21 +0000 Received: from blue.greenie.muc.de (localhost [127.0.0.1]) by blue.greenie.muc.de (8.18.1/8.18.1) with ESMTP id 5AELLDTG006413 for ; Fri, 14 Nov 2025 22:21:13 +0100 Received: (from gert@localhost) by blue.greenie.muc.de (8.18.1/8.18.1/Submit) id 5AELLDxc006412 for openvpn-devel@lists.sourceforge.net; Fri, 14 Nov 2025 22:21:13 +0100 From: Gert Doering To: openvpn-devel@lists.sourceforge.net Date: Fri, 14 Nov 2025 22:21:07 +0100 Message-ID: <20251114212112.6370-1-gert@greenie.muc.de> X-Mailer: git-send-email 2.49.1 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Score: 1.3 (+) X-Spam-Report: Spam detection software, running on the system "sfi-spamd-2.hosts.colo.sdot.me", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: From: Lev Stipakov Change-Id: I432e07216f9adb8f767af172fa37b626b350f994 Signed-off-by: Lev Stipakov Acked-by: Gert Doering Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1370 [...] Content analysis details: (1.3 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 1.3 RDNS_NONE Delivered to internal network by a host with no rDNS X-Headers-End: 1vK1EO-0006dj-5f Subject: [Openvpn-devel] [PATCH v1] tapctl: factor out command handlers 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 X-GMAIL-THRID: =?utf-8?q?1848802316026998703?= X-GMAIL-MSGID: =?utf-8?q?1848802316026998703?= From: Lev Stipakov Change-Id: I432e07216f9adb8f767af172fa37b626b350f994 Signed-off-by: Lev Stipakov Acked-by: Gert Doering Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1370 --- This change was reviewed on Gerrit and approved by at least one developer. I request to merge it to master. Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1370 This mail reflects revision 1 of this Change. Acked-by according to Gerrit (reflected above): Gert Doering diff --git a/src/tapctl/main.c b/src/tapctl/main.c index 031e262..3caffd8 100644 --- a/src/tapctl/main.c +++ b/src/tapctl/main.c @@ -201,6 +201,198 @@ return NULL; } +static int command_create(int argc, LPCWSTR argv[], BOOL *bRebootRequired); +static int command_list(int argc, LPCWSTR argv[]); +static int command_delete(int argc, LPCWSTR argv[], BOOL *bRebootRequired); + +static int +command_create(int argc, LPCWSTR argv[], BOOL *bRebootRequired) +{ + LPCWSTR szName = NULL; + LPCWSTR szHwId = L"root\\" _L(TAP_WIN_COMPONENT_ID); + struct tap_adapter_node *adapter_list = NULL; + LPWSTR adapter_name = NULL; + LPOLESTR adapter_id = NULL; + GUID guidAdapter; + int result = 1; + + for (int i = 2; i < argc; i++) + { + if (wcsicmp(argv[i], L"--name") == 0) + { + szName = argv[++i]; + } + else if (wcsicmp(argv[i], L"--hwid") == 0) + { + szHwId = argv[++i]; + } + else + { + fwprintf(stderr, + L"Unknown option \"%ls" + L"\". Please, use \"tapctl help create\" to list supported options. Ignored.\n", + argv[i]); + } + } + + DWORD dwResult = + tap_create_adapter(NULL, L"Virtual Ethernet", szHwId, bRebootRequired, &guidAdapter); + if (dwResult != ERROR_SUCCESS) + { + fwprintf(stderr, L"Creating TUN/TAP adapter failed (error 0x%x).\n", dwResult); + return result; + } + + dwResult = tap_list_adapters(NULL, NULL, &adapter_list); + if (dwResult != ERROR_SUCCESS) + { + fwprintf(stderr, L"Enumerating adapters failed (error 0x%x).\n", dwResult); + tap_delete_adapter(NULL, &guidAdapter, bRebootRequired); + return result; + } + + adapter_name = szName ? wcsdup(szName) : get_unique_adapter_name(szHwId, adapter_list); + if (adapter_name) + { + if (szName && !is_adapter_name_available(adapter_name, adapter_list, TRUE)) + { + tap_delete_adapter(NULL, &guidAdapter, bRebootRequired); + goto cleanup; + } + + dwResult = tap_set_adapter_name(&guidAdapter, adapter_name, FALSE); + if (dwResult != ERROR_SUCCESS) + { + StringFromIID((REFIID)&guidAdapter, &adapter_id); + fwprintf(stderr, + L"Renaming TUN/TAP adapter %ls" + L" to \"%ls\" failed (error 0x%x).\n", + adapter_id, adapter_name, dwResult); + CoTaskMemFree(adapter_id); + goto cleanup; + } + } + + result = 0; + +cleanup: + free(adapter_name); + tap_free_adapter_list(adapter_list); + + if (result == 0) + { + StringFromIID((REFIID)&guidAdapter, &adapter_id); + fwprintf(stdout, L"%ls\n", adapter_id); + CoTaskMemFree(adapter_id); + } + + return result; +} + +static int +command_list(int argc, LPCWSTR argv[]) +{ + WCHAR szzHwId[0x100] = + L"root\\" _L(TAP_WIN_COMPONENT_ID) L"\0" _L(TAP_WIN_COMPONENT_ID) L"\0" + L"ovpn-dco\0"; + + for (int i = 2; i < argc; i++) + { + if (wcsicmp(argv[i], L"--hwid") == 0) + { + memset(szzHwId, 0, sizeof(szzHwId)); + ++i; + memcpy_s(szzHwId, + sizeof(szzHwId) - 2 * sizeof(WCHAR), + argv[i], wcslen(argv[i]) * sizeof(WCHAR)); + } + else + { + fwprintf(stderr, + L"Unknown option \"%ls" + L"\". Please, use \"tapctl help list\" to list supported options. Ignored.\n", + argv[i]); + } + } + + struct tap_adapter_node *adapter_list = NULL; + DWORD dwResult = tap_list_adapters(NULL, szzHwId, &adapter_list); + if (dwResult != ERROR_SUCCESS) + { + fwprintf(stderr, L"Enumerating TUN/TAP adapters failed (error 0x%x).\n", dwResult); + return 1; + } + + for (struct tap_adapter_node *adapter = adapter_list; adapter; adapter = adapter->pNext) + { + LPOLESTR adapter_id = NULL; + StringFromIID((REFIID)&adapter->guid, &adapter_id); + fwprintf(stdout, + L"%ls\t%" + L"ls\n", + adapter_id, adapter->szName); + CoTaskMemFree(adapter_id); + } + + tap_free_adapter_list(adapter_list); + + return 0; +} + +static int +command_delete(int argc, LPCWSTR argv[], BOOL *bRebootRequired) +{ + if (argc < 3) + { + fwprintf(stderr, + L"Missing adapter GUID or name. Please, use \"tapctl help delete\" for usage info.\n"); + return 1; + } + + GUID guidAdapter; + if (FAILED(IIDFromString(argv[2], (LPIID)&guidAdapter))) + { + struct tap_adapter_node *adapter_list = NULL; + DWORD dwResult = tap_list_adapters(NULL, NULL, &adapter_list); + if (dwResult != ERROR_SUCCESS) + { + fwprintf(stderr, L"Enumerating TUN/TAP adapters failed (error 0x%x).\n", dwResult); + return 1; + } + + BOOL found = FALSE; + for (struct tap_adapter_node *adapter = adapter_list; adapter; adapter = adapter->pNext) + { + if (wcsicmp(argv[2], adapter->szName) == 0) + { + memcpy(&guidAdapter, &adapter->guid, sizeof(GUID)); + found = TRUE; + break; + } + } + + tap_free_adapter_list(adapter_list); + + if (!found) + { + fwprintf(stderr, L"\"%ls\" adapter not found.\n", argv[2]); + return 1; + } + } + + DWORD dwResult = tap_delete_adapter(NULL, &guidAdapter, bRebootRequired); + if (dwResult != ERROR_SUCCESS) + { + fwprintf(stderr, + L"Deleting adapter \"%ls" + L"\" failed (error 0x%x).\n", + argv[2], dwResult); + return 1; + } + + return 0; +} + /** * Program entry point */ @@ -248,215 +440,17 @@ } else if (wcsicmp(argv[1], L"create") == 0) { - LPCWSTR szName = NULL; - LPCWSTR szHwId = L"root\\" _L(TAP_WIN_COMPONENT_ID); - - /* Parse options. */ - for (int i = 2; i < argc; i++) - { - if (wcsicmp(argv[i], L"--name") == 0) - { - szName = argv[++i]; - } - else if (wcsicmp(argv[i], L"--hwid") == 0) - { - szHwId = argv[++i]; - } - else - { - fwprintf( - stderr, - L"Unknown option \"%ls" - L"\". Please, use \"tapctl help create\" to list supported options. Ignored.\n", - argv[i]); - } - } - - /* Create TUN/TAP adapter. */ - GUID guidAdapter; - LPOLESTR szAdapterId = NULL; - DWORD dwResult = - tap_create_adapter(NULL, L"Virtual Ethernet", szHwId, &bRebootRequired, &guidAdapter); - if (dwResult != ERROR_SUCCESS) - { - fwprintf(stderr, L"Creating TUN/TAP adapter failed (error 0x%x).\n", dwResult); - iResult = 1; - goto quit; - } - - /* Get existing network adapters. */ - struct tap_adapter_node *pAdapterList = NULL; - dwResult = tap_list_adapters(NULL, NULL, &pAdapterList); - if (dwResult != ERROR_SUCCESS) - { - fwprintf(stderr, L"Enumerating adapters failed (error 0x%x).\n", dwResult); - iResult = 1; - goto create_delete_adapter; - } - - LPWSTR adapter_name = - szName ? wcsdup(szName) : get_unique_adapter_name(szHwId, pAdapterList); - if (adapter_name) - { - /* Check for duplicates when name was specified, - * otherwise get_adapter_default_name() takes care of it */ - if (szName && !is_adapter_name_available(adapter_name, pAdapterList, TRUE)) - { - iResult = 1; - goto create_cleanup_pAdapterList; - } - - /* Rename the adapter. */ - dwResult = tap_set_adapter_name(&guidAdapter, adapter_name, FALSE); - if (dwResult != ERROR_SUCCESS) - { - StringFromIID((REFIID)&guidAdapter, &szAdapterId); - fwprintf(stderr, - L"Renaming TUN/TAP adapter %ls" - L" to \"%ls\" failed (error 0x%x).\n", - szAdapterId, adapter_name, dwResult); - CoTaskMemFree(szAdapterId); - iResult = 1; - goto quit; - } - } - - iResult = 0; - -create_cleanup_pAdapterList: - free(adapter_name); - - tap_free_adapter_list(pAdapterList); - if (iResult) - { - goto create_delete_adapter; - } - - /* Output adapter GUID. */ - StringFromIID((REFIID)&guidAdapter, &szAdapterId); - fwprintf(stdout, L"%ls\n", szAdapterId); - CoTaskMemFree(szAdapterId); - - iResult = 0; - goto quit; - -create_delete_adapter: - tap_delete_adapter(NULL, &guidAdapter, &bRebootRequired); - iResult = 1; + iResult = command_create(argc, argv, &bRebootRequired); goto quit; } else if (wcsicmp(argv[1], L"list") == 0) { - WCHAR szzHwId[0x100] = - L"root\\" _L(TAP_WIN_COMPONENT_ID) L"\0" _L(TAP_WIN_COMPONENT_ID) L"\0" - L"ovpn-dco\0"; - - /* Parse options. */ - for (int i = 2; i < argc; i++) - { - if (wcsicmp(argv[i], L"--hwid") == 0) - { - memset(szzHwId, 0, sizeof(szzHwId)); - ++i; - memcpy_s(szzHwId, - sizeof(szzHwId) - 2 * sizeof(WCHAR) /*requires double zero termination*/, - argv[i], wcslen(argv[i]) * sizeof(WCHAR)); - } - else - { - fwprintf( - stderr, - L"Unknown option \"%ls" - L"\". Please, use \"tapctl help list\" to list supported options. Ignored.\n", - argv[i]); - } - } - - /* Output list of adapters with given hardware ID. */ - struct tap_adapter_node *pAdapterList = NULL; - DWORD dwResult = tap_list_adapters(NULL, szzHwId, &pAdapterList); - if (dwResult != ERROR_SUCCESS) - { - fwprintf(stderr, L"Enumerating TUN/TAP adapters failed (error 0x%x).\n", dwResult); - iResult = 1; - goto quit; - } - - for (struct tap_adapter_node *pAdapter = pAdapterList; pAdapter; pAdapter = pAdapter->pNext) - { - LPOLESTR szAdapterId = NULL; - StringFromIID((REFIID)&pAdapter->guid, &szAdapterId); - fwprintf(stdout, - L"%ls\t%" - L"ls\n", - szAdapterId, pAdapter->szName); - CoTaskMemFree(szAdapterId); - } - - iResult = 0; - tap_free_adapter_list(pAdapterList); + iResult = command_list(argc, argv); + goto quit; } else if (wcsicmp(argv[1], L"delete") == 0) { - if (argc < 3) - { - fwprintf( - stderr, - L"Missing adapter GUID or name. Please, use \"tapctl help delete\" for usage info.\n"); - return 1; - } - - GUID guidAdapter; - if (FAILED(IIDFromString(argv[2], (LPIID)&guidAdapter))) - { - /* 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); - if (dwResult != ERROR_SUCCESS) - { - fwprintf(stderr, L"Enumerating TUN/TAP adapters failed (error 0x%x).\n", dwResult); - iResult = 1; - goto quit; - } - - for (struct tap_adapter_node *pAdapter = pAdapterList;; pAdapter = pAdapter->pNext) - { - if (pAdapter == NULL) - { - fwprintf(stderr, L"\"%ls\" adapter not found.\n", argv[2]); - iResult = 1; - goto delete_cleanup_pAdapterList; - } - else if (wcsicmp(argv[2], pAdapter->szName) == 0) - { - memcpy(&guidAdapter, &pAdapter->guid, sizeof(GUID)); - break; - } - } - - iResult = 0; - -delete_cleanup_pAdapterList: - tap_free_adapter_list(pAdapterList); - if (iResult) - { - goto quit; - } - } - - /* Delete the network adapter. */ - DWORD dwResult = tap_delete_adapter(NULL, &guidAdapter, &bRebootRequired); - if (dwResult != ERROR_SUCCESS) - { - fwprintf(stderr, - L"Deleting adapter \"%ls" - L"\" failed (error 0x%x).\n", - argv[2], dwResult); - iResult = 1; - goto quit; - } - - iResult = 0; + iResult = command_delete(argc, argv, &bRebootRequired); goto quit; } else