From 85c32a5566f1025ff250dfe85c87d57450e720f8 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Wed, 14 Oct 2020 09:09:27 +0200 Subject: [PATCH] api: disable driver management for wintun.dll that don't have a driver Namely the 32-bit ARM platform, which we will ship wintun.dll for ARM on ARM64 clients exclusively. Signed-off-by: Simon Rozman --- api/driver.c | 194 ++++++++++++++++++++++++++------------------------- api/driver.h | 4 ++ 2 files changed, 102 insertions(+), 96 deletions(-) diff --git a/api/driver.c b/api/driver.c index a65c0a9..d46f641 100644 --- a/api/driver.c +++ b/api/driver.c @@ -62,6 +62,102 @@ out: return NULL; } +/** + * Checks if the device (i.e. network adapter) is using Wintun driver. + * + * @param DevInfo A handle to the device information set that contains a device information element that + * represents the device. + * + * @param DevInfoData A pointer to a structure that specifies the device information element in DevInfo. + * + * @return non-zero when using Wintun driver; zero when not or error - use GetLastError(). + */ +BOOL +DriverIsWintunAdapter(_In_ HDEVINFO DevInfo, _In_opt_ SP_DEVINFO_DATA *DevInfoData) +{ + BOOL Found = FALSE; + if (!SetupDiBuildDriverInfoList(DevInfo, DevInfoData, SPDIT_COMPATDRIVER)) + { + WINTUN_LOGGER_LAST_ERROR(L"Failed to build list of drivers"); + return FALSE; + } + HANDLE Heap = GetProcessHeap(); + for (DWORD EnumIndex = 0; !Found; ++EnumIndex) + { + SP_DRVINFO_DATA_W DrvInfoData = { .cbSize = sizeof(SP_DRVINFO_DATA_W) }; + if (!SetupDiEnumDriverInfoW(DevInfo, DevInfoData, SPDIT_COMPATDRIVER, EnumIndex, &DrvInfoData)) + { + if (GetLastError() == ERROR_NO_MORE_ITEMS) + break; + continue; + } + SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData = DriverGetDrvInfoDetail(DevInfo, DevInfoData, &DrvInfoData); + if (!DrvInfoDetailData) + continue; + Found = !_wcsicmp(DrvInfoDetailData->HardwareID, WINTUN_HWID); + HeapFree(Heap, 0, DrvInfoDetailData); + } + SetupDiDestroyDriverInfoList(DevInfo, DevInfoData, SPDIT_COMPATDRIVER); + SetLastError(ERROR_SUCCESS); + return Found; +} + +/** + * Returns a handle to the adapter device object. + * + * @param InstanceId Adapter device instance ID. + * + * @return device handle on success; INVALID_HANDLE_VALUE otherwise - use GetLastError(). + */ +_Return_type_success_(return != INVALID_HANDLE_VALUE) HANDLE + DriverGetAdapterDeviceObject(_In_opt_z_ const WCHAR *InstanceId) +{ + HANDLE Heap = GetProcessHeap(); + ULONG InterfacesLen; + HANDLE Handle = INVALID_HANDLE_VALUE; + DWORD Result = CM_Get_Device_Interface_List_SizeW( + &InterfacesLen, (GUID *)&GUID_DEVINTERFACE_NET, (DEVINSTID_W)InstanceId, CM_GET_DEVICE_INTERFACE_LIST_PRESENT); + if (Result != CR_SUCCESS) + { + WINTUN_LOGGER(WINTUN_LOG_ERR, L"Failed to get device associated device instances size"); + SetLastError(ERROR_GEN_FAILURE); + return INVALID_HANDLE_VALUE; + } + WCHAR *Interfaces = HeapAlloc(Heap, 0, InterfacesLen * sizeof(WCHAR)); + if (!Interfaces) + { + SetLastError(ERROR_OUTOFMEMORY); + return INVALID_HANDLE_VALUE; + } + Result = CM_Get_Device_Interface_ListW( + (GUID *)&GUID_DEVINTERFACE_NET, + (DEVINSTID_W)InstanceId, + Interfaces, + InterfacesLen, + CM_GET_DEVICE_INTERFACE_LIST_PRESENT); + if (Result != CR_SUCCESS) + { + WINTUN_LOGGER(WINTUN_LOG_ERR, L"Failed to get device associated device instances"); + Result = ERROR_GEN_FAILURE; + goto cleanupBuf; + } + Handle = CreateFileW( + Interfaces, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, + OPEN_EXISTING, + 0, + NULL); + Result = Handle != INVALID_HANDLE_VALUE ? ERROR_SUCCESS : WINTUN_LOGGER_LAST_ERROR(L"Failed to connect to device"); +cleanupBuf: + HeapFree(Heap, 0, Interfaces); + SetLastError(Result); + return Handle; +} + +#if defined(HAVE_EV) || defined(HAVE_WHQL) + /** * Checks if the Wintun driver is loaded. * @@ -267,8 +363,6 @@ InstallDriver(_In_ BOOL UpdateExisting) UseWHQL = FALSE; #elif defined(HAVE_WHQL) UseWHQL = TRUE; -#else -# error No driver available #endif if (!UseWHQL && (Result = InstallCertificate(L"wintun.sys")) != ERROR_SUCCESS) WINTUN_LOGGER_ERROR(L"Unable to install code signing certificate", Result); @@ -353,100 +447,6 @@ cleanupDeviceInfoSet: return Result; } -/** - * Checks if the device (i.e. network adapter) is using Wintun driver. - * - * @param DevInfo A handle to the device information set that contains a device information element that - * represents the device. - * - * @param DevInfoData A pointer to a structure that specifies the device information element in DevInfo. - * - * @return non-zero when using Wintun driver; zero when not or error - use GetLastError(). - */ -BOOL -DriverIsWintunAdapter(_In_ HDEVINFO DevInfo, _In_opt_ SP_DEVINFO_DATA *DevInfoData) -{ - BOOL Found = FALSE; - if (!SetupDiBuildDriverInfoList(DevInfo, DevInfoData, SPDIT_COMPATDRIVER)) - { - WINTUN_LOGGER_LAST_ERROR(L"Failed to build list of drivers"); - return FALSE; - } - HANDLE Heap = GetProcessHeap(); - for (DWORD EnumIndex = 0; !Found; ++EnumIndex) - { - SP_DRVINFO_DATA_W DrvInfoData = { .cbSize = sizeof(SP_DRVINFO_DATA_W) }; - if (!SetupDiEnumDriverInfoW(DevInfo, DevInfoData, SPDIT_COMPATDRIVER, EnumIndex, &DrvInfoData)) - { - if (GetLastError() == ERROR_NO_MORE_ITEMS) - break; - continue; - } - SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData = DriverGetDrvInfoDetail(DevInfo, DevInfoData, &DrvInfoData); - if (!DrvInfoDetailData) - continue; - Found = !_wcsicmp(DrvInfoDetailData->HardwareID, WINTUN_HWID); - HeapFree(Heap, 0, DrvInfoDetailData); - } - SetupDiDestroyDriverInfoList(DevInfo, DevInfoData, SPDIT_COMPATDRIVER); - SetLastError(ERROR_SUCCESS); - return Found; -} - -/** - * Returns a handle to the adapter device object. - * - * @param InstanceId Adapter device instance ID. - * - * @return device handle on success; INVALID_HANDLE_VALUE otherwise - use GetLastError(). - */ -_Return_type_success_(return != INVALID_HANDLE_VALUE) HANDLE - DriverGetAdapterDeviceObject(_In_opt_z_ const WCHAR *InstanceId) -{ - HANDLE Heap = GetProcessHeap(); - ULONG InterfacesLen; - HANDLE Handle = INVALID_HANDLE_VALUE; - DWORD Result = CM_Get_Device_Interface_List_SizeW( - &InterfacesLen, (GUID *)&GUID_DEVINTERFACE_NET, (DEVINSTID_W)InstanceId, CM_GET_DEVICE_INTERFACE_LIST_PRESENT); - if (Result != CR_SUCCESS) - { - WINTUN_LOGGER(WINTUN_LOG_ERR, L"Failed to get device associated device instances size"); - SetLastError(ERROR_GEN_FAILURE); - return INVALID_HANDLE_VALUE; - } - WCHAR *Interfaces = HeapAlloc(Heap, 0, InterfacesLen * sizeof(WCHAR)); - if (!Interfaces) - { - SetLastError(ERROR_OUTOFMEMORY); - return INVALID_HANDLE_VALUE; - } - Result = CM_Get_Device_Interface_ListW( - (GUID *)&GUID_DEVINTERFACE_NET, - (DEVINSTID_W)InstanceId, - Interfaces, - InterfacesLen, - CM_GET_DEVICE_INTERFACE_LIST_PRESENT); - if (Result != CR_SUCCESS) - { - WINTUN_LOGGER(WINTUN_LOG_ERR, L"Failed to get device associated device instances"); - Result = ERROR_GEN_FAILURE; - goto cleanupBuf; - } - Handle = CreateFileW( - Interfaces, - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - 0, - NULL); - Result = Handle != INVALID_HANDLE_VALUE ? ERROR_SUCCESS : WINTUN_LOGGER_LAST_ERROR(L"Failed to connect to device"); -cleanupBuf: - HeapFree(Heap, 0, Interfaces); - SetLastError(Result); - return Handle; -} - #define TUN_IOCTL_FORCE_CLOSE_HANDLES CTL_CODE(51820U, 0x971U, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA) /** @@ -695,3 +695,5 @@ WINTUN_STATUS DriverUninstall(VOID) WINTUN_LOGGER(WINTUN_LOG_INFO, L"Uninstallation successful"); return Result; } + +#endif diff --git a/api/driver.h b/api/driver.h index e8514df..c17787c 100644 --- a/api/driver.h +++ b/api/driver.h @@ -22,6 +22,10 @@ DriverIsWintunAdapter(_In_ HDEVINFO DevInfo, _In_opt_ SP_DEVINFO_DATA *DevInfoDa _Return_type_success_(return != INVALID_HANDLE_VALUE) HANDLE DriverGetAdapterDeviceObject(_In_opt_z_ const WCHAR *InstanceId); +#if defined(HAVE_EV) || defined(HAVE_WHQL) + WINTUN_STATUS DriverInstallOrUpdate(VOID); WINTUN_STATUS DriverUninstall(VOID); + +#endif \ No newline at end of file