diff options
author | Simon Rozman <simon@rozman.si> | 2020-10-15 11:32:06 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2020-10-30 16:51:00 +0100 |
commit | 16a9737578c585db969be64b522777c18d2b1ad6 (patch) | |
tree | e52f5b04d7c92811a8987cccdc2a0a52363202ef /api | |
parent | api: simplify logger macros names (diff) | |
download | wintun-16a9737578c585db969be64b522777c18d2b1ad6.tar.xz wintun-16a9737578c585db969be64b522777c18d2b1ad6.zip |
api: internal reorganization
Gather adapter management in adapter.h/.c (formerly devmgmt.h/.c) and
unify HwID tests.
Use "Namespace" namespace in all functions from namespace.h/.c.
Fix char strings in LOG_...
Signed-off-by: Simon Rozman <simon@rozman.si>
Diffstat (limited to 'api')
-rw-r--r-- | api/adapter.c (renamed from api/devmgmt.c) | 415 | ||||
-rw-r--r-- | api/adapter.h (renamed from api/devmgmt.h) | 35 | ||||
-rw-r--r-- | api/api.c | 4 | ||||
-rw-r--r-- | api/api.vcxproj | 4 | ||||
-rw-r--r-- | api/api.vcxproj.filters | 12 | ||||
-rw-r--r-- | api/driver.c | 368 | ||||
-rw-r--r-- | api/driver.h | 12 | ||||
-rw-r--r-- | api/namespace.c | 4 | ||||
-rw-r--r-- | api/namespace.h | 4 | ||||
-rw-r--r-- | api/pch.h | 2 | ||||
-rw-r--r-- | api/registry.c | 6 | ||||
-rw-r--r-- | api/resource.c | 2 |
12 files changed, 424 insertions, 444 deletions
diff --git a/api/devmgmt.c b/api/adapter.c index c57cdf1..319e3bc 100644 --- a/api/devmgmt.c +++ b/api/adapter.c @@ -11,6 +11,56 @@ static _locale_t Locale; /** + * Retrieves driver information detail for a device information set or a particular device information element in the + * device information set. + * + * @param DevInfo A handle to the device information set that contains a device information element that + * represents the device for which to retrieve driver information. + * + * @param DevInfoData A pointer to a structure that specifies the device information element in DevInfo. + * + * @param DrvInfoData A pointer to a structure that specifies the driver information element that represents the + * driver for which to retrieve details. + * + * @param DrvInfoDetailData A pointer to a structure that receives detailed information about the specified driver. + * Must be released with HeapFree(GetProcessHeap(), 0, *DrvInfoDetailData) after use. + * + * @return ERROR_SUCCESS on success; Win32 error code otherwise. + */ +WINTUN_STATUS +AdapterGetDrvInfoDetail( + _In_ HDEVINFO DevInfo, + _In_opt_ SP_DEVINFO_DATA *DevInfoData, + _In_ SP_DRVINFO_DATA_W *DrvInfoData, + _Out_ SP_DRVINFO_DETAIL_DATA_W **DrvInfoDetailData) +{ + HANDLE Heap = GetProcessHeap(); + DWORD Size = sizeof(SP_DRVINFO_DETAIL_DATA_W) + 0x100; + DWORD Result; + for (;;) + { + *DrvInfoDetailData = HeapAlloc(Heap, 0, Size); + if (!*DrvInfoDetailData) + { + Result = ERROR_OUTOFMEMORY; + goto out; + } + (*DrvInfoDetailData)->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA_W); + if (SetupDiGetDriverInfoDetailW(DevInfo, DevInfoData, DrvInfoData, *DrvInfoDetailData, Size, &Size)) + return ERROR_SUCCESS; + Result = GetLastError(); + HeapFree(Heap, 0, *DrvInfoDetailData); + if (Result != ERROR_INSUFFICIENT_BUFFER) + { + LOG_ERROR(L"Failed", Result); + goto out; + } + } +out: + return Result; +} + +/** * Retrieves a specified Plug and Play device property. * * @param DevInfo A handle to the device information set that contains a device information element that @@ -140,19 +190,273 @@ GetDeviceRegistryMultiString( } /** - * Tests if any of the hardware IDs match ours. + * Tests if any of device compatible hardware IDs match ours. * - * @param Hwids Multi-string containing a list of hardware IDs. + * @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 TRUE on match; FALSE otherwise. + * @return ERROR_SUCCESS on success; Win32 error code otherwise. */ -static BOOL -IsOurHardwareID(_In_z_ WCHAR *Hwids) +static WINTUN_STATUS +IsOurAdapter(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData, _Out_ BOOL *IsOur) { - for (; Hwids[0]; Hwids += wcslen(Hwids) + 1) - if (!_wcsicmp(Hwids, WINTUN_HWID)) - return TRUE; - return FALSE; + WCHAR *Hwids; + DWORD Result = GetDeviceRegistryMultiString(DevInfo, DevInfoData, SPDRP_HARDWAREID, &Hwids); + if (Result != ERROR_SUCCESS) + return LOG_ERROR(L"Failed to query hardware ID", Result); + *IsOur = DriverIsOurHardwareID(Hwids); + return ERROR_SUCCESS; +} + +/** + * Returns a handle to the adapter device object. + * + * @param InstanceId Adapter device instance ID. + * + * @param Handle Pointer to receive the adapter device object handle. Must be released with CloseHandle. + * + * @return ERROR_SUCCESS on success; Win32 error code otherwise. + */ +static WINTUN_STATUS +GetDeviceObject(_In_opt_z_ const WCHAR *InstanceId, _Out_ HANDLE *Handle) +{ + HANDLE Heap = GetProcessHeap(); + ULONG InterfacesLen; + 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) + { + LOG(WINTUN_LOG_ERR, L"Failed to get device associated device instances size"); + return ERROR_GEN_FAILURE; + } + WCHAR *Interfaces = HeapAlloc(Heap, 0, InterfacesLen * sizeof(WCHAR)); + if (!Interfaces) + return ERROR_OUTOFMEMORY; + 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) + { + LOG(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 : LOG_LAST_ERROR(L"Failed to connect to device"); +cleanupBuf: + HeapFree(Heap, 0, Interfaces); + return Result; +} + +#define TUN_IOCTL_FORCE_CLOSE_HANDLES CTL_CODE(51820U, 0x971U, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA) + +/** + * Closes all client handles to the Wintun adapter. + * + * @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 ERROR_SUCCESS on success; Win32 error code otherwise. + */ +static WINTUN_STATUS +ForceCloseWintunAdapterHandle(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData) +{ + DWORD Result = ERROR_SUCCESS; + DWORD RequiredBytes; + if (SetupDiGetDeviceInstanceIdW(DevInfo, DevInfoData, NULL, 0, &RequiredBytes) || + (Result = GetLastError()) != ERROR_INSUFFICIENT_BUFFER) + return LOG_ERROR(L"Failed to query device instance ID size", Result); + HANDLE Heap = GetProcessHeap(); + WCHAR *InstanceId = HeapAlloc(Heap, HEAP_ZERO_MEMORY, sizeof(*InstanceId) * RequiredBytes); + if (!InstanceId) + return ERROR_OUTOFMEMORY; + if (!SetupDiGetDeviceInstanceIdW(DevInfo, DevInfoData, InstanceId, RequiredBytes, &RequiredBytes)) + { + Result = LOG_LAST_ERROR(L"Failed to get device instance ID"); + goto out; + } + HANDLE NdisHandle; + Result = GetDeviceObject(InstanceId, &NdisHandle); + if (Result != ERROR_SUCCESS) + { + LOG_ERROR(L"Failed to get adapter device object", Result); + goto out; + } + Result = DeviceIoControl(NdisHandle, TUN_IOCTL_FORCE_CLOSE_HANDLES, NULL, 0, NULL, 0, &RequiredBytes, NULL) + ? ERROR_SUCCESS + : LOG_LAST_ERROR(L"Failed to perform ioctl"); + CloseHandle(NdisHandle); +out: + HeapFree(Heap, 0, InstanceId); + return Result; +} + +/** + * Disables all Wintun adapters. + * + * @param DevInfo A handle to the device information set. + * + * @param DisabledAdapters Output list of disabled adapters. The adapters disabled are inserted in the list head. + * + * @return ERROR_SUCCESS on success; Win32 error code otherwise. + */ +WINTUN_STATUS +AdapterDisableAllOurs(_In_ HDEVINFO DevInfo, _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 }; + DWORD Result = ERROR_SUCCESS; + HANDLE Heap = GetProcessHeap(); + for (DWORD EnumIndex = 0;; ++EnumIndex) + { + SP_DEVINFO_DATA_LIST *DeviceNode = HeapAlloc(Heap, 0, sizeof(SP_DEVINFO_DATA_LIST)); + if (!DeviceNode) + return ERROR_OUTOFMEMORY; + DeviceNode->Data.cbSize = sizeof(SP_DEVINFO_DATA); + if (!SetupDiEnumDeviceInfo(DevInfo, EnumIndex, &DeviceNode->Data)) + { + if (GetLastError() == ERROR_NO_MORE_ITEMS) + { + HeapFree(Heap, 0, DeviceNode); + break; + } + goto cleanupDeviceInfoData; + } + BOOL IsOur; + if (IsOurAdapter(DevInfo, &DeviceNode->Data, &IsOur) != ERROR_SUCCESS || !IsOur) + 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; + + LOG(WINTUN_LOG_INFO, L"Force closing all open handles for existing adapter"); + if (ForceCloseWintunAdapterHandle(DevInfo, &DeviceNode->Data) != ERROR_SUCCESS) + LOG(WINTUN_LOG_WARN, L"Failed to force close adapter handles"); + Sleep(200); + + LOG(WINTUN_LOG_INFO, L"Disabling existing adapter"); + if (!SetupDiSetClassInstallParamsW(DevInfo, &DeviceNode->Data, &Params.ClassInstallHeader, sizeof(Params)) || + !SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, DevInfo, &DeviceNode->Data)) + { + LOG_LAST_ERROR(L"Unable to disable existing adapter"); + Result = Result != ERROR_SUCCESS ? Result : GetLastError(); + goto cleanupDeviceInfoData; + } + + DeviceNode->Next = *DisabledAdapters; + *DisabledAdapters = DeviceNode; + continue; + + cleanupDeviceInfoData: + HeapFree(Heap, 0, &DeviceNode->Data); + } + return Result; +} + +/** + * Enables all adapters. + * + * @param DevInfo A handle to the device information set. + * + * @param AdaptersToEnable Input list of adapters to enable. + * + * @return ERROR_SUCCESS on success; Win32 error code otherwise. + */ +WINTUN_STATUS +AdapterEnableAll(_In_ HDEVINFO DevInfo, _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 }; + DWORD Result = ERROR_SUCCESS; + for (SP_DEVINFO_DATA_LIST *DeviceNode = AdaptersToEnable; DeviceNode; DeviceNode = DeviceNode->Next) + { + LOG(WINTUN_LOG_INFO, L"Enabling existing adapter"); + if (!SetupDiSetClassInstallParamsW(DevInfo, &DeviceNode->Data, &Params.ClassInstallHeader, sizeof(Params)) || + !SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, DevInfo, &DeviceNode->Data)) + { + LOG_LAST_ERROR(L"Unable to enable existing adapter"); + Result = Result != ERROR_SUCCESS ? Result : GetLastError(); + } + } + return Result; +} + +/** + * Removes all Wintun adapters. + * + * @return ERROR_SUCCESS on success; Win32 error code otherwise. + */ +WINTUN_STATUS +AdapterDeleteAllOurs() +{ + DWORD Result = ERROR_SUCCESS; + HDEVINFO DevInfo = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL); + if (DevInfo == INVALID_HANDLE_VALUE) + return LOG_LAST_ERROR(L"Failed to get present class devices"); + SP_REMOVEDEVICE_PARAMS Params = { .ClassInstallHeader = { .cbSize = sizeof(SP_CLASSINSTALL_HEADER), + .InstallFunction = DIF_REMOVE }, + .Scope = DI_REMOVEDEVICE_GLOBAL }; + for (DWORD EnumIndex = 0;; ++EnumIndex) + { + SP_DEVINFO_DATA DevInfoData = { .cbSize = sizeof(SP_DEVINFO_DATA) }; + if (!SetupDiEnumDeviceInfo(DevInfo, EnumIndex, &DevInfoData)) + { + if (GetLastError() == ERROR_NO_MORE_ITEMS) + break; + continue; + } + + BOOL IsOur; + if (IsOurAdapter(DevInfo, &DevInfoData, &IsOur) != ERROR_SUCCESS || !IsOur) + continue; + + LOG(WINTUN_LOG_INFO, L"Force closing all open handles for existing adapter"); + if (ForceCloseWintunAdapterHandle(DevInfo, &DevInfoData) != ERROR_SUCCESS) + LOG(WINTUN_LOG_WARN, L"Failed to force close adapter handles"); + Sleep(200); + + LOG(WINTUN_LOG_INFO, L"Removing existing adapter"); + if (!SetupDiSetClassInstallParamsW(DevInfo, &DevInfoData, &Params.ClassInstallHeader, sizeof(Params)) || + !SetupDiCallClassInstaller(DIF_REMOVE, DevInfo, &DevInfoData)) + { + LOG_LAST_ERROR(L"Unable to remove existing adapter"); + Result = Result != ERROR_SUCCESS ? Result : GetLastError(); + } + } + SetupDiDestroyDeviceInfoList(DevInfo); + return Result; +} + +void +AdapterInit() +{ + Locale = _wcreate_locale(LC_ALL, L""); +} + +void +AdapterCleanup() +{ + _free_locale(Locale); } /** @@ -528,7 +832,7 @@ WintunGetAdapter( _Out_ WINTUN_ADAPTER **Adapter) { DWORD Result; - HANDLE Mutex = TakeNameMutex(Pool); + HANDLE Mutex = NamespaceTakeMutex(Pool); if (!Mutex) return ERROR_INVALID_HANDLE; @@ -539,7 +843,6 @@ WintunGetAdapter( goto cleanupMutex; } - HANDLE Heap = GetProcessHeap(); for (DWORD EnumIndex = 0;; ++EnumIndex) { SP_DEVINFO_DATA DevInfoData = { .cbSize = sizeof(SP_DEVINFO_DATA) }; @@ -566,25 +869,17 @@ WintunGetAdapter( continue; } - /* Check the Hardware ID to make sure it's a real Wintun device. This avoids doing slow operations on non-Wintun - * devices. */ - WCHAR *Hwids; - Result = GetDeviceRegistryMultiString(DevInfo, &DevInfoData, SPDRP_HARDWAREID, &Hwids); + /* Check the Hardware ID to make sure it's a real Wintun device. */ + BOOL IsOur; + Result = IsOurAdapter(DevInfo, &DevInfoData, &IsOur); if (Result != ERROR_SUCCESS) { - LOG_ERROR(L"Failed to query hardware ID", Result); - goto cleanupDevInfo; - } - if (!IsOurHardwareID(Hwids)) - { - HeapFree(Heap, 0, Hwids); - Result = ERROR_ALREADY_EXISTS; + LOG_ERROR(L"Failed to determine hardware ID", Result); goto cleanupDevInfo; } - HeapFree(Heap, 0, Hwids); - - if (!DriverIsWintunAdapter(DevInfo, &DevInfoData)) + if (!IsOur) { + LOG_ERROR(L"Foreign adapter with the same name exists", Result); Result = ERROR_ALREADY_EXISTS; goto cleanupDevInfo; } @@ -598,6 +893,7 @@ WintunGetAdapter( } if (!IsMember) { + LOG_ERROR(L"Wintun adapter with the same name exists in another pool", Result); Result = ERROR_ALREADY_EXISTS; goto cleanupDevInfo; } @@ -612,7 +908,7 @@ WintunGetAdapter( cleanupDevInfo: SetupDiDestroyDeviceInfoList(DevInfo); cleanupMutex: - ReleaseNameMutex(Mutex); + NamespaceReleaseMutex(Mutex); return Result; } @@ -739,8 +1035,7 @@ WintunGetAdapterLUID(_In_ const WINTUN_ADAPTER *Adapter, _Out_ LUID *Luid) WINTUN_STATUS WINAPI WintunGetAdapterDeviceObject(_In_ const WINTUN_ADAPTER *Adapter, _Out_ HANDLE *Handle) { - *Handle = DriverGetAdapterDeviceObject(Adapter->DevInstanceID); - return *Handle != INVALID_HANDLE_VALUE ? ERROR_SUCCESS : GetLastError(); + return GetDeviceObject(Adapter->DevInstanceID, Handle); } /** @@ -797,7 +1092,7 @@ WintunCreateAdapter( _Inout_ BOOL *RebootRequired) { DWORD Result; - HANDLE Mutex = TakeNameMutex(Pool); + HANDLE Mutex = NamespaceTakeMutex(Pool); if (!Mutex) return ERROR_INVALID_HANDLE; @@ -862,12 +1157,10 @@ WintunCreateAdapter( if (!IsNewer(&DrvInfoData, &DriverDate, DriverVersion)) continue; - SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData = DriverGetDrvInfoDetail(DevInfo, &DevInfoData, &DrvInfoData); - if (!DrvInfoDetailData) + SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData; + if (AdapterGetDrvInfoDetail(DevInfo, &DevInfoData, &DrvInfoData, &DrvInfoDetailData) != ERROR_SUCCESS) continue; - if ((DrvInfoDetailData->CompatIDsOffset <= 1 || _wcsicmp(DrvInfoDetailData->HardwareID, WINTUN_HWID)) && - (!DrvInfoDetailData->CompatIDsLength || - !IsOurHardwareID(DrvInfoDetailData->HardwareID + DrvInfoDetailData->CompatIDsOffset))) + if (!DriverIsOurDrvInfoDetail(DrvInfoDetailData)) { HeapFree(Heap, 0, DrvInfoDetailData); continue; @@ -1021,7 +1314,7 @@ WintunCreateAdapter( goto cleanupTcpipAdapterRegKey; } - const static DWORD EnableDeadGWDetect = 0; + static const DWORD EnableDeadGWDetect = 0; Result = RegSetKeyValueW( TcpipInterfaceRegKey, NULL, L"EnableDeadGWDetect", REG_DWORD, &EnableDeadGWDetect, sizeof(EnableDeadGWDetect)); if (Result != ERROR_SUCCESS) @@ -1055,7 +1348,7 @@ cleanupDriverInfoList: cleanupDevInfo: SetupDiDestroyDeviceInfoList(DevInfo); cleanupMutex: - ReleaseNameMutex(Mutex); + NamespaceReleaseMutex(Mutex); return Result; } @@ -1111,10 +1404,10 @@ WintunDeleteAdapter(_In_ const WINTUN_ADAPTER *Adapter, _Inout_ BOOL *RebootRequ WINTUN_STATUS WINAPI WintunEnumAdapters(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_ WINTUN_ENUM_FUNC Func, _In_ LPARAM Param) { - DWORD Result; - HANDLE Mutex = TakeNameMutex(Pool); + HANDLE Mutex = NamespaceTakeMutex(Pool); if (!Mutex) return ERROR_INVALID_HANDLE; + DWORD Result = ERROR_SUCCESS; HDEVINFO DevInfo = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL); if (DevInfo == INVALID_HANDLE_VALUE) { @@ -1122,36 +1415,25 @@ WintunEnumAdapters(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_ WINTUN_ENUM_ goto cleanupMutex; } HANDLE Heap = GetProcessHeap(); - for (DWORD EnumIndex = 0;; ++EnumIndex) + BOOL Continue = TRUE; + for (DWORD EnumIndex = 0; Continue; ++EnumIndex) { SP_DEVINFO_DATA DevInfoData = { .cbSize = sizeof(SP_DEVINFO_DATA) }; if (!SetupDiEnumDeviceInfo(DevInfo, EnumIndex, &DevInfoData)) { if (GetLastError() == ERROR_NO_MORE_ITEMS) - { - Result = ERROR_SUCCESS; break; - } continue; } - /* Check the Hardware ID to make sure it's a real Wintun device. This avoids doing slow operations on non-Wintun - * devices. */ - WCHAR *Hwids; - Result = GetDeviceRegistryMultiString(DevInfo, &DevInfoData, SPDRP_HARDWAREID, &Hwids); + BOOL IsOur; + Result = IsOurAdapter(DevInfo, &DevInfoData, &IsOur); if (Result != ERROR_SUCCESS) { - LOG_ERROR(L"Failed to query hardware ID", Result); + LOG_ERROR(L"Failed to determine hardware ID", Result); break; } - if (!IsOurHardwareID(Hwids)) - { - HeapFree(Heap, 0, Hwids); - continue; - } - HeapFree(Heap, 0, Hwids); - - if (!DriverIsWintunAdapter(DevInfo, &DevInfoData)) + if (!IsOur) continue; BOOL IsMember; @@ -1171,28 +1453,11 @@ WintunEnumAdapters(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_ WINTUN_ENUM_ LOG_ERROR(L"Failed to create adapter data", Result); break; } - if (Func(Adapter, Param)) - HeapFree(Heap, 0, Adapter); - else - { - HeapFree(Heap, 0, Adapter); - break; - } + Continue = Func(Adapter, Param); + HeapFree(Heap, 0, Adapter); } SetupDiDestroyDeviceInfoList(DevInfo); cleanupMutex: - ReleaseNameMutex(Mutex); + NamespaceReleaseMutex(Mutex); return Result; } - -void -DevmgmtInit() -{ - Locale = _wcreate_locale(LC_ALL, L""); -} - -void -DevmgmtCleanup() -{ - _free_locale(Locale); -} diff --git a/api/devmgmt.h b/api/adapter.h index 48dced5..5f38e46 100644 --- a/api/devmgmt.h +++ b/api/adapter.h @@ -6,11 +6,40 @@ #pragma once #include "api.h" +#include <SetupAPI.h> #include <IPExport.h> #define MAX_POOL 256 #define MAX_INSTANCE_ID MAX_PATH /* TODO: Is MAX_PATH always enough? */ +typedef struct _SP_DEVINFO_DATA_LIST +{ + SP_DEVINFO_DATA Data; + struct _SP_DEVINFO_DATA_LIST *Next; +} SP_DEVINFO_DATA_LIST; + +WINTUN_STATUS +AdapterGetDrvInfoDetail( + _In_ HDEVINFO DevInfo, + _In_opt_ SP_DEVINFO_DATA *DevInfoData, + _In_ SP_DRVINFO_DATA_W *DrvInfoData, + _Out_ SP_DRVINFO_DETAIL_DATA_W **DrvInfoDetailData); + +WINTUN_STATUS +AdapterDisableAllOurs(_In_ HDEVINFO DevInfo, _Inout_ SP_DEVINFO_DATA_LIST **DisabledAdapters); + +WINTUN_STATUS +AdapterEnableAll(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA_LIST *AdaptersToEnable); + +WINTUN_STATUS +AdapterDeleteAllOurs(); + +void +AdapterInit(); + +void +AdapterCleanup(); + typedef struct _WINTUN_ADAPTER { GUID CfgInstanceID; @@ -59,9 +88,3 @@ typedef BOOL(CALLBACK *WINTUN_ENUM_FUNC)(_In_ const WINTUN_ADAPTER *Adapter, _In WINTUN_STATUS WINAPI WintunEnumAdapters(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_ WINTUN_ENUM_FUNC Func, _In_ LPARAM Param); - -void -DevmgmtInit(); - -void -DevmgmtCleanup(); @@ -67,15 +67,15 @@ DllMain(_In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved) { case DLL_PROCESS_ATTACH: ResourceModule = hinstDLL; + AdapterInit(); NamespaceInit(); NciInit(); - DevmgmtInit(); break; case DLL_PROCESS_DETACH: - DevmgmtCleanup(); NciCleanup(); NamespaceCleanup(); + AdapterCleanup(); break; } return TRUE; diff --git a/api/api.vcxproj b/api/api.vcxproj index e405f0e..b65726f 100644 --- a/api/api.vcxproj +++ b/api/api.vcxproj @@ -190,7 +190,7 @@ </ItemGroup> <ItemGroup> <ClInclude Include="api.h" /> - <ClInclude Include="devmgmt.h" /> + <ClInclude Include="adapter.h" /> <ClInclude Include="driver.h" /> <ClInclude Include="logger.h" /> <ClInclude Include="namespace.h" /> @@ -201,7 +201,7 @@ </ItemGroup> <ItemGroup> <ClCompile Include="api.c" /> - <ClCompile Include="devmgmt.c" /> + <ClCompile Include="adapter.c" /> <ClCompile Include="driver.c" /> <ClCompile Include="logger.c" /> <ClCompile Include="namespace.c" /> diff --git a/api/api.vcxproj.filters b/api/api.vcxproj.filters index 188ad86..b64b00b 100644 --- a/api/api.vcxproj.filters +++ b/api/api.vcxproj.filters @@ -40,9 +40,6 @@ <ClInclude Include="registry.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="devmgmt.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="logger.h"> <Filter>Header Files</Filter> </ClInclude> @@ -52,6 +49,9 @@ <ClInclude Include="driver.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="adapter.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="api.c"> @@ -60,9 +60,6 @@ <ClCompile Include="namespace.c"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="devmgmt.c"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="nci.c"> <Filter>Source Files</Filter> </ClCompile> @@ -84,5 +81,8 @@ <ClCompile Include="driver.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="adapter.c"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> </Project>
\ No newline at end of file diff --git a/api/driver.c b/api/driver.c index 3a27f0a..60d9a25 100644 --- a/api/driver.c +++ b/api/driver.c @@ -7,153 +7,35 @@ #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; - /** - * Retrieves driver information detail for a device information set or a particular device information element in the - * device information set. - * - * @param DevInfo A handle to the device information set that contains a device information element that - * represents the device for which to retrieve driver information. - * - * @param DevInfoData A pointer to a structure that specifies the device information element in DevInfo. - * - * @param DrvInfoData A pointer to a structure that specifies the driver information element that represents the - * driver for which to retrieve details. + * Tests if any of the hardware IDs match ours. * - * @param DrvInfoDetailData A pointer to a structure that receives detailed information about the specified driver. - * Must be released with HeapFree(GetProcessHeap(), 0, *DrvInfoDetailData) after use. + * @param Hwids Multi-string containing a list of hardware IDs. * - * @return non-zero on success; zero otherwise - use GetLastError(). - */ -_Return_type_success_(return != NULL) SP_DRVINFO_DETAIL_DATA_W *DriverGetDrvInfoDetail( - _In_ HDEVINFO DevInfo, - _In_opt_ SP_DEVINFO_DATA *DevInfoData, - _In_ SP_DRVINFO_DATA_W *DrvInfoData) -{ - HANDLE Heap = GetProcessHeap(); - DWORD Size = sizeof(SP_DRVINFO_DETAIL_DATA_W) + 0x100; - DWORD Result; - for (;;) - { - SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData = HeapAlloc(Heap, 0, Size); - if (!DrvInfoDetailData) - { - Result = ERROR_OUTOFMEMORY; - goto out; - } - DrvInfoDetailData->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA_W); - if (SetupDiGetDriverInfoDetailW(DevInfo, DevInfoData, DrvInfoData, DrvInfoDetailData, Size, &Size)) - return DrvInfoDetailData; - Result = GetLastError(); - HeapFree(Heap, 0, DrvInfoDetailData); - if (Result != ERROR_INSUFFICIENT_BUFFER) - { - LOG_ERROR(L"Failed", Result); - goto out; - } - } -out: - SetLastError(Result); - 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(). + * @return TRUE on match; FALSE otherwise. */ BOOL -DriverIsWintunAdapter(_In_ HDEVINFO DevInfo, _In_opt_ SP_DEVINFO_DATA *DevInfoData) +DriverIsOurHardwareID(_In_z_ const WCHAR *Hwids) { - BOOL Found = FALSE; - if (!SetupDiBuildDriverInfoList(DevInfo, DevInfoData, SPDIT_COMPATDRIVER)) - { - LOG_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; + for (; Hwids[0]; Hwids += wcslen(Hwids) + 1) + if (!_wcsicmp(Hwids, WINTUN_HWID)) + return TRUE; + return FALSE; } /** - * Returns a handle to the adapter device object. + * Tests if hardware ID or any of the compatible IDs match ours. * - * @param InstanceId Adapter device instance ID. + * @param DrvInfoDetailData Detailed information about a particular driver information structure. * - * @return device handle on success; INVALID_HANDLE_VALUE otherwise - use GetLastError(). + * @return TRUE on match; FALSE otherwise. */ -_Return_type_success_(return != INVALID_HANDLE_VALUE) HANDLE - DriverGetAdapterDeviceObject(_In_opt_z_ const WCHAR *InstanceId) +BOOL +DriverIsOurDrvInfoDetail(_In_ const SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData) { - 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) - { - LOG(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) - { - LOG(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 : LOG_LAST_ERROR(L"Failed to connect to device"); -cleanupBuf: - HeapFree(Heap, 0, Interfaces); - SetLastError(Result); - return Handle; + return DrvInfoDetailData->CompatIDsOffset > 1 && !_wcsicmp(DrvInfoDetailData->HardwareID, WINTUN_HWID) || + DrvInfoDetailData->CompatIDsLength && + DriverIsOurHardwareID(DrvInfoDetailData->HardwareID + DrvInfoDetailData->CompatIDsOffset); } #if defined(HAVE_EV) || defined(HAVE_WHQL) @@ -405,7 +287,7 @@ InstallCertificate(_In_z_ const WCHAR *SignedResource) DWORD SizeResource; DWORD Result = ResourceGetAddress(SignedResource, &LockedResource, &SizeResource); if (Result != ERROR_SUCCESS) - return LOG_ERROR("Failed to locate resource", Result); + return LOG_ERROR(L"Failed to locate resource", Result); const CERT_BLOB CertBlob = { .cbData = SizeResource, .pbData = (BYTE *)LockedResource }; HCERTSTORE QueriedStore; if (!CryptQueryObject( @@ -420,7 +302,7 @@ InstallCertificate(_In_z_ const WCHAR *SignedResource) &QueriedStore, 0, NULL)) - return LOG_LAST_ERROR("Failed to find certificate"); + return LOG_LAST_ERROR(L"Failed to find certificate"); HCERTSTORE TrustedStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, L"TrustedPublisher"); if (!TrustedStore) @@ -576,207 +458,26 @@ static WINTUN_STATUS RemoveDriver(VOID) break; continue; } - SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData = DriverGetDrvInfoDetail(DevInfo, NULL, &DrvInfoData); - if (!DrvInfoDetailData) + SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData; + if (AdapterGetDrvInfoDetail(DevInfo, NULL, &DrvInfoData, &DrvInfoDetailData) != ERROR_SUCCESS) continue; - if (!_wcsicmp(DrvInfoDetailData->HardwareID, WINTUN_HWID)) - { - 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(Heap, 0, DrvInfoDetailData); - } - SetupDiDestroyDriverInfoList(DevInfo, NULL, SPDIT_CLASSDRIVER); -cleanupDeviceInfoSet: - SetupDiDestroyDeviceInfoList(DevInfo); - return Result; -} - -# define TUN_IOCTL_FORCE_CLOSE_HANDLES CTL_CODE(51820U, 0x971U, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA) - -/** - * Closes all client handles to the Wintun adapter. - * - * @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 ERROR_SUCCESS on success; Win32 error code otherwise. - */ -static WINTUN_STATUS -ForceCloseWintunAdapterHandle(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData) -{ - DWORD Result = ERROR_SUCCESS; - DWORD RequiredBytes; - if (SetupDiGetDeviceInstanceIdW(DevInfo, DevInfoData, NULL, 0, &RequiredBytes) || - (Result = GetLastError()) != ERROR_INSUFFICIENT_BUFFER) - return LOG_ERROR(L"Failed to query device instance ID size", Result); - HANDLE Heap = GetProcessHeap(); - WCHAR *InstanceId = HeapAlloc(Heap, HEAP_ZERO_MEMORY, sizeof(*InstanceId) * RequiredBytes); - if (!InstanceId) - return ERROR_OUTOFMEMORY; - if (!SetupDiGetDeviceInstanceIdW(DevInfo, DevInfoData, InstanceId, RequiredBytes, &RequiredBytes)) - { - Result = LOG_LAST_ERROR(L"Failed to get device instance ID"); - goto out; - } - HANDLE NdisHandle = DriverGetAdapterDeviceObject(InstanceId); - if (NdisHandle == INVALID_HANDLE_VALUE) - { - Result = GetLastError(); - goto out; - } - Result = DeviceIoControl(NdisHandle, TUN_IOCTL_FORCE_CLOSE_HANDLES, NULL, 0, NULL, 0, &RequiredBytes, NULL) - ? ERROR_SUCCESS - : LOG_LAST_ERROR(L"Failed to perform ioctl"); - CloseHandle(NdisHandle); -out: - HeapFree(Heap, 0, InstanceId); - return Result; -} - -/** - * Disables Wintun adapters. - * - * @param DevInfo A handle to the device information set. - * - * @param DisabledAdapters Output list of disabled adapters. The adapters disabled are inserted in the list head. - * - * @return ERROR_SUCCESS on success; Win32 error code otherwise. - */ -static WINTUN_STATUS -DisableWintunAdapters(_In_ HDEVINFO DevInfo, _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 }; - DWORD Result = ERROR_SUCCESS; - HANDLE Heap = GetProcessHeap(); - for (DWORD EnumIndex = 0;; ++EnumIndex) - { - SP_DEVINFO_DATA_LIST *DeviceNode = HeapAlloc(Heap, 0, sizeof(SP_DEVINFO_DATA_LIST)); - if (!DeviceNode) - return ERROR_OUTOFMEMORY; - DeviceNode->Data.cbSize = sizeof(SP_DEVINFO_DATA); - if (!SetupDiEnumDeviceInfo(DevInfo, EnumIndex, &DeviceNode->Data)) - { - if (GetLastError() == ERROR_NO_MORE_ITEMS) - { - HeapFree(Heap, 0, DeviceNode); - break; - } - goto cleanupDeviceInfoData; - } - if (!DriverIsWintunAdapter(DevInfo, &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; - - LOG(WINTUN_LOG_INFO, L"Force closing all open handles for existing adapter"); - if (ForceCloseWintunAdapterHandle(DevInfo, &DeviceNode->Data) != ERROR_SUCCESS) - LOG(WINTUN_LOG_WARN, L"Failed to force close adapter handles"); - Sleep(200); - - LOG(WINTUN_LOG_INFO, L"Disabling existing adapter"); - if (!SetupDiSetClassInstallParamsW(DevInfo, &DeviceNode->Data, &Params.ClassInstallHeader, sizeof(Params)) || - !SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, DevInfo, &DeviceNode->Data)) - { - LOG_LAST_ERROR(L"Unable to disable existing adapter"); - Result = Result != ERROR_SUCCESS ? Result : GetLastError(); - goto cleanupDeviceInfoData; - } - - DeviceNode->Next = *DisabledAdapters; - *DisabledAdapters = DeviceNode; - continue; - - cleanupDeviceInfoData: - HeapFree(Heap, 0, &DeviceNode->Data); - } - return Result; -} - -/** - * Removes all Wintun adapters. - * - * @param DevInfo A handle to the device information set. - * - * @param DisabledAdapters Output list of disabled adapters. - * - * @return ERROR_SUCCESS on success; Win32 error code otherwise. - */ -static WINTUN_STATUS -RemoveWintunAdapters(_In_ HDEVINFO DevInfo) -{ - SP_REMOVEDEVICE_PARAMS Params = { .ClassInstallHeader = { .cbSize = sizeof(SP_CLASSINSTALL_HEADER), - .InstallFunction = DIF_REMOVE }, - .Scope = DI_REMOVEDEVICE_GLOBAL }; - DWORD Result = ERROR_SUCCESS; - for (DWORD EnumIndex = 0;; ++EnumIndex) - { - SP_DEVINFO_DATA DevInfoData = { .cbSize = sizeof(SP_DEVINFO_DATA) }; - if (!SetupDiEnumDeviceInfo(DevInfo, EnumIndex, &DevInfoData)) + if (!DriverIsOurDrvInfoDetail(DrvInfoDetailData)) { - if (GetLastError() == ERROR_NO_MORE_ITEMS) - break; + HeapFree(Heap, 0, DrvInfoDetailData); continue; } - if (!DriverIsWintunAdapter(DevInfo, &DevInfoData)) - continue; - - LOG(WINTUN_LOG_INFO, L"Force closing all open handles for existing adapter"); - if (ForceCloseWintunAdapterHandle(DevInfo, &DevInfoData) != ERROR_SUCCESS) - LOG(WINTUN_LOG_WARN, L"Failed to force close adapter handles"); - Sleep(200); - - LOG(WINTUN_LOG_INFO, L"Removing existing adapter"); - if (!SetupDiSetClassInstallParamsW(DevInfo, &DevInfoData, &Params.ClassInstallHeader, sizeof(Params)) || - !SetupDiCallClassInstaller(DIF_REMOVE, DevInfo, &DevInfoData)) + 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 adapter"); - Result = Result != ERROR_SUCCESS ? Result : GetLastError(); - } - } - return Result; -} - -/** - * Enables Wintun adapters. - * - * @param DevInfo A handle to the device information set. - * - * @param AdaptersToEnable Input list of adapters to enable. - * - * @return ERROR_SUCCESS on success; Win32 error code otherwise. - */ -static WINTUN_STATUS -EnableWintunAdapters(_In_ HDEVINFO DevInfo, _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 }; - DWORD Result = ERROR_SUCCESS; - for (SP_DEVINFO_DATA_LIST *DeviceNode = AdaptersToEnable; DeviceNode; DeviceNode = DeviceNode->Next) - { - LOG(WINTUN_LOG_INFO, L"Enabling existing adapter"); - if (!SetupDiSetClassInstallParamsW(DevInfo, &DeviceNode->Data, &Params.ClassInstallHeader, sizeof(Params)) || - !SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, DevInfo, &DeviceNode->Data)) - { - LOG_LAST_ERROR(L"Unable to enable existing adapter"); + LOG_LAST_ERROR(L"Unable to remove existing driver"); Result = Result != ERROR_SUCCESS ? Result : GetLastError(); } + HeapFree(Heap, 0, DrvInfoDetailData); } + SetupDiDestroyDriverInfoList(DevInfo, NULL, SPDIT_CLASSDRIVER); +cleanupDeviceInfoSet: + SetupDiDestroyDeviceInfoList(DevInfo); return Result; } @@ -794,7 +495,7 @@ WINTUN_STATUS DriverInstallOrUpdate(VOID) SP_DEVINFO_DATA_LIST *ExistingAdapters = NULL; if (IsDriverLoaded()) { - DisableWintunAdapters(DevInfo, &ExistingAdapters); + AdapterDisableAllOurs(DevInfo, &ExistingAdapters); LOG(WINTUN_LOG_INFO, L"Waiting for driver to unload from kernel"); if (!EnsureDriverUnloaded()) LOG(WINTUN_LOG_WARN, L"Unable to unload driver, which means a reboot will likely be required"); @@ -815,7 +516,7 @@ WINTUN_STATUS DriverInstallOrUpdate(VOID) cleanupAdapters:; if (ExistingAdapters) { - EnableWintunAdapters(DevInfo, ExistingAdapters); + AdapterEnableAll(DevInfo, ExistingAdapters); while (ExistingAdapters) { SP_DEVINFO_DATA_LIST *Next = ExistingAdapters->Next; @@ -834,10 +535,7 @@ cleanupAdapters:; */ WINTUN_STATUS DriverUninstall(VOID) { - HDEVINFO DevInfo = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL); - if (DevInfo == INVALID_HANDLE_VALUE) - return LOG_LAST_ERROR(L"Failed to get present class devices"); - RemoveWintunAdapters(DevInfo); + AdapterDeleteAllOurs(); DWORD Result = RemoveDriver(); if (Result != ERROR_SUCCESS) LOG_ERROR(L"Failed to uninstall driver", Result); diff --git a/api/driver.h b/api/driver.h index 3f91025..d7906b3 100644 --- a/api/driver.h +++ b/api/driver.h @@ -7,20 +7,14 @@ #include "api.h" #include <Windows.h> -#include <SetupAPI.h> #define WINTUN_HWID L"Wintun" -_Return_type_success_(return != NULL) SP_DRVINFO_DETAIL_DATA_W *DriverGetDrvInfoDetail( - _In_ HDEVINFO DevInfo, - _In_opt_ SP_DEVINFO_DATA *DevInfoData, - _In_ SP_DRVINFO_DATA_W *DrvInfoData); - BOOL -DriverIsWintunAdapter(_In_ HDEVINFO DevInfo, _In_opt_ SP_DEVINFO_DATA *DevInfoData); +DriverIsOurHardwareID(_In_z_ const WCHAR *Hwids); -_Return_type_success_(return != INVALID_HANDLE_VALUE) HANDLE - DriverGetAdapterDeviceObject(_In_opt_z_ const WCHAR *InstanceId); +BOOL +DriverIsOurDrvInfoDetail(_In_ const SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData); #if defined(HAVE_EV) || defined(HAVE_WHQL) diff --git a/api/namespace.c b/api/namespace.c index c69d5b7..91410b2 100644 --- a/api/namespace.c +++ b/api/namespace.c @@ -122,7 +122,7 @@ cleanupLeaveCriticalSection: _Check_return_ HANDLE -TakeNameMutex(_In_z_ const WCHAR *Pool) +NamespaceTakeMutex(_In_z_ const WCHAR *Pool) { HANDLE Mutex = NULL; @@ -171,7 +171,7 @@ cleanupSha256: } void -ReleaseNameMutex(_In_ HANDLE Mutex) +NamespaceReleaseMutex(_In_ HANDLE Mutex) { ReleaseMutex(Mutex); CloseHandle(Mutex); diff --git a/api/namespace.h b/api/namespace.h index b5e77a9..8a26c4b 100644 --- a/api/namespace.h +++ b/api/namespace.h @@ -9,10 +9,10 @@ _Check_return_ HANDLE -TakeNameMutex(_In_z_ const WCHAR *Pool); +NamespaceTakeMutex(_In_z_ const WCHAR *Pool); void -ReleaseNameMutex(_In_ HANDLE Mutex); +NamespaceReleaseMutex(_In_ HANDLE Mutex); void NamespaceInit(); @@ -5,8 +5,8 @@ #pragma once +#include "adapter.h" #include "api.h" -#include "devmgmt.h" #include "driver.h" #include "logger.h" #include "namespace.h" diff --git a/api/registry.c b/api/registry.c index e591a46..f735d4d 100644 --- a/api/registry.c +++ b/api/registry.c @@ -49,7 +49,7 @@ OpenKeyWait(_In_ HKEY Key, _Inout_z_ WCHAR *Path, _In_ DWORD Access, _In_ ULONGL TimeLeft = 0; if (WaitForSingleObject(Event, (DWORD)TimeLeft) != WAIT_OBJECT_0) { - LOG(WINTUN_LOG_ERR, "Timeout waiting"); + LOG(WINTUN_LOG_ERR, L"Timeout waiting"); break; } } @@ -349,7 +349,7 @@ RegistryQueryStringWait(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _In_ DWORD TimeLeft = 0; if (WaitForSingleObject(Event, (DWORD)TimeLeft) != WAIT_OBJECT_0) { - LOG(WINTUN_LOG_ERR, "Timeout waiting"); + LOG(WINTUN_LOG_ERR, L"Timeout waiting"); break; } } @@ -427,7 +427,7 @@ RegistryQueryDWORDWait(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _In_ DWORD T TimeLeft = 0; if (WaitForSingleObject(Event, (DWORD)TimeLeft) != WAIT_OBJECT_0) { - LOG(WINTUN_LOG_ERR, "Timeout waiting"); + LOG(WINTUN_LOG_ERR, L"Timeout waiting"); break; } } diff --git a/api/resource.c b/api/resource.c index b59911e..7b1ea59 100644 --- a/api/resource.c +++ b/api/resource.c @@ -58,7 +58,7 @@ ResourceCopyToFile( DWORD SizeResource; DWORD Result = ResourceGetAddress(ResourceName, &LockedResource, &SizeResource); if (Result != ERROR_SUCCESS) - return LOG_ERROR("Failed to locate resource", Result); + return LOG_ERROR(L"Failed to locate resource", Result); HANDLE DestinationHandle = CreateFileW( DestinationPath, GENERIC_WRITE, |