diff --git a/installer/exports.def b/installer/exports.def deleted file mode 100644 index 95eafde..0000000 --- a/installer/exports.def +++ /dev/null @@ -1,5 +0,0 @@ -EXPORTS - InstallWintun - UninstallWintun - MsiEvaluate - MsiProcess 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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; -} diff --git a/installer/installation.h b/installer/installation.h deleted file mode 100644 index e5ce781..0000000 --- a/installer/installation.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * Copyright (C) 2018-2019 WireGuard LLC. All Rights Reserved. - */ - -#pragma once - -#include - -typedef enum _LOGGER_LEVEL -{ - LOG_INFO = 0, - LOG_WARN, - LOG_ERR -} LOGGER_LEVEL; -typedef VOID (*LoggerFunction)(_In_ LOGGER_LEVEL, _In_ const TCHAR *); -VOID -SetLogger(_In_ LoggerFunction NewLogger); - -BOOL InstallOrUpdate(VOID); -BOOL Uninstall(VOID); - -extern HINSTANCE ResourceModule; diff --git a/installer/installer.vcxproj b/installer/installer.vcxproj deleted file mode 100644 index b00a2e7..0000000 --- a/installer/installer.vcxproj +++ /dev/null @@ -1,242 +0,0 @@ - - - - - Debug - ARM64 - - - Debug - Win32 - - - Release - ARM64 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - {D19E6354-A643-4ACC-82D5-B2780BB83475} - Win32Proj - installer - 10.0 - installer - - - - DynamicLibrary - Unicode - v142 - true - false - - - DynamicLibrary - true - Unicode - v142 - false - - - DynamicLibrary - Unicode - v142 - true - false - - - DynamicLibrary - Unicode - v142 - true - - - DynamicLibrary - true - Unicode - v142 - false - - - DynamicLibrary - true - Unicode - v142 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 200 - 500 - - - ..\$(Configuration)\$(WintunPlatform)\ - ..\$(Configuration)\$(WintunPlatform)\$(ProjectName)-intermediate\ - NativeRecommendedRules.ruleset - true - rundll32.exe - $(OutDir)$(TargetName)$(TargetExt),InstallWintun - WindowsLocalDebugger - x86 - x64 - arm64 - $(WixCandleFlags) -nologo -arch $(WixArch) -dWINTUN_PLATFORM=$(WintunPlatform) -dWINTUN_VERSION=$(WintunVersion) -dINSTALLER_VERSION_MIN=$(InstallerVersionMin) -sw1086 - $(WixLightFlags) -nologo -b output_dir="$(OutDir.TrimEnd('\'))" -spdb -sw1076 -sw1079 - $(WixLightFlags) -b output_dir_wow64="..\$(Configuration)\x86" - $(WixLightFlags) -b output_dir_wow64="..\$(Configuration)\arm" - $(OutDir) - wintun - .msm - - - ..\$(DistributionDir) - wintun-$(WintunPlatform)-$(WintunVersionStr) - - - - _WINDOWS;_USRDLL;%(PreprocessorDefinitions) - HAVE_EV;%(PreprocessorDefinitions) - HAVE_WHQL;%(PreprocessorDefinitions) - - - ..\$(Configuration)\$(WintunPlatform);%(AdditionalIncludeDirectories) - HAVE_EV;%(PreprocessorDefinitions) - HAVE_WHQL;%(PreprocessorDefinitions) - - - exports.def - newdev.lib;ntdll.lib;Crypt32.lib;Msi.lib;Setupapi.lib;shlwapi.lib;%(AdditionalDependencies) - Windows - - - - - _DEBUG;%(PreprocessorDefinitions) - MultiThreadedDebug - - - _DEBUG;%(PreprocessorDefinitions) - - - - - NDEBUG;%(PreprocessorDefinitions) - MultiThreaded - - - NDEBUG;%(PreprocessorDefinitions) - - - true - true - UseLinkTimeCodeGeneration - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $(BuildDependsOn);TestSignTarget;ProductionSignTarget - $(MSMDependsOn);WixCompile;WixLink;WixTestSign;WixProductionSign - CleanSignTarget;WixClean;$(CleanDependsOn) - - - - - - - - - - - - - - - - - - $(WixCandleFlags) -dINSTALLER_LIBRARY_HASH=@(InstallerLibraryHash->Metadata('FileHash')) -dINSTALLER_LIBRARY_TIME=$([System.IO.File]::GetLastWriteTime('$(OutDir)$(TargetName)$(TargetExt)').Ticks) - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/installer/installer.vcxproj.filters b/installer/installer.vcxproj.filters deleted file mode 100644 index e9d0282..0000000 --- a/installer/installer.vcxproj.filters +++ /dev/null @@ -1,49 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {1ae72c39-669d-49e5-85c7-f6956595e079} - - - - - Source Files - - - Source Files - - - Source Files - - - - - Resource Files - - - - - Header Files - - - - - Source Files - - - MSM - - - \ No newline at end of file diff --git a/installer/installer.wxs b/installer/installer.wxs deleted file mode 100644 index b9f5c1a..0000000 --- a/installer/installer.wxs +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/installer/msi.c b/installer/msi.c deleted file mode 100644 index 348ef42..0000000 --- a/installer/msi.c +++ /dev/null @@ -1,266 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * Copyright (C) 2018-2019 WireGuard LLC. All Rights Reserved. - */ - -#include "installation.h" -#include -#include -#include -#include - -#pragma warning(disable : 4100) /* unreferenced formal parameter */ - -static MSIHANDLE MsiHandle; - -#define ANCHOR_COMPONENT TEXT("{B668D4C7-ABB3-485A-B8DF-D34200489A43}") -#define PROCESS_ACTION TEXT("ProcessWintun") -#define ACTION_INSTALL TEXT("/WintunAction=Install") -#define ACTION_INSTALL_SEPERATOR TEXT('-') -#define ACTION_INSTALL_SEPERATORS TEXT("-%s-%s-%s") -#define ACTION_UNINSTALL TEXT("/WintunAction=Uninstall") -#define PROPERTY_INSTALLER_HASH TEXT("WintunInstallerHash") -#define PROPERTY_INSTALLER_BUILDTIME TEXT("WintunInstallerBuildtime") -#define PROPERTY_VERSION TEXT("WintunVersion") -#define REGKEY_WINTUN TEXT("Software\\Wintun") -#define REGKEY_INSTALLER_HASH TEXT("InstallerHash") -#define REGKEY_INSTALLER_BUILDTIME TEXT("InstallerBuildtime") -#define REGKEY_VERSION TEXT("Version") - -static VOID -MsiLogger(_In_ LOGGER_LEVEL Level, _In_ const TCHAR *LogLine) -{ - MSIHANDLE Record = MsiCreateRecord(2); - if (!Record) - return; - TCHAR *Template; - INSTALLMESSAGE Type; - switch (Level) - { - case LOG_INFO: - Template = TEXT("Wintun: [1]"); - Type = INSTALLMESSAGE_INFO; - break; - case LOG_WARN: - Template = TEXT("Wintun warning: [1]"); - Type = INSTALLMESSAGE_INFO; - break; - case LOG_ERR: - Template = TEXT("Wintun error: [1]"); - Type = INSTALLMESSAGE_ERROR; - break; - default: - goto cleanup; - } - MsiRecordSetString(Record, 0, Template); - MsiRecordSetString(Record, 1, LogLine); - MsiProcessMessage(MsiHandle, Type, Record); -cleanup: - MsiCloseHandle(Record); -} - -static BOOL -IsInstalling(_In_ INSTALLSTATE InstallState, _In_ INSTALLSTATE ActionState) -{ - return INSTALLSTATE_LOCAL == ActionState || INSTALLSTATE_SOURCE == ActionState || - (INSTALLSTATE_DEFAULT == ActionState && - (INSTALLSTATE_LOCAL == InstallState || INSTALLSTATE_SOURCE == InstallState)); -} - -static BOOL -IsReInstalling(_In_ INSTALLSTATE InstallState, _In_ INSTALLSTATE ActionState) -{ - return (INSTALLSTATE_LOCAL == ActionState || INSTALLSTATE_SOURCE == ActionState || - INSTALLSTATE_DEFAULT == ActionState) && - (INSTALLSTATE_LOCAL == InstallState || INSTALLSTATE_SOURCE == InstallState); -} - -static BOOL -IsUninstalling(_In_ INSTALLSTATE InstallState, _In_ INSTALLSTATE ActionState) -{ - return (INSTALLSTATE_ABSENT == ActionState || INSTALLSTATE_REMOVED == ActionState) && - (INSTALLSTATE_LOCAL == InstallState || INSTALLSTATE_SOURCE == InstallState); -} - -static UINT64 -ParseVersion(_In_ const TCHAR *Version) -{ - ULONG Major = 0, Minor = 0, Revision = 0, Build = 0; - _stscanf_s(Version, TEXT("%u.%u.%u.%u"), &Major, &Minor, &Revision, &Build); - return ((UINT64)Major << 48) | ((UINT64)Minor << 32) | ((UINT64)Revision << 16) | ((UINT64)Build << 0); -} - -_Success_(return ) -static BOOL -Newer(_In_ MSIHANDLE Handle, _In_ BOOL SkipHashComparison, _Out_ TCHAR *InstallAction, _In_ SIZE_T InstallActionSize) -{ - INT64 NewTime, OldTime; - UINT64 NewVersion, OldVersion; - TCHAR NewHash[0x100], OldHash[0x100], NewTimeString[0x100], OldTimeString[0x100], NewVersionString[0x100], - OldVersionString[0x100]; - DWORD Size, Type; - HKEY Key; - BOOL Ret = TRUE; - - Size = _countof(NewHash); - if (MsiGetProperty(Handle, PROPERTY_INSTALLER_HASH, NewHash, &Size) != ERROR_SUCCESS) - return FALSE; - Size = _countof(NewTimeString); - if (MsiGetProperty(Handle, PROPERTY_INSTALLER_BUILDTIME, NewTimeString, &Size) != ERROR_SUCCESS) - return FALSE; - NewTime = _tstoll(NewTimeString); - Size = _countof(NewVersionString); - if (MsiGetProperty(Handle, PROPERTY_VERSION, NewVersionString, &Size) != ERROR_SUCCESS) - return FALSE; - NewVersion = ParseVersion(NewVersionString); - - _stprintf_s( - InstallAction, - InstallActionSize, - ACTION_INSTALL ACTION_INSTALL_SEPERATORS, - NewHash, - NewTimeString, - NewVersionString); - - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY_WINTUN, 0, KEY_READ, &Key) != ERROR_SUCCESS) - return TRUE; - Size = sizeof(OldHash); - if (RegQueryValueEx(Key, REGKEY_INSTALLER_HASH, NULL, &Type, (LPBYTE)OldHash, &Size) != ERROR_SUCCESS || - Type != REG_SZ) - goto cleanup; - Size = sizeof(OldTimeString); - if (RegQueryValueEx(Key, REGKEY_INSTALLER_BUILDTIME, NULL, &Type, (LPBYTE)OldTimeString, &Size) != ERROR_SUCCESS || - Type != REG_SZ) - goto cleanup; - OldTime = _tstoll(OldTimeString); - Size = sizeof(OldVersionString); - if (RegQueryValueEx(Key, REGKEY_VERSION, NULL, &Type, (LPBYTE)OldVersionString, &Size) != ERROR_SUCCESS || - Type != REG_SZ) - goto cleanup; - OldVersion = ParseVersion(OldVersionString); - - Ret = NewVersion >= OldVersion && NewTime >= OldTime && (SkipHashComparison || _tcscmp(NewHash, OldHash)); - -cleanup: - RegCloseKey(Key); - return Ret; -} - -UINT __stdcall MsiEvaluate(MSIHANDLE Handle) -{ - MsiHandle = Handle; - SetLogger(MsiLogger); - BOOL IsComInitialized = SUCCEEDED(CoInitialize(NULL)); - UINT Ret = ERROR_INSTALL_FAILURE; - MSIHANDLE View = 0, Record = 0, Database = MsiGetActiveDatabase(Handle); - if (!Database) - goto cleanup; - Ret = MsiDatabaseOpenView( - Database, TEXT("SELECT `Component` FROM `Component` WHERE `ComponentId` = '" ANCHOR_COMPONENT "'"), &View); - if (Ret != ERROR_SUCCESS) - goto cleanup; - Ret = MsiViewExecute(View, 0); - if (Ret != ERROR_SUCCESS) - goto cleanup; - Ret = MsiViewFetch(View, &Record); - if (Ret != ERROR_SUCCESS) - goto cleanup; - TCHAR ComponentName[0x1000]; - DWORD Size = _countof(ComponentName); - Ret = MsiRecordGetString(Record, 1, ComponentName, &Size); - if (Ret != ERROR_SUCCESS) - goto cleanup; - INSTALLSTATE InstallState, ActionState; - Ret = MsiGetComponentState(Handle, ComponentName, &InstallState, &ActionState); - if (Ret != ERROR_SUCCESS) - goto cleanup; - TCHAR InstallAction[0x400]; - if ((IsReInstalling(InstallState, ActionState) || IsInstalling(InstallState, ActionState)) && - Newer(Handle, IsReInstalling(InstallState, ActionState), InstallAction, _countof(InstallAction))) - Ret = MsiSetProperty(Handle, PROCESS_ACTION, InstallAction); - else if (IsUninstalling(InstallState, ActionState)) - Ret = MsiSetProperty(Handle, PROCESS_ACTION, ACTION_UNINSTALL); - if (Ret != ERROR_SUCCESS) - goto cleanup; - - Ret = MsiDoAction(Handle, TEXT("DisableRollback")); - -cleanup: - if (View) - MsiCloseHandle(View); - if (Record) - MsiCloseHandle(Record); - if (Database) - MsiCloseHandle(Database); - if (IsComInitialized) - CoUninitialize(); - return Ret; -} - -static BOOL -WriteRegKeys(_In_ TCHAR *Values) -{ - TCHAR *Hash, *Time, *Version; - Hash = Values; - Time = _tcschr(Hash, ACTION_INSTALL_SEPERATOR); - if (!Time) - return FALSE; - *Time++ = TEXT('\0'); - Version = _tcschr(Time, ACTION_INSTALL_SEPERATOR); - if (!Version) - return FALSE; - *Version++ = TEXT('\0'); - - HKEY Key; - if (RegCreateKeyEx( - HKEY_LOCAL_MACHINE, REGKEY_WINTUN, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &Key, NULL) != - ERROR_SUCCESS) - return FALSE; - BOOL Ret = - RegSetValueEx( - Key, REGKEY_INSTALLER_HASH, 0, REG_SZ, (LPBYTE)Hash, ((DWORD)_tcslen(Hash) + 1) * sizeof(*Hash)) == - ERROR_SUCCESS && - RegSetValueEx( - Key, REGKEY_INSTALLER_BUILDTIME, 0, REG_SZ, (LPBYTE)Time, ((DWORD)_tcslen(Time) + 1) * sizeof(*Time)) == - ERROR_SUCCESS && - RegSetValueEx( - Key, REGKEY_VERSION, 0, REG_SZ, (LPBYTE)Version, ((DWORD)_tcslen(Version) + 1) * sizeof(*Version)) == - ERROR_SUCCESS; - RegCloseKey(Key); - return Ret; -} - -UINT __stdcall MsiProcess(MSIHANDLE Handle) -{ - MsiHandle = Handle; - SetLogger(MsiLogger); - BOOL IsComInitialized = SUCCEEDED(CoInitialize(NULL)); - DWORD LastError = ERROR_SUCCESS; - BOOL Ret = FALSE; - TCHAR Value[0x1000], *RegValues; - DWORD Size = _countof(Value); - LastError = MsiGetProperty(Handle, TEXT("CustomActionData"), Value, &Size); - if (LastError != ERROR_SUCCESS) - goto cleanup; - if ((RegValues = _tcschr(Value, ACTION_INSTALL_SEPERATOR)) != NULL) - *RegValues++ = TEXT('\0'); - if (!_tcscmp(Value, ACTION_INSTALL)) - { - Ret = InstallOrUpdate(); - if (RegValues && Ret) - Ret = WriteRegKeys(RegValues); - } - else if (!_tcscmp(Value, ACTION_UNINSTALL)) - { - Ret = Uninstall(); - if (Ret) - RegDeleteKeyEx(HKEY_LOCAL_MACHINE, REGKEY_WINTUN, 0, 0); - } - else - Ret = TRUE; - LastError = GetLastError(); -cleanup: - if (IsComInitialized) - CoUninitialize(); - return Ret ? ERROR_SUCCESS : LastError ? LastError : ERROR_INSTALL_FAILED; -} diff --git a/installer/resources.rc b/installer/resources.rc deleted file mode 100644 index b0bca3c..0000000 --- a/installer/resources.rc +++ /dev/null @@ -1,50 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * Copyright (C) 2018-2019 WireGuard LLC. All Rights Reserved. - */ - -#include -#include - -#ifdef HAVE_EV -wintun.cat RCDATA "wintun\\wintun.cat" -wintun.inf RCDATA "wintun\\wintun.inf" -wintun.sys RCDATA "wintun\\wintun.sys" -#endif - -#ifdef HAVE_WHQL -wintun-whql.cat RCDATA "whql\\wintun.cat" -wintun-whql.inf RCDATA "whql\\wintun.inf" -wintun-whql.sys RCDATA "whql\\wintun.sys" -#endif - -#define STRINGIZE(x) #x -#define EXPAND(x) STRINGIZE(x) - -VS_VERSION_INFO VERSIONINFO -FILEVERSION WINTUN_VERSION_MAJ, WINTUN_VERSION_MIN, 0, 0 -PRODUCTVERSION WINTUN_VERSION_MAJ, WINTUN_VERSION_MIN, 0, 0 -FILEOS VOS_NT_WINDOWS32 -FILETYPE VFT_DLL -FILESUBTYPE VFT2_UNKNOWN -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", "WireGuard LLC" - VALUE "FileDescription", "Wintun Installer Library" - VALUE "FileVersion", EXPAND(WINTUN_VERSION_STR) - VALUE "InternalName", "installer.dll" - VALUE "LegalCopyright", "Copyright \xa9 2018-2019 WireGuard LLC. All Rights Reserved." - VALUE "OriginalFilename", "installer.dll" - VALUE "ProductName", "Wintun Driver" - VALUE "ProductVersion", EXPAND(WINTUN_VERSION_STR) - VALUE "Comments", "https://www.wintun.net/" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff --git a/installer/rundll32.c b/installer/rundll32.c deleted file mode 100644 index 17295e0..0000000 --- a/installer/rundll32.c +++ /dev/null @@ -1,180 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * Copyright (C) 2018-2019 WireGuard LLC. All Rights Reserved. - */ - -#include "installation.h" -#include -#include -#include -#include -#include - -#pragma warning(disable : 4100) /* unreferenced formal parameter */ - -static VOID -ConsoleLogger(_In_ LOGGER_LEVEL Level, _In_ const TCHAR *LogLine) -{ - TCHAR *Template; - switch (Level) - { - case LOG_INFO: - Template = TEXT("[+] %s\n"); - break; - case LOG_WARN: - Template = TEXT("[-] %s\n"); - break; - case LOG_ERR: - Template = TEXT("[!] %s\n"); - break; - default: - return; - } - _ftprintf(stdout, Template, LogLine); -} - -static BOOL ElevateToSystem(VOID) -{ - HANDLE CurrentProcessToken, ThreadToken, ProcessSnapshot, WinlogonProcess, WinlogonToken, DuplicatedToken; - PROCESSENTRY32 ProcessEntry = { .dwSize = sizeof(PROCESSENTRY32) }; - BOOL Ret; - DWORD LastError = ERROR_SUCCESS; - TOKEN_PRIVILEGES Privileges = { .PrivilegeCount = 1, .Privileges = { { .Attributes = SE_PRIVILEGE_ENABLED } } }; - CHAR LocalSystemSid[0x400]; - DWORD RequiredBytes = sizeof(LocalSystemSid); - struct - { - TOKEN_USER MaybeLocalSystem; - CHAR LargeEnoughForLocalSystem[0x400]; - } TokenUserBuffer; - - Ret = CreateWellKnownSid(WinLocalSystemSid, NULL, &LocalSystemSid, &RequiredBytes); - LastError = GetLastError(); - if (!Ret) - goto cleanup; - Ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &CurrentProcessToken); - LastError = GetLastError(); - if (!Ret) - goto cleanup; - Ret = - GetTokenInformation(CurrentProcessToken, TokenUser, &TokenUserBuffer, sizeof(TokenUserBuffer), &RequiredBytes); - LastError = GetLastError(); - CloseHandle(CurrentProcessToken); - if (!Ret) - goto cleanup; - if (EqualSid(TokenUserBuffer.MaybeLocalSystem.User.Sid, LocalSystemSid)) - return TRUE; - Ret = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Privileges.Privileges[0].Luid); - LastError = GetLastError(); - if (!Ret) - goto cleanup; - ProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - LastError = GetLastError(); - if (ProcessSnapshot == INVALID_HANDLE_VALUE) - goto cleanup; - for (Ret = Process32First(ProcessSnapshot, &ProcessEntry); Ret; Ret = Process32Next(ProcessSnapshot, &ProcessEntry)) - { - if (_tcsicmp(ProcessEntry.szExeFile, TEXT("winlogon.exe"))) - continue; - RevertToSelf(); - Ret = ImpersonateSelf(SecurityImpersonation); - LastError = GetLastError(); - if (!Ret) - continue; - Ret = OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES, FALSE, &ThreadToken); - LastError = GetLastError(); - if (!Ret) - continue; - Ret = AdjustTokenPrivileges(ThreadToken, FALSE, &Privileges, sizeof(Privileges), NULL, NULL); - LastError = GetLastError(); - CloseHandle(ThreadToken); - if (!Ret) - continue; - - WinlogonProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ProcessEntry.th32ProcessID); - LastError = GetLastError(); - if (!WinlogonProcess) - continue; - Ret = OpenProcessToken(WinlogonProcess, TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &WinlogonToken); - LastError = GetLastError(); - CloseHandle(WinlogonProcess); - if (!Ret) - continue; - Ret = DuplicateToken(WinlogonToken, SecurityImpersonation, &DuplicatedToken); - LastError = GetLastError(); - CloseHandle(WinlogonToken); - if (!Ret) - continue; - if (!GetTokenInformation(DuplicatedToken, TokenUser, &TokenUserBuffer, sizeof(TokenUserBuffer), &RequiredBytes)) - goto next; - if (SetLastError(ERROR_ACCESS_DENIED), !EqualSid(TokenUserBuffer.MaybeLocalSystem.User.Sid, LocalSystemSid)) - goto next; - if (!SetThreadToken(NULL, DuplicatedToken)) - goto next; - CloseHandle(DuplicatedToken); - CloseHandle(ProcessSnapshot); - SetLastError(ERROR_SUCCESS); - return TRUE; - next: - LastError = GetLastError(); - CloseHandle(DuplicatedToken); - } - RevertToSelf(); - CloseHandle(ProcessSnapshot); -cleanup: - SetLastError(LastError); - return FALSE; -} - -static VOID -RunAsAdministrator(HWND hwnd, TCHAR *Verb, int nCmdShow) -{ - TOKEN_ELEVATION Elevation; - DWORD Required; - HANDLE CurrentProcessToken; - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &CurrentProcessToken)) - return; - BOOL Ret = GetTokenInformation(CurrentProcessToken, TokenElevation, &Elevation, sizeof(Elevation), &Required); - CloseHandle(CurrentProcessToken); - if (!Ret) - return; - if (Elevation.TokenIsElevated) - return; - TCHAR ProcessPath[MAX_PATH], DllPath[MAX_PATH]; - if (!GetModuleFileName(NULL, ProcessPath, _countof(ProcessPath)) || - !GetModuleFileName(ResourceModule, DllPath, _countof(DllPath))) - return; - TCHAR Params[0x1000]; - _stprintf_s(Params, _countof(Params), TEXT("\"%s\",%s"), DllPath, Verb); - ShellExecute(hwnd, TEXT("runas"), ProcessPath, Params, NULL, nCmdShow); - exit(0); -} - -static VOID -Do(BOOL Install, BOOL ShowConsole) -{ - if (ShowConsole) - { - AllocConsole(); - FILE *Stream; - freopen_s(&Stream, "CONOUT$", "w", stdout); - } - SetLogger(ConsoleLogger); - ElevateToSystem(); - Install ? InstallOrUpdate() : Uninstall(); - RevertToSelf(); - _putws(TEXT("\nPress any key to close . . .")); - (VOID) _getch(); -} - -VOID __stdcall InstallWintun(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) -{ - RunAsAdministrator(hwnd, TEXT(__FUNCTION__), nCmdShow); - Do(TRUE, !!nCmdShow); -} - -VOID __stdcall UninstallWintun(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) -{ - RunAsAdministrator(hwnd, TEXT(__FUNCTION__), nCmdShow); - Do(FALSE, !!nCmdShow); -} \ No newline at end of file diff --git a/wintun.proj b/wintun.proj index 1cae706..de38711 100644 --- a/wintun.proj +++ b/wintun.proj @@ -13,7 +13,6 @@ - @@ -68,18 +67,50 @@ - - + + - - + + - - + + + + + + + + + + $(DistributionDir)wintun-$(WintunVersionStr).zip + $(DistributionDir).tmp\ + + + + + + + + + + + + + + + diff --git a/wintun.sln b/wintun.sln index 3105137..00b37ef 100644 --- a/wintun.sln +++ b/wintun.sln @@ -7,11 +7,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "api", "api\api.vcxproj", "{ {F7679B65-2FEC-469A-8BAC-B07BF4439422} = {F7679B65-2FEC-469A-8BAC-B07BF4439422} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "installer", "installer\installer.vcxproj", "{D19E6354-A643-4ACC-82D5-B2780BB83475}" - ProjectSection(ProjectDependencies) = postProject - {F7679B65-2FEC-469A-8BAC-B07BF4439422} = {F7679B65-2FEC-469A-8BAC-B07BF4439422} - EndProjectSection -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wintun", "wintun.vcxproj", "{F7679B65-2FEC-469A-8BAC-B07BF4439422}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3A98F138-EE02-4488-B856-B3C48500BEA8}" @@ -50,20 +45,6 @@ Global {897F02E3-3EAA-40AF-A6DC-17EB2376EDAF}.Release|arm64.Build.0 = Release|ARM64 {897F02E3-3EAA-40AF-A6DC-17EB2376EDAF}.Release|x86.ActiveCfg = Release|Win32 {897F02E3-3EAA-40AF-A6DC-17EB2376EDAF}.Release|x86.Build.0 = Release|Win32 - {D19E6354-A643-4ACC-82D5-B2780BB83475}.Debug|amd64.ActiveCfg = Debug|x64 - {D19E6354-A643-4ACC-82D5-B2780BB83475}.Debug|amd64.Build.0 = Debug|x64 - {D19E6354-A643-4ACC-82D5-B2780BB83475}.Debug|arm.ActiveCfg = Debug|Win32 - {D19E6354-A643-4ACC-82D5-B2780BB83475}.Debug|arm64.ActiveCfg = Debug|ARM64 - {D19E6354-A643-4ACC-82D5-B2780BB83475}.Debug|arm64.Build.0 = Debug|ARM64 - {D19E6354-A643-4ACC-82D5-B2780BB83475}.Debug|x86.ActiveCfg = Debug|Win32 - {D19E6354-A643-4ACC-82D5-B2780BB83475}.Debug|x86.Build.0 = Debug|Win32 - {D19E6354-A643-4ACC-82D5-B2780BB83475}.Release|amd64.ActiveCfg = Release|x64 - {D19E6354-A643-4ACC-82D5-B2780BB83475}.Release|amd64.Build.0 = Release|x64 - {D19E6354-A643-4ACC-82D5-B2780BB83475}.Release|arm.ActiveCfg = Release|Win32 - {D19E6354-A643-4ACC-82D5-B2780BB83475}.Release|arm64.ActiveCfg = Release|ARM64 - {D19E6354-A643-4ACC-82D5-B2780BB83475}.Release|arm64.Build.0 = Release|ARM64 - {D19E6354-A643-4ACC-82D5-B2780BB83475}.Release|x86.ActiveCfg = Release|Win32 - {D19E6354-A643-4ACC-82D5-B2780BB83475}.Release|x86.Build.0 = Release|Win32 {F7679B65-2FEC-469A-8BAC-B07BF4439422}.Debug|amd64.ActiveCfg = Debug|x64 {F7679B65-2FEC-469A-8BAC-B07BF4439422}.Debug|amd64.Build.0 = Debug|x64 {F7679B65-2FEC-469A-8BAC-B07BF4439422}.Debug|arm.ActiveCfg = Debug|Win32