api: introduce logging
And other unifications with installer before merging. Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
parent
abd20337e2
commit
f316c13b3e
13
api/api.c
13
api/api.c
@ -31,17 +31,28 @@ WintunGetVersion(
|
|||||||
DWORD Result =
|
DWORD Result =
|
||||||
RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Wintun", 0, KEY_QUERY_VALUE, &Key);
|
RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Wintun", 0, KEY_QUERY_VALUE, &Key);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
return Result;
|
return WINTUN_LOGGER_ERROR(L"Failed to open registry key", Result);
|
||||||
Result = RegistryQueryDWORD(Key, L"DriverMajorVersion", DriverVersionMaj);
|
Result = RegistryQueryDWORD(Key, L"DriverMajorVersion", DriverVersionMaj);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to query DriverMajorVersion value", Result);
|
||||||
goto cleanupKey;
|
goto cleanupKey;
|
||||||
|
}
|
||||||
Result = RegistryQueryDWORD(Key, L"DriverMinorVersion", DriverVersionMin);
|
Result = RegistryQueryDWORD(Key, L"DriverMinorVersion", DriverVersionMin);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to query DriverMinorVersion value", Result);
|
||||||
goto cleanupKey;
|
goto cleanupKey;
|
||||||
|
}
|
||||||
Result = RegistryQueryDWORD(Key, L"NdisMajorVersion", NdisVersionMaj);
|
Result = RegistryQueryDWORD(Key, L"NdisMajorVersion", NdisVersionMaj);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to query NdisMajorVersion value", Result);
|
||||||
goto cleanupKey;
|
goto cleanupKey;
|
||||||
|
}
|
||||||
Result = RegistryQueryDWORD(Key, L"NdisMinorVersion", NdisVersionMin);
|
Result = RegistryQueryDWORD(Key, L"NdisMinorVersion", NdisVersionMin);
|
||||||
|
if (Result != ERROR_SUCCESS)
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to query NdisMinorVersion value", Result);
|
||||||
cleanupKey:
|
cleanupKey:
|
||||||
RegCloseKey(Key);
|
RegCloseKey(Key);
|
||||||
return Result;
|
return Result;
|
||||||
|
@ -7,6 +7,13 @@
|
|||||||
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
|
||||||
|
#ifndef __L
|
||||||
|
# define __L(x) L##x
|
||||||
|
#endif
|
||||||
|
#ifndef _L
|
||||||
|
# define _L(x) __L(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef _Return_type_success_(return == ERROR_SUCCESS) DWORD WINTUN_STATUS;
|
typedef _Return_type_success_(return == ERROR_SUCCESS) DWORD WINTUN_STATUS;
|
||||||
|
|
||||||
extern HINSTANCE ResourceModule;
|
extern HINSTANCE ResourceModule;
|
||||||
|
@ -187,6 +187,8 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="api.h" />
|
<ClInclude Include="api.h" />
|
||||||
<ClInclude Include="devmgmt.h" />
|
<ClInclude Include="devmgmt.h" />
|
||||||
|
<ClInclude Include="driver.h" />
|
||||||
|
<ClInclude Include="logger.h" />
|
||||||
<ClInclude Include="namespace.h" />
|
<ClInclude Include="namespace.h" />
|
||||||
<ClInclude Include="nci.h" />
|
<ClInclude Include="nci.h" />
|
||||||
<ClInclude Include="pch.h" />
|
<ClInclude Include="pch.h" />
|
||||||
@ -195,6 +197,8 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="api.c" />
|
<ClCompile Include="api.c" />
|
||||||
<ClCompile Include="devmgmt.c" />
|
<ClCompile Include="devmgmt.c" />
|
||||||
|
<ClCompile Include="driver.c" />
|
||||||
|
<ClCompile Include="logger.c" />
|
||||||
<ClCompile Include="namespace.c" />
|
<ClCompile Include="namespace.c" />
|
||||||
<ClCompile Include="nci.c" />
|
<ClCompile Include="nci.c" />
|
||||||
<ClCompile Include="pch.c">
|
<ClCompile Include="pch.c">
|
||||||
|
@ -43,6 +43,12 @@
|
|||||||
<ClInclude Include="devmgmt.h">
|
<ClInclude Include="devmgmt.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="logger.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="driver.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="api.c">
|
<ClCompile Include="api.c">
|
||||||
@ -66,5 +72,11 @@
|
|||||||
<ClCompile Include="pch.c">
|
<ClCompile Include="pch.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="logger.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="driver.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
368
api/devmgmt.c
368
api/devmgmt.c
@ -9,12 +9,6 @@
|
|||||||
#define WAIT_FOR_REGISTRY_TIMEOUT 10000 /* ms */
|
#define WAIT_FOR_REGISTRY_TIMEOUT 10000 /* ms */
|
||||||
#define MAX_POOL_DEVICE_TYPE (MAX_POOL + 8) /* Should accommodate a pool name with " Tunnel" appended */
|
#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 ADAPTER_NET_GUID = { 0xcac88484L,
|
|
||||||
0x7515,
|
|
||||||
0x4c03,
|
|
||||||
{ 0x82, 0xe6, 0x71, 0xa8, 0x7a, 0xba, 0xc3, 0x61 } };
|
|
||||||
|
|
||||||
static _locale_t Locale;
|
static _locale_t Locale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,7 +52,7 @@ GetDeviceRegistryProperty(
|
|||||||
DWORD Result = GetLastError();
|
DWORD Result = GetLastError();
|
||||||
HeapFree(Heap, 0, *Buf);
|
HeapFree(Heap, 0, *Buf);
|
||||||
if (Result != ERROR_INSUFFICIENT_BUFFER)
|
if (Result != ERROR_INSUFFICIENT_BUFFER)
|
||||||
return Result;
|
return WINTUN_LOGGER_ERROR(L"Querying property failed", Result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,6 +92,7 @@ GetDeviceRegistryString(
|
|||||||
HeapFree(GetProcessHeap(), 0, *Buf);
|
HeapFree(GetProcessHeap(), 0, *Buf);
|
||||||
return Result;
|
return Result;
|
||||||
default:
|
default:
|
||||||
|
WINTUN_LOGGER(WINTUN_LOG_ERR, L"Property is not a string");
|
||||||
HeapFree(GetProcessHeap(), 0, *Buf);
|
HeapFree(GetProcessHeap(), 0, *Buf);
|
||||||
return ERROR_INVALID_DATATYPE;
|
return ERROR_INVALID_DATATYPE;
|
||||||
}
|
}
|
||||||
@ -139,52 +134,12 @@ GetDeviceRegistryMultiString(
|
|||||||
HeapFree(GetProcessHeap(), 0, *Buf);
|
HeapFree(GetProcessHeap(), 0, *Buf);
|
||||||
return Result;
|
return Result;
|
||||||
default:
|
default:
|
||||||
|
WINTUN_LOGGER(WINTUN_LOG_ERR, L"Property is not a string");
|
||||||
HeapFree(GetProcessHeap(), 0, *Buf);
|
HeapFree(GetProcessHeap(), 0, *Buf);
|
||||||
return ERROR_INVALID_DATATYPE;
|
return ERROR_INVALID_DATATYPE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves driver information detail for a device information set or a particular device information element in the
|
|
||||||
* device information set.
|
|
||||||
*
|
|
||||||
* @param DevInfo A handle to the device information set that contains a device information element that
|
|
||||||
* represents the device for which to open a registry key.
|
|
||||||
*
|
|
||||||
* @param DevInfoData A pointer to a structure that specifies the device information element in DevInfo.
|
|
||||||
*
|
|
||||||
* @param DriverData A pointer to a structure that specifies the driver information element that represents the
|
|
||||||
* driver for which to retrieve details.
|
|
||||||
*
|
|
||||||
* @param DriverDetailData A pointer to a structure that receives detailed information about the specified driver.
|
|
||||||
* Must be released with HeapFree(GetProcessHeap(), 0, *DriverDetailData) after use.
|
|
||||||
*
|
|
||||||
* @return ERROR_SUCCESS on success; Win32 error code otherwise.
|
|
||||||
*/
|
|
||||||
static WINTUN_STATUS
|
|
||||||
GetDriverInfoDetail(
|
|
||||||
_In_ HDEVINFO DevInfo,
|
|
||||||
_In_ SP_DEVINFO_DATA *DevInfoData,
|
|
||||||
_In_ SP_DRVINFO_DATA_W *DriverData,
|
|
||||||
_Out_ SP_DRVINFO_DETAIL_DATA_W **DriverDetailData)
|
|
||||||
{
|
|
||||||
HANDLE Heap = GetProcessHeap();
|
|
||||||
DWORD Size = sizeof(SP_DRVINFO_DETAIL_DATA_W) + 0x100;
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
*DriverDetailData = HeapAlloc(Heap, 0, Size);
|
|
||||||
if (!*DriverDetailData)
|
|
||||||
return ERROR_OUTOFMEMORY;
|
|
||||||
(*DriverDetailData)->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA_W);
|
|
||||||
if (SetupDiGetDriverInfoDetailW(DevInfo, DevInfoData, DriverData, *DriverDetailData, Size, &Size))
|
|
||||||
return ERROR_SUCCESS;
|
|
||||||
DWORD Result = GetLastError();
|
|
||||||
HeapFree(Heap, 0, *DriverDetailData);
|
|
||||||
if (Result != ERROR_INSUFFICIENT_BUFFER)
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests if any of the hardware IDs match ours.
|
* Tests if any of the hardware IDs match ours.
|
||||||
*
|
*
|
||||||
@ -201,42 +156,6 @@ IsOurHardwareID(_In_z_ WCHAR *Hwids)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the device is using Wintun driver.
|
|
||||||
*/
|
|
||||||
static WINTUN_STATUS
|
|
||||||
IsUsingOurDriver(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData, _Out_ BOOL *IsOurDriver)
|
|
||||||
{
|
|
||||||
if (!SetupDiBuildDriverInfoList(DevInfo, DevInfoData, SPDIT_COMPATDRIVER))
|
|
||||||
return GetLastError();
|
|
||||||
*IsOurDriver = FALSE;
|
|
||||||
HANDLE Heap = GetProcessHeap();
|
|
||||||
for (DWORD DriverIndex = 0;; ++DriverIndex)
|
|
||||||
{
|
|
||||||
SP_DRVINFO_DATA_W DriverData = { .cbSize = sizeof(SP_DRVINFO_DATA_W) };
|
|
||||||
if (!SetupDiEnumDriverInfoW(DevInfo, DevInfoData, SPDIT_COMPATDRIVER, DriverIndex, &DriverData))
|
|
||||||
{
|
|
||||||
if (GetLastError() == ERROR_NO_MORE_ITEMS)
|
|
||||||
break;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SP_DRVINFO_DETAIL_DATA_W *DriverDetailData;
|
|
||||||
if (GetDriverInfoDetail(DevInfo, DevInfoData, &DriverData, &DriverDetailData) != ERROR_SUCCESS)
|
|
||||||
continue;
|
|
||||||
if (DriverDetailData->CompatIDsOffset > 1 && !_wcsicmp(DriverDetailData->HardwareID, WINTUN_HWID) ||
|
|
||||||
DriverDetailData->CompatIDsLength &&
|
|
||||||
IsOurHardwareID(DriverDetailData->HardwareID + DriverDetailData->CompatIDsOffset))
|
|
||||||
{
|
|
||||||
HeapFree(Heap, 0, DriverDetailData);
|
|
||||||
*IsOurDriver = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
HeapFree(Heap, 0, DriverDetailData);
|
|
||||||
}
|
|
||||||
SetupDiDestroyDriverInfoList(DevInfo, DevInfoData, SPDIT_COMPATDRIVER);
|
|
||||||
return ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks device install parameters if a system reboot is required.
|
* Checks device install parameters if a system reboot is required.
|
||||||
*/
|
*/
|
||||||
@ -245,7 +164,10 @@ CheckReboot(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData)
|
|||||||
{
|
{
|
||||||
SP_DEVINSTALL_PARAMS_W DevInstallParams = { .cbSize = sizeof(SP_DEVINSTALL_PARAMS_W) };
|
SP_DEVINSTALL_PARAMS_W DevInstallParams = { .cbSize = sizeof(SP_DEVINSTALL_PARAMS_W) };
|
||||||
if (!SetupDiGetDeviceInstallParamsW(DevInfo, DevInfoData, &DevInstallParams))
|
if (!SetupDiGetDeviceInstallParamsW(DevInfo, DevInfoData, &DevInstallParams))
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_LAST_ERROR(L"Retrieving device installation parameters failed");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
return (DevInstallParams.Flags & (DI_NEEDREBOOT | DI_NEEDRESTART)) != 0;
|
return (DevInstallParams.Flags & (DI_NEEDREBOOT | DI_NEEDRESTART)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,10 +179,10 @@ SetQuietInstall(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData)
|
|||||||
{
|
{
|
||||||
SP_DEVINSTALL_PARAMS_W DevInstallParams = { .cbSize = sizeof(SP_DEVINSTALL_PARAMS_W) };
|
SP_DEVINSTALL_PARAMS_W DevInstallParams = { .cbSize = sizeof(SP_DEVINSTALL_PARAMS_W) };
|
||||||
if (!SetupDiGetDeviceInstallParamsW(DevInfo, DevInfoData, &DevInstallParams))
|
if (!SetupDiGetDeviceInstallParamsW(DevInfo, DevInfoData, &DevInstallParams))
|
||||||
return GetLastError();
|
return WINTUN_LOGGER_LAST_ERROR(L"Retrieving device installation parameters failed");
|
||||||
DevInstallParams.Flags |= DI_QUIETINSTALL;
|
DevInstallParams.Flags |= DI_QUIETINSTALL;
|
||||||
if (!SetupDiSetDeviceInstallParamsW(DevInfo, DevInfoData, &DevInstallParams))
|
if (!SetupDiSetDeviceInstallParamsW(DevInfo, DevInfoData, &DevInstallParams))
|
||||||
return GetLastError();
|
return WINTUN_LOGGER_LAST_ERROR(L"Setting device installation parameters failed");
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,12 +203,21 @@ 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 WINTUN_LOGGER_LAST_ERROR(L"Opening device registry key failed");
|
||||||
WCHAR *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)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to query NetCfgInstanceId value", Result);
|
||||||
goto cleanupKey;
|
goto cleanupKey;
|
||||||
Result = SUCCEEDED(CLSIDFromString(ValueStr, CfgInstanceID)) ? ERROR_SUCCESS : ERROR_INVALID_DATA;
|
}
|
||||||
|
if (FAILED(CLSIDFromString(ValueStr, CfgInstanceID)))
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER(WINTUN_LOG_ERR, L"NetCfgInstanceId is not a GUID");
|
||||||
|
Result = ERROR_INVALID_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Result = ERROR_SUCCESS;
|
||||||
HeapFree(GetProcessHeap(), 0, ValueStr);
|
HeapFree(GetProcessHeap(), 0, ValueStr);
|
||||||
cleanupKey:
|
cleanupKey:
|
||||||
RegCloseKey(Key);
|
RegCloseKey(Key);
|
||||||
@ -310,13 +241,13 @@ cleanupKey:
|
|||||||
static WINTUN_STATUS
|
static WINTUN_STATUS
|
||||||
GetDevInfoData(_In_ const GUID *CfgInstanceID, _Out_ HDEVINFO *DevInfo, _Out_ SP_DEVINFO_DATA *DevInfoData)
|
GetDevInfoData(_In_ const GUID *CfgInstanceID, _Out_ HDEVINFO *DevInfo, _Out_ SP_DEVINFO_DATA *DevInfoData)
|
||||||
{
|
{
|
||||||
*DevInfo = SetupDiGetClassDevsExW(&CLASS_NET_GUID, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
|
*DevInfo = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
|
||||||
if (!*DevInfo)
|
if (!*DevInfo)
|
||||||
return GetLastError();
|
return WINTUN_LOGGER_LAST_ERROR(L"Failed to get present class devices");
|
||||||
for (DWORD MemberIndex = 0;; ++MemberIndex)
|
for (DWORD EnumIndex = 0;; ++EnumIndex)
|
||||||
{
|
{
|
||||||
DevInfoData->cbSize = sizeof(SP_DEVINFO_DATA);
|
DevInfoData->cbSize = sizeof(SP_DEVINFO_DATA);
|
||||||
if (!SetupDiEnumDeviceInfo(*DevInfo, MemberIndex, DevInfoData))
|
if (!SetupDiEnumDeviceInfo(*DevInfo, EnumIndex, DevInfoData))
|
||||||
{
|
{
|
||||||
if (GetLastError() == ERROR_NO_MORE_ITEMS)
|
if (GetLastError() == ERROR_NO_MORE_ITEMS)
|
||||||
break;
|
break;
|
||||||
@ -381,10 +312,16 @@ IsPoolMember(
|
|||||||
WCHAR *DeviceDesc, *FriendlyName;
|
WCHAR *DeviceDesc, *FriendlyName;
|
||||||
DWORD Result = GetDeviceRegistryString(DevInfo, DevInfoData, SPDRP_DEVICEDESC, &DeviceDesc);
|
DWORD Result = GetDeviceRegistryString(DevInfo, DevInfoData, SPDRP_DEVICEDESC, &DeviceDesc);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to query device description property", Result);
|
||||||
return Result;
|
return Result;
|
||||||
|
}
|
||||||
Result = GetDeviceRegistryString(DevInfo, DevInfoData, SPDRP_FRIENDLYNAME, &FriendlyName);
|
Result = GetDeviceRegistryString(DevInfo, DevInfoData, SPDRP_FRIENDLYNAME, &FriendlyName);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to query friendly name property", Result);
|
||||||
goto cleanupDeviceDesc;
|
goto cleanupDeviceDesc;
|
||||||
|
}
|
||||||
WCHAR PoolDeviceTypeName[MAX_POOL_DEVICE_TYPE];
|
WCHAR PoolDeviceTypeName[MAX_POOL_DEVICE_TYPE];
|
||||||
GetPoolDeviceTypeName(Pool, PoolDeviceTypeName);
|
GetPoolDeviceTypeName(Pool, PoolDeviceTypeName);
|
||||||
if (!_wcsicmp_l(FriendlyName, PoolDeviceTypeName, Locale) || !_wcsicmp_l(DeviceDesc, PoolDeviceTypeName, Locale))
|
if (!_wcsicmp_l(FriendlyName, PoolDeviceTypeName, Locale) || !_wcsicmp_l(DeviceDesc, PoolDeviceTypeName, Locale))
|
||||||
@ -435,7 +372,7 @@ CreateAdapterData(
|
|||||||
/* Open HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\<class>\<id> registry key. */
|
/* Open HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\<class>\<id> registry key. */
|
||||||
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 WINTUN_LOGGER_LAST_ERROR(L"Opening device registry key failed");
|
||||||
|
|
||||||
HANDLE Heap = GetProcessHeap();
|
HANDLE Heap = GetProcessHeap();
|
||||||
*Adapter = HeapAlloc(Heap, 0, sizeof(WINTUN_ADAPTER));
|
*Adapter = HeapAlloc(Heap, 0, sizeof(WINTUN_ADAPTER));
|
||||||
@ -449,30 +386,40 @@ CreateAdapterData(
|
|||||||
WCHAR *ValueStr;
|
WCHAR *ValueStr;
|
||||||
Result = RegistryQueryString(Key, L"NetCfgInstanceId", &ValueStr);
|
Result = RegistryQueryString(Key, L"NetCfgInstanceId", &ValueStr);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to query NetCfgInstanceId value", Result);
|
||||||
goto cleanupAdapter;
|
goto cleanupAdapter;
|
||||||
|
}
|
||||||
if (FAILED(CLSIDFromString(ValueStr, &(*Adapter)->CfgInstanceID)))
|
if (FAILED(CLSIDFromString(ValueStr, &(*Adapter)->CfgInstanceID)))
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, ValueStr);
|
WINTUN_LOGGER(WINTUN_LOG_ERR, L"NetCfgInstanceId is not a GUID");
|
||||||
|
HeapFree(Heap, 0, ValueStr);
|
||||||
Result = ERROR_INVALID_DATA;
|
Result = ERROR_INVALID_DATA;
|
||||||
goto cleanupAdapter;
|
goto cleanupAdapter;
|
||||||
}
|
}
|
||||||
HeapFree(GetProcessHeap(), 0, ValueStr);
|
HeapFree(Heap, 0, ValueStr);
|
||||||
|
|
||||||
/* Read the NetLuidIndex value. */
|
/* Read the NetLuidIndex value. */
|
||||||
Result = RegistryQueryDWORD(Key, L"NetLuidIndex", &(*Adapter)->LuidIndex);
|
Result = RegistryQueryDWORD(Key, L"NetLuidIndex", &(*Adapter)->LuidIndex);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to query NetLuidIndex value", Result);
|
||||||
goto cleanupAdapter;
|
goto cleanupAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
/* Read the NetLuidIndex value. */
|
/* Read the NetLuidIndex value. */
|
||||||
Result = RegistryQueryDWORD(Key, L"*IfType", &(*Adapter)->IfType);
|
Result = RegistryQueryDWORD(Key, L"*IfType", &(*Adapter)->IfType);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to query *IfType value", Result);
|
||||||
goto cleanupAdapter;
|
goto cleanupAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
DWORD Size;
|
DWORD Size;
|
||||||
if (!SetupDiGetDeviceInstanceIdW(
|
if (!SetupDiGetDeviceInstanceIdW(
|
||||||
DevInfo, DevInfoData, (*Adapter)->DevInstanceID, _countof((*Adapter)->DevInstanceID), &Size))
|
DevInfo, DevInfoData, (*Adapter)->DevInstanceID, _countof((*Adapter)->DevInstanceID), &Size))
|
||||||
{
|
{
|
||||||
Result = GetLastError();
|
Result = WINTUN_LOGGER_LAST_ERROR(L"Failed to get device instance ID");
|
||||||
goto cleanupAdapter;
|
goto cleanupAdapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -530,13 +477,17 @@ GetTcpipInterfaceRegPath(_In_ const WINTUN_ADAPTER *Adapter, _Out_cap_c_(MAX_REG
|
|||||||
GetTcpipAdapterRegPath(Adapter, TcpipAdapterRegPath);
|
GetTcpipAdapterRegPath(Adapter, TcpipAdapterRegPath);
|
||||||
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 WINTUN_LOGGER_ERROR(L"Failed to open registry key", Result);
|
||||||
WCHAR *Paths;
|
WCHAR *Paths;
|
||||||
Result = RegistryQueryString(TcpipAdapterRegKey, L"IpConfig", &Paths);
|
Result = RegistryQueryString(TcpipAdapterRegKey, L"IpConfig", &Paths);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to query IpConfig value", Result);
|
||||||
goto cleanupTcpipAdapterRegKey;
|
goto cleanupTcpipAdapterRegKey;
|
||||||
|
}
|
||||||
if (!Paths[0])
|
if (!Paths[0])
|
||||||
{
|
{
|
||||||
|
WINTUN_LOGGER(WINTUN_LOG_ERR, L"IpConfig is empty");
|
||||||
Result = ERROR_INVALID_DATA;
|
Result = ERROR_INVALID_DATA;
|
||||||
goto cleanupPaths;
|
goto cleanupPaths;
|
||||||
}
|
}
|
||||||
@ -582,18 +533,18 @@ WintunGetAdapter(
|
|||||||
if (!Mutex)
|
if (!Mutex)
|
||||||
return ERROR_INVALID_HANDLE;
|
return ERROR_INVALID_HANDLE;
|
||||||
|
|
||||||
HDEVINFO DevInfo = SetupDiGetClassDevsExW(&CLASS_NET_GUID, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
|
HDEVINFO DevInfo = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
|
||||||
if (DevInfo == INVALID_HANDLE_VALUE)
|
if (DevInfo == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
Result = GetLastError();
|
Result = WINTUN_LOGGER_LAST_ERROR(L"Failed to get present class devices");
|
||||||
goto cleanupMutex;
|
goto cleanupMutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE Heap = GetProcessHeap();
|
HANDLE Heap = GetProcessHeap();
|
||||||
for (DWORD MemberIndex = 0;; ++MemberIndex)
|
for (DWORD EnumIndex = 0;; ++EnumIndex)
|
||||||
{
|
{
|
||||||
SP_DEVINFO_DATA DevInfoData = { .cbSize = sizeof(SP_DEVINFO_DATA) };
|
SP_DEVINFO_DATA DevInfoData = { .cbSize = sizeof(SP_DEVINFO_DATA) };
|
||||||
if (!SetupDiEnumDeviceInfo(DevInfo, MemberIndex, &DevInfoData))
|
if (!SetupDiEnumDeviceInfo(DevInfo, EnumIndex, &DevInfoData))
|
||||||
{
|
{
|
||||||
if (GetLastError() == ERROR_NO_MORE_ITEMS)
|
if (GetLastError() == ERROR_NO_MORE_ITEMS)
|
||||||
break;
|
break;
|
||||||
@ -621,7 +572,10 @@ WintunGetAdapter(
|
|||||||
WCHAR *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)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to query hardware ID", Result);
|
||||||
goto cleanupDevInfo;
|
goto cleanupDevInfo;
|
||||||
|
}
|
||||||
if (!IsOurHardwareID(Hwids))
|
if (!IsOurHardwareID(Hwids))
|
||||||
{
|
{
|
||||||
HeapFree(Heap, 0, Hwids);
|
HeapFree(Heap, 0, Hwids);
|
||||||
@ -630,11 +584,7 @@ WintunGetAdapter(
|
|||||||
}
|
}
|
||||||
HeapFree(Heap, 0, Hwids);
|
HeapFree(Heap, 0, Hwids);
|
||||||
|
|
||||||
BOOL IsOurDriver;
|
if (!DriverIsWintunAdapter(DevInfo, &DevInfoData))
|
||||||
Result = IsUsingOurDriver(DevInfo, &DevInfoData, &IsOurDriver);
|
|
||||||
if (Result != ERROR_SUCCESS)
|
|
||||||
goto cleanupDevInfo;
|
|
||||||
if (!IsOurDriver)
|
|
||||||
{
|
{
|
||||||
Result = ERROR_ALREADY_EXISTS;
|
Result = ERROR_ALREADY_EXISTS;
|
||||||
goto cleanupDevInfo;
|
goto cleanupDevInfo;
|
||||||
@ -643,7 +593,10 @@ WintunGetAdapter(
|
|||||||
BOOL IsMember;
|
BOOL IsMember;
|
||||||
Result = IsPoolMember(Pool, DevInfo, &DevInfoData, &IsMember);
|
Result = IsPoolMember(Pool, DevInfo, &DevInfoData, &IsMember);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to determine pool membership", Result);
|
||||||
goto cleanupDevInfo;
|
goto cleanupDevInfo;
|
||||||
|
}
|
||||||
if (!IsMember)
|
if (!IsMember)
|
||||||
{
|
{
|
||||||
Result = ERROR_ALREADY_EXISTS;
|
Result = ERROR_ALREADY_EXISTS;
|
||||||
@ -651,6 +604,9 @@ WintunGetAdapter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result = CreateAdapterData(Pool, DevInfo, &DevInfoData, Adapter);
|
Result = CreateAdapterData(Pool, DevInfo, &DevInfoData, Adapter);
|
||||||
|
if (Result != ERROR_SUCCESS)
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to create adapter data", Result);
|
||||||
|
|
||||||
goto cleanupDevInfo;
|
goto cleanupDevInfo;
|
||||||
}
|
}
|
||||||
Result = ERROR_FILE_NOT_FOUND;
|
Result = ERROR_FILE_NOT_FOUND;
|
||||||
@ -676,7 +632,7 @@ ConvertInterfaceAliasToGuid(_In_z_ const WCHAR *Name, _Out_ GUID *Guid)
|
|||||||
NET_LUID Luid;
|
NET_LUID Luid;
|
||||||
DWORD Result = ConvertInterfaceAliasToLuid(Name, &Luid);
|
DWORD Result = ConvertInterfaceAliasToLuid(Name, &Luid);
|
||||||
if (Result != NO_ERROR)
|
if (Result != NO_ERROR)
|
||||||
return Result;
|
return WINTUN_LOGGER_ERROR(L"Failed convert interface alias name to the locally unique identifier", Result);
|
||||||
return ConvertInterfaceLuidToGuid(&Luid, Guid);
|
return ConvertInterfaceLuidToGuid(&Luid, Guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -721,7 +677,7 @@ WintunSetAdapterName(_In_ const WINTUN_ADAPTER *Adapter, _In_z_count_c_(MAX_ADAP
|
|||||||
if (Result == ERROR_SUCCESS)
|
if (Result == ERROR_SUCCESS)
|
||||||
break;
|
break;
|
||||||
if (i > MaxSuffix || Result != ERROR_DUP_NAME)
|
if (i > MaxSuffix || Result != ERROR_DUP_NAME)
|
||||||
return Result;
|
return WINTUN_LOGGER_ERROR(L"Setting adapter name failed", Result);
|
||||||
_snwprintf_s(AvailableName, _countof(AvailableName), _TRUNCATE, L"%.*s %d", MAX_ADAPTER_NAME, Name, i + 1);
|
_snwprintf_s(AvailableName, _countof(AvailableName), _TRUNCATE, L"%.*s %d", MAX_ADAPTER_NAME, Name, i + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -731,7 +687,7 @@ WintunSetAdapterName(_In_ const WINTUN_ADAPTER *Adapter, _In_z_count_c_(MAX_ADAP
|
|||||||
GetDeviceRegPath(Adapter, DeviceRegPath);
|
GetDeviceRegPath(Adapter, DeviceRegPath);
|
||||||
Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, DeviceRegPath, 0, KEY_SET_VALUE, &DeviceRegKey);
|
Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, DeviceRegPath, 0, KEY_SET_VALUE, &DeviceRegKey);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
return Result;
|
return WINTUN_LOGGER_ERROR(L"Failed to open registry key", Result);
|
||||||
WCHAR PoolDeviceTypeName[MAX_POOL_DEVICE_TYPE];
|
WCHAR PoolDeviceTypeName[MAX_POOL_DEVICE_TYPE];
|
||||||
GetPoolDeviceTypeName(Adapter->Pool, PoolDeviceTypeName);
|
GetPoolDeviceTypeName(Adapter->Pool, PoolDeviceTypeName);
|
||||||
Result = RegSetKeyValueW(
|
Result = RegSetKeyValueW(
|
||||||
@ -784,60 +740,29 @@ WintunGetAdapterLUID(_In_ const WINTUN_ADAPTER *Adapter, _Out_ LUID *Luid)
|
|||||||
WINTUN_STATUS WINAPI
|
WINTUN_STATUS WINAPI
|
||||||
WintunGetAdapterDeviceObject(_In_ const WINTUN_ADAPTER *Adapter, _Out_ HANDLE *Handle)
|
WintunGetAdapterDeviceObject(_In_ const WINTUN_ADAPTER *Adapter, _Out_ HANDLE *Handle)
|
||||||
{
|
{
|
||||||
HANDLE Heap = GetProcessHeap();
|
*Handle = DriverGetAdapterDeviceObject(Adapter->DevInstanceID);
|
||||||
ULONG InterfacesLen;
|
return *Handle != INVALID_HANDLE_VALUE ? ERROR_SUCCESS : GetLastError();
|
||||||
DWORD Result = CM_Get_Device_Interface_List_SizeW(
|
|
||||||
&InterfacesLen,
|
|
||||||
(GUID *)&ADAPTER_NET_GUID,
|
|
||||||
(DEVINSTID_W)Adapter->DevInstanceID,
|
|
||||||
CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
|
|
||||||
if (Result != CR_SUCCESS)
|
|
||||||
return Result;
|
|
||||||
WCHAR *Interfaces = HeapAlloc(Heap, 0, InterfacesLen * sizeof(WCHAR));
|
|
||||||
if (!Interfaces)
|
|
||||||
return ERROR_OUTOFMEMORY;
|
|
||||||
Result = CM_Get_Device_Interface_ListW(
|
|
||||||
(GUID *)&ADAPTER_NET_GUID,
|
|
||||||
(DEVINSTID_W)Adapter->DevInstanceID,
|
|
||||||
Interfaces,
|
|
||||||
InterfacesLen,
|
|
||||||
CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
|
|
||||||
if (Result != CR_SUCCESS)
|
|
||||||
goto cleanupBuf;
|
|
||||||
*Handle = CreateFileW(
|
|
||||||
Interfaces,
|
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
|
||||||
NULL,
|
|
||||||
OPEN_EXISTING,
|
|
||||||
0,
|
|
||||||
NULL);
|
|
||||||
if (*Handle == INVALID_HANDLE_VALUE)
|
|
||||||
Result = GetLastError();
|
|
||||||
cleanupBuf:
|
|
||||||
HeapFree(Heap, 0, Interfaces);
|
|
||||||
return Result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return TRUE if DriverData date and version is newer than supplied parameters.
|
* @return TRUE if DrvInfoData date and version is newer than supplied parameters.
|
||||||
*/
|
*/
|
||||||
static BOOL
|
static BOOL
|
||||||
IsNewer(_In_ const SP_DRVINFO_DATA_W *DriverData, _In_ const FILETIME *DriverDate, _In_ DWORDLONG DriverVersion)
|
IsNewer(_In_ const SP_DRVINFO_DATA_W *DrvInfoData, _In_ const FILETIME *DriverDate, _In_ DWORDLONG DriverVersion)
|
||||||
{
|
{
|
||||||
if (DriverData->DriverDate.dwHighDateTime > DriverDate->dwHighDateTime)
|
if (DrvInfoData->DriverDate.dwHighDateTime > DriverDate->dwHighDateTime)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if (DriverData->DriverDate.dwHighDateTime < DriverDate->dwHighDateTime)
|
if (DrvInfoData->DriverDate.dwHighDateTime < DriverDate->dwHighDateTime)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (DriverData->DriverDate.dwLowDateTime > DriverDate->dwLowDateTime)
|
if (DrvInfoData->DriverDate.dwLowDateTime > DriverDate->dwLowDateTime)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if (DriverData->DriverDate.dwLowDateTime < DriverDate->dwLowDateTime)
|
if (DrvInfoData->DriverDate.dwLowDateTime < DriverDate->dwLowDateTime)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (DriverData->DriverVersion > DriverVersion)
|
if (DrvInfoData->DriverVersion > DriverVersion)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if (DriverData->DriverVersion < DriverVersion)
|
if (DrvInfoData->DriverVersion < DriverVersion)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -877,17 +802,17 @@ WintunCreateAdapter(
|
|||||||
if (!Mutex)
|
if (!Mutex)
|
||||||
return ERROR_INVALID_HANDLE;
|
return ERROR_INVALID_HANDLE;
|
||||||
|
|
||||||
HDEVINFO DevInfo = SetupDiCreateDeviceInfoListExW(&CLASS_NET_GUID, NULL, NULL, NULL);
|
HDEVINFO DevInfo = SetupDiCreateDeviceInfoListExW(&GUID_DEVCLASS_NET, NULL, NULL, NULL);
|
||||||
if (DevInfo == INVALID_HANDLE_VALUE)
|
if (DevInfo == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
Result = GetLastError();
|
Result = WINTUN_LOGGER_LAST_ERROR(L"Creating empty device information set failed");
|
||||||
goto cleanupMutex;
|
goto cleanupMutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
WCHAR ClassName[MAX_CLASS_NAME_LEN];
|
WCHAR ClassName[MAX_CLASS_NAME_LEN];
|
||||||
if (!SetupDiClassNameFromGuidExW(&CLASS_NET_GUID, ClassName, _countof(ClassName), NULL, NULL, NULL))
|
if (!SetupDiClassNameFromGuidExW(&GUID_DEVCLASS_NET, ClassName, _countof(ClassName), NULL, NULL, NULL))
|
||||||
{
|
{
|
||||||
Result = GetLastError();
|
Result = WINTUN_LOGGER_LAST_ERROR(L"Retrieving class name associated with class GUID failed");
|
||||||
goto cleanupDevInfo;
|
goto cleanupDevInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -896,39 +821,37 @@ WintunCreateAdapter(
|
|||||||
GetPoolDeviceTypeName(Pool, PoolDeviceTypeName);
|
GetPoolDeviceTypeName(Pool, PoolDeviceTypeName);
|
||||||
SP_DEVINFO_DATA DevInfoData = { .cbSize = sizeof(SP_DEVINFO_DATA) };
|
SP_DEVINFO_DATA DevInfoData = { .cbSize = sizeof(SP_DEVINFO_DATA) };
|
||||||
if (!SetupDiCreateDeviceInfoW(
|
if (!SetupDiCreateDeviceInfoW(
|
||||||
DevInfo, ClassName, &CLASS_NET_GUID, PoolDeviceTypeName, NULL, DICD_GENERATE_ID, &DevInfoData))
|
DevInfo, ClassName, &GUID_DEVCLASS_NET, PoolDeviceTypeName, NULL, DICD_GENERATE_ID, &DevInfoData))
|
||||||
{
|
{
|
||||||
Result = GetLastError();
|
Result = WINTUN_LOGGER_LAST_ERROR(L"Creating new device information element failed");
|
||||||
goto cleanupDevInfo;
|
goto cleanupDevInfo;
|
||||||
}
|
}
|
||||||
Result = SetQuietInstall(DevInfo, &DevInfoData);
|
SetQuietInstall(DevInfo, &DevInfoData);
|
||||||
if (Result != ERROR_SUCCESS)
|
|
||||||
goto cleanupDevInfo;
|
|
||||||
|
|
||||||
if (!SetupDiSetSelectedDevice(DevInfo, &DevInfoData))
|
if (!SetupDiSetSelectedDevice(DevInfo, &DevInfoData))
|
||||||
{
|
{
|
||||||
Result = GetLastError();
|
Result = WINTUN_LOGGER_LAST_ERROR(L"Failed selecting device");
|
||||||
goto cleanupDevInfo;
|
goto cleanupDevInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const WCHAR Hwids[_countof(WINTUN_HWID) + 1 /*Multi-string terminator*/] = WINTUN_HWID;
|
static const WCHAR Hwids[_countof(WINTUN_HWID) + 1 /*Multi-string terminator*/] = WINTUN_HWID;
|
||||||
if (!SetupDiSetDeviceRegistryPropertyW(DevInfo, &DevInfoData, SPDRP_HARDWAREID, (const BYTE *)Hwids, sizeof(Hwids)))
|
if (!SetupDiSetDeviceRegistryPropertyW(DevInfo, &DevInfoData, SPDRP_HARDWAREID, (const BYTE *)Hwids, sizeof(Hwids)))
|
||||||
{
|
{
|
||||||
Result = GetLastError();
|
Result = WINTUN_LOGGER_LAST_ERROR(L"Failed setting hardware ID");
|
||||||
goto cleanupDevInfo;
|
goto cleanupDevInfo;
|
||||||
}
|
}
|
||||||
if (!SetupDiBuildDriverInfoList(DevInfo, &DevInfoData, SPDIT_COMPATDRIVER)) /* TODO: This takes ~510ms */
|
if (!SetupDiBuildDriverInfoList(DevInfo, &DevInfoData, SPDIT_COMPATDRIVER)) /* TODO: This takes ~510ms */
|
||||||
{
|
{
|
||||||
Result = GetLastError();
|
Result = WINTUN_LOGGER_LAST_ERROR(L"Failed building driver info list");
|
||||||
goto cleanupDevInfo;
|
goto cleanupDevInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILETIME DriverDate = { 0, 0 };
|
FILETIME DriverDate = { 0, 0 };
|
||||||
DWORDLONG DriverVersion = 0;
|
DWORDLONG DriverVersion = 0;
|
||||||
for (DWORD DriverIndex = 0;; ++DriverIndex) /* TODO: This loop takes ~600ms */
|
for (DWORD EnumIndex = 0;; ++EnumIndex) /* TODO: This loop takes ~600ms */
|
||||||
{
|
{
|
||||||
SP_DRVINFO_DATA_W DriverData = { .cbSize = sizeof(SP_DRVINFO_DATA_W) };
|
SP_DRVINFO_DATA_W DrvInfoData = { .cbSize = sizeof(SP_DRVINFO_DATA_W) };
|
||||||
if (!SetupDiEnumDriverInfoW(DevInfo, &DevInfoData, SPDIT_COMPATDRIVER, DriverIndex, &DriverData))
|
if (!SetupDiEnumDriverInfoW(DevInfo, &DevInfoData, SPDIT_COMPATDRIVER, EnumIndex, &DrvInfoData))
|
||||||
{
|
{
|
||||||
if (GetLastError() == ERROR_NO_MORE_ITEMS)
|
if (GetLastError() == ERROR_NO_MORE_ITEMS)
|
||||||
break;
|
break;
|
||||||
@ -937,40 +860,42 @@ WintunCreateAdapter(
|
|||||||
|
|
||||||
/* Check the driver version first, since the check is trivial and will save us iterating over hardware IDs for
|
/* Check the driver version first, since the check is trivial and will save us iterating over hardware IDs for
|
||||||
* any driver versioned prior our best match. */
|
* any driver versioned prior our best match. */
|
||||||
if (!IsNewer(&DriverData, &DriverDate, DriverVersion))
|
if (!IsNewer(&DrvInfoData, &DriverDate, DriverVersion))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SP_DRVINFO_DETAIL_DATA_W *DriverDetailData;
|
SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData = DriverGetDrvInfoDetail(DevInfo, &DevInfoData, &DrvInfoData);
|
||||||
if (GetDriverInfoDetail(DevInfo, &DevInfoData, &DriverData, &DriverDetailData) != ERROR_SUCCESS)
|
if (!DrvInfoDetailData)
|
||||||
continue;
|
continue;
|
||||||
if ((DriverDetailData->CompatIDsOffset <= 1 || _wcsicmp(DriverDetailData->HardwareID, WINTUN_HWID)) &&
|
if ((DrvInfoDetailData->CompatIDsOffset <= 1 || _wcsicmp(DrvInfoDetailData->HardwareID, WINTUN_HWID)) &&
|
||||||
(!DriverDetailData->CompatIDsLength ||
|
(!DrvInfoDetailData->CompatIDsLength ||
|
||||||
!IsOurHardwareID(DriverDetailData->HardwareID + DriverDetailData->CompatIDsOffset)))
|
!IsOurHardwareID(DrvInfoDetailData->HardwareID + DrvInfoDetailData->CompatIDsOffset)))
|
||||||
{
|
{
|
||||||
HeapFree(Heap, 0, DriverDetailData);
|
HeapFree(Heap, 0, DrvInfoDetailData);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
HeapFree(Heap, 0, DriverDetailData);
|
HeapFree(Heap, 0, DrvInfoDetailData);
|
||||||
|
|
||||||
if (!SetupDiSetSelectedDriverW(DevInfo, &DevInfoData, &DriverData))
|
if (!SetupDiSetSelectedDriverW(DevInfo, &DevInfoData, &DrvInfoData))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
DriverDate = DriverData.DriverDate;
|
DriverDate = DrvInfoData.DriverDate;
|
||||||
DriverVersion = DriverData.DriverVersion;
|
DriverVersion = DrvInfoData.DriverVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!DriverVersion)
|
if (!DriverVersion)
|
||||||
{
|
{
|
||||||
|
WINTUN_LOGGER(WINTUN_LOG_ERR, L"No appropriate drivers found");
|
||||||
Result = ERROR_FILE_NOT_FOUND;
|
Result = ERROR_FILE_NOT_FOUND;
|
||||||
goto cleanupDriverInfoList;
|
goto cleanupDriverInfoList;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, DevInfo, &DevInfoData))
|
if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, DevInfo, &DevInfoData))
|
||||||
{
|
{
|
||||||
Result = GetLastError();
|
Result = WINTUN_LOGGER_LAST_ERROR(L"Registering device failed");
|
||||||
goto cleanupDevice;
|
goto cleanupDevice;
|
||||||
}
|
}
|
||||||
SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS, DevInfo, &DevInfoData); /* Ignore errors */
|
if (!SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS, DevInfo, &DevInfoData))
|
||||||
|
WINTUN_LOGGER_LAST_ERROR(L"Registering coinstallers failed");
|
||||||
|
|
||||||
HKEY NetDevRegKey = INVALID_HANDLE_VALUE;
|
HKEY NetDevRegKey = INVALID_HANDLE_VALUE;
|
||||||
const int PollTimeout = 50 /* ms */;
|
const int PollTimeout = 50 /* ms */;
|
||||||
@ -983,7 +908,7 @@ WintunCreateAdapter(
|
|||||||
}
|
}
|
||||||
if (NetDevRegKey == INVALID_HANDLE_VALUE)
|
if (NetDevRegKey == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
Result = GetLastError();
|
Result = WINTUN_LOGGER_LAST_ERROR(L"Failed to open device-specific registry key");
|
||||||
goto cleanupDevice;
|
goto cleanupDevice;
|
||||||
}
|
}
|
||||||
if (RequestedGUID)
|
if (RequestedGUID)
|
||||||
@ -997,14 +922,18 @@ WintunCreateAdapter(
|
|||||||
(const BYTE *)RequestedGUIDStr,
|
(const BYTE *)RequestedGUIDStr,
|
||||||
StringFromGUID2(RequestedGUID, RequestedGUIDStr, _countof(RequestedGUIDStr)) * sizeof(WCHAR));
|
StringFromGUID2(RequestedGUID, RequestedGUIDStr, _countof(RequestedGUIDStr)) * sizeof(WCHAR));
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_LAST_ERROR(L"Failed to set NetSetupAnticipatedInstanceId");
|
||||||
goto cleanupNetDevRegKey;
|
goto cleanupNetDevRegKey;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetupDiCallClassInstaller(DIF_INSTALLINTERFACES, DevInfo, &DevInfoData); /* Ignore errors */
|
if (!SetupDiCallClassInstaller(DIF_INSTALLINTERFACES, DevInfo, &DevInfoData))
|
||||||
|
WINTUN_LOGGER_LAST_ERROR(L"Installing interfaces failed");
|
||||||
|
|
||||||
if (!SetupDiCallClassInstaller(DIF_INSTALLDEVICE, DevInfo, &DevInfoData))
|
if (!SetupDiCallClassInstaller(DIF_INSTALLDEVICE, DevInfo, &DevInfoData))
|
||||||
{
|
{
|
||||||
Result = GetLastError();
|
Result = WINTUN_LOGGER_LAST_ERROR(L"Installing device failed");
|
||||||
goto cleanupNetDevRegKey;
|
goto cleanupNetDevRegKey;
|
||||||
}
|
}
|
||||||
*RebootRequired = *RebootRequired || CheckReboot(DevInfo, &DevInfoData);
|
*RebootRequired = *RebootRequired || CheckReboot(DevInfo, &DevInfoData);
|
||||||
@ -1016,7 +945,7 @@ WintunCreateAdapter(
|
|||||||
(const BYTE *)PoolDeviceTypeName,
|
(const BYTE *)PoolDeviceTypeName,
|
||||||
(DWORD)((wcslen(PoolDeviceTypeName) + 1) * sizeof(WCHAR))))
|
(DWORD)((wcslen(PoolDeviceTypeName) + 1) * sizeof(WCHAR))))
|
||||||
{
|
{
|
||||||
Result = GetLastError();
|
Result = WINTUN_LOGGER_LAST_ERROR(L"Failed to set device description");
|
||||||
goto cleanupNetDevRegKey;
|
goto cleanupNetDevRegKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1025,19 +954,31 @@ WintunCreateAdapter(
|
|||||||
WCHAR *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)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to query NetCfgInstanceId value", Result);
|
||||||
goto cleanupNetDevRegKey;
|
goto cleanupNetDevRegKey;
|
||||||
|
}
|
||||||
HeapFree(Heap, 0, DummyStr);
|
HeapFree(Heap, 0, DummyStr);
|
||||||
DWORD DummyDWORD;
|
DWORD DummyDWORD;
|
||||||
Result = RegistryQueryDWORDWait(NetDevRegKey, L"NetLuidIndex", WAIT_FOR_REGISTRY_TIMEOUT, &DummyDWORD);
|
Result = RegistryQueryDWORDWait(NetDevRegKey, L"NetLuidIndex", WAIT_FOR_REGISTRY_TIMEOUT, &DummyDWORD);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to query NetLuidIndex value", Result);
|
||||||
goto cleanupNetDevRegKey;
|
goto cleanupNetDevRegKey;
|
||||||
|
}
|
||||||
Result = RegistryQueryDWORDWait(NetDevRegKey, L"*IfType", WAIT_FOR_REGISTRY_TIMEOUT, &DummyDWORD);
|
Result = RegistryQueryDWORDWait(NetDevRegKey, L"*IfType", WAIT_FOR_REGISTRY_TIMEOUT, &DummyDWORD);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to query *IfType value", Result);
|
||||||
goto cleanupNetDevRegKey;
|
goto cleanupNetDevRegKey;
|
||||||
|
}
|
||||||
|
|
||||||
Result = CreateAdapterData(Pool, DevInfo, &DevInfoData, Adapter);
|
Result = CreateAdapterData(Pool, DevInfo, &DevInfoData, Adapter);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to create adapter data", Result);
|
||||||
goto cleanupNetDevRegKey;
|
goto cleanupNetDevRegKey;
|
||||||
|
}
|
||||||
|
|
||||||
HKEY TcpipAdapterRegKey;
|
HKEY TcpipAdapterRegKey;
|
||||||
WCHAR TcpipAdapterRegPath[MAX_REG_PATH];
|
WCHAR TcpipAdapterRegPath[MAX_REG_PATH];
|
||||||
@ -1049,17 +990,26 @@ WintunCreateAdapter(
|
|||||||
WAIT_FOR_REGISTRY_TIMEOUT,
|
WAIT_FOR_REGISTRY_TIMEOUT,
|
||||||
&TcpipAdapterRegKey);
|
&TcpipAdapterRegKey);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to open adapter-specific TCP/IP adapter registry key", Result);
|
||||||
goto cleanupAdapter;
|
goto cleanupAdapter;
|
||||||
|
}
|
||||||
Result = RegistryQueryStringWait(TcpipAdapterRegKey, L"IpConfig", WAIT_FOR_REGISTRY_TIMEOUT, &DummyStr);
|
Result = RegistryQueryStringWait(TcpipAdapterRegKey, L"IpConfig", WAIT_FOR_REGISTRY_TIMEOUT, &DummyStr);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to query IpConfig value", Result);
|
||||||
goto cleanupTcpipAdapterRegKey;
|
goto cleanupTcpipAdapterRegKey;
|
||||||
|
}
|
||||||
HeapFree(Heap, 0, DummyStr);
|
HeapFree(Heap, 0, DummyStr);
|
||||||
|
|
||||||
HKEY TcpipInterfaceRegKey;
|
HKEY TcpipInterfaceRegKey;
|
||||||
WCHAR TcpipInterfaceRegPath[MAX_REG_PATH];
|
WCHAR TcpipInterfaceRegPath[MAX_REG_PATH];
|
||||||
Result = GetTcpipInterfaceRegPath(*Adapter, TcpipInterfaceRegPath);
|
Result = GetTcpipInterfaceRegPath(*Adapter, TcpipInterfaceRegPath);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to determine interface-specific TCP/IP network registry key path", Result);
|
||||||
goto cleanupTcpipAdapterRegKey;
|
goto cleanupTcpipAdapterRegKey;
|
||||||
|
}
|
||||||
Result = RegistryOpenKeyWait(
|
Result = RegistryOpenKeyWait(
|
||||||
HKEY_LOCAL_MACHINE,
|
HKEY_LOCAL_MACHINE,
|
||||||
TcpipInterfaceRegPath,
|
TcpipInterfaceRegPath,
|
||||||
@ -1067,18 +1017,25 @@ WintunCreateAdapter(
|
|||||||
WAIT_FOR_REGISTRY_TIMEOUT,
|
WAIT_FOR_REGISTRY_TIMEOUT,
|
||||||
&TcpipInterfaceRegKey);
|
&TcpipInterfaceRegKey);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to open interface-specific TCP/IP network registry key", Result);
|
||||||
goto cleanupTcpipAdapterRegKey;
|
goto cleanupTcpipAdapterRegKey;
|
||||||
|
}
|
||||||
|
|
||||||
const static DWORD EnableDeadGWDetect = 0;
|
const static DWORD EnableDeadGWDetect = 0;
|
||||||
RegSetKeyValueW(
|
Result = RegSetKeyValueW(
|
||||||
TcpipInterfaceRegKey,
|
TcpipInterfaceRegKey,
|
||||||
NULL,
|
NULL,
|
||||||
L"EnableDeadGWDetect",
|
L"EnableDeadGWDetect",
|
||||||
REG_DWORD,
|
REG_DWORD,
|
||||||
&EnableDeadGWDetect,
|
&EnableDeadGWDetect,
|
||||||
sizeof(EnableDeadGWDetect)); /* Ignore errors */
|
sizeof(EnableDeadGWDetect));
|
||||||
|
if (Result != ERROR_SUCCESS)
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to set EnableDeadGWDetect", Result);
|
||||||
|
|
||||||
Result = WintunSetAdapterName(*Adapter, Name);
|
Result = WintunSetAdapterName(*Adapter, Name);
|
||||||
|
if (Result != ERROR_SUCCESS)
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to set adapter name", Result);
|
||||||
RegCloseKey(TcpipInterfaceRegKey);
|
RegCloseKey(TcpipInterfaceRegKey);
|
||||||
cleanupTcpipAdapterRegKey:
|
cleanupTcpipAdapterRegKey:
|
||||||
RegCloseKey(TcpipAdapterRegKey);
|
RegCloseKey(TcpipAdapterRegKey);
|
||||||
@ -1127,10 +1084,11 @@ WintunDeleteAdapter(_In_ const WINTUN_ADAPTER *Adapter, _Inout_ BOOL *RebootRequ
|
|||||||
if (Result == ERROR_FILE_NOT_FOUND)
|
if (Result == ERROR_FILE_NOT_FOUND)
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to get device info data", Result);
|
||||||
return Result;
|
return Result;
|
||||||
Result = SetQuietInstall(DevInfo, &DevInfoData);
|
}
|
||||||
if (Result != ERROR_SUCCESS)
|
SetQuietInstall(DevInfo, &DevInfoData);
|
||||||
goto cleanupDevInfo;
|
|
||||||
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 };
|
||||||
@ -1139,8 +1097,7 @@ WintunDeleteAdapter(_In_ const WINTUN_ADAPTER *Adapter, _Inout_ BOOL *RebootRequ
|
|||||||
SetupDiCallClassInstaller(DIF_REMOVE, DevInfo, &DevInfoData))
|
SetupDiCallClassInstaller(DIF_REMOVE, DevInfo, &DevInfoData))
|
||||||
*RebootRequired = *RebootRequired || CheckReboot(DevInfo, &DevInfoData);
|
*RebootRequired = *RebootRequired || CheckReboot(DevInfo, &DevInfoData);
|
||||||
else
|
else
|
||||||
Result = GetLastError();
|
Result = WINTUN_LOGGER_LAST_ERROR(L"Unable to remove existing adapter");
|
||||||
cleanupDevInfo:
|
|
||||||
SetupDiDestroyDeviceInfoList(DevInfo);
|
SetupDiDestroyDeviceInfoList(DevInfo);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
@ -1164,17 +1121,17 @@ WintunEnumAdapters(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_ WINTUN_ENUMP
|
|||||||
HANDLE Mutex = TakeNameMutex(Pool);
|
HANDLE Mutex = TakeNameMutex(Pool);
|
||||||
if (!Mutex)
|
if (!Mutex)
|
||||||
return ERROR_INVALID_HANDLE;
|
return ERROR_INVALID_HANDLE;
|
||||||
HDEVINFO DevInfo = SetupDiGetClassDevsExW(&CLASS_NET_GUID, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
|
HDEVINFO DevInfo = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
|
||||||
if (DevInfo == INVALID_HANDLE_VALUE)
|
if (DevInfo == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
Result = GetLastError();
|
Result = WINTUN_LOGGER_LAST_ERROR(L"Failed to get present class devices");
|
||||||
goto cleanupMutex;
|
goto cleanupMutex;
|
||||||
}
|
}
|
||||||
HANDLE Heap = GetProcessHeap();
|
HANDLE Heap = GetProcessHeap();
|
||||||
for (DWORD MemberIndex = 0;; ++MemberIndex)
|
for (DWORD EnumIndex = 0;; ++EnumIndex)
|
||||||
{
|
{
|
||||||
SP_DEVINFO_DATA DevInfoData = { .cbSize = sizeof(SP_DEVINFO_DATA) };
|
SP_DEVINFO_DATA DevInfoData = { .cbSize = sizeof(SP_DEVINFO_DATA) };
|
||||||
if (!SetupDiEnumDeviceInfo(DevInfo, MemberIndex, &DevInfoData))
|
if (!SetupDiEnumDeviceInfo(DevInfo, EnumIndex, &DevInfoData))
|
||||||
{
|
{
|
||||||
if (GetLastError() == ERROR_NO_MORE_ITEMS)
|
if (GetLastError() == ERROR_NO_MORE_ITEMS)
|
||||||
{
|
{
|
||||||
@ -1189,7 +1146,10 @@ WintunEnumAdapters(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_ WINTUN_ENUMP
|
|||||||
WCHAR *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)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to query hardware ID", Result);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
if (!IsOurHardwareID(Hwids))
|
if (!IsOurHardwareID(Hwids))
|
||||||
{
|
{
|
||||||
HeapFree(Heap, 0, Hwids);
|
HeapFree(Heap, 0, Hwids);
|
||||||
@ -1197,24 +1157,26 @@ WintunEnumAdapters(_In_z_count_c_(MAX_POOL) const WCHAR *Pool, _In_ WINTUN_ENUMP
|
|||||||
}
|
}
|
||||||
HeapFree(Heap, 0, Hwids);
|
HeapFree(Heap, 0, Hwids);
|
||||||
|
|
||||||
BOOL IsOurDriver;
|
if (!DriverIsWintunAdapter(DevInfo, &DevInfoData))
|
||||||
Result = IsUsingOurDriver(DevInfo, &DevInfoData, &IsOurDriver);
|
|
||||||
if (Result != ERROR_SUCCESS)
|
|
||||||
break;
|
|
||||||
if (!IsOurDriver)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
BOOL IsMember;
|
BOOL IsMember;
|
||||||
Result = IsPoolMember(Pool, DevInfo, &DevInfoData, &IsMember);
|
Result = IsPoolMember(Pool, DevInfo, &DevInfoData, &IsMember);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to determine pool membership", Result);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
if (!IsMember)
|
if (!IsMember)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
WINTUN_ADAPTER *Adapter;
|
WINTUN_ADAPTER *Adapter;
|
||||||
Result = CreateAdapterData(Pool, DevInfo, &DevInfoData, &Adapter);
|
Result = CreateAdapterData(Pool, DevInfo, &DevInfoData, &Adapter);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to create adapter data", Result);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
if (Func(Adapter, Param))
|
if (Func(Adapter, Param))
|
||||||
HeapFree(Heap, 0, Adapter);
|
HeapFree(Heap, 0, Adapter);
|
||||||
else
|
else
|
||||||
|
149
api/driver.c
Normal file
149
api/driver.c
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves driver information detail for a device information set or a particular device information element in the
|
||||||
|
* device information set.
|
||||||
|
*
|
||||||
|
* @param DevInfo A handle to the device information set that contains a device information element that
|
||||||
|
* represents the device for which to retrieve driver information.
|
||||||
|
*
|
||||||
|
* @param DevInfoData A pointer to a structure that specifies the device information element in DevInfo.
|
||||||
|
*
|
||||||
|
* @param DrvInfoData A pointer to a structure that specifies the driver information element that represents the
|
||||||
|
* driver for which to retrieve details.
|
||||||
|
*
|
||||||
|
* @param DrvInfoDetailData A pointer to a structure that receives detailed information about the specified driver.
|
||||||
|
* Must be released with HeapFree(GetProcessHeap(), 0, *DrvInfoDetailData) after use.
|
||||||
|
*
|
||||||
|
* @return non-zero on success; zero otherwise - use GetLastError().
|
||||||
|
*/
|
||||||
|
_Return_type_success_(return != NULL) SP_DRVINFO_DETAIL_DATA_W *DriverGetDrvInfoDetail(
|
||||||
|
_In_ HDEVINFO DevInfo,
|
||||||
|
_In_opt_ SP_DEVINFO_DATA *DevInfoData,
|
||||||
|
_In_ SP_DRVINFO_DATA_W *DrvInfoData)
|
||||||
|
{
|
||||||
|
HANDLE Heap = GetProcessHeap();
|
||||||
|
DWORD Size = sizeof(SP_DRVINFO_DETAIL_DATA_W) + 0x100;
|
||||||
|
DWORD Result;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData = HeapAlloc(Heap, 0, Size);
|
||||||
|
if (!DrvInfoDetailData)
|
||||||
|
{
|
||||||
|
Result = ERROR_OUTOFMEMORY;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
DrvInfoDetailData->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA_W);
|
||||||
|
if (SetupDiGetDriverInfoDetailW(DevInfo, DevInfoData, DrvInfoData, DrvInfoDetailData, Size, &Size))
|
||||||
|
return DrvInfoDetailData;
|
||||||
|
Result = GetLastError();
|
||||||
|
HeapFree(Heap, 0, DrvInfoDetailData);
|
||||||
|
if (Result != ERROR_INSUFFICIENT_BUFFER)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed", Result);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
SetLastError(Result);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the device (i.e. network adapter) is using Wintun driver.
|
||||||
|
*
|
||||||
|
* @param DevInfo A handle to the device information set that contains a device information element that
|
||||||
|
* represents the device.
|
||||||
|
*
|
||||||
|
* @param DevInfoData A pointer to a structure that specifies the device information element in DevInfo.
|
||||||
|
*
|
||||||
|
* @return non-zero when using Wintun driver; zero when not or error - use GetLastError().
|
||||||
|
*/
|
||||||
|
BOOL
|
||||||
|
DriverIsWintunAdapter(_In_ HDEVINFO DevInfo, _In_opt_ SP_DEVINFO_DATA *DevInfoData)
|
||||||
|
{
|
||||||
|
BOOL Found = FALSE;
|
||||||
|
if (!SetupDiBuildDriverInfoList(DevInfo, DevInfoData, SPDIT_COMPATDRIVER))
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_LAST_ERROR(L"Failed to build list of drivers");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
HANDLE Heap = GetProcessHeap();
|
||||||
|
for (DWORD EnumIndex = 0; !Found; ++EnumIndex)
|
||||||
|
{
|
||||||
|
SP_DRVINFO_DATA_W DrvInfoData = { .cbSize = sizeof(SP_DRVINFO_DATA_W) };
|
||||||
|
if (!SetupDiEnumDriverInfoW(DevInfo, DevInfoData, SPDIT_COMPATDRIVER, EnumIndex, &DrvInfoData))
|
||||||
|
{
|
||||||
|
if (GetLastError() == ERROR_NO_MORE_ITEMS)
|
||||||
|
break;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
SP_DRVINFO_DETAIL_DATA_W *DrvInfoDetailData = DriverGetDrvInfoDetail(DevInfo, DevInfoData, &DrvInfoData);
|
||||||
|
if (!DrvInfoDetailData)
|
||||||
|
continue;
|
||||||
|
Found = !_wcsicmp(DrvInfoDetailData->HardwareID, L"wintun");
|
||||||
|
HeapFree(Heap, 0, DrvInfoDetailData);
|
||||||
|
}
|
||||||
|
SetupDiDestroyDriverInfoList(DevInfo, DevInfoData, SPDIT_COMPATDRIVER);
|
||||||
|
SetLastError(ERROR_SUCCESS);
|
||||||
|
return Found;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a handle to the adapter device object.
|
||||||
|
*
|
||||||
|
* @param InstanceId Adapter device instance ID.
|
||||||
|
*
|
||||||
|
* @return device handle on success; INVALID_HANDLE_VALUE otherwise - use GetLastError().
|
||||||
|
*/
|
||||||
|
_Return_type_success_(return != INVALID_HANDLE_VALUE) HANDLE
|
||||||
|
DriverGetAdapterDeviceObject(_In_opt_z_ const WCHAR *InstanceId)
|
||||||
|
{
|
||||||
|
HANDLE Heap = GetProcessHeap();
|
||||||
|
ULONG InterfacesLen;
|
||||||
|
HANDLE Handle = INVALID_HANDLE_VALUE;
|
||||||
|
DWORD Result = CM_Get_Device_Interface_List_SizeW(
|
||||||
|
&InterfacesLen, (GUID *)&GUID_DEVINTERFACE_NET, (DEVINSTID_W)InstanceId, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
|
||||||
|
if (Result != CR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER(WINTUN_LOG_ERR, L"Failed to get device associated device instances size");
|
||||||
|
SetLastError(ERROR_GEN_FAILURE);
|
||||||
|
return INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
WCHAR *Interfaces = HeapAlloc(Heap, 0, InterfacesLen * sizeof(WCHAR));
|
||||||
|
if (!Interfaces)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_OUTOFMEMORY);
|
||||||
|
return INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
Result = CM_Get_Device_Interface_ListW(
|
||||||
|
(GUID *)&GUID_DEVINTERFACE_NET,
|
||||||
|
(DEVINSTID_W)InstanceId,
|
||||||
|
Interfaces,
|
||||||
|
InterfacesLen,
|
||||||
|
CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
|
||||||
|
if (Result != CR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER(WINTUN_LOG_ERR, L"Failed to get device associated device instances");
|
||||||
|
Result = ERROR_GEN_FAILURE;
|
||||||
|
goto cleanupBuf;
|
||||||
|
}
|
||||||
|
Handle = CreateFileW(
|
||||||
|
Interfaces,
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
|
NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
Result = Handle != INVALID_HANDLE_VALUE ? ERROR_SUCCESS : WINTUN_LOGGER_LAST_ERROR(L"Failed to connect to device");
|
||||||
|
cleanupBuf:
|
||||||
|
HeapFree(Heap, 0, Interfaces);
|
||||||
|
SetLastError(Result);
|
||||||
|
return Handle;
|
||||||
|
}
|
21
api/driver.h
Normal file
21
api/driver.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "api.h"
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <SetupAPI.h>
|
||||||
|
|
||||||
|
_Return_type_success_(return != NULL) SP_DRVINFO_DETAIL_DATA_W *DriverGetDrvInfoDetail(
|
||||||
|
_In_ HDEVINFO DevInfo,
|
||||||
|
_In_opt_ SP_DEVINFO_DATA *DevInfoData,
|
||||||
|
_In_ SP_DRVINFO_DATA_W *DrvInfoData);
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
DriverIsWintunAdapter(_In_ HDEVINFO DevInfo, _In_opt_ SP_DEVINFO_DATA *DevInfoData);
|
||||||
|
|
||||||
|
_Return_type_success_(return != INVALID_HANDLE_VALUE) HANDLE
|
||||||
|
DriverGetAdapterDeviceObject(_In_opt_z_ const WCHAR *InstanceId);
|
@ -1,12 +1,13 @@
|
|||||||
EXPORTS
|
EXPORTS
|
||||||
WintunFreeAdapter
|
|
||||||
WintunGetAdapter
|
|
||||||
WintunGetAdapterName
|
|
||||||
WintunSetAdapterName
|
|
||||||
WintunGetAdapterGUID
|
|
||||||
WintunGetAdapterLUID
|
|
||||||
WintunGetAdapterDeviceObject
|
|
||||||
WintunGetVersion
|
|
||||||
WintunCreateAdapter
|
WintunCreateAdapter
|
||||||
WintunDeleteAdapter
|
WintunDeleteAdapter
|
||||||
WintunEnumAdapters
|
WintunEnumAdapters
|
||||||
|
WintunFreeAdapter
|
||||||
|
WintunGetAdapter
|
||||||
|
WintunGetAdapterDeviceObject
|
||||||
|
WintunGetAdapterGUID
|
||||||
|
WintunGetAdapterLUID
|
||||||
|
WintunGetAdapterName
|
||||||
|
WintunGetVersion
|
||||||
|
WintunSetAdapterName
|
||||||
|
WintunSetLogger
|
||||||
|
49
api/logger.c
Normal file
49
api/logger.c
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
|
||||||
|
static VOID CALLBACK
|
||||||
|
NopLogger(_In_ WINTUN_LOGGER_LEVEL Level, _In_z_ const WCHAR *LogLine)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(Level);
|
||||||
|
UNREFERENCED_PARAMETER(LogLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
WINTUN_LOGGER_FUNC Logger = NopLogger;
|
||||||
|
|
||||||
|
VOID CALLBACK
|
||||||
|
WintunSetLogger(_In_ WINTUN_LOGGER_FUNC NewLogger)
|
||||||
|
{
|
||||||
|
Logger = NewLogger;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Post_equals_last_error_ DWORD
|
||||||
|
LoggerError(_In_z_ const WCHAR *Prefix, _In_ DWORD Error)
|
||||||
|
{
|
||||||
|
WCHAR *SystemMessage = NULL, *FormattedMessage = NULL;
|
||||||
|
FormatMessageW(
|
||||||
|
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_MAX_WIDTH_MASK,
|
||||||
|
NULL,
|
||||||
|
HRESULT_FROM_SETUPAPI(Error),
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
(VOID *)&SystemMessage,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
FormatMessageW(
|
||||||
|
FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY |
|
||||||
|
FORMAT_MESSAGE_MAX_WIDTH_MASK,
|
||||||
|
SystemMessage ? L"%1: %3(Code 0x%2!08X!)" : L"%1: Code 0x%2!08X!",
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
(VOID *)&FormattedMessage,
|
||||||
|
0,
|
||||||
|
(va_list *)(DWORD_PTR[]){ (DWORD_PTR)Prefix, (DWORD_PTR)Error, (DWORD_PTR)SystemMessage });
|
||||||
|
if (FormattedMessage)
|
||||||
|
Logger(WINTUN_LOG_ERR, FormattedMessage);
|
||||||
|
LocalFree(FormattedMessage);
|
||||||
|
LocalFree(SystemMessage);
|
||||||
|
return Error;
|
||||||
|
}
|
38
api/logger.h
Normal file
38
api/logger.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
typedef enum _WINTUN_LOGGER_LEVEL
|
||||||
|
{
|
||||||
|
WINTUN_LOG_INFO = 0,
|
||||||
|
WINTUN_LOG_WARN,
|
||||||
|
WINTUN_LOG_ERR
|
||||||
|
} WINTUN_LOGGER_LEVEL;
|
||||||
|
|
||||||
|
typedef VOID(CALLBACK *WINTUN_LOGGER_FUNC)(_In_ WINTUN_LOGGER_LEVEL Level, _In_z_ const WCHAR *Message);
|
||||||
|
|
||||||
|
extern WINTUN_LOGGER_FUNC Logger;
|
||||||
|
|
||||||
|
VOID WINAPI
|
||||||
|
WintunSetLogger(_In_ WINTUN_LOGGER_FUNC NewLogger);
|
||||||
|
|
||||||
|
_Post_equals_last_error_ DWORD
|
||||||
|
LoggerError(_In_z_ const WCHAR *Prefix, _In_ DWORD Error);
|
||||||
|
|
||||||
|
inline _Post_equals_last_error_ DWORD
|
||||||
|
LoggerLastError(_In_z_ const WCHAR *Prefix)
|
||||||
|
{
|
||||||
|
DWORD Error = GetLastError();
|
||||||
|
LoggerError(Prefix, Error);
|
||||||
|
SetLastError(Error);
|
||||||
|
return Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WINTUN_LOGGER(lvl, msg) Logger((lvl), _L(__FUNCTION__) L": " msg)
|
||||||
|
#define WINTUN_LOGGER_ERROR(msg, err) LoggerError(_L(__FUNCTION__) L": " msg, (err))
|
||||||
|
#define WINTUN_LOGGER_LAST_ERROR(msg) LoggerLastError(_L(__FUNCTION__) L": " msg)
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include "api.h"
|
#include "api.h"
|
||||||
#include "devmgmt.h"
|
#include "devmgmt.h"
|
||||||
|
#include "driver.h"
|
||||||
|
#include "logger.h"
|
||||||
#include "namespace.h"
|
#include "namespace.h"
|
||||||
#include "nci.h"
|
#include "nci.h"
|
||||||
#include "registry.h"
|
#include "registry.h"
|
||||||
@ -15,6 +17,7 @@
|
|||||||
#include <cfgmgr32.h>
|
#include <cfgmgr32.h>
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
#include <ndisguid.h>
|
||||||
#include <objbase.h>
|
#include <objbase.h>
|
||||||
#include <sddl.h>
|
#include <sddl.h>
|
||||||
#include <SetupAPI.h>
|
#include <SetupAPI.h>
|
||||||
|
@ -15,12 +15,15 @@ OpenKeyWait(_In_ HKEY Key, _Inout_z_ WCHAR *Path, _In_ DWORD Access, _In_ ULONGL
|
|||||||
|
|
||||||
HANDLE Event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
HANDLE Event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||||
if (!Event)
|
if (!Event)
|
||||||
return GetLastError();
|
return WINTUN_LOGGER_LAST_ERROR(L"Failed to create event");
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Result = RegNotifyChangeKeyValue(Key, FALSE, REG_NOTIFY_CHANGE_NAME, Event, TRUE);
|
Result = RegNotifyChangeKeyValue(Key, FALSE, REG_NOTIFY_CHANGE_NAME, Event, TRUE);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to setup notification", Result);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
HKEY Subkey;
|
HKEY Subkey;
|
||||||
Result = RegOpenKeyExW(Key, Path, 0, PathNext ? KEY_NOTIFY : Access, &Subkey);
|
Result = RegOpenKeyExW(Key, Path, 0, PathNext ? KEY_NOTIFY : Access, &Subkey);
|
||||||
@ -36,13 +39,19 @@ OpenKeyWait(_In_ HKEY Key, _Inout_z_ WCHAR *Path, _In_ DWORD Access, _In_ ULONGL
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (Result != ERROR_FILE_NOT_FOUND && Result != ERROR_PATH_NOT_FOUND)
|
if (Result != ERROR_FILE_NOT_FOUND && Result != ERROR_PATH_NOT_FOUND)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to open", Result);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
LONGLONG TimeLeft = Deadline - GetTickCount64();
|
LONGLONG TimeLeft = Deadline - GetTickCount64();
|
||||||
if (TimeLeft < 0)
|
if (TimeLeft < 0)
|
||||||
TimeLeft = 0;
|
TimeLeft = 0;
|
||||||
if (WaitForSingleObject(Event, (DWORD)TimeLeft) != WAIT_OBJECT_0)
|
if (WaitForSingleObject(Event, (DWORD)TimeLeft) != WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER(WINTUN_LOG_ERR, "Timeout waiting");
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CloseHandle(Event);
|
CloseHandle(Event);
|
||||||
return Result;
|
return Result;
|
||||||
@ -136,7 +145,7 @@ RegistryGetString(_Inout_ WCHAR **Buf, _In_ DWORD Len, _In_ DWORD ValueType)
|
|||||||
DWORD Result = ExpandEnvironmentStringsW(*Buf, Expanded, Len);
|
DWORD Result = ExpandEnvironmentStringsW(*Buf, Expanded, Len);
|
||||||
if (!Result)
|
if (!Result)
|
||||||
{
|
{
|
||||||
Result = GetLastError();
|
Result = WINTUN_LOGGER_LAST_ERROR(L"Failed to expand environment variables");
|
||||||
HeapFree(Heap, 0, Expanded);
|
HeapFree(Heap, 0, Expanded);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
@ -257,7 +266,7 @@ RegistryQuery(
|
|||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
HeapFree(Heap, 0, *Buf);
|
HeapFree(Heap, 0, *Buf);
|
||||||
if (Result != ERROR_MORE_DATA)
|
if (Result != ERROR_MORE_DATA)
|
||||||
return Result;
|
return WINTUN_LOGGER_ERROR(L"Querying value failed", Result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,6 +302,7 @@ RegistryQueryString(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _Out_ WCHAR **V
|
|||||||
HeapFree(GetProcessHeap(), 0, *Value);
|
HeapFree(GetProcessHeap(), 0, *Value);
|
||||||
return Result;
|
return Result;
|
||||||
default:
|
default:
|
||||||
|
WINTUN_LOGGER(WINTUN_LOG_ERR, L"Value is not a string");
|
||||||
HeapFree(GetProcessHeap(), 0, *Value);
|
HeapFree(GetProcessHeap(), 0, *Value);
|
||||||
return ERROR_INVALID_DATATYPE;
|
return ERROR_INVALID_DATATYPE;
|
||||||
}
|
}
|
||||||
@ -312,7 +322,7 @@ RegistryQueryString(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _Out_ WCHAR **V
|
|||||||
* string from the multi-string is returned. The string must be released with
|
* string from the multi-string is returned. The string must be released with
|
||||||
* HeapFree(GetProcessHeap(), 0, Value) after use.
|
* HeapFree(GetProcessHeap(), 0, Value) after use.
|
||||||
*
|
*
|
||||||
* @return ERROR_SUCCESS on success; WAIT_TIMEOUT on timeout; ERROR_INVALID_DATATYPE when the registry value is a
|
* @return ERROR_SUCCESS on success; WAIT_TIMEOUT on timeout; ERROR_INVALID_DATATYPE when the registry value is not a
|
||||||
* string; Win32 error code otherwise.
|
* string; Win32 error code otherwise.
|
||||||
*/
|
*/
|
||||||
WINTUN_STATUS
|
WINTUN_STATUS
|
||||||
@ -322,12 +332,15 @@ RegistryQueryStringWait(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _In_ DWORD
|
|||||||
ULONGLONG Deadline = GetTickCount64() + Timeout;
|
ULONGLONG Deadline = GetTickCount64() + Timeout;
|
||||||
HANDLE Event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
HANDLE Event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||||
if (!Event)
|
if (!Event)
|
||||||
return GetLastError();
|
return WINTUN_LOGGER_LAST_ERROR(L"Failed to create event");
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Result = RegNotifyChangeKeyValue(Key, FALSE, REG_NOTIFY_CHANGE_LAST_SET, Event, TRUE);
|
Result = RegNotifyChangeKeyValue(Key, FALSE, REG_NOTIFY_CHANGE_LAST_SET, Event, TRUE);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to setup notification", Result);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
Result = RegistryQueryString(Key, Name, Value);
|
Result = RegistryQueryString(Key, Name, Value);
|
||||||
if (Result != ERROR_FILE_NOT_FOUND && Result != ERROR_PATH_NOT_FOUND)
|
if (Result != ERROR_FILE_NOT_FOUND && Result != ERROR_PATH_NOT_FOUND)
|
||||||
break;
|
break;
|
||||||
@ -335,7 +348,10 @@ RegistryQueryStringWait(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _In_ DWORD
|
|||||||
if (TimeLeft < 0)
|
if (TimeLeft < 0)
|
||||||
TimeLeft = 0;
|
TimeLeft = 0;
|
||||||
if (WaitForSingleObject(Event, (DWORD)TimeLeft) != WAIT_OBJECT_0)
|
if (WaitForSingleObject(Event, (DWORD)TimeLeft) != WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER(WINTUN_LOG_ERR, "Timeout waiting");
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CloseHandle(Event);
|
CloseHandle(Event);
|
||||||
return Result;
|
return Result;
|
||||||
@ -359,11 +375,17 @@ RegistryQueryDWORD(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _Out_ DWORD *Val
|
|||||||
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);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
return Result;
|
return WINTUN_LOGGER_ERROR(L"Querying failed", Result);
|
||||||
if (ValueType != REG_DWORD)
|
if (ValueType != REG_DWORD)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER(WINTUN_LOG_ERR, L"Value is not a DWORD");
|
||||||
return ERROR_INVALID_DATATYPE;
|
return ERROR_INVALID_DATATYPE;
|
||||||
|
}
|
||||||
if (Size != sizeof(DWORD))
|
if (Size != sizeof(DWORD))
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER(WINTUN_LOG_ERR, L"Value size is not 4 bytes");
|
||||||
return ERROR_INVALID_DATA;
|
return ERROR_INVALID_DATA;
|
||||||
|
}
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,12 +410,15 @@ RegistryQueryDWORDWait(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _In_ DWORD T
|
|||||||
ULONGLONG Deadline = GetTickCount64() + Timeout;
|
ULONGLONG Deadline = GetTickCount64() + Timeout;
|
||||||
HANDLE Event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
HANDLE Event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||||
if (!Event)
|
if (!Event)
|
||||||
return GetLastError();
|
return WINTUN_LOGGER_LAST_ERROR(L"Failed to create event");
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Result = RegNotifyChangeKeyValue(Key, FALSE, REG_NOTIFY_CHANGE_LAST_SET, Event, TRUE);
|
Result = RegNotifyChangeKeyValue(Key, FALSE, REG_NOTIFY_CHANGE_LAST_SET, Event, TRUE);
|
||||||
if (Result != ERROR_SUCCESS)
|
if (Result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER_ERROR(L"Failed to setup notification", Result);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
Result = RegistryQueryDWORD(Key, Name, Value);
|
Result = RegistryQueryDWORD(Key, Name, Value);
|
||||||
if (Result != ERROR_FILE_NOT_FOUND && Result != ERROR_PATH_NOT_FOUND)
|
if (Result != ERROR_FILE_NOT_FOUND && Result != ERROR_PATH_NOT_FOUND)
|
||||||
break;
|
break;
|
||||||
@ -401,7 +426,10 @@ RegistryQueryDWORDWait(_In_ HKEY Key, _In_opt_z_ const WCHAR *Name, _In_ DWORD T
|
|||||||
if (TimeLeft < 0)
|
if (TimeLeft < 0)
|
||||||
TimeLeft = 0;
|
TimeLeft = 0;
|
||||||
if (WaitForSingleObject(Event, (DWORD)TimeLeft) != WAIT_OBJECT_0)
|
if (WaitForSingleObject(Event, (DWORD)TimeLeft) != WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
WINTUN_LOGGER(WINTUN_LOG_ERR, "Timeout waiting");
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CloseHandle(Event);
|
CloseHandle(Event);
|
||||||
return Result;
|
return Result;
|
||||||
|
Loading…
Reference in New Issue
Block a user