From abf6962144969a3821063ccb68707c17508747cc Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Fri, 30 Oct 2020 09:53:09 +0100 Subject: [PATCH] api: simplify driver removal When we install the Wintun driver to the store, we get exact oem.inf filename of the driver in the store we just installed. Since the installation should be only temporarily, we should uninstall only the driver we installed. This also eliminates the need for iterating driver store speeding up things. The code we removed was inherited from the installer.dll, where it made perfect sense to remove all installed Wintun drivers in the update process. Suggested-by: Jason A. Donenfeld Signed-off-by: Simon Rozman --- api/adapter.c | 34 ++++++++++++++++--- api/adapter.h | 1 + api/api.vcxproj | 2 -- api/api.vcxproj.filters | 6 ---- api/driver.c | 72 ----------------------------------------- api/driver.h | 38 ---------------------- api/pch.h | 1 - 7 files changed, 31 insertions(+), 123 deletions(-) delete mode 100644 api/driver.c delete mode 100644 api/driver.h diff --git a/api/adapter.c b/api/adapter.c index a922dda..6ad7ec7 100644 --- a/api/adapter.c +++ b/api/adapter.c @@ -123,6 +123,15 @@ GetDeviceRegistryMultiString( } } +static BOOL +IsOurHardwareID(_In_z_ const WCHAR *Hwids) +{ + for (; Hwids[0]; Hwids += wcslen(Hwids) + 1) + if (!_wcsicmp(Hwids, WINTUN_HWID)) + return TRUE; + return FALSE; +} + static WINTUN_STATUS IsOurAdapter(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData, _Out_ BOOL *IsOurs) { @@ -130,7 +139,7 @@ IsOurAdapter(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData, _Out_ BOO DWORD Result = GetDeviceRegistryMultiString(DevInfo, DevInfoData, SPDRP_HARDWAREID, &Hwids); if (Result != ERROR_SUCCESS) return LOG(WINTUN_LOG_ERR, L"Failed to query hardware ID"), Result; - *IsOurs = DriverIsOurHardwareID(Hwids); + *IsOurs = IsOurHardwareID(Hwids); return ERROR_SUCCESS; } @@ -869,6 +878,15 @@ cleanupQueriedStore: return Result; } + +static BOOL +IsOurDrvInfoDetail(_In_ const SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData) +{ + return DrvInfoDetailData->CompatIDsOffset > 1 && !_wcsicmp(DrvInfoDetailData->HardwareID, WINTUN_HWID) || + DrvInfoDetailData->CompatIDsLength && + IsOurHardwareID(DrvInfoDetailData->HardwareID + DrvInfoDetailData->CompatIDsOffset); +} + static BOOL IsNewer(_In_ const SP_DRVINFO_DATA_W *DrvInfoData, _In_ const FILETIME *DriverDate, _In_ DWORDLONG DriverVersion) { @@ -1038,7 +1056,7 @@ CreateAdapter( LOG(WINTUN_LOG_WARN, L"Failed getting driver info detail"); continue; } - if (!DriverIsOurDrvInfoDetail(DrvInfoDetailData)) + if (!IsOurDrvInfoDetail(DrvInfoDetailData)) { HeapFree(ModuleHeap, 0, DrvInfoDetailData); continue; @@ -1581,14 +1599,22 @@ WintunCreateAdapter( } LOG(WINTUN_LOG_INFO, L"Installing driver"); - if (!SetupCopyOEMInfW(InfPath, NULL, SPOST_PATH, 0, NULL, 0, NULL, NULL)) + WCHAR InfStorePath[MAX_PATH]; + WCHAR *InfStoreFilename; + if (!SetupCopyOEMInfW(InfPath, NULL, SPOST_PATH, 0, InfStorePath, _countof(InfStorePath), NULL, &InfStoreFilename)) { Result = LOG_LAST_ERROR(L"Could not install driver to store"); goto cleanupDelete; } Result = CreateAdapter(InfPath, Pool, Name, RequestedGUID, Adapter, RebootRequired); - DriverRemoveAllOurs(); + + LOG(WINTUN_LOG_INFO, L"Removing driver"); + if (!SetupUninstallOEMInfW(InfStoreFilename, SUOI_FORCEDELETE, NULL)) + { + LOG_LAST_ERROR(L"Unable to remove existing driver"); + Result = Result != ERROR_SUCCESS ? Result : GetLastError(); + } cleanupDelete: DeleteFileW(CatPath); DeleteFileW(SysPath); diff --git a/api/adapter.h b/api/adapter.h index 7ac67ad..c0e4c53 100644 --- a/api/adapter.h +++ b/api/adapter.h @@ -9,6 +9,7 @@ #include #define MAX_INSTANCE_ID MAX_PATH /* TODO: Is MAX_PATH always enough? */ +#define WINTUN_HWID L"Wintun" typedef struct _SP_DEVINFO_DATA_LIST { diff --git a/api/api.vcxproj b/api/api.vcxproj index 16b8102..8bb4092 100644 --- a/api/api.vcxproj +++ b/api/api.vcxproj @@ -196,7 +196,6 @@ - @@ -208,7 +207,6 @@ - diff --git a/api/api.vcxproj.filters b/api/api.vcxproj.filters index cda6b16..e59284e 100644 --- a/api/api.vcxproj.filters +++ b/api/api.vcxproj.filters @@ -46,9 +46,6 @@ Header Files - - Header Files - Header Files @@ -84,9 +81,6 @@ Source Files - - Source Files - Source Files diff --git a/api/driver.c b/api/driver.c deleted file mode 100644 index 4b226c4..0000000 --- a/api/driver.c +++ /dev/null @@ -1,72 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved. - */ - -#include "pch.h" - -#pragma warning(disable : 4221) /* nonstandard: address of automatic in initializer */ - -BOOL -DriverIsOurHardwareID(_In_z_ const WCHAR *Hwids) -{ - for (; Hwids[0]; Hwids += wcslen(Hwids) + 1) - if (!_wcsicmp(Hwids, WINTUN_HWID)) - return TRUE; - return FALSE; -} - -BOOL -DriverIsOurDrvInfoDetail(_In_ const SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData) -{ - return DrvInfoDetailData->CompatIDsOffset > 1 && !_wcsicmp(DrvInfoDetailData->HardwareID, WINTUN_HWID) || - DrvInfoDetailData->CompatIDsLength && - DriverIsOurHardwareID(DrvInfoDetailData->HardwareID + DrvInfoDetailData->CompatIDsOffset); -} - -WINTUN_STATUS -DriverRemoveAllOurs(void) -{ - HDEVINFO DevInfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_NET, NULL, NULL, 0); - if (!DevInfo) - return LOG_LAST_ERROR(L"Failed to request device information"); - DWORD Result = ERROR_SUCCESS; - if (!SetupDiBuildDriverInfoList(DevInfo, NULL, SPDIT_CLASSDRIVER)) - { - Result = LOG_LAST_ERROR(L"Failed to build list of drivers"); - goto cleanupDeviceInfoSet; - } - for (DWORD EnumIndex = 0;; ++EnumIndex) - { - SP_DRVINFO_DATA_W DrvInfoData = { .cbSize = sizeof(DrvInfoData) }; - if (!SetupDiEnumDriverInfoW(DevInfo, NULL, SPDIT_CLASSDRIVER, EnumIndex, &DrvInfoData)) - { - if (GetLastError() == ERROR_NO_MORE_ITEMS) - break; - continue; - } - SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData; - if (AdapterGetDrvInfoDetail(DevInfo, NULL, &DrvInfoData, &DrvInfoDetailData) != ERROR_SUCCESS) - { - LOG(WINTUN_LOG_WARN, L"Failed getting driver info detail"); - continue; - } - if (!DriverIsOurDrvInfoDetail(DrvInfoDetailData)) - { - HeapFree(ModuleHeap, 0, DrvInfoDetailData); - continue; - } - PathStripPathW(DrvInfoDetailData->InfFileName); - LOG(WINTUN_LOG_INFO, L"Removing existing driver"); - if (!SetupUninstallOEMInfW(DrvInfoDetailData->InfFileName, SUOI_FORCEDELETE, NULL)) - { - LOG_LAST_ERROR(L"Unable to remove existing driver"); - Result = Result != ERROR_SUCCESS ? Result : GetLastError(); - } - HeapFree(ModuleHeap, 0, DrvInfoDetailData); - } - SetupDiDestroyDriverInfoList(DevInfo, NULL, SPDIT_CLASSDRIVER); -cleanupDeviceInfoSet: - SetupDiDestroyDeviceInfoList(DevInfo); - return Result; -} diff --git a/api/driver.h b/api/driver.h deleted file mode 100644 index e4835df..0000000 --- a/api/driver.h +++ /dev/null @@ -1,38 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved. - */ - -#pragma once - -#include "wintun.h" -#include - -#define WINTUN_HWID L"Wintun" - -/** - * Tests if any of the hardware IDs match ours. - * - * @param Hwids Multi-string containing a list of hardware IDs. - * - * @return TRUE on match; FALSE otherwise. - */ -BOOL -DriverIsOurHardwareID(_In_z_ const WCHAR *Hwids); - -/** - * Tests if hardware ID or any of the compatible IDs match ours. - * - * @param DrvInfoDetailData Detailed information about a particular driver information structure. - * - * @return TRUE on match; FALSE otherwise. - */ -BOOL -DriverIsOurDrvInfoDetail(_In_ const SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData); - -/** - * Removes all Wintun drivers from the driver store. - * - * @return ERROR_SUCCESS on success or the adapter was not found; Win32 error code otherwise. - */ -WINTUN_STATUS DriverRemoveAllOurs(void); diff --git a/api/pch.h b/api/pch.h index a4320e4..930a034 100644 --- a/api/pch.h +++ b/api/pch.h @@ -8,7 +8,6 @@ #include "adapter.h" #include "atomic.h" #include "api.h" -#include "driver.h" #include "logger.h" #include "namespace.h" #include "nci.h"