diff options
author | Simon Rozman <simon@rozman.si> | 2020-10-17 15:44:47 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2020-10-30 16:51:01 +0100 |
commit | 52738e17b18d83c015d9cbd5f2096e73e32a96f9 (patch) | |
tree | 5f7f3f584cc8cdb1811e85fc90f007e45c29810c /installer/installation.c | |
parent | api: use standard C void (diff) | |
download | wintun-52738e17b18d83c015d9cbd5f2096e73e32a96f9.tar.xz wintun-52738e17b18d83c015d9cbd5f2096e73e32a96f9.zip |
api: installer: switch from MSM to ZIP distribution
Signed-off-by: Simon Rozman <simon@rozman.si>
Diffstat (limited to 'installer/installation.c')
-rw-r--r-- | installer/installation.c | 666 |
1 files changed, 0 insertions, 666 deletions
diff --git a/installer/installation.c b/installer/installation.c deleted file mode 100644 index cd5c300..0000000 --- a/installer/installation.c +++ /dev/null @@ -1,666 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * Copyright (C) 2018-2019 WireGuard LLC. All Rights Reserved. - */ - -#include "installation.h" -#include <Windows.h> -#include <NTSecAPI.h> -#include <SetupAPI.h> -#include <newdev.h> -#include <Shlwapi.h> -#include <Psapi.h> -#include <sddl.h> -#include <devguid.h> -#include <ndisguid.h> -#include <cfgmgr32.h> -#include <WinCrypt.h> -#include <tchar.h> -#include <stdio.h> - -#pragma warning(disable : 4100) /* unreferenced formal parameter */ -#pragma warning(disable : 4204) /* nonstandard: non-constant aggregate initializer */ -#pragma warning(disable : 4221) /* nonstandard: address of automatic in initializer */ - -typedef struct _SP_DEVINFO_DATA_LIST -{ - SP_DEVINFO_DATA Data; - struct _SP_DEVINFO_DATA_LIST *Next; -} SP_DEVINFO_DATA_LIST; - -static VOID -NopLogger(_In_ LOGGER_LEVEL Level, _In_ const TCHAR *LogLine) -{ -} - -static LoggerFunction Logger = NopLogger; - -VOID -SetLogger(_In_ LoggerFunction NewLogger) -{ - Logger = NewLogger; -} - -static VOID -PrintError(_In_ LOGGER_LEVEL Level, _In_ const TCHAR *Prefix) -{ - DWORD ErrorCode = GetLastError(); - TCHAR *SystemMessage = NULL, *FormattedMessage = NULL; - FormatMessage( - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_MAX_WIDTH_MASK, - NULL, - HRESULT_FROM_SETUPAPI(ErrorCode), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (VOID *)&SystemMessage, - 0, - NULL); - FormatMessage( - FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY | - FORMAT_MESSAGE_MAX_WIDTH_MASK, - SystemMessage ? TEXT("%1: %3(Code 0x%2!08X!)") : TEXT("%1: Code 0x%2!08X!"), - 0, - 0, - (VOID *)&FormattedMessage, - 0, - (va_list *)(DWORD_PTR[]){ (DWORD_PTR)Prefix, (DWORD_PTR)ErrorCode, (DWORD_PTR)SystemMessage }); - if (FormattedMessage) - Logger(Level, FormattedMessage); - LocalFree(FormattedMessage); - LocalFree(SystemMessage); -} - -HINSTANCE ResourceModule; - -static BOOL IsWintunLoaded(VOID) -{ - DWORD RequiredSize = 0, CurrentSize = 0; - VOID **Drivers = NULL; - BOOL Found = FALSE; - for (;;) - { - if (!EnumDeviceDrivers(Drivers, CurrentSize, &RequiredSize)) - goto out; - if (CurrentSize == RequiredSize) - break; - free(Drivers); - Drivers = malloc(RequiredSize); - if (!Drivers) - goto out; - CurrentSize = RequiredSize; - } - TCHAR MaybeWintun[11]; - for (DWORD i = CurrentSize / sizeof(Drivers[0]); i-- > 0;) - { - if (GetDeviceDriverBaseName(Drivers[i], MaybeWintun, _countof(MaybeWintun)) == 10 && - !_tcsicmp(MaybeWintun, TEXT("wintun.sys"))) - { - Found = TRUE; - goto out; - } - } -out: - free(Drivers); - return Found; -} - -static BOOL EnsureWintunUnloaded(VOID) -{ - BOOL Loaded; - for (int i = 0; (Loaded = IsWintunLoaded()) != 0 && i < 300; ++i) - Sleep(50); - return !Loaded; -} - -static BOOL -CopyResource( - _In_ const TCHAR *DestinationPath, - _In_opt_ SECURITY_ATTRIBUTES *SecurityAttributes, - _In_ const TCHAR *ResourceName) -{ - HRSRC FoundResource = FindResource(ResourceModule, ResourceName, RT_RCDATA); - if (!FoundResource) - return FALSE; - DWORD SizeResource = SizeofResource(ResourceModule, FoundResource); - if (!SizeResource) - return FALSE; - HGLOBAL LoadedResource = LoadResource(ResourceModule, FoundResource); - if (!LoadedResource) - return FALSE; - LPVOID LockedResource = LockResource(LoadedResource); - if (!LockedResource) - return FALSE; - HANDLE DestinationHandle = CreateFile( - DestinationPath, - GENERIC_WRITE, - 0, - SecurityAttributes, - CREATE_NEW, - FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, - NULL); - if (DestinationHandle == INVALID_HANDLE_VALUE) - return FALSE; - DWORD BytesWritten; - BOOL Ret = - WriteFile(DestinationHandle, LockedResource, SizeResource, &BytesWritten, NULL) && BytesWritten == SizeResource; - CloseHandle(DestinationHandle); - return Ret; -} - -static BOOL -InstallWintunCertificate(const TCHAR *SignedResource) -{ - DWORD LastError = ERROR_SUCCESS; - Logger(LOG_INFO, TEXT("Trusting code signing certificate")); - BOOL Ret = TRUE; - HRSRC FoundResource = FindResource(ResourceModule, SignedResource, RT_RCDATA); - if (!FoundResource) - return FALSE; - DWORD SizeResource = SizeofResource(ResourceModule, FoundResource); - if (!SizeResource) - return FALSE; - HGLOBAL LoadedResource = LoadResource(ResourceModule, FoundResource); - if (!LoadedResource) - return FALSE; - LPVOID LockedResource = LockResource(LoadedResource); - if (!LockedResource) - return FALSE; - const CERT_BLOB CertBlob = { .cbData = SizeResource, .pbData = LockedResource }; - HCERTSTORE QueriedStore; - if (!CryptQueryObject( - CERT_QUERY_OBJECT_BLOB, - &CertBlob, - CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, - CERT_QUERY_FORMAT_FLAG_ALL, - 0, - 0, - 0, - 0, - &QueriedStore, - 0, - NULL)) - return FALSE; - HCERTSTORE TrustedStore = - CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, TEXT("TrustedPublisher")); - if (!TrustedStore) - { - LastError = GetLastError(); - goto cleanupQueriedStore; - } - LPSTR CodeSigningOid[] = { szOID_PKIX_KP_CODE_SIGNING }; - CERT_ENHKEY_USAGE EnhancedUsage = { .cUsageIdentifier = 1, .rgpszUsageIdentifier = CodeSigningOid }; - for (const CERT_CONTEXT *CertContext = NULL; (CertContext = CertFindCertificateInStore( - QueriedStore, - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, - CERT_FIND_ENHKEY_USAGE, - &EnhancedUsage, - CertContext)) != NULL;) - { - CERT_EXTENSION *Ext = CertFindExtension( - szOID_BASIC_CONSTRAINTS2, CertContext->pCertInfo->cExtension, CertContext->pCertInfo->rgExtension); - CERT_BASIC_CONSTRAINTS2_INFO Constraints; - DWORD Size = sizeof(Constraints); - if (Ext && - CryptDecodeObjectEx( - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - szOID_BASIC_CONSTRAINTS2, - Ext->Value.pbData, - Ext->Value.cbData, - 0, - NULL, - &Constraints, - &Size) && - !Constraints.fCA) - Ret &= CertAddCertificateContextToStore(TrustedStore, CertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL); - if (!Ret) - LastError = LastError ? LastError : GetLastError(); - } - CertCloseStore(TrustedStore, 0); -cleanupQueriedStore: - CertCloseStore(QueriedStore, 0); - SetLastError(LastError); - return Ret; -} - -/* We can't use RtlGetVersion, because appcompat's aclayers.dll shims it to report Vista - * when run from MSI context. So, we instead use the undocumented RtlGetNtVersionNumbers. - * - * Another way would be reading from the PEB directly: - * ((DWORD *)NtCurrentTeb()->ProcessEnvironmentBlock)[sizeof(void *) == 8 ? 70 : 41] - * Or just read from KUSER_SHARED_DATA the same way on 32-bit and 64-bit: - * *(DWORD *)0x7FFE026C - */ -extern VOID NTAPI -RtlGetNtVersionNumbers(_Out_opt_ DWORD *MajorVersion, _Out_opt_ DWORD *MinorVersion, _Out_opt_ DWORD *BuildNumber); - -static BOOL -InstallWintun(BOOL UpdateExisting) -{ - DWORD LastError = ERROR_SUCCESS; - TCHAR WindowsDirectory[MAX_PATH]; - if (!GetWindowsDirectory(WindowsDirectory, _countof(WindowsDirectory))) - return FALSE; - TCHAR WindowsTempDirectory[MAX_PATH]; - if (!PathCombine(WindowsTempDirectory, WindowsDirectory, TEXT("Temp"))) - return FALSE; - UCHAR RandomBytes[32] = { 0 }; -#pragma warning(suppress : 6387) - if (!RtlGenRandom(RandomBytes, sizeof(RandomBytes))) - return FALSE; - TCHAR RandomSubDirectory[sizeof(RandomBytes) * 2 + 1]; - for (int i = 0; i < sizeof(RandomBytes); ++i) - _stprintf_s(&RandomSubDirectory[i * 2], 3, TEXT("%02x"), RandomBytes[i]); - TCHAR RandomTempSubDirectory[MAX_PATH]; - if (!PathCombine(RandomTempSubDirectory, WindowsTempDirectory, RandomSubDirectory)) - return FALSE; - SECURITY_ATTRIBUTES SecurityAttributes = { .nLength = sizeof(SecurityAttributes) }; - if (!ConvertStringSecurityDescriptorToSecurityDescriptor( - TEXT("O:SYD:P(A;;GA;;;SY)"), SDDL_REVISION_1, &SecurityAttributes.lpSecurityDescriptor, NULL)) - return FALSE; - BOOL Ret = CreateDirectory(RandomTempSubDirectory, &SecurityAttributes); - if (!Ret) - goto cleanupFree; - - TCHAR CatPath[MAX_PATH] = { 0 }; - if (!PathCombine(CatPath, RandomTempSubDirectory, TEXT("wintun.cat"))) - goto cleanupFree; - TCHAR SysPath[MAX_PATH] = { 0 }; - if (!PathCombine(SysPath, RandomTempSubDirectory, TEXT("wintun.sys"))) - goto cleanupFree; - TCHAR InfPath[MAX_PATH] = { 0 }; - if (!PathCombine(InfPath, RandomTempSubDirectory, TEXT("wintun.inf"))) - goto cleanupFree; - - BOOL UseWHQL = FALSE; -#if defined(HAVE_EV) && defined(HAVE_WHQL) - DWORD MajorVersion; - RtlGetNtVersionNumbers(&MajorVersion, NULL, NULL); - UseWHQL = MajorVersion >= 10; -#elif defined(HAVE_EV) - UseWHQL = FALSE; -#elif defined(HAVE_WHQL) - UseWHQL = TRUE; -#else - #error No driver available -#endif - if (!UseWHQL && !InstallWintunCertificate(TEXT("wintun.sys"))) - PrintError(LOG_WARN, TEXT("Unable to install code signing certificate")); - - Logger(LOG_INFO, TEXT("Copying resources to temporary path")); - Ret = CopyResource(CatPath, &SecurityAttributes, UseWHQL ? TEXT("wintun-whql.cat") : TEXT("wintun.cat")) && - CopyResource(SysPath, &SecurityAttributes, UseWHQL ? TEXT("wintun-whql.sys") : TEXT("wintun.sys")) && - CopyResource(InfPath, &SecurityAttributes, UseWHQL ? TEXT("wintun-whql.inf") : TEXT("wintun.inf")); - if (!Ret) - goto cleanupDelete; - - Logger(LOG_INFO, TEXT("Installing driver")); - Ret = SetupCopyOEMInf(InfPath, NULL, SPOST_PATH, 0, NULL, 0, NULL, NULL); - BOOL RebootRequired = FALSE; - if (UpdateExisting && - !UpdateDriverForPlugAndPlayDevices( - NULL, TEXT("Wintun"), InfPath, INSTALLFLAG_FORCE | INSTALLFLAG_NONINTERACTIVE, &RebootRequired)) - PrintError(LOG_WARN, TEXT("Could not update existing adapters")); - if (RebootRequired) - Logger(LOG_WARN, TEXT("A reboot might be required, which really should not be the case")); - -cleanupDelete: - LastError = GetLastError(); - DeleteFile(CatPath); - DeleteFile(SysPath); - DeleteFile(InfPath); - RemoveDirectory(RandomTempSubDirectory); -cleanupFree: - LastError = LastError ? LastError : GetLastError(); - LocalFree(SecurityAttributes.lpSecurityDescriptor); - SetLastError(LastError); - return Ret; -} - -static BOOL RemoveWintun(VOID) -{ - BOOL Ret = FALSE; - HDEVINFO DeviceInfoSet = SetupDiGetClassDevs(&GUID_DEVCLASS_NET, NULL, NULL, 0); - if (!DeviceInfoSet) - return FALSE; - if (!SetupDiBuildDriverInfoList(DeviceInfoSet, NULL, SPDIT_CLASSDRIVER)) - goto cleanupDeviceInfoSet; - Ret = TRUE; - for (DWORD EnumIndex = 0;; ++EnumIndex) - { - SP_DRVINFO_DATA DriverInfo = { .cbSize = sizeof(DriverInfo) }; - if (!SetupDiEnumDriverInfo(DeviceInfoSet, NULL, SPDIT_CLASSDRIVER, EnumIndex, &DriverInfo)) - { - if (GetLastError() == ERROR_NO_MORE_ITEMS) - break; - goto cleanupDriverInfoList; - } - DWORD RequiredSize; - if (SetupDiGetDriverInfoDetail(DeviceInfoSet, NULL, &DriverInfo, NULL, 0, &RequiredSize) || - GetLastError() != ERROR_INSUFFICIENT_BUFFER) - goto cleanupDriverInfoList; - PSP_DRVINFO_DETAIL_DATA DriverDetail = calloc(1, RequiredSize); - if (!DriverDetail) - goto cleanupDriverInfoList; - DriverDetail->cbSize = sizeof(*DriverDetail); - if (!SetupDiGetDriverInfoDetail(DeviceInfoSet, NULL, &DriverInfo, DriverDetail, RequiredSize, &RequiredSize)) - { - free(DriverDetail); - goto cleanupDriverInfoList; - } - if (!_tcsicmp(DriverDetail->HardwareID, TEXT("wintun"))) - { - PathStripPath(DriverDetail->InfFileName); - Logger(LOG_INFO, TEXT("Removing existing driver")); - if (!SetupUninstallOEMInf(DriverDetail->InfFileName, SUOI_FORCEDELETE, NULL)) - { - PrintError(LOG_ERR, TEXT("Unable to remove existing driver")); - Ret = FALSE; - } - } - free(DriverDetail); - } - -cleanupDriverInfoList: - SetupDiDestroyDriverInfoList(DeviceInfoSet, NULL, SPDIT_CLASSDRIVER); -cleanupDeviceInfoSet: - SetupDiDestroyDeviceInfoList(DeviceInfoSet); - return Ret; -} - -static BOOL -IsWintunAdapter(_In_ HDEVINFO DeviceInfoSet, _Inout_ SP_DEVINFO_DATA *DeviceInfo) -{ - BOOL Found = FALSE; - if (!SetupDiBuildDriverInfoList(DeviceInfoSet, DeviceInfo, SPDIT_COMPATDRIVER)) - return FALSE; - for (DWORD EnumIndex = 0;; ++EnumIndex) - { - SP_DRVINFO_DATA DriverInfo = { .cbSize = sizeof(SP_DRVINFO_DATA) }; - if (!SetupDiEnumDriverInfo(DeviceInfoSet, DeviceInfo, SPDIT_COMPATDRIVER, EnumIndex, &DriverInfo)) - { - if (GetLastError() == ERROR_NO_MORE_ITEMS) - break; - continue; - } - DWORD RequiredSize; - if (SetupDiGetDriverInfoDetail(DeviceInfoSet, DeviceInfo, &DriverInfo, NULL, 0, &RequiredSize) || - GetLastError() != ERROR_INSUFFICIENT_BUFFER) - continue; - PSP_DRVINFO_DETAIL_DATA DriverDetail = calloc(1, RequiredSize); - if (!DriverDetail) - continue; - DriverDetail->cbSize = sizeof(*DriverDetail); - if (SetupDiGetDriverInfoDetail( - DeviceInfoSet, DeviceInfo, &DriverInfo, DriverDetail, RequiredSize, &RequiredSize) && - !_tcsicmp(DriverDetail->HardwareID, TEXT("wintun"))) - { - free(DriverDetail); - Found = TRUE; - break; - } - free(DriverDetail); - } - SetupDiDestroyDriverInfoList(DeviceInfoSet, DeviceInfo, SPDIT_COMPATDRIVER); - return Found; -} - -#define TUN_IOCTL_FORCE_CLOSE_HANDLES CTL_CODE(51820U, 0x971U, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA) - -static BOOL -ForceCloseWintunAdapterHandle(_In_ HDEVINFO DeviceInfoSet, _In_ SP_DEVINFO_DATA *DeviceInfo) -{ - DWORD RequiredBytes; - if (SetupDiGetDeviceInstanceId(DeviceInfoSet, DeviceInfo, NULL, 0, &RequiredBytes) || - GetLastError() != ERROR_INSUFFICIENT_BUFFER) - return FALSE; - TCHAR *InstanceId = calloc(sizeof(*InstanceId), RequiredBytes); - if (!InstanceId) - return FALSE; - BOOL Ret = FALSE; - if (!SetupDiGetDeviceInstanceId(DeviceInfoSet, DeviceInfo, InstanceId, RequiredBytes, &RequiredBytes)) - goto out; - TCHAR *InterfaceList = NULL; - for (;;) - { - free(InterfaceList); - if (CM_Get_Device_Interface_List_Size( - &RequiredBytes, (LPGUID)&GUID_DEVINTERFACE_NET, InstanceId, CM_GET_DEVICE_INTERFACE_LIST_PRESENT) != - CR_SUCCESS) - goto out; - InterfaceList = calloc(sizeof(*InterfaceList), RequiredBytes); - if (!InterfaceList) - goto out; - CONFIGRET CRet = CM_Get_Device_Interface_List( - (LPGUID)&GUID_DEVINTERFACE_NET, - InstanceId, - InterfaceList, - RequiredBytes, - CM_GET_DEVICE_INTERFACE_LIST_PRESENT); - if (CRet == CR_SUCCESS) - break; - if (CRet != CR_BUFFER_SMALL) - { - free(InterfaceList); - goto out; - } - } - - HANDLE NdisHandle = CreateFile( - InterfaceList, - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - 0, - NULL); - free(InterfaceList); - if (NdisHandle == INVALID_HANDLE_VALUE) - goto out; - Ret = DeviceIoControl(NdisHandle, TUN_IOCTL_FORCE_CLOSE_HANDLES, NULL, 0, NULL, 0, &RequiredBytes, NULL); - DWORD LastError = GetLastError(); - CloseHandle(NdisHandle); - SetLastError(LastError); -out: - free(InstanceId); - return Ret; -} - -static BOOL -DisableWintunAdapters(_In_ HDEVINFO DeviceInfoSet, _Inout_ SP_DEVINFO_DATA_LIST **DisabledAdapters) -{ - SP_PROPCHANGE_PARAMS Params = { .ClassInstallHeader = { .cbSize = sizeof(SP_CLASSINSTALL_HEADER), - .InstallFunction = DIF_PROPERTYCHANGE }, - .StateChange = DICS_DISABLE, - .Scope = DICS_FLAG_GLOBAL }; - BOOL Ret = TRUE; - DWORD LastError = ERROR_SUCCESS; - for (DWORD EnumIndex = 0;; ++EnumIndex) - { - SP_DEVINFO_DATA_LIST *DeviceNode = malloc(sizeof(SP_DEVINFO_DATA_LIST)); - if (!DeviceNode) - return FALSE; - DeviceNode->Data.cbSize = sizeof(SP_DEVINFO_DATA); - if (!SetupDiEnumDeviceInfo(DeviceInfoSet, EnumIndex, &DeviceNode->Data)) - { - if (GetLastError() == ERROR_NO_MORE_ITEMS) - { - free(DeviceNode); - break; - } - goto cleanupDeviceInfoData; - } - if (!IsWintunAdapter(DeviceInfoSet, &DeviceNode->Data)) - goto cleanupDeviceInfoData; - - ULONG Status, ProblemCode; - if (CM_Get_DevNode_Status(&Status, &ProblemCode, DeviceNode->Data.DevInst, 0) != CR_SUCCESS || - ((Status & DN_HAS_PROBLEM) && ProblemCode == CM_PROB_DISABLED)) - goto cleanupDeviceInfoData; - - Logger(LOG_INFO, TEXT("Force closing all open handles for existing adapter")); - if (!ForceCloseWintunAdapterHandle(DeviceInfoSet, &DeviceNode->Data)) - PrintError(LOG_WARN, TEXT("Failed to force close adapter handles")); - Sleep(200); - - Logger(LOG_INFO, TEXT("Disabling existing adapter")); - if (!SetupDiSetClassInstallParams( - DeviceInfoSet, &DeviceNode->Data, &Params.ClassInstallHeader, sizeof(Params)) || - !SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, DeviceInfoSet, &DeviceNode->Data)) - { - PrintError(LOG_WARN, TEXT("Unable to disable existing adapter")); - LastError = LastError ? LastError : GetLastError(); - Ret = FALSE; - goto cleanupDeviceInfoData; - } - - DeviceNode->Next = *DisabledAdapters; - *DisabledAdapters = DeviceNode; - continue; - - cleanupDeviceInfoData: - free(&DeviceNode->Data); - } - SetLastError(LastError); - return Ret; -} - -static BOOL -RemoveWintunAdapters(_In_ HDEVINFO DeviceInfoSet) -{ - SP_REMOVEDEVICE_PARAMS Params = { .ClassInstallHeader = { .cbSize = sizeof(SP_CLASSINSTALL_HEADER), - .InstallFunction = DIF_REMOVE }, - .Scope = DI_REMOVEDEVICE_GLOBAL }; - BOOL Ret = TRUE; - DWORD LastError = ERROR_SUCCESS; - for (DWORD EnumIndex = 0;; ++EnumIndex) - { - SP_DEVINFO_DATA DeviceInfo = { .cbSize = sizeof(SP_DEVINFO_DATA) }; - if (!SetupDiEnumDeviceInfo(DeviceInfoSet, EnumIndex, &DeviceInfo)) - { - if (GetLastError() == ERROR_NO_MORE_ITEMS) - break; - continue; - } - if (!IsWintunAdapter(DeviceInfoSet, &DeviceInfo)) - continue; - - Logger(LOG_INFO, TEXT("Force closing all open handles for existing adapter")); - if (!ForceCloseWintunAdapterHandle(DeviceInfoSet, &DeviceInfo)) - PrintError(LOG_WARN, TEXT("Failed to force close adapter handles")); - Sleep(200); - - Logger(LOG_INFO, TEXT("Removing existing adapter")); - if (!SetupDiSetClassInstallParams(DeviceInfoSet, &DeviceInfo, &Params.ClassInstallHeader, sizeof(Params)) || - !SetupDiCallClassInstaller(DIF_REMOVE, DeviceInfoSet, &DeviceInfo)) - { - PrintError(LOG_WARN, TEXT("Unable to remove existing adapter")); - LastError = LastError ? LastError : GetLastError(); - Ret = FALSE; - } - } - SetLastError(LastError); - return Ret; -} - -static BOOL -EnableWintunAdapters(_In_ HDEVINFO DeviceInfoSet, _In_ SP_DEVINFO_DATA_LIST *AdaptersToEnable) -{ - SP_PROPCHANGE_PARAMS Params = { .ClassInstallHeader = { .cbSize = sizeof(SP_CLASSINSTALL_HEADER), - .InstallFunction = DIF_PROPERTYCHANGE }, - .StateChange = DICS_ENABLE, - .Scope = DICS_FLAG_GLOBAL }; - BOOL Ret = TRUE; - DWORD LastError = ERROR_SUCCESS; - - for (SP_DEVINFO_DATA_LIST *DeviceNode = AdaptersToEnable; DeviceNode; DeviceNode = DeviceNode->Next) - { - Logger(LOG_INFO, TEXT("Enabling existing adapter")); - if (!SetupDiSetClassInstallParams( - DeviceInfoSet, &DeviceNode->Data, &Params.ClassInstallHeader, sizeof(Params)) || - !SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, DeviceInfoSet, &DeviceNode->Data)) - { - LastError = LastError ? LastError : GetLastError(); - PrintError(LOG_WARN, TEXT("Unable to enable existing adapter")); - Ret = FALSE; - } - } - SetLastError(LastError); - return Ret; -} - -BOOL InstallOrUpdate(VOID) -{ - BOOL Ret = FALSE; - HDEVINFO DeviceInfoSet = SetupDiGetClassDevsEx(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL); - if (DeviceInfoSet == INVALID_HANDLE_VALUE) - { - PrintError(LOG_ERR, TEXT("Failed to get present class devices")); - return FALSE; - } - SP_DEVINFO_DATA_LIST *ExistingAdapters = NULL; - if (IsWintunLoaded()) - { - DisableWintunAdapters(DeviceInfoSet, &ExistingAdapters); - Logger(LOG_INFO, TEXT("Waiting for driver to unload from kernel")); - if (!EnsureWintunUnloaded()) - Logger(LOG_WARN, TEXT("Unable to unload driver, which means a reboot will likely be required")); - } - if (!RemoveWintun()) - { - PrintError(LOG_ERR, TEXT("Failed to uninstall old drivers")); - goto cleanupAdapters; - } - if (!InstallWintun(!!ExistingAdapters)) - { - PrintError(LOG_ERR, TEXT("Failed to install driver")); - goto cleanupAdapters; - } - Logger(LOG_INFO, TEXT("Installation successful")); - Ret = TRUE; - -cleanupAdapters: - if (ExistingAdapters) - { - EnableWintunAdapters(DeviceInfoSet, ExistingAdapters); - while (ExistingAdapters) - { - SP_DEVINFO_DATA_LIST *Next = ExistingAdapters->Next; - free(ExistingAdapters); - ExistingAdapters = Next; - } - } - SetupDiDestroyDeviceInfoList(DeviceInfoSet); - return Ret; -} - -BOOL Uninstall(VOID) -{ - HDEVINFO DeviceInfoSet = SetupDiGetClassDevsEx(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL); - if (DeviceInfoSet == INVALID_HANDLE_VALUE) - { - PrintError(LOG_ERR, TEXT("Failed to get present class devices")); - return FALSE; - } - RemoveWintunAdapters(DeviceInfoSet); - BOOL Ret = RemoveWintun(); - if (!Ret) - PrintError(LOG_ERR, TEXT("Failed to uninstall driver")); - else - Logger(LOG_INFO, TEXT("Uninstallation successful")); - return Ret; -} - -BOOL APIENTRY -DllMain(_In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved) -{ - switch (fdwReason) - { - case DLL_PROCESS_ATTACH: - ResourceModule = hinstDLL; - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - } - return TRUE; -} |