api: cleanup
Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
parent
0a986ce9fc
commit
08e2993d23
30
api/api.c
30
api/api.c
@ -7,6 +7,36 @@
|
|||||||
|
|
||||||
HINSTANCE ResourceModule;
|
HINSTANCE ResourceModule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the version of the Wintun driver and NDIS system currently loaded.
|
||||||
|
*/
|
||||||
|
WINTUN_STATUS WINAPI
|
||||||
|
WintunGetVersion(
|
||||||
|
_Out_ DWORD *DriverVersionMaj,
|
||||||
|
_Out_ DWORD *DriverVersionMin,
|
||||||
|
_Out_ DWORD *NdisVersionMaj,
|
||||||
|
_Out_ DWORD *NdisVersionMin)
|
||||||
|
{
|
||||||
|
HKEY Key;
|
||||||
|
DWORD Result =
|
||||||
|
RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Wintun", 0, KEY_QUERY_VALUE, &Key);
|
||||||
|
if (Result != ERROR_SUCCESS)
|
||||||
|
return Result;
|
||||||
|
Result = RegistryQueryDWORD(Key, L"DriverMajorVersion", DriverVersionMaj);
|
||||||
|
if (Result != ERROR_SUCCESS)
|
||||||
|
goto cleanupKey;
|
||||||
|
Result = RegistryQueryDWORD(Key, L"DriverMinorVersion", DriverVersionMin);
|
||||||
|
if (Result != ERROR_SUCCESS)
|
||||||
|
goto cleanupKey;
|
||||||
|
Result = RegistryQueryDWORD(Key, L"NdisMajorVersion", NdisVersionMaj);
|
||||||
|
if (Result != ERROR_SUCCESS)
|
||||||
|
goto cleanupKey;
|
||||||
|
Result = RegistryQueryDWORD(Key, L"NdisMinorVersion", NdisVersionMin);
|
||||||
|
cleanupKey:
|
||||||
|
RegCloseKey(Key);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL APIENTRY
|
BOOL APIENTRY
|
||||||
DllMain(_In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved)
|
DllMain(_In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved)
|
||||||
{
|
{
|
||||||
|
38
api/api.h
38
api/api.h
@ -13,7 +13,7 @@ extern HINSTANCE ResourceModule;
|
|||||||
|
|
||||||
_Check_return_
|
_Check_return_
|
||||||
HANDLE
|
HANDLE
|
||||||
TakeNameMutex(_In_z_ LPCWSTR Pool);
|
TakeNameMutex(_In_z_ const WCHAR *Pool);
|
||||||
|
|
||||||
void
|
void
|
||||||
ReleaseNameMutex(_In_ HANDLE Mutex);
|
ReleaseNameMutex(_In_ HANDLE Mutex);
|
||||||
@ -24,11 +24,11 @@ NamespaceInit();
|
|||||||
void
|
void
|
||||||
NamespaceCleanup();
|
NamespaceCleanup();
|
||||||
|
|
||||||
extern DWORD(WINAPI *NciSetConnectionName)(_In_ LPCGUID Guid, _In_z_ LPCWSTR NewName);
|
extern DWORD(WINAPI *NciSetConnectionName)(_In_ const GUID *Guid, _In_z_ const WCHAR *NewName);
|
||||||
|
|
||||||
extern DWORD(WINAPI *NciGetConnectionName)(
|
extern DWORD(WINAPI *NciGetConnectionName)(
|
||||||
_In_ LPCGUID Guid,
|
_In_ const GUID *Guid,
|
||||||
_Out_z_bytecap_(InDestNameBytes) LPWSTR Name,
|
_Out_z_bytecap_(InDestNameBytes) WCHAR *Name,
|
||||||
_In_ DWORD InDestNameBytes,
|
_In_ DWORD InDestNameBytes,
|
||||||
_Out_opt_ DWORD *OutDestNameBytes);
|
_Out_opt_ DWORD *OutDestNameBytes);
|
||||||
|
|
||||||
@ -41,31 +41,31 @@ NciCleanup();
|
|||||||
WINTUN_STATUS
|
WINTUN_STATUS
|
||||||
RegistryOpenKeyWait(
|
RegistryOpenKeyWait(
|
||||||
_In_ HKEY Key,
|
_In_ HKEY Key,
|
||||||
_In_z_count_c_(MAX_PATH) LPCWSTR Path,
|
_In_z_count_c_(MAX_PATH) const WCHAR *Path,
|
||||||
_In_ DWORD Access,
|
_In_ DWORD Access,
|
||||||
_In_ DWORD Timeout,
|
_In_ DWORD Timeout,
|
||||||
_Out_ HKEY *KeyOut);
|
_Out_ HKEY *KeyOut);
|
||||||
|
|
||||||
WINTUN_STATUS
|
WINTUN_STATUS
|
||||||
RegistryWaitForKey(_In_ HKEY Key, _In_z_count_c_(MAX_PATH) LPCWSTR Path, _In_ DWORD Timeout);
|
RegistryWaitForKey(_In_ HKEY Key, _In_z_count_c_(MAX_PATH) const WCHAR *Path, _In_ DWORD Timeout);
|
||||||
|
|
||||||
WINTUN_STATUS
|
WINTUN_STATUS
|
||||||
RegistryGetString(_Inout_ LPWSTR *Buf, _In_ DWORD Len, _In_ DWORD ValueType);
|
RegistryGetString(_Inout_ WCHAR **Buf, _In_ DWORD Len, _In_ DWORD ValueType);
|
||||||
|
|
||||||
WINTUN_STATUS
|
WINTUN_STATUS
|
||||||
RegistryGetMultiString(_Inout_ LPWSTR *Buf, _In_ DWORD Len, _In_ DWORD ValueType);
|
RegistryGetMultiString(_Inout_ WCHAR **Buf, _In_ DWORD Len, _In_ DWORD ValueType);
|
||||||
|
|
||||||
WINTUN_STATUS
|
WINTUN_STATUS
|
||||||
RegistryQueryString(_In_ HKEY Key, _In_opt_z_ LPCWSTR Name, _Out_ LPWSTR *Value);
|
RegistryQueryString(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _Out_ WCHAR **Value);
|
||||||
|
|
||||||
WINTUN_STATUS
|
WINTUN_STATUS
|
||||||
RegistryQueryStringWait(_In_ HKEY Key, _In_opt_z_ LPCWSTR Name, _In_ DWORD Timeout, _Out_ LPWSTR *Value);
|
RegistryQueryStringWait(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _In_ DWORD Timeout, _Out_ WCHAR **Value);
|
||||||
|
|
||||||
WINTUN_STATUS
|
WINTUN_STATUS
|
||||||
RegistryQueryDWORD(_In_ HKEY Key, _In_opt_z_ LPCWSTR Name, _Out_ DWORD *Value);
|
RegistryQueryDWORD(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _Out_ DWORD *Value);
|
||||||
|
|
||||||
WINTUN_STATUS
|
WINTUN_STATUS
|
||||||
RegistryQueryDWORDWait(_In_ HKEY Key, _In_opt_z_ LPCWSTR Name, _In_ DWORD Timeout, _Out_ DWORD *Value);
|
RegistryQueryDWORDWait(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _In_ DWORD Timeout, _Out_ DWORD *Value);
|
||||||
|
|
||||||
WINTUN_STATUS WINAPI
|
WINTUN_STATUS WINAPI
|
||||||
WintunGetVersion(
|
WintunGetVersion(
|
||||||
@ -86,17 +86,17 @@ typedef struct _WINTUN_ADAPTER
|
|||||||
WCHAR Pool[MAX_POOL];
|
WCHAR Pool[MAX_POOL];
|
||||||
} WINTUN_ADAPTER;
|
} WINTUN_ADAPTER;
|
||||||
|
|
||||||
VOID WINAPI
|
void WINAPI
|
||||||
WintunFreeAdapter(_In_ WINTUN_ADAPTER *Adapter);
|
WintunFreeAdapter(_In_ WINTUN_ADAPTER *Adapter);
|
||||||
|
|
||||||
WINTUN_STATUS WINAPI
|
WINTUN_STATUS WINAPI
|
||||||
WintunGetAdapter(_In_z_count_c_(MAX_POOL) LPCWSTR Pool, _In_z_ LPCWSTR Name, _Out_ WINTUN_ADAPTER **Adapter);
|
WintunGetAdapter(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_z_ const WCHAR *Name, _Out_ WINTUN_ADAPTER **Adapter);
|
||||||
|
|
||||||
WINTUN_STATUS WINAPI
|
WINTUN_STATUS WINAPI
|
||||||
WintunGetAdapterName(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_ADAPTER_NAME) LPWSTR Name);
|
WintunGetAdapterName(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_ADAPTER_NAME) WCHAR *Name);
|
||||||
|
|
||||||
WINTUN_STATUS WINAPI
|
WINTUN_STATUS WINAPI
|
||||||
WintunSetAdapterName(_In_ const WINTUN_ADAPTER *Adapter, _In_z_count_c_(MAX_ADAPTER_NAME) LPCWSTR Name);
|
WintunSetAdapterName(_In_ const WINTUN_ADAPTER *Adapter, _In_z_count_c_(MAX_ADAPTER_NAME) const WCHAR *Name);
|
||||||
|
|
||||||
void WINAPI
|
void WINAPI
|
||||||
WintunGetAdapterGUID(_In_ const WINTUN_ADAPTER *Adapter, _Out_ GUID *Guid);
|
WintunGetAdapterGUID(_In_ const WINTUN_ADAPTER *Adapter, _Out_ GUID *Guid);
|
||||||
@ -109,8 +109,8 @@ WintunGetAdapterDeviceObject(_In_ const WINTUN_ADAPTER *Adapter, _Out_ HANDLE *H
|
|||||||
|
|
||||||
WINTUN_STATUS WINAPI
|
WINTUN_STATUS WINAPI
|
||||||
WintunCreateAdapter(
|
WintunCreateAdapter(
|
||||||
_In_z_count_c_(MAX_POOL) LPCWSTR Pool,
|
_In_z_count_c_(MAX_POOL) const WCHAR *Pool,
|
||||||
_In_z_ LPCWSTR Name,
|
_In_z_ const WCHAR *Name,
|
||||||
_In_opt_ const GUID *RequestedGUID,
|
_In_opt_ const GUID *RequestedGUID,
|
||||||
_Out_ WINTUN_ADAPTER **Adapter,
|
_Out_ WINTUN_ADAPTER **Adapter,
|
||||||
_Inout_ BOOL *RebootRequired);
|
_Inout_ BOOL *RebootRequired);
|
||||||
@ -121,4 +121,4 @@ WintunDeleteAdapter(_In_ const WINTUN_ADAPTER *Adapter, _Inout_ BOOL *RebootRequ
|
|||||||
typedef BOOL(CALLBACK *WINTUN_ENUMPROC)(_In_ const WINTUN_ADAPTER *Adapter, _In_ LPARAM Param);
|
typedef BOOL(CALLBACK *WINTUN_ENUMPROC)(_In_ const WINTUN_ADAPTER *Adapter, _In_ LPARAM Param);
|
||||||
|
|
||||||
WINTUN_STATUS WINAPI
|
WINTUN_STATUS WINAPI
|
||||||
WintunEnumAdapters(_In_z_count_c_(MAX_POOL) LPCWSTR Pool, _In_ WINTUN_ENUMPROC Func, _In_ LPARAM Param);
|
WintunEnumAdapters(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_ WINTUN_ENUMPROC Func, _In_ LPARAM Param);
|
||||||
|
450
api/devmgmt.c
450
api/devmgmt.c
@ -6,8 +6,8 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
|
||||||
#define WINTUN_HWID L"Wintun"
|
#define WINTUN_HWID L"Wintun"
|
||||||
#define WAIT_FOR_REGISTRY_TIMEOUT 10000 /* ms */
|
#define WAIT_FOR_REGISTRY_TIMEOUT 10000 /* ms */
|
||||||
#define MAX_POOL_DEVICE_TYPE (MAX_POOL + 0x100)
|
#define MAX_POOL_DEVICE_TYPE (MAX_POOL + 8) /* Should accommodate a pool name with " Tunnel" appended */
|
||||||
|
|
||||||
const static GUID CLASS_NET_GUID = { 0x4d36e972L, 0xe325, 0x11ce, { 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 } };
|
const static GUID CLASS_NET_GUID = { 0x4d36e972L, 0xe325, 0x11ce, { 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 } };
|
||||||
const static GUID ADAPTER_NET_GUID = { 0xcac88484L,
|
const static GUID ADAPTER_NET_GUID = { 0xcac88484L,
|
||||||
@ -15,36 +15,6 @@ const static GUID ADAPTER_NET_GUID = { 0xcac88484L,
|
|||||||
0x4c03,
|
0x4c03,
|
||||||
{ 0x82, 0xe6, 0x71, 0xa8, 0x7a, 0xba, 0xc3, 0x61 } };
|
{ 0x82, 0xe6, 0x71, 0xa8, 0x7a, 0xba, 0xc3, 0x61 } };
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the version of the Wintun driver and NDIS system currently loaded.
|
|
||||||
*/
|
|
||||||
WINTUN_STATUS WINAPI
|
|
||||||
WintunGetVersion(
|
|
||||||
_Out_ DWORD *DriverVersionMaj,
|
|
||||||
_Out_ DWORD *DriverVersionMin,
|
|
||||||
_Out_ DWORD *NdisVersionMaj,
|
|
||||||
_Out_ DWORD *NdisVersionMin)
|
|
||||||
{
|
|
||||||
HKEY Key;
|
|
||||||
DWORD Result =
|
|
||||||
RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Wintun", 0, KEY_QUERY_VALUE, &Key);
|
|
||||||
if (Result != ERROR_SUCCESS)
|
|
||||||
return Result;
|
|
||||||
Result = RegistryQueryDWORD(Key, L"DriverMajorVersion", DriverVersionMaj);
|
|
||||||
if (Result != ERROR_SUCCESS)
|
|
||||||
goto cleanupKey;
|
|
||||||
Result = RegistryQueryDWORD(Key, L"DriverMinorVersion", DriverVersionMin);
|
|
||||||
if (Result != ERROR_SUCCESS)
|
|
||||||
goto cleanupKey;
|
|
||||||
Result = RegistryQueryDWORD(Key, L"NdisMajorVersion", NdisVersionMaj);
|
|
||||||
if (Result != ERROR_SUCCESS)
|
|
||||||
goto cleanupKey;
|
|
||||||
Result = RegistryQueryDWORD(Key, L"NdisMinorVersion", NdisVersionMin);
|
|
||||||
cleanupKey:
|
|
||||||
RegCloseKey(Key);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a specified Plug and Play device property.
|
* Retrieves a specified Plug and Play device property.
|
||||||
*
|
*
|
||||||
@ -122,7 +92,7 @@ GetDeviceRegistryString(
|
|||||||
_In_ HDEVINFO DevInfo,
|
_In_ HDEVINFO DevInfo,
|
||||||
_In_ SP_DEVINFO_DATA *DevInfoData,
|
_In_ SP_DEVINFO_DATA *DevInfoData,
|
||||||
_In_ DWORD Property,
|
_In_ DWORD Property,
|
||||||
_Out_ LPWSTR *PropertyBuffer)
|
_Out_ WCHAR **PropertyBuffer)
|
||||||
{
|
{
|
||||||
DWORD Result, ValueType, Size;
|
DWORD Result, ValueType, Size;
|
||||||
Result = GetDeviceRegistryProperty(DevInfo, DevInfoData, Property, &ValueType, PropertyBuffer, &Size);
|
Result = GetDeviceRegistryProperty(DevInfo, DevInfoData, Property, &ValueType, PropertyBuffer, &Size);
|
||||||
@ -164,7 +134,7 @@ GetDeviceRegistryMultiString(
|
|||||||
_In_ HDEVINFO DevInfo,
|
_In_ HDEVINFO DevInfo,
|
||||||
_In_ SP_DEVINFO_DATA *DevInfoData,
|
_In_ SP_DEVINFO_DATA *DevInfoData,
|
||||||
_In_ DWORD Property,
|
_In_ DWORD Property,
|
||||||
_Out_ LPWSTR *PropertyBuffer)
|
_Out_ WCHAR **PropertyBuffer)
|
||||||
{
|
{
|
||||||
DWORD Result, ValueType, Size;
|
DWORD Result, ValueType, Size;
|
||||||
Result = GetDeviceRegistryProperty(DevInfo, DevInfoData, Property, &ValueType, PropertyBuffer, &Size);
|
Result = GetDeviceRegistryProperty(DevInfo, DevInfoData, Property, &ValueType, PropertyBuffer, &Size);
|
||||||
@ -186,98 +156,6 @@ GetDeviceRegistryMultiString(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes numbered suffix from adapter name.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
RemoveNumberedSuffix(_In_z_ LPCWSTR Name, _Out_ LPWSTR Removed)
|
|
||||||
{
|
|
||||||
size_t Len = wcslen(Name);
|
|
||||||
if (Len && Name[Len - 1] < L'0' || Name[Len - 1] > L'9')
|
|
||||||
{
|
|
||||||
wmemcpy(Removed, Name, Len + 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (size_t i = Len; i--;)
|
|
||||||
{
|
|
||||||
if (Name[i] >= L'0' && Name[i] <= L'9')
|
|
||||||
continue;
|
|
||||||
if (Name[i] == L' ')
|
|
||||||
{
|
|
||||||
wmemcpy(Removed, Name, i);
|
|
||||||
Removed[i] = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
wmemcpy(Removed, Name, Len + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests if any of the hardware IDs match ours.
|
|
||||||
*
|
|
||||||
* @param Hwids Multi-string containing a list of hardware IDs
|
|
||||||
*
|
|
||||||
* @return TRUE on match; FALSE otherwise.
|
|
||||||
*/
|
|
||||||
static BOOL
|
|
||||||
IsOurHardwareID(_In_z_ LPWSTR Hwids)
|
|
||||||
{
|
|
||||||
for (; Hwids[0]; Hwids += wcslen(Hwids) + 1)
|
|
||||||
if (!_wcsicmp(Hwids, WINTUN_HWID))
|
|
||||||
return TRUE;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns pool-specific device type name.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
GetPoolDeviceTypeName(_In_z_count_c_(MAX_POOL) LPCWSTR Pool, _Out_cap_c_(MAX_POOL_DEVICE_TYPE) LPWSTR Name)
|
|
||||||
{
|
|
||||||
_snwprintf_s(Name, MAX_POOL_DEVICE_TYPE, _TRUNCATE, L"%.*s Tunnel", MAX_POOL, Pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if SPDRP_DEVICEDESC or SPDRP_FRIENDLYNAME match device type name.
|
|
||||||
*/
|
|
||||||
static WINTUN_STATUS
|
|
||||||
IsPoolMember(
|
|
||||||
_In_z_count_c_(MAX_POOL) LPCWSTR Pool,
|
|
||||||
_In_ HDEVINFO DevInfo,
|
|
||||||
_In_ SP_DEVINFO_DATA *DevInfoData,
|
|
||||||
_Out_ BOOL *IsMember)
|
|
||||||
{
|
|
||||||
HANDLE Heap = GetProcessHeap();
|
|
||||||
LPWSTR DeviceDesc, FriendlyName;
|
|
||||||
DWORD Result = GetDeviceRegistryString(DevInfo, DevInfoData, SPDRP_DEVICEDESC, &DeviceDesc);
|
|
||||||
if (Result != ERROR_SUCCESS)
|
|
||||||
return Result;
|
|
||||||
Result = GetDeviceRegistryString(DevInfo, DevInfoData, SPDRP_FRIENDLYNAME, &FriendlyName);
|
|
||||||
if (Result != ERROR_SUCCESS)
|
|
||||||
goto cleanupDeviceDesc;
|
|
||||||
WCHAR PoolDeviceTypeName[MAX_POOL_DEVICE_TYPE];
|
|
||||||
GetPoolDeviceTypeName(Pool, PoolDeviceTypeName);
|
|
||||||
if (!_wcsicmp(FriendlyName, PoolDeviceTypeName) || !_wcsicmp(DeviceDesc, PoolDeviceTypeName))
|
|
||||||
{
|
|
||||||
*IsMember = TRUE;
|
|
||||||
goto cleanupFriendlyName;
|
|
||||||
}
|
|
||||||
RemoveNumberedSuffix(FriendlyName, FriendlyName);
|
|
||||||
RemoveNumberedSuffix(DeviceDesc, DeviceDesc);
|
|
||||||
if (!_wcsicmp(FriendlyName, PoolDeviceTypeName) || !_wcsicmp(DeviceDesc, PoolDeviceTypeName))
|
|
||||||
{
|
|
||||||
*IsMember = TRUE;
|
|
||||||
goto cleanupFriendlyName;
|
|
||||||
}
|
|
||||||
*IsMember = FALSE;
|
|
||||||
cleanupFriendlyName:
|
|
||||||
HeapFree(Heap, 0, FriendlyName);
|
|
||||||
cleanupDeviceDesc:
|
|
||||||
HeapFree(Heap, 0, DeviceDesc);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves driver information detail for a device information set or a particular device information element in the
|
* Retrieves driver information detail for a device information set or a particular device information element in the
|
||||||
* device information set.
|
* device information set.
|
||||||
@ -322,6 +200,22 @@ GetDriverInfoDetail(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if any of the hardware IDs match ours.
|
||||||
|
*
|
||||||
|
* @param Hwids Multi-string containing a list of hardware IDs
|
||||||
|
*
|
||||||
|
* @return TRUE on match; FALSE otherwise.
|
||||||
|
*/
|
||||||
|
static BOOL
|
||||||
|
IsOurHardwareID(_In_z_ WCHAR *Hwids)
|
||||||
|
{
|
||||||
|
for (; Hwids[0]; Hwids += wcslen(Hwids) + 1)
|
||||||
|
if (!_wcsicmp(Hwids, WINTUN_HWID))
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the device is using Wintun driver.
|
* Check if the device is using Wintun driver.
|
||||||
*/
|
*/
|
||||||
@ -359,17 +253,41 @@ IsUsingOurDriver(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData, _Out_
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a Wintun interface descriptor and populates it from the device's registry key.
|
* Checks device install parameters if a system reboot is required.
|
||||||
|
*/
|
||||||
|
static BOOL
|
||||||
|
CheckReboot(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData)
|
||||||
|
{
|
||||||
|
SP_DEVINSTALL_PARAMS_W DevInstallParams = { .cbSize = sizeof(SP_DEVINSTALL_PARAMS_W) };
|
||||||
|
if (!SetupDiGetDeviceInstallParamsW(DevInfo, DevInfoData, &DevInstallParams))
|
||||||
|
return FALSE;
|
||||||
|
return (DevInstallParams.Flags & (DI_NEEDREBOOT | DI_NEEDRESTART)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets device install parameters for a quiet installation.
|
||||||
|
*/
|
||||||
|
static WINTUN_STATUS
|
||||||
|
SetQuietInstall(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData)
|
||||||
|
{
|
||||||
|
SP_DEVINSTALL_PARAMS_W DevInstallParams = { .cbSize = sizeof(SP_DEVINSTALL_PARAMS_W) };
|
||||||
|
if (!SetupDiGetDeviceInstallParamsW(DevInfo, DevInfoData, &DevInstallParams))
|
||||||
|
return GetLastError();
|
||||||
|
DevInstallParams.Flags |= DI_QUIETINSTALL;
|
||||||
|
if (!SetupDiSetDeviceInstallParamsW(DevInfo, DevInfoData, &DevInstallParams))
|
||||||
|
return GetLastError();
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns adapter GUID associated with device.
|
||||||
*
|
*
|
||||||
* @param DevInfo A handle to the device information set that contains a device information element that
|
* @param DevInfo A handle to the device information set that contains a device information element that
|
||||||
* represents the device for which to open a registry key.
|
* represents the device for which to open a registry key.
|
||||||
*
|
*
|
||||||
* @param DevInfoData A pointer to a structure that specifies the device information element in DeviceInfoSet.
|
* @param DevInfoData A pointer to a structure that specifies the device information element in DeviceInfoSet.
|
||||||
*
|
*
|
||||||
* @param Pool Name of the adapter pool
|
* @param CfgInstanceID Pointer to a GUID to receive the adapter GUID.
|
||||||
*
|
|
||||||
* @param Adapter Pointer to a handle to receive the adapter descriptor. Must be released with
|
|
||||||
* HeapFree(GetProcessHeap(), 0, *Adapter).
|
|
||||||
*
|
*
|
||||||
* @return ERROR_SUCCESS on success; Win32 error code otherwise
|
* @return ERROR_SUCCESS on success; Win32 error code otherwise
|
||||||
*/
|
*/
|
||||||
@ -379,7 +297,7 @@ GetNetCfgInstanceId(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData, _O
|
|||||||
HKEY Key = SetupDiOpenDevRegKey(DevInfo, DevInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_QUERY_VALUE);
|
HKEY Key = SetupDiOpenDevRegKey(DevInfo, DevInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_QUERY_VALUE);
|
||||||
if (Key == INVALID_HANDLE_VALUE)
|
if (Key == INVALID_HANDLE_VALUE)
|
||||||
return GetLastError();
|
return GetLastError();
|
||||||
LPWSTR ValueStr;
|
WCHAR *ValueStr;
|
||||||
DWORD Result = RegistryQueryString(Key, L"NetCfgInstanceId", &ValueStr);
|
DWORD Result = RegistryQueryString(Key, L"NetCfgInstanceId", &ValueStr);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
goto cleanupKey;
|
goto cleanupKey;
|
||||||
@ -391,7 +309,132 @@ cleanupKey:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a Wintun interface descriptor and populates it from the device's registry key.
|
* Returns device info list handle and adapter device info data.
|
||||||
|
*
|
||||||
|
* @param CfgInstanceID The adapter GUID
|
||||||
|
*
|
||||||
|
* @param DevInfo A pointer to receive the handle of the device information set that contains a device information
|
||||||
|
* element that represents the device. Must be released with SetupDiDestroyDeviceInfoList(*DevInfo)
|
||||||
|
* after use.
|
||||||
|
*
|
||||||
|
* @param DevInfoData A pointer to a structure that receives specification of the device information element in
|
||||||
|
* DeviceInfoSet.
|
||||||
|
*
|
||||||
|
* @return ERROR_SUCCESS on success; ERROR_OBJECT_NOT_FOUND if the device is not found; Win32 error code otherwise
|
||||||
|
*/
|
||||||
|
static WINTUN_STATUS
|
||||||
|
GetDevInfoData(_In_ const GUID *CfgInstanceID, _Out_ HDEVINFO *DevInfo, _Out_ SP_DEVINFO_DATA *DevInfoData)
|
||||||
|
{
|
||||||
|
DWORD Result;
|
||||||
|
*DevInfo = SetupDiGetClassDevsExW(&CLASS_NET_GUID, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
|
||||||
|
if (!*DevInfo)
|
||||||
|
return GetLastError();
|
||||||
|
for (DWORD MemberIndex = 0;; ++MemberIndex)
|
||||||
|
{
|
||||||
|
DevInfoData->cbSize = sizeof(SP_DEVINFO_DATA);
|
||||||
|
if (!SetupDiEnumDeviceInfo(*DevInfo, MemberIndex, DevInfoData))
|
||||||
|
{
|
||||||
|
Result = GetLastError();
|
||||||
|
if (Result == ERROR_NO_MORE_ITEMS)
|
||||||
|
break;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
GUID CfgInstanceID2;
|
||||||
|
Result = GetNetCfgInstanceId(*DevInfo, DevInfoData, &CfgInstanceID2);
|
||||||
|
if (Result != ERROR_SUCCESS || memcmp(CfgInstanceID, &CfgInstanceID2, sizeof(GUID)) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Result = SetQuietInstall(*DevInfo, DevInfoData);
|
||||||
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
SetupDiDestroyDeviceInfoList(*DevInfo);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
SetupDiDestroyDeviceInfoList(*DevInfo);
|
||||||
|
return ERROR_OBJECT_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes numbered suffix from adapter name.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
RemoveNumberedSuffix(_In_z_ const WCHAR *Name, _Out_ WCHAR *Removed)
|
||||||
|
{
|
||||||
|
size_t Len = wcslen(Name);
|
||||||
|
if (Len && Name[Len - 1] < L'0' || Name[Len - 1] > L'9')
|
||||||
|
{
|
||||||
|
wmemcpy(Removed, Name, Len + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (size_t i = Len; i--;)
|
||||||
|
{
|
||||||
|
if (Name[i] >= L'0' && Name[i] <= L'9')
|
||||||
|
continue;
|
||||||
|
if (Name[i] == L' ')
|
||||||
|
{
|
||||||
|
wmemcpy(Removed, Name, i);
|
||||||
|
Removed[i] = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
wmemcpy(Removed, Name, Len + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns pool-specific device type name.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
GetPoolDeviceTypeName(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _Out_cap_c_(MAX_POOL_DEVICE_TYPE) WCHAR *Name)
|
||||||
|
{
|
||||||
|
_snwprintf_s(Name, MAX_POOL_DEVICE_TYPE, _TRUNCATE, L"%.*s Tunnel", MAX_POOL, Pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if SPDRP_DEVICEDESC or SPDRP_FRIENDLYNAME match device type name.
|
||||||
|
*/
|
||||||
|
static WINTUN_STATUS
|
||||||
|
IsPoolMember(
|
||||||
|
_In_z_count_c_(MAX_POOL) const WCHAR *Pool,
|
||||||
|
_In_ HDEVINFO DevInfo,
|
||||||
|
_In_ SP_DEVINFO_DATA *DevInfoData,
|
||||||
|
_Out_ BOOL *IsMember)
|
||||||
|
{
|
||||||
|
HANDLE Heap = GetProcessHeap();
|
||||||
|
WCHAR *DeviceDesc, *FriendlyName;
|
||||||
|
DWORD Result = GetDeviceRegistryString(DevInfo, DevInfoData, SPDRP_DEVICEDESC, &DeviceDesc);
|
||||||
|
if (Result != ERROR_SUCCESS)
|
||||||
|
return Result;
|
||||||
|
Result = GetDeviceRegistryString(DevInfo, DevInfoData, SPDRP_FRIENDLYNAME, &FriendlyName);
|
||||||
|
if (Result != ERROR_SUCCESS)
|
||||||
|
goto cleanupDeviceDesc;
|
||||||
|
WCHAR PoolDeviceTypeName[MAX_POOL_DEVICE_TYPE];
|
||||||
|
GetPoolDeviceTypeName(Pool, PoolDeviceTypeName);
|
||||||
|
if (!_wcsicmp(FriendlyName, PoolDeviceTypeName) || !_wcsicmp(DeviceDesc, PoolDeviceTypeName))
|
||||||
|
{
|
||||||
|
*IsMember = TRUE;
|
||||||
|
goto cleanupFriendlyName;
|
||||||
|
}
|
||||||
|
RemoveNumberedSuffix(FriendlyName, FriendlyName);
|
||||||
|
RemoveNumberedSuffix(DeviceDesc, DeviceDesc);
|
||||||
|
if (!_wcsicmp(FriendlyName, PoolDeviceTypeName) || !_wcsicmp(DeviceDesc, PoolDeviceTypeName))
|
||||||
|
{
|
||||||
|
*IsMember = TRUE;
|
||||||
|
goto cleanupFriendlyName;
|
||||||
|
}
|
||||||
|
*IsMember = FALSE;
|
||||||
|
cleanupFriendlyName:
|
||||||
|
HeapFree(Heap, 0, FriendlyName);
|
||||||
|
cleanupDeviceDesc:
|
||||||
|
HeapFree(Heap, 0, DeviceDesc);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Wintun adapter descriptor and populates it from the device's registry key.
|
||||||
*
|
*
|
||||||
* @param DevInfo A handle to the device information set that contains a device information element that
|
* @param DevInfo A handle to the device information set that contains a device information element that
|
||||||
* represents the device for which to open a registry key.
|
* represents the device for which to open a registry key.
|
||||||
@ -407,9 +450,9 @@ cleanupKey:
|
|||||||
*/
|
*/
|
||||||
static WINTUN_STATUS
|
static WINTUN_STATUS
|
||||||
CreateAdapterData(
|
CreateAdapterData(
|
||||||
|
_In_z_count_c_(MAX_POOL) const WCHAR *Pool,
|
||||||
_In_ HDEVINFO DevInfo,
|
_In_ HDEVINFO DevInfo,
|
||||||
_In_ SP_DEVINFO_DATA *DevInfoData,
|
_In_ SP_DEVINFO_DATA *DevInfoData,
|
||||||
_In_z_count_c_(MAX_POOL) LPCWSTR Pool,
|
|
||||||
_Out_ WINTUN_ADAPTER **Adapter)
|
_Out_ WINTUN_ADAPTER **Adapter)
|
||||||
{
|
{
|
||||||
DWORD Result;
|
DWORD Result;
|
||||||
@ -428,7 +471,7 @@ CreateAdapterData(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Read the NetCfgInstanceId value and convert to GUID. */
|
/* Read the NetCfgInstanceId value and convert to GUID. */
|
||||||
LPWSTR ValueStr;
|
WCHAR *ValueStr;
|
||||||
Result = RegistryQueryString(Key, L"NetCfgInstanceId", &ValueStr);
|
Result = RegistryQueryString(Key, L"NetCfgInstanceId", &ValueStr);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
goto cleanupAdapter;
|
goto cleanupAdapter;
|
||||||
@ -473,7 +516,7 @@ cleanupKey:
|
|||||||
* Returns the device-level registry key path.
|
* Returns the device-level registry key path.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
GetDeviceRegPath(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_PATH + MAX_INSTANCE_ID) LPWSTR Path)
|
GetDeviceRegPath(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_PATH + MAX_INSTANCE_ID) WCHAR *Path)
|
||||||
{
|
{
|
||||||
_snwprintf_s(
|
_snwprintf_s(
|
||||||
Path,
|
Path,
|
||||||
@ -488,7 +531,7 @@ GetDeviceRegPath(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_PATH + MAX_
|
|||||||
* Returns the adapter-specific TCP/IP network registry key path.
|
* Returns the adapter-specific TCP/IP network registry key path.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
GetTcpipAdapterRegPath(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_PATH) LPWSTR Path)
|
GetTcpipAdapterRegPath(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_PATH) WCHAR *Path)
|
||||||
{
|
{
|
||||||
WCHAR Guid[MAX_GUID_STRING_LEN];
|
WCHAR Guid[MAX_GUID_STRING_LEN];
|
||||||
_snwprintf_s(
|
_snwprintf_s(
|
||||||
@ -504,7 +547,7 @@ GetTcpipAdapterRegPath(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_PATH)
|
|||||||
* Returns the interface-specific TCP/IP network registry key path.
|
* Returns the interface-specific TCP/IP network registry key path.
|
||||||
*/
|
*/
|
||||||
static WINTUN_STATUS
|
static WINTUN_STATUS
|
||||||
GetTcpipInterfaceRegPath(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_PATH) LPWSTR Path)
|
GetTcpipInterfaceRegPath(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_PATH) WCHAR *Path)
|
||||||
{
|
{
|
||||||
DWORD Result;
|
DWORD Result;
|
||||||
HKEY TcpipAdapterRegKey;
|
HKEY TcpipAdapterRegKey;
|
||||||
@ -513,7 +556,7 @@ GetTcpipInterfaceRegPath(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_PAT
|
|||||||
Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, TcpipAdapterRegPath, 0, KEY_QUERY_VALUE, &TcpipAdapterRegKey);
|
Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, TcpipAdapterRegPath, 0, KEY_QUERY_VALUE, &TcpipAdapterRegKey);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
return Result;
|
return Result;
|
||||||
LPWSTR Paths;
|
WCHAR *Paths;
|
||||||
Result = RegistryQueryString(TcpipAdapterRegKey, L"IpConfig", &Paths);
|
Result = RegistryQueryString(TcpipAdapterRegKey, L"IpConfig", &Paths);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
goto cleanupTcpipAdapterRegKey;
|
goto cleanupTcpipAdapterRegKey;
|
||||||
@ -535,7 +578,7 @@ cleanupTcpipAdapterRegKey:
|
|||||||
*
|
*
|
||||||
* @param Adapter Adapter handle obtained with WintunGetAdapter or WintunCreateAdapter
|
* @param Adapter Adapter handle obtained with WintunGetAdapter or WintunCreateAdapter
|
||||||
*/
|
*/
|
||||||
VOID WINAPI
|
void WINAPI
|
||||||
WintunFreeAdapter(_In_ WINTUN_ADAPTER *Adapter)
|
WintunFreeAdapter(_In_ WINTUN_ADAPTER *Adapter)
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, Adapter);
|
HeapFree(GetProcessHeap(), 0, Adapter);
|
||||||
@ -556,7 +599,7 @@ WintunFreeAdapter(_In_ WINTUN_ADAPTER *Adapter)
|
|||||||
* ERROR_ALREADY_EXISTS if adapter is found but not a Wintun-class or not a member of the pool
|
* ERROR_ALREADY_EXISTS if adapter is found but not a Wintun-class or not a member of the pool
|
||||||
*/
|
*/
|
||||||
WINTUN_STATUS WINAPI
|
WINTUN_STATUS WINAPI
|
||||||
WintunGetAdapter(_In_z_count_c_(MAX_POOL) LPCWSTR Pool, _In_z_ LPCWSTR Name, _Out_ WINTUN_ADAPTER **Adapter)
|
WintunGetAdapter(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_z_ const WCHAR *Name, _Out_ WINTUN_ADAPTER **Adapter)
|
||||||
{
|
{
|
||||||
DWORD Result;
|
DWORD Result;
|
||||||
HANDLE Mutex = TakeNameMutex(Pool);
|
HANDLE Mutex = TakeNameMutex(Pool);
|
||||||
@ -597,7 +640,7 @@ WintunGetAdapter(_In_z_count_c_(MAX_POOL) LPCWSTR Pool, _In_z_ LPCWSTR Name, _Ou
|
|||||||
|
|
||||||
/* Check the Hardware ID to make sure it's a real Wintun device. This avoids doing slow operations on non-Wintun
|
/* Check the Hardware ID to make sure it's a real Wintun device. This avoids doing slow operations on non-Wintun
|
||||||
* devices. */
|
* devices. */
|
||||||
LPWSTR Hwids;
|
WCHAR *Hwids;
|
||||||
Result = GetDeviceRegistryMultiString(DevInfo, &DevInfoData, SPDRP_HARDWAREID, &Hwids);
|
Result = GetDeviceRegistryMultiString(DevInfo, &DevInfoData, SPDRP_HARDWAREID, &Hwids);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
goto cleanupDevInfo;
|
goto cleanupDevInfo;
|
||||||
@ -629,7 +672,7 @@ WintunGetAdapter(_In_z_count_c_(MAX_POOL) LPCWSTR Pool, _In_z_ LPCWSTR Name, _Ou
|
|||||||
goto cleanupDevInfo;
|
goto cleanupDevInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result = CreateAdapterData(DevInfo, &DevInfoData, Pool, Adapter);
|
Result = CreateAdapterData(Pool, DevInfo, &DevInfoData, Adapter);
|
||||||
goto cleanupDevInfo;
|
goto cleanupDevInfo;
|
||||||
}
|
}
|
||||||
Result = ERROR_FILE_NOT_FOUND;
|
Result = ERROR_FILE_NOT_FOUND;
|
||||||
@ -641,29 +684,29 @@ cleanupMutex:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the Wintun interface.
|
* Returns the name of the Wintun adapter.
|
||||||
*/
|
*/
|
||||||
WINTUN_STATUS WINAPI
|
WINTUN_STATUS WINAPI
|
||||||
WintunGetAdapterName(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_ADAPTER_NAME) LPWSTR Name)
|
WintunGetAdapterName(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_ADAPTER_NAME) WCHAR *Name)
|
||||||
{
|
{
|
||||||
return NciGetConnectionName(&Adapter->CfgInstanceID, Name, MAX_ADAPTER_NAME * sizeof(WCHAR), NULL);
|
return NciGetConnectionName(&Adapter->CfgInstanceID, Name, MAX_ADAPTER_NAME * sizeof(WCHAR), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static WINTUN_STATUS
|
static WINTUN_STATUS
|
||||||
InterfaceGuidFromAlias(_In_z_ LPCWSTR Alias, _Out_ GUID *Guid)
|
ConvertInterfaceAliasToGuid(_In_z_ const WCHAR *Name, _Out_ GUID *Guid)
|
||||||
{
|
{
|
||||||
NET_LUID Luid;
|
NET_LUID Luid;
|
||||||
DWORD Result = ConvertInterfaceAliasToLuid(Alias, &Luid);
|
DWORD Result = ConvertInterfaceAliasToLuid(Name, &Luid);
|
||||||
if (Result != NO_ERROR)
|
if (Result != NO_ERROR)
|
||||||
return Result;
|
return Result;
|
||||||
return ConvertInterfaceLuidToGuid(&Luid, Guid);
|
return ConvertInterfaceLuidToGuid(&Luid, Guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets name of the Wintun interface.
|
* Sets name of the Wintun adapter.
|
||||||
*/
|
*/
|
||||||
WINTUN_STATUS WINAPI
|
WINTUN_STATUS WINAPI
|
||||||
WintunSetAdapterName(_In_ const WINTUN_ADAPTER *Adapter, _In_z_count_c_(MAX_ADAPTER_NAME) LPCWSTR Name)
|
WintunSetAdapterName(_In_ const WINTUN_ADAPTER *Adapter, _In_z_count_c_(MAX_ADAPTER_NAME) const WCHAR *Name)
|
||||||
{
|
{
|
||||||
DWORD Result;
|
DWORD Result;
|
||||||
const int MaxSuffix = 1000;
|
const int MaxSuffix = 1000;
|
||||||
@ -675,7 +718,7 @@ WintunSetAdapterName(_In_ const WINTUN_ADAPTER *Adapter, _In_z_count_c_(MAX_ADAP
|
|||||||
if (Result == ERROR_DUP_NAME)
|
if (Result == ERROR_DUP_NAME)
|
||||||
{
|
{
|
||||||
GUID Guid2;
|
GUID Guid2;
|
||||||
DWORD Result2 = InterfaceGuidFromAlias(AvailableName, &Guid2);
|
DWORD Result2 = ConvertInterfaceAliasToGuid(AvailableName, &Guid2);
|
||||||
if (Result2 == ERROR_SUCCESS)
|
if (Result2 == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < MaxSuffix; ++j)
|
for (int j = 0; j < MaxSuffix; ++j)
|
||||||
@ -725,7 +768,7 @@ WintunSetAdapterName(_In_ const WINTUN_ADAPTER *Adapter, _In_z_count_c_(MAX_ADAP
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the GUID of the interface.
|
* Returns the GUID of the adapter.
|
||||||
*
|
*
|
||||||
* @param Adapter Adapter handle obtained with WintunGetAdapter or WintunCreateAdapter
|
* @param Adapter Adapter handle obtained with WintunGetAdapter or WintunCreateAdapter
|
||||||
*
|
*
|
||||||
@ -738,7 +781,7 @@ WintunGetAdapterGUID(_In_ const WINTUN_ADAPTER *Adapter, _Out_ GUID *Guid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the LUID of the interface.
|
* Returns the LUID of the adapter.
|
||||||
*
|
*
|
||||||
* @param Adapter Adapter handle obtained with WintunGetAdapter or WintunCreateAdapter
|
* @param Adapter Adapter handle obtained with WintunGetAdapter or WintunCreateAdapter
|
||||||
*
|
*
|
||||||
@ -753,6 +796,12 @@ WintunGetAdapterLUID(_In_ const WINTUN_ADAPTER *Adapter, _Out_ LUID *Luid)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a handle to the adapter device object.
|
* Returns a handle to the adapter device object.
|
||||||
|
*
|
||||||
|
* @param Adapter Adapter handle obtained with WintunGetAdapter or WintunCreateAdapter
|
||||||
|
*
|
||||||
|
* @param Handle Pointer to receive the adapter device object handle. Must be released with CloseHandle.
|
||||||
|
*
|
||||||
|
* @return ERROR_SUCCESS on success; Win32 error code otherwise
|
||||||
*/
|
*/
|
||||||
WINTUN_STATUS WINAPI
|
WINTUN_STATUS WINAPI
|
||||||
WintunGetAdapterDeviceObject(_In_ const WINTUN_ADAPTER *Adapter, _Out_ HANDLE *Handle)
|
WintunGetAdapterDeviceObject(_In_ const WINTUN_ADAPTER *Adapter, _Out_ HANDLE *Handle)
|
||||||
@ -766,7 +815,7 @@ WintunGetAdapterDeviceObject(_In_ const WINTUN_ADAPTER *Adapter, _Out_ HANDLE *H
|
|||||||
CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
|
CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
|
||||||
if (Result != CR_SUCCESS)
|
if (Result != CR_SUCCESS)
|
||||||
return Result;
|
return Result;
|
||||||
LPWSTR Interfaces = HeapAlloc(Heap, 0, InterfacesLen * sizeof(WCHAR));
|
WCHAR *Interfaces = HeapAlloc(Heap, 0, InterfacesLen * sizeof(WCHAR));
|
||||||
if (!Interfaces)
|
if (!Interfaces)
|
||||||
return ERROR_OUTOFMEMORY;
|
return ERROR_OUTOFMEMORY;
|
||||||
Result = CM_Get_Device_Interface_ListW(
|
Result = CM_Get_Device_Interface_ListW(
|
||||||
@ -792,21 +841,6 @@ cleanupBuf:
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets device install parameters for a quiet installation.
|
|
||||||
*/
|
|
||||||
static WINTUN_STATUS
|
|
||||||
SetQuietInstall(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData)
|
|
||||||
{
|
|
||||||
SP_DEVINSTALL_PARAMS_W DevInstallParams = { .cbSize = sizeof(SP_DEVINSTALL_PARAMS_W) };
|
|
||||||
if (!SetupDiGetDeviceInstallParamsW(DevInfo, DevInfoData, &DevInstallParams))
|
|
||||||
return GetLastError();
|
|
||||||
DevInstallParams.Flags |= DI_QUIETINSTALL;
|
|
||||||
if (!SetupDiSetDeviceInstallParams(DevInfo, DevInfoData, &DevInstallParams))
|
|
||||||
return GetLastError();
|
|
||||||
return ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return TRUE if DriverData date and version is newer than supplied parameters.
|
* @return TRUE if DriverData date and version is newer than supplied parameters.
|
||||||
*/
|
*/
|
||||||
@ -832,28 +866,15 @@ IsNewer(_In_ const SP_DRVINFO_DATA_W *DriverData, _In_ const FILETIME *DriverDat
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks device install parameters if a system reboot is required.
|
* Creates a Wintun adapter.
|
||||||
*/
|
|
||||||
static BOOL
|
|
||||||
CheckReboot(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData)
|
|
||||||
{
|
|
||||||
SP_DEVINSTALL_PARAMS_W DevInstallParams = { .cbSize = sizeof(SP_DEVINSTALL_PARAMS_W) };
|
|
||||||
if (!SetupDiGetDeviceInstallParamsW(DevInfo, DevInfoData, &DevInstallParams))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return (DevInstallParams.Flags & (DI_NEEDREBOOT | DI_NEEDRESTART)) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Wintun interface.
|
|
||||||
*
|
*
|
||||||
* @param Pool Name of the adapter pool
|
* @param Pool Name of the adapter pool
|
||||||
*
|
*
|
||||||
* @param Name The requested name of the interface
|
* @param Name The requested name of the adapter
|
||||||
*
|
*
|
||||||
* @param RequestedGUID The GUID of the created network interface, which then influences NLA generation
|
* @param RequestedGUID The GUID of the created network adapter, which then influences NLA generation
|
||||||
* deterministically. If it is set to NULL, the GUID is chosen by the system at random, and hence
|
* deterministically. If it is set to NULL, the GUID is chosen by the system at random, and hence
|
||||||
* a new NLA entry is created for each new interface. It is called "requested" GUID because the API
|
* a new NLA entry is created for each new adapter. It is called "requested" GUID because the API
|
||||||
* it uses is completely undocumented, and so there could be minor interesting complications with
|
* it uses is completely undocumented, and so there could be minor interesting complications with
|
||||||
* its usage.
|
* its usage.
|
||||||
*
|
*
|
||||||
@ -867,8 +888,8 @@ CheckReboot(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData)
|
|||||||
*/
|
*/
|
||||||
WINTUN_STATUS WINAPI
|
WINTUN_STATUS WINAPI
|
||||||
WintunCreateAdapter(
|
WintunCreateAdapter(
|
||||||
_In_z_count_c_(MAX_POOL) LPCWSTR Pool,
|
_In_z_count_c_(MAX_POOL) const WCHAR *Pool,
|
||||||
_In_z_ LPCWSTR Name,
|
_In_z_ const WCHAR *Name,
|
||||||
_In_opt_ const GUID *RequestedGUID,
|
_In_opt_ const GUID *RequestedGUID,
|
||||||
_Out_ WINTUN_ADAPTER **Adapter,
|
_Out_ WINTUN_ADAPTER **Adapter,
|
||||||
_Inout_ BOOL *RebootRequired)
|
_Inout_ BOOL *RebootRequired)
|
||||||
@ -1023,7 +1044,7 @@ WintunCreateAdapter(
|
|||||||
|
|
||||||
/* DIF_INSTALLDEVICE returns almost immediately, while the device installation continues in the background. It might
|
/* DIF_INSTALLDEVICE returns almost immediately, while the device installation continues in the background. It might
|
||||||
* take a while, before all registry keys and values are populated. */
|
* take a while, before all registry keys and values are populated. */
|
||||||
LPWSTR DummyStr;
|
WCHAR *DummyStr;
|
||||||
Result = RegistryQueryStringWait(NetDevRegKey, L"NetCfgInstanceId", WAIT_FOR_REGISTRY_TIMEOUT, &DummyStr);
|
Result = RegistryQueryStringWait(NetDevRegKey, L"NetCfgInstanceId", WAIT_FOR_REGISTRY_TIMEOUT, &DummyStr);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
goto cleanupNetDevRegKey;
|
goto cleanupNetDevRegKey;
|
||||||
@ -1036,7 +1057,7 @@ WintunCreateAdapter(
|
|||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
goto cleanupNetDevRegKey;
|
goto cleanupNetDevRegKey;
|
||||||
|
|
||||||
Result = CreateAdapterData(DevInfo, &DevInfoData, Pool, Adapter);
|
Result = CreateAdapterData(Pool, DevInfo, &DevInfoData, Adapter);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
goto cleanupNetDevRegKey;
|
goto cleanupNetDevRegKey;
|
||||||
|
|
||||||
@ -1091,7 +1112,7 @@ cleanupNetDevRegKey:
|
|||||||
cleanupDevice:
|
cleanupDevice:
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
/* The interface failed to install, or the interface ID was unobtainable. Clean-up. */
|
/* The adapter failed to install, or the adapter ID was unobtainable. Clean-up. */
|
||||||
SP_REMOVEDEVICE_PARAMS RemoveDeviceParams = { .ClassInstallHeader = { .cbSize = sizeof(SP_CLASSINSTALL_HEADER),
|
SP_REMOVEDEVICE_PARAMS RemoveDeviceParams = { .ClassInstallHeader = { .cbSize = sizeof(SP_CLASSINSTALL_HEADER),
|
||||||
.InstallFunction = DIF_REMOVE },
|
.InstallFunction = DIF_REMOVE },
|
||||||
.Scope = DI_REMOVEDEVICE_GLOBAL };
|
.Scope = DI_REMOVEDEVICE_GLOBAL };
|
||||||
@ -1110,53 +1131,14 @@ cleanupMutex:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns TUN device info list handle and interface device info data. The device info list handle must be closed after
|
* Deletes a Wintun adapter.
|
||||||
* use. In case the device is not found, ERROR_OBJECT_NOT_FOUND is returned.
|
|
||||||
*/
|
|
||||||
static WINTUN_STATUS
|
|
||||||
GetDevInfoData(_In_ const GUID *CfgInstanceID, _Out_ HDEVINFO *DevInfo, _Out_ SP_DEVINFO_DATA *DevInfoData)
|
|
||||||
{
|
|
||||||
DWORD Result;
|
|
||||||
*DevInfo = SetupDiGetClassDevsExW(&CLASS_NET_GUID, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
|
|
||||||
if (!*DevInfo)
|
|
||||||
return GetLastError();
|
|
||||||
for (DWORD MemberIndex = 0;; ++MemberIndex)
|
|
||||||
{
|
|
||||||
DevInfoData->cbSize = sizeof(SP_DEVINFO_DATA);
|
|
||||||
if (!SetupDiEnumDeviceInfo(*DevInfo, MemberIndex, DevInfoData))
|
|
||||||
{
|
|
||||||
Result = GetLastError();
|
|
||||||
if (Result == ERROR_NO_MORE_ITEMS)
|
|
||||||
break;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
GUID CfgInstanceID2;
|
|
||||||
Result = GetNetCfgInstanceId(*DevInfo, DevInfoData, &CfgInstanceID2);
|
|
||||||
if (Result != ERROR_SUCCESS || memcmp(CfgInstanceID, &CfgInstanceID2, sizeof(GUID)) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Result = SetQuietInstall(*DevInfo, DevInfoData);
|
|
||||||
if (Result != ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
SetupDiDestroyDeviceInfoList(*DevInfo);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
return ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
SetupDiDestroyDeviceInfoList(*DevInfo);
|
|
||||||
return ERROR_OBJECT_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes a Wintun interface.
|
|
||||||
*
|
*
|
||||||
* @param Adapter Adapter handle obtained with WintunGetAdapter or WintunCreateAdapter
|
* @param Adapter Adapter handle obtained with WintunGetAdapter or WintunCreateAdapter
|
||||||
*
|
*
|
||||||
* @param RebootRequired Pointer to a boolean flag to be set to TRUE in case SetupAPI suggests a reboot. Must be
|
* @param RebootRequired Pointer to a boolean flag to be set to TRUE in case SetupAPI suggests a reboot. Must be
|
||||||
* initialised to FALSE manually before this function is called.
|
* initialised to FALSE manually before this function is called.
|
||||||
*
|
*
|
||||||
* @return ERROR_SUCCESS on success; Win32 error code otherwise. This function succeeds if the interface was not found.
|
* @return ERROR_SUCCESS on success; Win32 error code otherwise. This function succeeds if the adapter was not found.
|
||||||
*/
|
*/
|
||||||
WINTUN_STATUS WINAPI
|
WINTUN_STATUS WINAPI
|
||||||
WintunDeleteAdapter(_In_ const WINTUN_ADAPTER *Adapter, _Inout_ BOOL *RebootRequired)
|
WintunDeleteAdapter(_In_ const WINTUN_ADAPTER *Adapter, _Inout_ BOOL *RebootRequired)
|
||||||
@ -1194,7 +1176,7 @@ WintunDeleteAdapter(_In_ const WINTUN_ADAPTER *Adapter, _Inout_ BOOL *RebootRequ
|
|||||||
* @return ERROR_SUCCESS on success; Win32 error code otherwise
|
* @return ERROR_SUCCESS on success; Win32 error code otherwise
|
||||||
*/
|
*/
|
||||||
WINTUN_STATUS WINAPI
|
WINTUN_STATUS WINAPI
|
||||||
WintunEnumAdapters(_In_z_count_c_(MAX_POOL) LPCWSTR Pool, _In_ WINTUN_ENUMPROC Func, _In_ LPARAM Param)
|
WintunEnumAdapters(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_ WINTUN_ENUMPROC Func, _In_ LPARAM Param)
|
||||||
{
|
{
|
||||||
DWORD Result;
|
DWORD Result;
|
||||||
HANDLE Mutex = TakeNameMutex(Pool);
|
HANDLE Mutex = TakeNameMutex(Pool);
|
||||||
@ -1222,7 +1204,7 @@ WintunEnumAdapters(_In_z_count_c_(MAX_POOL) LPCWSTR Pool, _In_ WINTUN_ENUMPROC F
|
|||||||
|
|
||||||
/* Check the Hardware ID to make sure it's a real Wintun device. This avoids doing slow operations on non-Wintun
|
/* Check the Hardware ID to make sure it's a real Wintun device. This avoids doing slow operations on non-Wintun
|
||||||
* devices. */
|
* devices. */
|
||||||
LPWSTR Hwids;
|
WCHAR *Hwids;
|
||||||
Result = GetDeviceRegistryMultiString(DevInfo, &DevInfoData, SPDRP_HARDWAREID, &Hwids);
|
Result = GetDeviceRegistryMultiString(DevInfo, &DevInfoData, SPDRP_HARDWAREID, &Hwids);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
break;
|
break;
|
||||||
@ -1250,7 +1232,7 @@ WintunEnumAdapters(_In_z_count_c_(MAX_POOL) LPCWSTR Pool, _In_ WINTUN_ENUMPROC F
|
|||||||
SetQuietInstall(DevInfo, &DevInfoData); /* Ignore errors */
|
SetQuietInstall(DevInfo, &DevInfoData); /* Ignore errors */
|
||||||
|
|
||||||
WINTUN_ADAPTER *Adapter;
|
WINTUN_ADAPTER *Adapter;
|
||||||
Result = CreateAdapterData(DevInfo, &DevInfoData, Pool, &Adapter);
|
Result = CreateAdapterData(Pool, DevInfo, &DevInfoData, &Adapter);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
break;
|
break;
|
||||||
if (Func(Adapter, Param))
|
if (Func(Adapter, Param))
|
||||||
|
@ -10,10 +10,10 @@ static BOOL HasInitialized = FALSE;
|
|||||||
static CRITICAL_SECTION Initializing;
|
static CRITICAL_SECTION Initializing;
|
||||||
static BCRYPT_ALG_HANDLE AlgProvider;
|
static BCRYPT_ALG_HANDLE AlgProvider;
|
||||||
|
|
||||||
static LPWSTR
|
static WCHAR *
|
||||||
NormalizeStringAlloc(_In_ NORM_FORM NormForm, _In_z_ LPCWSTR Source)
|
NormalizeStringAlloc(_In_ NORM_FORM NormForm, _In_z_ const WCHAR *Source)
|
||||||
{
|
{
|
||||||
LPWSTR Result = NULL;
|
WCHAR *Result = NULL;
|
||||||
HANDLE Heap = GetProcessHeap();
|
HANDLE Heap = GetProcessHeap();
|
||||||
int Len = NormalizeString(NormForm, Source, -1, NULL, 0);
|
int Len = NormalizeString(NormForm, Source, -1, NULL, 0);
|
||||||
for (int i = 0; i < 10; ++i)
|
for (int i = 0; i < 10; ++i)
|
||||||
@ -34,7 +34,7 @@ NormalizeStringAlloc(_In_ NORM_FORM NormForm, _In_z_ LPCWSTR Source)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
Bin2Hex(_In_bytecount_(Size) const void *Source, size_t Size, _Out_capcount_(Size * 2) LPWSTR Destination)
|
Bin2Hex(_In_bytecount_(Size) const void *Source, size_t Size, _Out_capcount_(Size * 2) WCHAR *Destination)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < Size; ++i)
|
for (size_t i = 0; i < Size; ++i)
|
||||||
{
|
{
|
||||||
@ -122,7 +122,7 @@ cleanupLeaveCriticalSection:
|
|||||||
|
|
||||||
_Check_return_
|
_Check_return_
|
||||||
HANDLE
|
HANDLE
|
||||||
TakeNameMutex(_In_z_ LPCWSTR Pool)
|
TakeNameMutex(_In_z_ const WCHAR *Pool)
|
||||||
{
|
{
|
||||||
HANDLE Mutex = NULL;
|
HANDLE Mutex = NULL;
|
||||||
|
|
||||||
@ -137,7 +137,7 @@ TakeNameMutex(_In_z_ LPCWSTR Pool)
|
|||||||
static const char mutex_label[] = "WireGuard Adapter Name Mutex Stable Suffix v1 jason@zx2c4.com";
|
static const char mutex_label[] = "WireGuard Adapter Name Mutex Stable Suffix v1 jason@zx2c4.com";
|
||||||
if (!BCRYPT_SUCCESS(BCryptHashData(Sha256, (PUCHAR)mutex_label, sizeof(mutex_label) - sizeof(char), 0)))
|
if (!BCRYPT_SUCCESS(BCryptHashData(Sha256, (PUCHAR)mutex_label, sizeof(mutex_label) - sizeof(char), 0)))
|
||||||
goto cleanupSha256;
|
goto cleanupSha256;
|
||||||
LPWSTR PoolNorm = NormalizeStringAlloc(NormalizationC, Pool);
|
WCHAR *PoolNorm = NormalizeStringAlloc(NormalizationC, Pool);
|
||||||
if (!PoolNorm)
|
if (!PoolNorm)
|
||||||
goto cleanupSha256;
|
goto cleanupSha256;
|
||||||
/* TODO: wireguard-go hashes UTF-8 normalized pool name. We hash UTF-16 here. */
|
/* TODO: wireguard-go hashes UTF-8 normalized pool name. We hash UTF-16 here. */
|
||||||
|
11
api/nci.c
11
api/nci.c
@ -7,11 +7,11 @@
|
|||||||
|
|
||||||
static HMODULE NciModule;
|
static HMODULE NciModule;
|
||||||
|
|
||||||
DWORD(WINAPI *NciSetConnectionName)(_In_ LPCGUID Guid, _In_z_ LPCWSTR NewName);
|
DWORD(WINAPI *NciSetConnectionName)(_In_ const GUID *Guid, _In_z_ const WCHAR *NewName);
|
||||||
|
|
||||||
DWORD(WINAPI *NciGetConnectionName)
|
DWORD(WINAPI *NciGetConnectionName)
|
||||||
(_In_ LPCGUID Guid,
|
(_In_ const GUID *Guid,
|
||||||
_Out_z_bytecap_(InDestNameBytes) LPWSTR Name,
|
_Out_z_bytecap_(InDestNameBytes) WCHAR *Name,
|
||||||
_In_ DWORD InDestNameBytes,
|
_In_ DWORD InDestNameBytes,
|
||||||
_Out_opt_ DWORD *OutDestNameBytes);
|
_Out_opt_ DWORD *OutDestNameBytes);
|
||||||
|
|
||||||
@ -21,9 +21,10 @@ NciInit()
|
|||||||
NciModule = LoadLibraryW(L"nci.dll");
|
NciModule = LoadLibraryW(L"nci.dll");
|
||||||
if (!NciModule)
|
if (!NciModule)
|
||||||
return;
|
return;
|
||||||
NciSetConnectionName = (DWORD(WINAPI *)(LPCGUID, LPCWSTR))GetProcAddress(NciModule, "NciSetConnectionName");
|
NciSetConnectionName =
|
||||||
|
(DWORD(WINAPI *)(const GUID *, const WCHAR *))GetProcAddress(NciModule, "NciSetConnectionName");
|
||||||
NciGetConnectionName =
|
NciGetConnectionName =
|
||||||
(DWORD(WINAPI *)(LPCGUID, LPWSTR, DWORD, DWORD *))GetProcAddress(NciModule, "NciGetConnectionName");
|
(DWORD(WINAPI *)(const GUID *, WCHAR *, DWORD, DWORD *))GetProcAddress(NciModule, "NciGetConnectionName");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
|
||||||
static WINTUN_STATUS
|
static WINTUN_STATUS
|
||||||
OpenKeyWait(_In_ HKEY Key, _Inout_z_ LPWSTR Path, _In_ DWORD Access, _In_ ULONGLONG Deadline, _Out_ HKEY *KeyOut)
|
OpenKeyWait(_In_ HKEY Key, _Inout_z_ WCHAR *Path, _In_ DWORD Access, _In_ ULONGLONG Deadline, _Out_ HKEY *KeyOut)
|
||||||
{
|
{
|
||||||
DWORD Result;
|
DWORD Result;
|
||||||
LPWSTR PathNext = wcschr(Path, L'\\');
|
WCHAR *PathNext = wcschr(Path, L'\\');
|
||||||
if (PathNext)
|
if (PathNext)
|
||||||
*PathNext = 0;
|
*PathNext = 0;
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ OpenKeyWait(_In_ HKEY Key, _Inout_z_ LPWSTR Path, _In_ DWORD Access, _In_ ULONGL
|
|||||||
WINTUN_STATUS
|
WINTUN_STATUS
|
||||||
RegistryOpenKeyWait(
|
RegistryOpenKeyWait(
|
||||||
_In_ HKEY Key,
|
_In_ HKEY Key,
|
||||||
_In_z_count_c_(MAX_PATH) LPCWSTR Path,
|
_In_z_count_c_(MAX_PATH) const WCHAR *Path,
|
||||||
_In_ DWORD Access,
|
_In_ DWORD Access,
|
||||||
_In_ DWORD Timeout,
|
_In_ DWORD Timeout,
|
||||||
_Out_ HKEY *KeyOut)
|
_Out_ HKEY *KeyOut)
|
||||||
@ -77,7 +77,7 @@ RegistryOpenKeyWait(
|
|||||||
}
|
}
|
||||||
|
|
||||||
WINTUN_STATUS
|
WINTUN_STATUS
|
||||||
RegistryWaitForKey(_In_ HKEY Key, _In_z_count_c_(MAX_PATH) LPCWSTR Path, _In_ DWORD Timeout)
|
RegistryWaitForKey(_In_ HKEY Key, _In_z_count_c_(MAX_PATH) const WCHAR *Path, _In_ DWORD Timeout)
|
||||||
{
|
{
|
||||||
HKEY k;
|
HKEY k;
|
||||||
DWORD Result = RegistryOpenKeyWait(Key, Path, KEY_NOTIFY, Timeout, &k);
|
DWORD Result = RegistryOpenKeyWait(Key, Path, KEY_NOTIFY, Timeout, &k);
|
||||||
@ -103,14 +103,14 @@ RegistryWaitForKey(_In_ HKEY Key, _In_z_count_c_(MAX_PATH) LPCWSTR Path, _In_ DW
|
|||||||
* @return ERROR_SUCCESS on success; Win32 error code otherwise
|
* @return ERROR_SUCCESS on success; Win32 error code otherwise
|
||||||
*/
|
*/
|
||||||
WINTUN_STATUS
|
WINTUN_STATUS
|
||||||
RegistryGetString(_Inout_ LPWSTR *Buf, _In_ DWORD Len, _In_ DWORD ValueType)
|
RegistryGetString(_Inout_ WCHAR **Buf, _In_ DWORD Len, _In_ DWORD ValueType)
|
||||||
{
|
{
|
||||||
HANDLE Heap = GetProcessHeap();
|
HANDLE Heap = GetProcessHeap();
|
||||||
|
|
||||||
if (wcsnlen(*Buf, Len) >= Len)
|
if (wcsnlen(*Buf, Len) >= Len)
|
||||||
{
|
{
|
||||||
/* String is missing zero-terminator. */
|
/* String is missing zero-terminator. */
|
||||||
LPWSTR BufZ = HeapAlloc(Heap, 0, ((size_t)Len + 1) * sizeof(WCHAR));
|
WCHAR *BufZ = HeapAlloc(Heap, 0, ((size_t)Len + 1) * sizeof(WCHAR));
|
||||||
if (!BufZ)
|
if (!BufZ)
|
||||||
return ERROR_OUTOFMEMORY;
|
return ERROR_OUTOFMEMORY;
|
||||||
wmemcpy(BufZ, *Buf, Len);
|
wmemcpy(BufZ, *Buf, Len);
|
||||||
@ -130,7 +130,7 @@ RegistryGetString(_Inout_ LPWSTR *Buf, _In_ DWORD Len, _In_ DWORD ValueType)
|
|||||||
Len = Len * 2 + 64;
|
Len = Len * 2 + 64;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
LPWSTR Expanded = HeapAlloc(Heap, 0, Len * sizeof(WCHAR));
|
WCHAR *Expanded = HeapAlloc(Heap, 0, Len * sizeof(WCHAR));
|
||||||
if (!Expanded)
|
if (!Expanded)
|
||||||
return ERROR_OUTOFMEMORY;
|
return ERROR_OUTOFMEMORY;
|
||||||
DWORD Result = ExpandEnvironmentStringsW(*Buf, Expanded, Len);
|
DWORD Result = ExpandEnvironmentStringsW(*Buf, Expanded, Len);
|
||||||
@ -167,7 +167,7 @@ RegistryGetString(_Inout_ LPWSTR *Buf, _In_ DWORD Len, _In_ DWORD ValueType)
|
|||||||
* @return ERROR_SUCCESS on success; Win32 error code otherwise
|
* @return ERROR_SUCCESS on success; Win32 error code otherwise
|
||||||
*/
|
*/
|
||||||
WINTUN_STATUS
|
WINTUN_STATUS
|
||||||
RegistryGetMultiString(_Inout_ LPWSTR *Buf, _In_ DWORD Len, _In_ DWORD ValueType)
|
RegistryGetMultiString(_Inout_ WCHAR **Buf, _In_ DWORD Len, _In_ DWORD ValueType)
|
||||||
{
|
{
|
||||||
HANDLE Heap = GetProcessHeap();
|
HANDLE Heap = GetProcessHeap();
|
||||||
|
|
||||||
@ -178,7 +178,7 @@ RegistryGetMultiString(_Inout_ LPWSTR *Buf, _In_ DWORD Len, _In_ DWORD ValueType
|
|||||||
if (i > Len)
|
if (i > Len)
|
||||||
{
|
{
|
||||||
/* Missing string and list terminators. */
|
/* Missing string and list terminators. */
|
||||||
LPWSTR BufZ = HeapAlloc(Heap, 0, ((size_t)Len + 2) * sizeof(WCHAR));
|
WCHAR *BufZ = HeapAlloc(Heap, 0, ((size_t)Len + 2) * sizeof(WCHAR));
|
||||||
if (!BufZ)
|
if (!BufZ)
|
||||||
return ERROR_OUTOFMEMORY;
|
return ERROR_OUTOFMEMORY;
|
||||||
wmemcpy(BufZ, *Buf, Len);
|
wmemcpy(BufZ, *Buf, Len);
|
||||||
@ -191,7 +191,7 @@ RegistryGetMultiString(_Inout_ LPWSTR *Buf, _In_ DWORD Len, _In_ DWORD ValueType
|
|||||||
if (i == Len)
|
if (i == Len)
|
||||||
{
|
{
|
||||||
/* Missing list terminator. */
|
/* Missing list terminator. */
|
||||||
LPWSTR BufZ = HeapAlloc(Heap, 0, ((size_t)Len + 1) * sizeof(WCHAR));
|
WCHAR *BufZ = HeapAlloc(Heap, 0, ((size_t)Len + 1) * sizeof(WCHAR));
|
||||||
if (!BufZ)
|
if (!BufZ)
|
||||||
return ERROR_OUTOFMEMORY;
|
return ERROR_OUTOFMEMORY;
|
||||||
wmemcpy(BufZ, *Buf, Len);
|
wmemcpy(BufZ, *Buf, Len);
|
||||||
@ -210,7 +210,7 @@ RegistryGetMultiString(_Inout_ LPWSTR *Buf, _In_ DWORD Len, _In_ DWORD ValueType
|
|||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
return Result;
|
return Result;
|
||||||
Len = (DWORD)wcslen(*Buf) + 1;
|
Len = (DWORD)wcslen(*Buf) + 1;
|
||||||
LPWSTR BufZ = HeapAlloc(Heap, 0, ((size_t)Len + 1) * sizeof(WCHAR));
|
WCHAR *BufZ = HeapAlloc(Heap, 0, ((size_t)Len + 1) * sizeof(WCHAR));
|
||||||
if (!BufZ)
|
if (!BufZ)
|
||||||
return ERROR_OUTOFMEMORY;
|
return ERROR_OUTOFMEMORY;
|
||||||
wmemcpy(BufZ, *Buf, Len);
|
wmemcpy(BufZ, *Buf, Len);
|
||||||
@ -242,7 +242,7 @@ RegistryGetMultiString(_Inout_ LPWSTR *Buf, _In_ DWORD Len, _In_ DWORD ValueType
|
|||||||
static WINTUN_STATUS
|
static WINTUN_STATUS
|
||||||
RegistryQuery(
|
RegistryQuery(
|
||||||
_In_ HKEY Key,
|
_In_ HKEY Key,
|
||||||
_In_opt_z_ LPCWSTR Name,
|
_In_opt_z_ const WCHAR *Name,
|
||||||
_Out_opt_ DWORD *ValueType,
|
_Out_opt_ DWORD *ValueType,
|
||||||
_Out_ void **Buf,
|
_Out_ void **Buf,
|
||||||
_Inout_ DWORD *BufLen)
|
_Inout_ DWORD *BufLen)
|
||||||
@ -278,7 +278,7 @@ RegistryQuery(
|
|||||||
* @return ERROR_SUCCESS on success; Win32 error code otherwise
|
* @return ERROR_SUCCESS on success; Win32 error code otherwise
|
||||||
*/
|
*/
|
||||||
WINTUN_STATUS
|
WINTUN_STATUS
|
||||||
RegistryQueryString(_In_ HKEY Key, _In_opt_z_ LPCWSTR Name, _Out_ LPWSTR *Value)
|
RegistryQueryString(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _Out_ WCHAR **Value)
|
||||||
{
|
{
|
||||||
DWORD ValueType, Size = 256 * sizeof(WCHAR);
|
DWORD ValueType, Size = 256 * sizeof(WCHAR);
|
||||||
DWORD Result = RegistryQuery(Key, Name, &ValueType, Value, &Size);
|
DWORD Result = RegistryQuery(Key, Name, &ValueType, Value, &Size);
|
||||||
@ -317,7 +317,7 @@ RegistryQueryString(_In_ HKEY Key, _In_opt_z_ LPCWSTR Name, _Out_ LPWSTR *Value)
|
|||||||
* @return ERROR_SUCCESS on success; Win32 error code otherwise
|
* @return ERROR_SUCCESS on success; Win32 error code otherwise
|
||||||
*/
|
*/
|
||||||
WINTUN_STATUS
|
WINTUN_STATUS
|
||||||
RegistryQueryStringWait(_In_ HKEY Key, _In_opt_z_ LPCWSTR Name, _In_ DWORD Timeout, _Out_ LPWSTR *Value)
|
RegistryQueryStringWait(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _In_ DWORD Timeout, _Out_ WCHAR **Value)
|
||||||
{
|
{
|
||||||
DWORD Result;
|
DWORD Result;
|
||||||
ULONGLONG Deadline = GetTickCount64() + Timeout;
|
ULONGLONG Deadline = GetTickCount64() + Timeout;
|
||||||
@ -355,7 +355,7 @@ RegistryQueryStringWait(_In_ HKEY Key, _In_opt_z_ LPCWSTR Name, _In_ DWORD Timeo
|
|||||||
* @return ERROR_SUCCESS on success; Win32 error code otherwise
|
* @return ERROR_SUCCESS on success; Win32 error code otherwise
|
||||||
*/
|
*/
|
||||||
WINTUN_STATUS
|
WINTUN_STATUS
|
||||||
RegistryQueryDWORD(_In_ HKEY Key, _In_opt_z_ LPCWSTR Name, _Out_ DWORD *Value)
|
RegistryQueryDWORD(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _Out_ DWORD *Value)
|
||||||
{
|
{
|
||||||
DWORD ValueType, Size = sizeof(DWORD);
|
DWORD ValueType, Size = sizeof(DWORD);
|
||||||
DWORD Result = RegQueryValueExW(Key, Name, NULL, &ValueType, (BYTE *)Value, &Size);
|
DWORD Result = RegQueryValueExW(Key, Name, NULL, &ValueType, (BYTE *)Value, &Size);
|
||||||
@ -383,7 +383,7 @@ RegistryQueryDWORD(_In_ HKEY Key, _In_opt_z_ LPCWSTR Name, _Out_ DWORD *Value)
|
|||||||
* @return ERROR_SUCCESS on success; Win32 error code otherwise
|
* @return ERROR_SUCCESS on success; Win32 error code otherwise
|
||||||
*/
|
*/
|
||||||
WINTUN_STATUS
|
WINTUN_STATUS
|
||||||
RegistryQueryDWORDWait(_In_ HKEY Key, _In_opt_z_ LPCWSTR Name, _In_ DWORD Timeout, _Out_ DWORD *Value)
|
RegistryQueryDWORDWait(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _In_ DWORD Timeout, _Out_ DWORD *Value)
|
||||||
{
|
{
|
||||||
DWORD Result;
|
DWORD Result;
|
||||||
ULONGLONG Deadline = GetTickCount64() + Timeout;
|
ULONGLONG Deadline = GetTickCount64() + Timeout;
|
||||||
|
Loading…
Reference in New Issue
Block a user