2020-07-07 15:42:39 +02:00
/* SPDX-License-Identifier: GPL-2.0
*
2021-01-30 16:45:26 +01:00
* Copyright ( C ) 2018 - 2021 WireGuard LLC . All Rights Reserved .
2020-07-07 15:42:39 +02:00
*/
2020-10-31 11:55:26 +01:00
# include <Windows.h>
# include <winternl.h>
# include <cfgmgr32.h>
# include <devguid.h>
# include <iphlpapi.h>
2021-10-12 07:21:31 +02:00
# include <objbase.h>
2020-10-31 11:55:26 +01:00
# include <ndisguid.h>
# include <SetupAPI.h>
# include <Shlwapi.h>
2021-10-12 07:21:31 +02:00
# include <devioctl.h>
2020-10-31 11:55:26 +01:00
# include <wchar.h>
2020-11-02 13:52:47 +01:00
# include <initguid.h> /* Keep these two at bottom in this order, so that we only generate extra GUIDs for devpkey. The other keys we'll get from uuid.lib like usual. */
# include <devpkey.h>
2021-10-12 07:21:31 +02:00
/* We pretend we're Windows 8, and then hack around the limitation in Windows 7 below. */
# if NTDDI_VERSION == NTDDI_WIN7
# undef NTDDI_VERSION
# define NTDDI_VERSION NTDDI_WIN8
# include <devquery.h>
# include <swdevice.h>
# undef NTDDI_VERSION
# define NTDDI_VERSION NTDDI_WIN7
# else
# include <devquery.h>
# include <swdevice.h>
# endif
2020-07-07 15:42:39 +02:00
2021-05-11 19:43:34 +02:00
# include "adapter.h"
2021-10-12 07:21:31 +02:00
# include "driver.h"
2021-05-11 19:43:34 +02:00
# include "logger.h"
2021-07-28 13:50:40 +02:00
# include "main.h"
2021-05-11 19:43:34 +02:00
# include "namespace.h"
# include "nci.h"
# include "ntdll.h"
2021-07-28 20:20:09 +02:00
# include "rundll32.h"
2021-10-12 07:21:31 +02:00
# include "registry.h"
# include "adapter_win7.h"
2021-05-11 19:43:34 +02:00
2020-10-15 15:54:37 +02:00
# pragma warning(disable : 4221) /* nonstandard: address of automatic in initializer */
2021-10-12 07:21:31 +02:00
const DEVPROPKEY DEVPKEY_Wintun_Name = {
2021-07-28 20:20:09 +02:00
{ 0x3361c968 , 0x2f2e , 0x4660 , { 0xb4 , 0x7e , 0x69 , 0x9c , 0xdc , 0x4c , 0x32 , 0xb9 } } ,
DEVPROPID_FIRST_USABLE + 1
} ;
_Must_inspect_result_
2021-10-12 07:21:31 +02:00
static _Return_type_success_ ( return ! = FALSE )
BOOL
PopulateAdapterData ( _Inout_ WINTUN_ADAPTER * Adapter )
2020-10-15 11:32:06 +02:00
{
2021-10-12 07:21:31 +02:00
DWORD LastError = ERROR_SUCCESS ;
/* Open HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\<class>\<id> registry key. */
HKEY Key =
SetupDiOpenDevRegKey ( Adapter - > DevInfo , & Adapter - > DevInfoData , DICS_FLAG_GLOBAL , 0 , DIREG_DRV , KEY_QUERY_VALUE ) ;
if ( Key = = INVALID_HANDLE_VALUE )
2020-10-15 11:32:06 +02:00
{
2021-10-12 07:21:31 +02:00
LOG_LAST_ERROR ( L " Failed to open adapter device registry key " ) ;
return FALSE ;
}
LPWSTR ValueStr = RegistryQueryString ( Key , L " NetCfgInstanceId " , TRUE ) ;
if ( ! ValueStr )
{
WCHAR RegPath [ MAX_REG_PATH ] ;
LoggerGetRegistryKeyPath ( Key , RegPath ) ;
LastError = LOG ( WINTUN_LOG_ERR , L " Failed to get %.*s \\ NetCfgInstanceId " , MAX_REG_PATH , RegPath ) ;
goto cleanupKey ;
2020-10-15 11:32:06 +02:00
}
2021-10-12 07:21:31 +02:00
if ( FAILED ( CLSIDFromString ( ValueStr , & Adapter - > CfgInstanceID ) ) )
{
WCHAR RegPath [ MAX_REG_PATH ] ;
LoggerGetRegistryKeyPath ( Key , RegPath ) ;
LastError = LOG ( WINTUN_LOG_ERR , L " %.*s \\ NetCfgInstanceId is not a GUID: %s " , MAX_REG_PATH , RegPath , ValueStr ) ;
Free ( ValueStr ) ;
goto cleanupKey ;
}
Free ( ValueStr ) ;
if ( ! RegistryQueryDWORD ( Key , L " NetLuidIndex " , & Adapter - > LuidIndex , TRUE ) )
{
WCHAR RegPath [ MAX_REG_PATH ] ;
LoggerGetRegistryKeyPath ( Key , RegPath ) ;
LastError = LOG ( WINTUN_LOG_ERR , L " Failed to get %.*s \\ NetLuidIndex " , MAX_REG_PATH , RegPath ) ;
goto cleanupKey ;
}
if ( ! RegistryQueryDWORD ( Key , L " *IfType " , & Adapter - > IfType , TRUE ) )
{
WCHAR RegPath [ MAX_REG_PATH ] ;
LoggerGetRegistryKeyPath ( Key , RegPath ) ;
LastError = LOG ( WINTUN_LOG_ERR , L " Failed to get %.*s \\ *IfType " , MAX_REG_PATH , RegPath ) ;
goto cleanupKey ;
}
Adapter - > InterfaceFilename = AdapterGetDeviceObjectFileName ( Adapter - > DevInstanceID ) ;
if ( ! Adapter - > InterfaceFilename )
{
LastError = LOG_LAST_ERROR ( L " Unable to determine device object file name " ) ;
goto cleanupKey ;
}
cleanupKey :
RegCloseKey ( Key ) ;
return RET_ERROR ( TRUE , LastError ) ;
2020-10-15 11:32:06 +02:00
}
2021-10-12 07:21:31 +02:00
static volatile LONG OrphanThreadIsWorking = FALSE ;
static DWORD
DoOrphanedDeviceCleanup ( _In_opt_ LPVOID Ctx )
{
AdapterCleanupOrphanedDevices ( ) ;
OrphanThreadIsWorking = FALSE ;
return 0 ;
}
static VOID QueueUpOrphanedDeviceCleanupRoutine ( VOID )
{
if ( InterlockedCompareExchange ( & OrphanThreadIsWorking , TRUE , FALSE ) = = FALSE )
QueueUserWorkItem ( DoOrphanedDeviceCleanup , NULL , 0 ) ;
}
VOID AdapterCleanupOrphanedDevices ( VOID )
2020-07-07 15:42:39 +02:00
{
2021-10-12 07:21:31 +02:00
HANDLE DeviceInstallationMutex = NamespaceTakeDeviceInstallationMutex ( ) ;
if ( ! DeviceInstallationMutex )
{
LOG_LAST_ERROR ( L " Failed to take device installation mutex " ) ;
return ;
}
if ( IsWindows7 )
{
AdapterCleanupOrphanedDevicesWin7 ( ) ;
goto cleanupDeviceInstallationMutex ;
}
HDEVINFO DevInfo = SetupDiGetClassDevsExW ( & GUID_DEVCLASS_NET , WINTUN_ENUMERATOR , NULL , 0 , NULL , NULL , NULL ) ;
if ( DevInfo = = INVALID_HANDLE_VALUE )
{
LOG_LAST_ERROR ( L " Failed to get adapters " ) ;
goto cleanupDeviceInstallationMutex ;
}
SP_DEVINFO_DATA DevInfoData = { . cbSize = sizeof ( DevInfoData ) } ;
for ( DWORD EnumIndex = 0 ; ; + + EnumIndex )
2020-07-07 15:42:39 +02:00
{
2021-10-12 07:21:31 +02:00
if ( ! SetupDiEnumDeviceInfo ( DevInfo , EnumIndex , & DevInfoData ) )
{
if ( GetLastError ( ) = = ERROR_NO_MORE_ITEMS )
break ;
continue ;
}
ULONG Status , Code ;
if ( CM_Get_DevNode_Status ( & Status , & Code , DevInfoData . DevInst , 0 ) = = CR_SUCCESS & & ! ( Status & DN_HAS_PROBLEM ) )
continue ;
DEVPROPTYPE PropType ;
WCHAR Name [ MAX_ADAPTER_NAME ] = L " <unknown> " ;
SetupDiGetDevicePropertyW (
DevInfo ,
& DevInfoData ,
& DEVPKEY_Wintun_Name ,
& PropType ,
( PBYTE ) Name ,
MAX_ADAPTER_NAME * sizeof ( Name [ 0 ] ) ,
NULL ,
0 ) ;
if ( ! AdapterRemoveInstance ( DevInfo , & DevInfoData ) )
2020-10-30 13:08:57 +01:00
{
2021-10-12 07:21:31 +02:00
LOG_LAST_ERROR ( L " Failed to remove orphaned adapter \" %s \" " , Name ) ;
continue ;
2020-10-30 13:08:57 +01:00
}
2021-10-12 07:21:31 +02:00
LOG ( WINTUN_LOG_INFO , L " Removed orphaned adapter \" %s \" " , Name ) ;
2020-07-07 15:42:39 +02:00
}
2021-10-12 07:21:31 +02:00
SetupDiDestroyDeviceInfoList ( DevInfo ) ;
cleanupDeviceInstallationMutex :
NamespaceReleaseMutex ( DeviceInstallationMutex ) ;
2020-07-07 15:42:39 +02:00
}
2021-10-12 07:21:31 +02:00
_Use_decl_annotations_
VOID WINAPI
WintunCloseAdapter ( WINTUN_ADAPTER * Adapter )
2020-07-07 15:42:39 +02:00
{
2021-10-12 07:21:31 +02:00
if ( ! Adapter )
return ;
Free ( Adapter - > InterfaceFilename ) ;
if ( Adapter - > SwDevice )
SwDeviceClose ( Adapter - > SwDevice ) ;
if ( Adapter - > DevInfo )
2020-07-07 15:42:39 +02:00
{
2021-10-12 07:21:31 +02:00
if ( ! AdapterRemoveInstance ( Adapter - > DevInfo , & Adapter - > DevInfoData ) )
LOG_LAST_ERROR ( L " Failed to remove adapter when closing " ) ;
SetupDiDestroyDeviceInfoList ( Adapter - > DevInfo ) ;
2020-07-07 15:42:39 +02:00
}
2021-10-12 07:21:31 +02:00
Free ( Adapter ) ;
QueueUpOrphanedDeviceCleanupRoutine ( ) ;
2020-07-07 15:42:39 +02:00
}
2021-10-12 07:21:31 +02:00
static _Return_type_success_ ( return ! = FALSE )
BOOL
RenameByNetGUID ( _In_ GUID * Guid , _In_reads_or_z_ ( MAX_ADAPTER_NAME ) LPCWSTR Name )
2020-07-07 15:42:39 +02:00
{
2021-10-12 07:21:31 +02:00
DWORD LastError = ERROR_NOT_FOUND ;
HDEVINFO DevInfo = SetupDiGetClassDevsExW ( & GUID_DEVCLASS_NET , WINTUN_ENUMERATOR , NULL , 0 , NULL , NULL , NULL ) ;
if ( DevInfo = = INVALID_HANDLE_VALUE )
2020-07-07 15:42:39 +02:00
{
2020-11-03 12:29:34 +01:00
LastError = GetLastError ( ) ;
2021-10-12 07:21:31 +02:00
goto cleanup ;
}
SP_DEVINFO_DATA DevInfoData = { . cbSize = sizeof ( DevInfoData ) } ;
for ( DWORD EnumIndex = 0 ; ; + + EnumIndex )
{
if ( ! SetupDiEnumDeviceInfo ( DevInfo , EnumIndex , & DevInfoData ) )
{
if ( GetLastError ( ) = = ERROR_NO_MORE_ITEMS )
break ;
continue ;
}
HKEY Key = SetupDiOpenDevRegKey ( DevInfo , & DevInfoData , DICS_FLAG_GLOBAL , 0 , DIREG_DRV , KEY_QUERY_VALUE ) ;
if ( Key = = INVALID_HANDLE_VALUE )
continue ;
LPWSTR ValueStr = RegistryQueryString ( Key , L " NetCfgInstanceId " , TRUE ) ;
RegCloseKey ( Key ) ;
if ( ! ValueStr )
continue ;
GUID Guid2 ;
HRESULT HRet = CLSIDFromString ( ValueStr , & Guid2 ) ;
Free ( ValueStr ) ;
if ( FAILED ( HRet ) | | memcmp ( Guid , & Guid2 , sizeof ( * Guid ) ) )
continue ;
LastError = SetupDiSetDevicePropertyW (
DevInfo ,
& DevInfoData ,
& DEVPKEY_Wintun_Name ,
DEVPROP_TYPE_STRING ,
( PBYTE ) Name ,
( DWORD ) ( ( wcslen ( Name ) + 1 ) * sizeof ( Name [ 0 ] ) ) ,
0 )
? ERROR_SUCCESS
: GetLastError ( ) ;
2020-11-03 12:29:34 +01:00
break ;
2020-07-07 15:42:39 +02:00
}
2021-10-12 07:21:31 +02:00
SetupDiDestroyDeviceInfoList ( DevInfo ) ;
cleanup :
return RET_ERROR ( TRUE , LastError ) ;
2020-07-07 15:42:39 +02:00
}
2021-10-12 07:21:31 +02:00
_Must_inspect_result_
static _Return_type_success_ ( return ! = FALSE )
BOOL
ConvertInterfaceAliasToGuid ( _In_z_ LPCWSTR Name , _Out_ GUID * Guid )
2020-10-30 09:53:09 +01:00
{
2021-10-12 07:21:31 +02:00
NET_LUID Luid ;
DWORD LastError = ConvertInterfaceAliasToLuid ( Name , & Luid ) ;
if ( LastError ! = NO_ERROR )
{
SetLastError ( LOG_ERROR ( LastError , L " Failed convert interface %s name to the locally unique identifier " , Name ) ) ;
return FALSE ;
}
LastError = ConvertInterfaceLuidToGuid ( & Luid , Guid ) ;
if ( LastError ! = NO_ERROR )
{
SetLastError ( LOG_ERROR ( LastError , L " Failed to convert interface %s LUID (%I64u) to GUID " , Name , Luid . Value ) ) ;
return FALSE ;
}
return TRUE ;
2020-10-30 09:53:09 +01:00
}
2021-10-12 07:21:31 +02:00
static _Return_type_success_ ( return ! = FALSE )
BOOL
NciSetAdapterName ( _In_ GUID * Guid , _In_reads_or_z_ ( MAX_ADAPTER_NAME ) LPCWSTR Name )
2020-07-21 18:19:15 +02:00
{
2021-10-12 07:21:31 +02:00
const int MaxSuffix = 1000 ;
WCHAR AvailableName [ MAX_ADAPTER_NAME ] ;
if ( wcsncpy_s ( AvailableName , _countof ( AvailableName ) , Name , _TRUNCATE ) = = STRUNCATE )
2020-11-03 12:29:34 +01:00
{
2021-10-12 07:21:31 +02:00
SetLastError ( ERROR_BUFFER_OVERFLOW ) ;
2020-11-03 12:29:34 +01:00
return FALSE ;
}
2021-10-12 07:21:31 +02:00
for ( int i = 0 ; ; + + i )
{
DWORD LastError = NciSetConnectionName ( Guid , AvailableName ) ;
if ( LastError = = ERROR_DUP_NAME )
{
GUID Guid2 ;
if ( ConvertInterfaceAliasToGuid ( AvailableName , & Guid2 ) )
{
for ( int j = 0 ; j < MaxSuffix ; + + j )
{
WCHAR Proposal [ MAX_ADAPTER_NAME ] ;
if ( _snwprintf_s ( Proposal , _countof ( Proposal ) , _TRUNCATE , L " %s %d " , Name , j + 1 ) = = - 1 )
{
SetLastError ( ERROR_BUFFER_OVERFLOW ) ;
return FALSE ;
}
if ( _wcsnicmp ( Proposal , AvailableName , MAX_ADAPTER_NAME ) = = 0 )
continue ;
DWORD LastError2 = NciSetConnectionName ( & Guid2 , Proposal ) ;
if ( LastError2 = = ERROR_DUP_NAME )
continue ;
if ( ! RenameByNetGUID ( & Guid2 , Proposal ) )
LOG_LAST_ERROR ( L " Failed to set foreign adapter name to \" %s \" " , Proposal ) ;
if ( LastError2 = = ERROR_SUCCESS )
{
LastError = NciSetConnectionName ( Guid , AvailableName ) ;
if ( LastError = = ERROR_SUCCESS )
break ;
}
break ;
}
}
}
if ( LastError = = ERROR_SUCCESS )
break ;
if ( i > = MaxSuffix | | LastError ! = ERROR_DUP_NAME )
{
SetLastError ( LastError ) ;
return FALSE ;
}
if ( _snwprintf_s ( AvailableName , _countof ( AvailableName ) , _TRUNCATE , L " %s %d " , Name , i + 1 ) = = - 1 )
{
SetLastError ( ERROR_BUFFER_OVERFLOW ) ;
return FALSE ;
}
}
return TRUE ;
2020-10-15 11:32:06 +02:00
}
2021-10-12 07:21:31 +02:00
_Use_decl_annotations_
VOID WINAPI
WintunGetAdapterLUID ( WINTUN_ADAPTER * Adapter , NET_LUID * Luid )
{
Luid - > Info . Reserved = 0 ;
Luid - > Info . NetLuidIndex = Adapter - > LuidIndex ;
Luid - > Info . IfType = Adapter - > IfType ;
}
_Use_decl_annotations_
HANDLE WINAPI
AdapterOpenDeviceObject ( const WINTUN_ADAPTER * Adapter )
{
HANDLE Handle = CreateFileW (
Adapter - > InterfaceFilename ,
GENERIC_READ | GENERIC_WRITE ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE ,
NULL ,
OPEN_EXISTING ,
0 ,
NULL ) ;
if ( Handle = = INVALID_HANDLE_VALUE )
LOG_LAST_ERROR ( L " Failed to connect to adapter interface %s " , Adapter - > InterfaceFilename ) ;
return Handle ;
}
_Use_decl_annotations_
2021-07-28 20:20:09 +02:00
LPWSTR
2021-10-12 07:21:31 +02:00
AdapterGetDeviceObjectFileName ( LPCWSTR InstanceId )
2020-10-15 11:32:06 +02:00
{
ULONG InterfacesLen ;
2020-11-03 12:29:34 +01:00
DWORD LastError = CM_MapCrToWin32Err (
2020-11-02 16:28:51 +01:00
CM_Get_Device_Interface_List_SizeW (
& InterfacesLen ,
( GUID * ) & GUID_DEVINTERFACE_NET ,
( DEVINSTID_W ) InstanceId ,
CM_GET_DEVICE_INTERFACE_LIST_PRESENT ) ,
ERROR_GEN_FAILURE ) ;
2020-11-03 12:29:34 +01:00
if ( LastError ! = ERROR_SUCCESS )
{
2021-02-02 13:12:45 +01:00
SetLastError ( LOG_ERROR ( LastError , L " Failed to query adapter %s associated instances size " , InstanceId ) ) ;
2021-02-03 22:32:58 +01:00
return NULL ;
2020-11-03 12:29:34 +01:00
}
2021-07-28 20:20:09 +02:00
LPWSTR Interfaces = AllocArray ( InterfacesLen , sizeof ( * Interfaces ) ) ;
2020-10-15 11:32:06 +02:00
if ( ! Interfaces )
2021-02-03 22:32:58 +01:00
return NULL ;
2020-11-03 12:29:34 +01:00
LastError = CM_MapCrToWin32Err (
2020-11-02 16:28:51 +01:00
CM_Get_Device_Interface_ListW (
( GUID * ) & GUID_DEVINTERFACE_NET ,
( DEVINSTID_W ) InstanceId ,
Interfaces ,
InterfacesLen ,
CM_GET_DEVICE_INTERFACE_LIST_PRESENT ) ,
ERROR_GEN_FAILURE ) ;
2020-11-03 12:29:34 +01:00
if ( LastError ! = ERROR_SUCCESS )
2020-10-15 11:32:06 +02:00
{
2021-02-02 13:12:45 +01:00
LOG_ERROR ( LastError , L " Failed to get adapter %s associated instances " , InstanceId ) ;
2021-02-03 22:32:58 +01:00
Free ( Interfaces ) ;
SetLastError ( LastError ) ;
return NULL ;
2020-10-15 11:32:06 +02:00
}
2021-05-04 12:19:30 +02:00
if ( ! Interfaces [ 0 ] )
{
Free ( Interfaces ) ;
SetLastError ( ERROR_DEVICE_NOT_AVAILABLE ) ;
return NULL ;
}
2021-02-03 22:32:58 +01:00
return Interfaces ;
}
2021-10-12 07:21:31 +02:00
typedef struct _WAIT_FOR_INTERFACE_CTX
2021-02-03 22:32:58 +01:00
{
2021-10-12 07:21:31 +02:00
HANDLE Event ;
DWORD LastError ;
} WAIT_FOR_INTERFACE_CTX ;
2020-10-15 11:32:06 +02:00
2021-10-12 07:21:31 +02:00
static VOID WINAPI
WaitForInterfaceCallback (
_In_ HDEVQUERY DevQuery ,
_Inout_ PVOID Context ,
_In_ const DEV_QUERY_RESULT_ACTION_DATA * ActionData )
2021-02-03 22:32:58 +01:00
{
2021-10-12 07:21:31 +02:00
WAIT_FOR_INTERFACE_CTX * Ctx = Context ;
2021-10-14 07:27:13 +02:00
DWORD Ret = ERROR_SUCCESS ;
switch ( ActionData - > Action )
2021-02-03 22:32:58 +01:00
{
2021-10-14 07:27:13 +02:00
case DevQueryResultStateChange :
2021-10-12 07:21:31 +02:00
if ( ActionData - > Data . State ! = DevQueryStateAborted )
return ;
2021-10-14 07:27:13 +02:00
Ret = ERROR_DEVICE_NOT_AVAILABLE ;
case DevQueryResultAdd :
case DevQueryResultUpdate :
break ;
default :
2021-10-12 07:21:31 +02:00
return ;
2021-10-14 07:27:13 +02:00
}
Ctx - > LastError = Ret ;
2021-10-12 07:21:31 +02:00
SetEvent ( Ctx - > Event ) ;
2021-02-03 22:32:58 +01:00
}
2021-10-12 07:21:31 +02:00
_Must_inspect_result_
2021-07-28 20:20:09 +02:00
static _Return_type_success_ ( return ! = FALSE )
BOOL
2021-10-12 07:21:31 +02:00
WaitForInterface ( _In_ WCHAR * InstanceId )
2020-10-15 11:32:06 +02:00
{
2021-10-12 07:21:31 +02:00
if ( IsWindows7 )
return TRUE ;
2020-11-03 12:29:34 +01:00
DWORD LastError = ERROR_SUCCESS ;
2021-10-12 07:21:31 +02:00
static const DEVPROP_BOOLEAN DevPropTrue = DEVPROP_TRUE ;
const DEVPROP_FILTER_EXPRESSION Filters [ ] = { { . Operator = DEVPROP_OPERATOR_EQUALS_IGNORE_CASE ,
. Property . CompKey . Key = DEVPKEY_Device_InstanceId ,
. Property . CompKey . Store = DEVPROP_STORE_SYSTEM ,
. Property . Type = DEVPROP_TYPE_STRING ,
. Property . Buffer = InstanceId ,
. Property . BufferSize =
( ULONG ) ( ( wcslen ( InstanceId ) + 1 ) * sizeof ( InstanceId [ 0 ] ) ) } ,
{ . Operator = DEVPROP_OPERATOR_EQUALS ,
. Property . CompKey . Key = DEVPKEY_DeviceInterface_Enabled ,
. Property . CompKey . Store = DEVPROP_STORE_SYSTEM ,
. Property . Type = DEVPROP_TYPE_BOOLEAN ,
. Property . Buffer = ( PVOID ) & DevPropTrue ,
. Property . BufferSize = sizeof ( DevPropTrue ) } ,
{ . Operator = DEVPROP_OPERATOR_EQUALS ,
. Property . CompKey . Key = DEVPKEY_DeviceInterface_ClassGuid ,
. Property . CompKey . Store = DEVPROP_STORE_SYSTEM ,
. Property . Type = DEVPROP_TYPE_GUID ,
. Property . Buffer = ( PVOID ) & GUID_DEVINTERFACE_NET ,
. Property . BufferSize = sizeof ( GUID_DEVINTERFACE_NET ) } } ;
WAIT_FOR_INTERFACE_CTX Ctx = { . Event = CreateEventW ( NULL , FALSE , FALSE , NULL ) } ;
if ( ! Ctx . Event )
{
LastError = LOG_LAST_ERROR ( L " Failed to create event " ) ;
goto cleanup ;
2020-11-03 12:29:34 +01:00
}
2021-10-12 07:21:31 +02:00
HDEVQUERY Query ;
HRESULT HRet = DevCreateObjectQuery (
DevObjectTypeDeviceInterface ,
DevQueryFlagUpdateResults ,
0 ,
NULL ,
_countof ( Filters ) ,
Filters ,
WaitForInterfaceCallback ,
& Ctx ,
& Query ) ;
if ( FAILED ( HRet ) )
2020-10-15 11:32:06 +02:00
{
2021-10-12 07:21:31 +02:00
LastError = LOG_ERROR ( HRet , L " Failed to create device query " ) ;
goto cleanupEvent ;
2020-10-15 11:32:06 +02:00
}
2021-10-12 07:21:31 +02:00
LastError = WaitForSingleObject ( Ctx . Event , 15000 ) ;
if ( LastError ! = WAIT_OBJECT_0 )
2020-10-15 11:32:06 +02:00
{
2021-10-12 07:21:31 +02:00
if ( LastError = = WAIT_FAILED )
LastError = LOG_LAST_ERROR ( L " Failed to wait for device query " ) ;
else
LastError = LOG_ERROR ( LastError , L " Timed out waiting for device query " ) ;
goto cleanupQuery ;
2020-11-03 12:29:34 +01:00
}
2021-10-12 07:21:31 +02:00
LastError = Ctx . LastError ;
2020-11-03 12:29:34 +01:00
if ( LastError ! = ERROR_SUCCESS )
2021-10-12 07:21:31 +02:00
LastError = LOG_ERROR ( LastError , L " Failed to get enabled device " ) ;
cleanupQuery :
DevCloseObjectQuery ( Query ) ;
cleanupEvent :
CloseHandle ( Ctx . Event ) ;
cleanup :
2020-11-03 12:29:34 +01:00
return RET_ERROR ( TRUE , LastError ) ;
2020-10-16 15:20:49 +02:00
}
2021-10-12 07:21:31 +02:00
typedef struct _SW_DEVICE_CREATE_CTX
2020-10-30 18:20:57 +01:00
{
2021-10-12 07:21:31 +02:00
HRESULT CreateResult ;
WCHAR * DeviceInstanceId ;
HANDLE Triggered ;
} SW_DEVICE_CREATE_CTX ;
2020-07-21 16:38:00 +02:00
2021-07-28 20:20:09 +02:00
static VOID
2021-10-12 07:21:31 +02:00
DeviceCreateCallback (
_In_ HSWDEVICE SwDevice ,
_In_ HRESULT CreateResult ,
_In_ VOID * Context ,
_In_opt_ PCWSTR DeviceInstanceId )
2021-07-28 20:20:09 +02:00
{
2021-10-12 07:21:31 +02:00
SW_DEVICE_CREATE_CTX * Ctx = Context ;
Ctx - > CreateResult = CreateResult ;
if ( DeviceInstanceId )
2021-10-14 08:37:50 +02:00
wcsncpy_s ( Ctx - > DeviceInstanceId , MAX_DEVICE_ID_LEN , DeviceInstanceId , _TRUNCATE ) ;
2021-10-12 07:21:31 +02:00
SetEvent ( Ctx - > Triggered ) ;
2020-11-02 16:28:51 +01:00
}
2021-07-28 20:20:09 +02:00
_Use_decl_annotations_
2021-10-12 07:21:31 +02:00
WINTUN_ADAPTER_HANDLE WINAPI
WintunCreateAdapter ( LPCWSTR Name , LPCWSTR TunnelType , const GUID * RequestedGUID )
2021-07-28 20:20:09 +02:00
{
DWORD LastError = ERROR_SUCCESS ;
2021-10-12 07:21:31 +02:00
WINTUN_ADAPTER * Adapter = NULL ;
HANDLE DeviceInstallationMutex = NamespaceTakeDeviceInstallationMutex ( ) ;
if ( ! DeviceInstallationMutex )
2021-07-28 20:20:09 +02:00
{
2021-10-12 07:21:31 +02:00
LastError = LOG_LAST_ERROR ( L " Failed to take device installation mutex " ) ;
2021-07-28 20:20:09 +02:00
goto cleanup ;
}
2021-10-12 07:21:31 +02:00
HDEVINFO DevInfoExistingAdapters ;
SP_DEVINFO_DATA_LIST * ExistingAdapters ;
if ( ! DriverInstall ( & DevInfoExistingAdapters , & ExistingAdapters ) )
{
LastError = GetLastError ( ) ;
goto cleanupDeviceInstallationMutex ;
}
2021-07-28 20:20:09 +02:00
2020-11-02 16:28:51 +01:00
LOG ( WINTUN_LOG_INFO , L " Creating adapter " ) ;
2021-10-12 07:21:31 +02:00
Adapter = Zalloc ( sizeof ( * Adapter ) ) ;
2021-07-28 20:20:09 +02:00
if ( ! Adapter )
2021-10-12 07:21:31 +02:00
goto cleanupDriverInstall ;
2021-07-28 20:20:09 +02:00
2021-10-12 07:21:31 +02:00
WCHAR TunnelTypeName [ MAX_ADAPTER_NAME + 8 ] ;
if ( _snwprintf_s ( TunnelTypeName , _countof ( TunnelTypeName ) , _TRUNCATE , L " %s Tunnel " , TunnelType ) = = - 1 )
2021-07-28 20:20:09 +02:00
{
2021-10-12 07:21:31 +02:00
LastError = ERROR_BUFFER_OVERFLOW ;
2021-07-28 20:20:09 +02:00
goto cleanupAdapter ;
2020-11-03 12:29:34 +01:00
}
2021-10-12 07:21:31 +02:00
DEVINST RootNode ;
WCHAR RootNodeName [ 200 /* rasmans.dll uses 200 hard coded instead of calling CM_Get_Device_ID_Size. */ ] ;
CONFIGRET ConfigRet ;
if ( ( ConfigRet = CM_Locate_DevNodeW ( & RootNode , NULL , CM_LOCATE_DEVNODE_NORMAL ) ) ! = CR_SUCCESS | |
( ConfigRet = CM_Get_Device_IDW ( RootNode , RootNodeName , _countof ( RootNodeName ) , 0 ) ) ! = CR_SUCCESS )
2020-11-02 16:28:51 +01:00
{
2021-10-12 07:21:31 +02:00
LastError = LOG_ERROR ( CM_MapCrToWin32Err ( ConfigRet , ERROR_GEN_FAILURE ) , L " Failed to get root node name " ) ;
2021-07-28 20:20:09 +02:00
goto cleanupAdapter ;
2020-11-02 16:28:51 +01:00
}
2021-10-12 07:21:31 +02:00
GUID InstanceId ;
HRESULT HRet = S_OK ;
if ( RequestedGUID )
memcpy ( & InstanceId , RequestedGUID , sizeof ( InstanceId ) ) ;
else
HRet = CoCreateGuid ( & InstanceId ) ;
WCHAR InstanceIdStr [ MAX_GUID_STRING_LEN ] ;
if ( FAILED ( HRet ) | | ! StringFromGUID2 ( & InstanceId , InstanceIdStr , _countof ( InstanceIdStr ) ) )
2020-11-03 12:29:34 +01:00
{
2021-10-12 07:21:31 +02:00
LastError = LOG_ERROR ( HRet , L " Failed to convert GUID " ) ;
2021-07-28 20:20:09 +02:00
goto cleanupAdapter ;
2020-11-03 12:29:34 +01:00
}
2021-10-12 07:21:31 +02:00
SW_DEVICE_CREATE_CTX CreateContext = { . DeviceInstanceId = Adapter - > DevInstanceID ,
. Triggered = CreateEventW ( NULL , FALSE , FALSE , NULL ) } ;
if ( ! CreateContext . Triggered )
2020-11-02 16:28:51 +01:00
{
2021-10-12 07:21:31 +02:00
LastError = LOG_LAST_ERROR ( L " Failed to create event trigger " ) ;
2021-07-28 20:20:09 +02:00
goto cleanupAdapter ;
2020-11-02 16:28:51 +01:00
}
2021-10-12 07:21:31 +02:00
if ( IsWindows7 )
2020-11-02 16:28:51 +01:00
{
2021-10-12 07:21:31 +02:00
if ( ! CreateAdapterWin7 ( Adapter , Name , TunnelTypeName ) )
{
LastError = GetLastError ( ) ;
goto cleanupCreateContext ;
}
goto skipSwDevice ;
2020-11-02 16:28:51 +01:00
}
2021-10-12 07:21:31 +02:00
if ( ! IsWindows10 )
goto skipStub ;
SW_DEVICE_CREATE_INFO StubCreateInfo = { . cbSize = sizeof ( StubCreateInfo ) ,
. pszInstanceId = InstanceIdStr ,
. pszzHardwareIds = L " " ,
. CapabilityFlags =
SWDeviceCapabilitiesSilentInstall | SWDeviceCapabilitiesDriverRequired ,
. pszDeviceDescription = TunnelTypeName } ;
DEVPROPERTY StubDeviceProperties [ ] = { { . CompKey = { . Key = DEVPKEY_Device_ClassGuid ,
. Store = DEVPROP_STORE_SYSTEM } ,
. Type = DEVPROP_TYPE_GUID ,
. Buffer = ( PVOID ) & GUID_DEVCLASS_NET ,
. BufferSize = sizeof ( GUID_DEVCLASS_NET ) } } ;
HRet = SwDeviceCreate (
WINTUN_HWID ,
RootNodeName ,
& StubCreateInfo ,
_countof ( StubDeviceProperties ) ,
StubDeviceProperties ,
DeviceCreateCallback ,
& CreateContext ,
& Adapter - > SwDevice ) ;
if ( FAILED ( HRet ) )
{
LastError = LOG_ERROR ( HRet , L " Failed to initiate stub device creation " ) ;
goto cleanupCreateContext ;
}
if ( WaitForSingleObject ( CreateContext . Triggered , INFINITE ) ! = WAIT_OBJECT_0 )
{
LastError = LOG_LAST_ERROR ( L " Failed to wait for stub device creation trigger " ) ;
goto cleanupCreateContext ;
}
if ( FAILED ( CreateContext . CreateResult ) )
{
LastError = LOG_ERROR ( CreateContext . CreateResult , L " Failed to create stub device " ) ;
goto cleanupCreateContext ;
}
DEVINST DevInst ;
CONFIGRET CRet = CM_Locate_DevNodeW ( & DevInst , Adapter - > DevInstanceID , CM_LOCATE_DEVNODE_PHANTOM ) ;
if ( CRet ! = CR_SUCCESS )
2020-11-02 16:28:51 +01:00
{
2021-07-28 20:20:09 +02:00
LastError =
2021-10-12 07:21:31 +02:00
LOG_ERROR ( CM_MapCrToWin32Err ( CRet , ERROR_DEVICE_ENUMERATION_ERROR ) , L " Failed to make stub device list " ) ;
goto cleanupCreateContext ;
2020-11-02 16:28:51 +01:00
}
2021-10-12 07:21:31 +02:00
HKEY DriverKey ;
CRet = CM_Open_DevNode_Key ( DevInst , KEY_SET_VALUE , 0 , RegDisposition_OpenAlways , & DriverKey , CM_REGISTRY_SOFTWARE ) ;
if ( CRet ! = CR_SUCCESS )
2020-11-02 16:28:51 +01:00
{
2021-10-12 07:21:31 +02:00
LastError =
LOG_ERROR ( CM_MapCrToWin32Err ( CRet , ERROR_PNP_REGISTRY_ERROR ) , L " Failed to create software registry key " ) ;
goto cleanupCreateContext ;
2020-11-02 16:28:51 +01:00
}
2021-10-12 07:21:31 +02:00
LastError =
RegSetValueExW ( DriverKey , L " SuggestedInstanceId " , 0 , REG_BINARY , ( const BYTE * ) & InstanceId , sizeof ( InstanceId ) ) ;
RegCloseKey ( DriverKey ) ;
if ( LastError ! = ERROR_SUCCESS )
2020-11-02 16:28:51 +01:00
{
2021-10-12 07:21:31 +02:00
LastError = LOG_ERROR ( LastError , L " Failed to set SuggestedInstanceId to %s " , InstanceIdStr ) ;
goto cleanupCreateContext ;
2020-11-02 16:28:51 +01:00
}
2021-10-12 07:21:31 +02:00
SwDeviceClose ( Adapter - > SwDevice ) ;
Adapter - > SwDevice = NULL ;
2020-11-02 16:28:51 +01:00
2021-10-12 07:21:31 +02:00
skipStub : ;
static const WCHAR Hwids [ _countof ( WINTUN_HWID ) + 1 /*Multi-string terminator*/ ] = WINTUN_HWID ;
SW_DEVICE_CREATE_INFO CreateInfo = { . cbSize = sizeof ( CreateInfo ) ,
. pszInstanceId = InstanceIdStr ,
. pszzHardwareIds = Hwids ,
. CapabilityFlags =
SWDeviceCapabilitiesSilentInstall | SWDeviceCapabilitiesDriverRequired ,
. pszDeviceDescription = TunnelTypeName } ;
DEVPROPERTY DeviceProperties [ ] = {
{ . CompKey = { . Key = DEVPKEY_Wintun_Name , . Store = DEVPROP_STORE_SYSTEM } ,
. Type = DEVPROP_TYPE_STRING ,
. Buffer = ( WCHAR * ) Name ,
. BufferSize = ( ULONG ) ( ( wcslen ( Name ) + 1 ) * sizeof ( * Name ) ) } ,
{ . CompKey = { . Key = DEVPKEY_Device_FriendlyName , . Store = DEVPROP_STORE_SYSTEM } ,
. Type = DEVPROP_TYPE_STRING ,
. Buffer = TunnelTypeName ,
. BufferSize = ( ULONG ) ( ( wcslen ( TunnelTypeName ) + 1 ) * sizeof ( * TunnelTypeName ) ) } ,
{ . CompKey = { . Key = DEVPKEY_Device_DeviceDesc , . Store = DEVPROP_STORE_SYSTEM } ,
. Type = DEVPROP_TYPE_STRING ,
. Buffer = TunnelTypeName ,
. BufferSize = ( ULONG ) ( ( wcslen ( TunnelTypeName ) + 1 ) * sizeof ( * TunnelTypeName ) ) }
} ;
HRet = SwDeviceCreate (
WINTUN_HWID ,
RootNodeName ,
& CreateInfo ,
_countof ( DeviceProperties ) ,
DeviceProperties ,
DeviceCreateCallback ,
& CreateContext ,
& Adapter - > SwDevice ) ;
if ( FAILED ( HRet ) )
{
LastError = LOG_ERROR ( HRet , L " Failed to initiate device creation " ) ;
goto cleanupCreateContext ;
}
if ( WaitForSingleObject ( CreateContext . Triggered , INFINITE ) ! = WAIT_OBJECT_0 )
{
LastError = LOG_LAST_ERROR ( L " Failed to wait for device creation trigger " ) ;
goto cleanupCreateContext ;
}
if ( FAILED ( CreateContext . CreateResult ) )
{
LastError = LOG_ERROR ( CreateContext . CreateResult , L " Failed to create device " ) ;
goto cleanupCreateContext ;
}
if ( ! WaitForInterface ( Adapter - > DevInstanceID ) )
2020-11-02 16:28:51 +01:00
{
2021-10-12 07:21:31 +02:00
LastError = GetLastError ( ) ;
DEVPROPTYPE PropertyType = 0 ;
NTSTATUS NtStatus = 0 ;
INT32 ProblemCode = 0 ;
Adapter - > DevInfo = SetupDiCreateDeviceInfoListExW ( NULL , NULL , NULL , NULL ) ;
if ( Adapter - > DevInfo = = INVALID_HANDLE_VALUE )
{
Adapter - > DevInfo = NULL ;
goto cleanupCreateContext ;
}
Adapter - > DevInfoData . cbSize = sizeof ( Adapter - > DevInfoData ) ;
if ( ! SetupDiOpenDeviceInfoW (
Adapter - > DevInfo , Adapter - > DevInstanceID , NULL , DIOD_INHERIT_CLASSDRVS , & Adapter - > DevInfoData ) )
{
SetupDiDestroyDeviceInfoList ( Adapter - > DevInfo ) ;
Adapter - > DevInfo = NULL ;
goto cleanupCreateContext ;
}
if ( ! SetupDiGetDevicePropertyW (
Adapter - > DevInfo ,
& Adapter - > DevInfoData ,
& DEVPKEY_Device_ProblemStatus ,
& PropertyType ,
( PBYTE ) & NtStatus ,
sizeof ( NtStatus ) ,
NULL ,
0 ) | |
PropertyType ! = DEVPROP_TYPE_NTSTATUS )
NtStatus = 0 ;
if ( ! SetupDiGetDevicePropertyW (
Adapter - > DevInfo ,
& Adapter - > DevInfoData ,
& DEVPKEY_Device_ProblemCode ,
& PropertyType ,
( PBYTE ) & ProblemCode ,
sizeof ( ProblemCode ) ,
NULL ,
0 ) | |
( PropertyType ! = DEVPROP_TYPE_INT32 & & PropertyType ! = DEVPROP_TYPE_UINT32 ) )
ProblemCode = 0 ;
LastError = RtlNtStatusToDosError ( NtStatus ) ;
if ( LastError = = ERROR_SUCCESS )
LastError = ERROR_DEVICE_NOT_AVAILABLE ;
LOG_ERROR ( LastError , L " Failed to setup adapter (problem code: 0x%X, ntstatus: 0x%X) " , ProblemCode , NtStatus ) ;
goto cleanupCreateContext ;
2020-11-02 16:28:51 +01:00
}
2021-10-12 07:21:31 +02:00
skipSwDevice :
Adapter - > DevInfo = SetupDiCreateDeviceInfoListExW ( & GUID_DEVCLASS_NET , NULL , NULL , NULL ) ;
if ( Adapter - > DevInfo = = INVALID_HANDLE_VALUE )
2020-11-02 16:28:51 +01:00
{
2021-10-12 07:21:31 +02:00
Adapter - > DevInfo = NULL ;
LastError = LOG_LAST_ERROR ( L " Failed to make device list " ) ;
goto cleanupCreateContext ;
2020-11-02 16:28:51 +01:00
}
2021-10-12 07:21:31 +02:00
Adapter - > DevInfoData . cbSize = sizeof ( Adapter - > DevInfoData ) ;
if ( ! SetupDiOpenDeviceInfoW (
Adapter - > DevInfo , Adapter - > DevInstanceID , NULL , DIOD_INHERIT_CLASSDRVS , & Adapter - > DevInfoData ) )
2020-11-02 16:28:51 +01:00
{
2021-10-12 07:21:31 +02:00
LastError = LOG_LAST_ERROR ( L " Failed to open device instance ID %s " , Adapter - > DevInstanceID ) ;
SetupDiDestroyDeviceInfoList ( Adapter - > DevInfo ) ;
Adapter - > DevInfo = NULL ;
goto cleanupCreateContext ;
2020-11-02 16:28:51 +01:00
}
2021-10-12 07:21:31 +02:00
if ( ! PopulateAdapterData ( Adapter ) )
2020-07-21 16:38:00 +02:00
{
2021-10-12 07:21:31 +02:00
LastError = LOG ( WINTUN_LOG_ERR , L " Failed to populate adapter data " ) ;
goto cleanupCreateContext ;
2020-07-21 16:38:00 +02:00
}
2021-10-12 07:21:31 +02:00
if ( ! NciSetAdapterName ( & Adapter - > CfgInstanceID , Name ) )
2020-07-21 16:38:00 +02:00
{
2021-10-12 07:21:31 +02:00
LastError = LOG ( WINTUN_LOG_ERR , L " Failed to set adapter name \" %s \" " , Name ) ;
goto cleanupCreateContext ;
2020-07-21 16:38:00 +02:00
}
2021-10-12 07:21:31 +02:00
if ( IsWindows7 )
CreateAdapterPostWin7 ( Adapter , TunnelTypeName ) ;
2020-07-21 16:38:00 +02:00
2021-10-12 07:21:31 +02:00
cleanupCreateContext :
CloseHandle ( CreateContext . Triggered ) ;
cleanupAdapter :
if ( LastError ! = ERROR_SUCCESS )
2020-07-21 16:38:00 +02:00
{
2021-10-12 07:21:31 +02:00
WintunCloseAdapter ( Adapter ) ;
Adapter = NULL ;
2020-07-21 16:38:00 +02:00
}
2021-10-12 07:21:31 +02:00
cleanupDriverInstall :
DriverInstallDeferredCleanup ( DevInfoExistingAdapters , ExistingAdapters ) ;
cleanupDeviceInstallationMutex :
NamespaceReleaseMutex ( DeviceInstallationMutex ) ;
cleanup :
QueueUpOrphanedDeviceCleanupRoutine ( ) ;
return RET_ERROR ( Adapter , LastError ) ;
}
2020-07-21 16:38:00 +02:00
2021-10-12 07:21:31 +02:00
_Use_decl_annotations_
WINTUN_ADAPTER_HANDLE WINAPI
WintunOpenAdapter ( LPCWSTR Name )
{
DWORD LastError = ERROR_SUCCESS ;
WINTUN_ADAPTER * Adapter = NULL ;
2020-07-21 16:38:00 +02:00
2021-10-12 07:21:31 +02:00
HANDLE DeviceInstallationMutex = NamespaceTakeDeviceInstallationMutex ( ) ;
if ( ! DeviceInstallationMutex )
2020-10-13 19:40:52 +02:00
{
2021-10-12 07:21:31 +02:00
LastError = LOG_LAST_ERROR ( L " Failed to take device installation mutex " ) ;
goto cleanup ;
2020-10-13 19:40:52 +02:00
}
2020-07-21 16:38:00 +02:00
2021-10-12 07:21:31 +02:00
Adapter = Zalloc ( sizeof ( * Adapter ) ) ;
if ( ! Adapter )
goto cleanupDeviceInstallationMutex ;
HDEVINFO DevInfo =
SetupDiGetClassDevsExW ( & GUID_DEVCLASS_NET , WINTUN_ENUMERATOR , NULL , DIGCF_PRESENT , NULL , NULL , NULL ) ;
if ( DevInfo = = INVALID_HANDLE_VALUE )
2020-11-03 12:29:34 +01:00
{
2021-10-12 07:21:31 +02:00
LastError = LOG_LAST_ERROR ( L " Failed to get present adapters " ) ;
2020-07-21 16:38:00 +02:00
goto cleanupAdapter ;
2020-10-13 19:40:52 +02:00
}
2020-07-21 16:38:00 +02:00
2021-10-12 07:21:31 +02:00
SP_DEVINFO_DATA DevInfoData = { . cbSize = sizeof ( DevInfoData ) } ;
BOOL Found = FALSE ;
for ( DWORD EnumIndex = 0 ; ! Found ; + + EnumIndex )
2020-10-13 19:40:52 +02:00
{
2021-10-12 07:21:31 +02:00
if ( ! SetupDiEnumDeviceInfo ( DevInfo , EnumIndex , & DevInfoData ) )
2020-11-17 15:30:00 +01:00
{
2021-10-12 07:21:31 +02:00
if ( GetLastError ( ) = = ERROR_NO_MORE_ITEMS )
break ;
continue ;
2020-11-17 15:30:00 +01:00
}
2020-07-21 16:38:00 +02:00
2021-10-12 07:21:31 +02:00
DEVPROPTYPE PropType ;
WCHAR OtherName [ MAX_ADAPTER_NAME ] ;
Found = SetupDiGetDevicePropertyW (
DevInfo ,
& DevInfoData ,
& DEVPKEY_Wintun_Name ,
& PropType ,
( PBYTE ) OtherName ,
MAX_ADAPTER_NAME * sizeof ( OtherName [ 0 ] ) ,
NULL ,
0 ) & &
PropType = = DEVPROP_TYPE_STRING & & ! _wcsicmp ( Name , OtherName ) ;
2020-11-01 03:19:21 +01:00
}
2021-10-12 07:21:31 +02:00
if ( ! Found )
2020-11-01 03:19:21 +01:00
{
2021-10-12 07:21:31 +02:00
LastError = LOG_ERROR ( ERROR_NOT_FOUND , L " Failed to find matching adapter name " ) ;
goto cleanupDevInfo ;
2020-11-01 03:19:21 +01:00
}
2021-10-12 07:21:31 +02:00
DWORD RequiredChars = _countof ( Adapter - > DevInstanceID ) ;
if ( ! SetupDiGetDeviceInstanceIdW ( DevInfo , & DevInfoData , Adapter - > DevInstanceID , RequiredChars , & RequiredChars ) )
2020-11-01 03:47:19 +01:00
{
2021-10-12 07:21:31 +02:00
LastError = LOG_LAST_ERROR ( L " Failed to get adapter instance ID " ) ;
goto cleanupDevInfo ;
2020-11-01 03:19:21 +01:00
}
2021-10-12 07:21:31 +02:00
Adapter - > DevInfo = DevInfo ;
Adapter - > DevInfoData = DevInfoData ;
BOOL Ret = WaitForInterface ( Adapter - > DevInstanceID ) & & PopulateAdapterData ( Adapter ) ;
Adapter - > DevInfo = NULL ;
if ( ! Ret )
2021-02-03 22:32:58 +01:00
{
2021-10-12 07:21:31 +02:00
LastError = LOG_LAST_ERROR ( L " Failed to populate adapter " ) ;
goto cleanupDevInfo ;
2021-02-03 22:32:58 +01:00
}
2020-11-01 03:19:21 +01:00
2021-10-12 07:21:31 +02:00
cleanupDevInfo :
SetupDiDestroyDeviceInfoList ( DevInfo ) ;
cleanupAdapter :
2020-11-03 12:29:34 +01:00
if ( LastError ! = ERROR_SUCCESS )
2020-07-21 16:38:00 +02:00
{
2021-10-12 07:21:31 +02:00
WintunCloseAdapter ( Adapter ) ;
Adapter = NULL ;
2020-07-21 16:38:00 +02:00
}
2021-10-12 07:21:31 +02:00
cleanupDeviceInstallationMutex :
NamespaceReleaseMutex ( DeviceInstallationMutex ) ;
cleanup :
QueueUpOrphanedDeviceCleanupRoutine ( ) ;
2020-11-03 12:29:34 +01:00
return RET_ERROR ( Adapter , LastError ) ;
2020-10-15 15:54:37 +02:00
}
2021-07-28 20:20:09 +02:00
_Use_decl_annotations_
2021-10-12 07:21:31 +02:00
BOOL
AdapterRemoveInstance ( HDEVINFO DevInfo , SP_DEVINFO_DATA * DevInfoData )
2020-11-02 16:28:51 +01:00
{
2021-07-28 13:50:40 +02:00
# ifdef MAYBE_WOW64
if ( NativeMachine ! = IMAGE_FILE_PROCESS )
2021-10-12 07:21:31 +02:00
return RemoveInstanceViaRundll32 ( DevInfo , DevInfoData ) ;
2021-07-28 13:50:40 +02:00
# endif
2020-11-02 16:28:51 +01:00
2021-10-12 07:21:31 +02:00
SP_REMOVEDEVICE_PARAMS RemoveDeviceParams = { . ClassInstallHeader = { . cbSize = sizeof ( SP_CLASSINSTALL_HEADER ) ,
. InstallFunction = DIF_REMOVE } ,
. Scope = DI_REMOVEDEVICE_GLOBAL } ;
return SetupDiSetClassInstallParamsW (
DevInfo , DevInfoData , & RemoveDeviceParams . ClassInstallHeader , sizeof ( RemoveDeviceParams ) ) & &
SetupDiCallClassInstaller ( DIF_REMOVE , DevInfo , DevInfoData ) ;
2020-11-02 16:28:51 +01:00
}
2021-07-28 20:20:09 +02:00
_Use_decl_annotations_
2021-10-12 07:21:31 +02:00
BOOL
AdapterEnableInstance ( HDEVINFO DevInfo , SP_DEVINFO_DATA * DevInfoData )
2020-07-21 16:38:00 +02:00
{
2021-10-12 07:21:31 +02:00
# ifdef MAYBE_WOW64
if ( NativeMachine ! = IMAGE_FILE_PROCESS )
return EnableInstanceViaRundll32 ( DevInfo , DevInfoData ) ;
# endif
2020-07-21 16:38:00 +02:00
2021-10-12 07:21:31 +02:00
SP_PROPCHANGE_PARAMS Params = { . ClassInstallHeader = { . cbSize = sizeof ( SP_CLASSINSTALL_HEADER ) ,
. InstallFunction = DIF_PROPERTYCHANGE } ,
. StateChange = DICS_ENABLE ,
. Scope = DICS_FLAG_GLOBAL } ;
return SetupDiSetClassInstallParamsW ( DevInfo , DevInfoData , & Params . ClassInstallHeader , sizeof ( Params ) ) & &
SetupDiCallClassInstaller ( DIF_PROPERTYCHANGE , DevInfo , DevInfoData ) ;
}
2020-07-21 16:38:00 +02:00
2021-10-12 07:21:31 +02:00
_Use_decl_annotations_
BOOL
AdapterDisableInstance ( HDEVINFO DevInfo , SP_DEVINFO_DATA * DevInfoData )
{
# ifdef MAYBE_WOW64
if ( NativeMachine ! = IMAGE_FILE_PROCESS )
return DisableInstanceViaRundll32 ( DevInfo , DevInfoData ) ;
# endif
SP_PROPCHANGE_PARAMS Params = { . ClassInstallHeader = { . cbSize = sizeof ( SP_CLASSINSTALL_HEADER ) ,
. InstallFunction = DIF_PROPERTYCHANGE } ,
. StateChange = DICS_DISABLE ,
. Scope = DICS_FLAG_GLOBAL } ;
return SetupDiSetClassInstallParamsW ( DevInfo , DevInfoData , & Params . ClassInstallHeader , sizeof ( Params ) ) & &
SetupDiCallClassInstaller ( DIF_PROPERTYCHANGE , DevInfo , DevInfoData ) ;
2020-07-21 16:38:00 +02:00
}