aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2021-10-04 00:54:24 +0000
committerJason A. Donenfeld <Jason@zx2c4.com>2021-10-06 05:16:14 +0000
commitc8ee696db51b70ef87386f083dbdf99e7051c85f (patch)
treef4d045e5d81b1acadb5e334cd700d959db236302
parentapi: logger: remove function prefixes (diff)
downloadwireguard-nt-c8ee696db51b70ef87386f083dbdf99e7051c85f.tar.xz
wireguard-nt-c8ee696db51b70ef87386f083dbdf99e7051c85f.zip
api: adapter: get rid of registry polling on Win8+
Wait for the device to come up as enabled instead using the proper Win8+ API. Fall back to polling for Win7. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--api/adapter.c258
-rw-r--r--api/api.vcxproj4
-rw-r--r--api/main.c7
-rw-r--r--api/main.h2
-rw-r--r--api/ntdll.h1
-rw-r--r--api/registry.c199
-rw-r--r--api/registry.h62
7 files changed, 190 insertions, 343 deletions
diff --git a/api/adapter.c b/api/adapter.c
index 42b191f..0775e12 100644
--- a/api/adapter.c
+++ b/api/adapter.c
@@ -18,6 +18,15 @@
#include <initguid.h> /* Keep these two at bottom in this order, so that we only generate extra GUIDs for devpkey. The other keys we'll get from uuid.lib like usual. */
#include <devpkey.h>
+/* We pretend we're Windows 8, and then hack around the limitation in Windows 7 below. */
+#if NTDDI_VERSION == NTDDI_WIN7
+# undef NTDDI_VERSION
+# define NTDDI_VERSION NTDDI_WIN8
+# include <devquery.h>
+# undef NTDDI_VERSION
+# define NTDDI_VERSION NTDDI_WIN7
+#endif
+
#include "../driver/ioctl.h"
#include "adapter.h"
#include "logger.h"
@@ -32,7 +41,6 @@
#pragma warning(disable : 4221) /* nonstandard: address of automatic in initializer */
-#define WAIT_FOR_REGISTRY_TIMEOUT 10000 /* ms */
#define MAX_POOL_DEVICE_TYPE (WIREGUARD_MAX_POOL + 8) /* Should accommodate a pool name with " Tunnel" appended */
static const DEVPROPKEY DEVPKEY_WireGuard_Pool = {
@@ -1339,6 +1347,147 @@ cleanup:
return RET_ERROR(Adapter, LastError);
}
+typedef struct _WAIT_FOR_INTERFACE_CTX
+{
+ HANDLE Event;
+ DWORD LastError;
+} WAIT_FOR_INTERFACE_CTX;
+
+static VOID WINAPI
+WaitForInterfaceCallback(
+ _In_ HDEVQUERY DevQuery,
+ _Inout_ PVOID Context,
+ _In_ const DEV_QUERY_RESULT_ACTION_DATA *ActionData)
+{
+ WAIT_FOR_INTERFACE_CTX *Ctx = Context;
+ Ctx->LastError = ERROR_SUCCESS;
+ if (ActionData->Action == DevQueryResultStateChange)
+ {
+ if (ActionData->Data.State != DevQueryStateAborted)
+ return;
+ Ctx->LastError = ERROR_DEVICE_NOT_AVAILABLE;
+ }
+ else if (ActionData->Action == DevQueryResultRemove)
+ return;
+ SetEvent(Ctx->Event);
+}
+
+#if NTDDI_VERSION == NTDDI_WIN7
+_Must_inspect_result_
+static _Return_type_success_(return != FALSE)
+BOOL
+WaitForInterfaceWin7(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData)
+{
+ ULONG Status, Number;
+ DWORD ValType, Zero;
+ HKEY Key = INVALID_HANDLE_VALUE;
+ BOOLEAN Ret = FALSE;
+ for (int i = 0; i < 1500; ++i)
+ {
+ if (i)
+ Sleep(10);
+ if (Key == INVALID_HANDLE_VALUE)
+ {
+ Key = SetupDiOpenDevRegKey(DevInfo, DevInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_QUERY_VALUE);
+ if (Key == INVALID_HANDLE_VALUE)
+ continue;
+ }
+ _Analysis_assume_(Key);
+ Zero = 0;
+ if (RegQueryValueExW(Key, L"NetCfgInstanceId", NULL, &ValType, NULL, &Zero) != ERROR_MORE_DATA &&
+ CM_Get_DevNode_Status(&Status, &Number, DevInfoData->DevInst, 0) == CR_SUCCESS &&
+ !(Status & DN_HAS_PROBLEM) && !Number)
+ {
+ Ret = TRUE;
+ break;
+ }
+ }
+ if (Key != INVALID_HANDLE_VALUE)
+ RegCloseKey(Key);
+ return Ret;
+}
+#endif
+
+_Must_inspect_result_
+static _Return_type_success_(return != FALSE)
+BOOL
+WaitForInterface(_In_ HDEVINFO DevInfo, _In_ SP_DEVINFO_DATA *DevInfoData)
+{
+#if NTDDI_VERSION == NTDDI_WIN7
+ if (IsWindows7)
+ return WaitForInterfaceWin7(DevInfo, DevInfoData);
+#endif
+
+ DWORD LastError = ERROR_SUCCESS, Size;
+ WCHAR InstanceId[MAX_INSTANCE_ID];
+ if (!SetupDiGetDeviceInstanceIdW(DevInfo, DevInfoData, InstanceId, _countof(InstanceId), &Size))
+ {
+ LastError = LOG_LAST_ERROR(L"Failed to get adapter %u instance ID", DevInfoData->DevInst);
+ goto cleanup;
+ }
+
+ static const DEVPROP_BOOLEAN DevPropTrue = DEVPROP_TRUE;
+ const DEVPROP_FILTER_EXPRESSION Filters[] = { { .Operator = DEVPROP_OPERATOR_EQUALS_IGNORE_CASE,
+ .Property.CompKey.Key = DEVPKEY_Device_InstanceId,
+ .Property.CompKey.Store = DEVPROP_STORE_SYSTEM,
+ .Property.Type = DEVPROP_TYPE_STRING,
+ .Property.Buffer = InstanceId,
+ .Property.BufferSize =
+ (ULONG)((wcslen(InstanceId) + 1) * sizeof(InstanceId[0])) },
+ { .Operator = DEVPROP_OPERATOR_EQUALS,
+ .Property.CompKey.Key = DEVPKEY_DeviceInterface_Enabled,
+ .Property.CompKey.Store = DEVPROP_STORE_SYSTEM,
+ .Property.Type = DEVPROP_TYPE_BOOLEAN,
+ .Property.Buffer = (PVOID)&DevPropTrue,
+ .Property.BufferSize = sizeof(DevPropTrue) },
+ { .Operator = DEVPROP_OPERATOR_EQUALS,
+ .Property.CompKey.Key = DEVPKEY_DeviceInterface_ClassGuid,
+ .Property.CompKey.Store = DEVPROP_STORE_SYSTEM,
+ .Property.Type = DEVPROP_TYPE_GUID,
+ .Property.Buffer = (PVOID)&GUID_DEVINTERFACE_NET,
+ .Property.BufferSize = sizeof(GUID_DEVINTERFACE_NET) } };
+ WAIT_FOR_INTERFACE_CTX Ctx = { .Event = CreateEventW(NULL, FALSE, FALSE, NULL) };
+ if (!Ctx.Event)
+ {
+ LastError = LOG_LAST_ERROR(L"Failed to create event");
+ goto cleanup;
+ }
+ HDEVQUERY Query;
+ HRESULT HRet = DevCreateObjectQuery(
+ DevObjectTypeDeviceInterface,
+ DevQueryFlagUpdateResults,
+ 0,
+ NULL,
+ _countof(Filters),
+ Filters,
+ WaitForInterfaceCallback,
+ &Ctx,
+ &Query);
+ if (HRet < 0)
+ {
+ LastError = LOG_ERROR(HRet, L"Failed to create device query");
+ goto cleanupEvent;
+ }
+ LastError = WaitForSingleObject(Ctx.Event, 15000);
+ if (LastError != WAIT_OBJECT_0)
+ {
+ if (LastError == WAIT_FAILED)
+ LastError = LOG_LAST_ERROR(L"Failed to wait for device query");
+ else
+ LastError = LOG_ERROR(LastError, L"Timed out waiting for device query");
+ goto cleanupQuery;
+ }
+ LastError = Ctx.LastError;
+ if (LastError != ERROR_SUCCESS)
+ LastError = LOG_ERROR(LastError, L"Failed to get enabled device");
+cleanupQuery:
+ DevCloseObjectQuery(Query);
+cleanupEvent:
+ CloseHandle(Ctx.Event);
+cleanup:
+ return RET_ERROR(TRUE, LastError);
+}
+
_Use_decl_annotations_
WIREGUARD_ADAPTER_HANDLE WINAPI
WireGuardCreateAdapter(LPCWSTR Pool, LPCWSTR Name, const GUID *RequestedGUID)
@@ -1441,51 +1590,51 @@ WireGuardCreateAdapter(LPCWSTR Pool, LPCWSTR Name, const GUID *RequestedGUID)
if (!SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS, Adapter->DevInfo, &Adapter->DevInfoData))
LOG_LAST_ERROR(L"Failed to register adapter %u coinstallers", Adapter->DevInfoData.DevInst);
- HKEY NetDevRegKey = INVALID_HANDLE_VALUE;
- const int PollTimeout = 50 /* ms */;
- for (int i = 0; NetDevRegKey == INVALID_HANDLE_VALUE && i < WAIT_FOR_REGISTRY_TIMEOUT / PollTimeout; ++i)
- {
- if (i)
- Sleep(PollTimeout);
- NetDevRegKey = SetupDiOpenDevRegKey(
- Adapter->DevInfo,
- &Adapter->DevInfoData,
- DICS_FLAG_GLOBAL,
- 0,
- DIREG_DRV,
- KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_NOTIFY);
- }
- if (NetDevRegKey == INVALID_HANDLE_VALUE)
- {
- LastError =
- LOG_LAST_ERROR(L"Failed to open adapter %u device-specific registry key", Adapter->DevInfoData.DevInst);
- goto cleanupDevice;
- }
if (RequestedGUID)
{
+ HKEY NetDevRegKey = INVALID_HANDLE_VALUE;
+ for (int i = 0; NetDevRegKey == INVALID_HANDLE_VALUE && i < 1000; ++i)
+ {
+ if (i)
+ Sleep(10);
+ NetDevRegKey = SetupDiOpenDevRegKey(
+ Adapter->DevInfo,
+ &Adapter->DevInfoData,
+ DICS_FLAG_GLOBAL,
+ 0,
+ DIREG_DRV,
+ KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_NOTIFY);
+ }
+ if (NetDevRegKey == INVALID_HANDLE_VALUE)
+ {
+ LastError =
+ LOG_LAST_ERROR(L"Failed to open adapter %u device-specific registry key", Adapter->DevInfoData.DevInst);
+ goto cleanupDevice;
+ }
LastError = RegSetValueExW(
NetDevRegKey, L"SuggestedInstanceId", 0, REG_BINARY, (const BYTE *)RequestedGUID, sizeof(*RequestedGUID));
+ RegCloseKey(NetDevRegKey);
if (LastError != ERROR_SUCCESS)
{
WCHAR RegPath[MAX_REG_PATH];
LoggerGetRegistryKeyPath(NetDevRegKey, RegPath);
LOG_ERROR(LastError, L"Failed to set %.*s\\SuggestedInstanceId", MAX_REG_PATH, RegPath);
- goto cleanupNetDevRegKey;
+ goto cleanupDevice;
}
}
if (!SetupDiCallClassInstaller(DIF_INSTALLINTERFACES, Adapter->DevInfo, &Adapter->DevInfoData))
LOG_LAST_ERROR(L"Failed to install adapter %u interfaces", Adapter->DevInfoData.DevInst);
-
if (!SetupDiCallClassInstaller(DIF_INSTALLDEVICE, Adapter->DevInfo, &Adapter->DevInfoData))
{
LastError = LOG_LAST_ERROR(L"Failed to install adapter %u device", Adapter->DevInfoData.DevInst);
- goto cleanupNetDevRegKey;
+ goto cleanupDevice;
}
+
if (CheckReboot(Adapter->DevInfo, &Adapter->DevInfoData))
{
LastError = ERROR_PNP_REBOOT_REQUIRED;
- goto cleanupNetDevRegKey;
+ goto cleanupDevice;
}
if (!SetupDiSetDevicePropertyW(
@@ -1499,7 +1648,7 @@ WireGuardCreateAdapter(LPCWSTR Pool, LPCWSTR Name, const GUID *RequestedGUID)
0))
{
LastError = LOG_LAST_ERROR(L"Failed to set adapter %u pool", Adapter->DevInfoData.DevInst);
- goto cleanupNetDevRegKey;
+ goto cleanupDevice;
}
if (!SetupDiSetDeviceRegistryPropertyW(
Adapter->DevInfo,
@@ -1509,15 +1658,14 @@ WireGuardCreateAdapter(LPCWSTR Pool, LPCWSTR Name, const GUID *RequestedGUID)
(DWORD)((wcslen(PoolDeviceTypeName) + 1) * sizeof(*PoolDeviceTypeName))))
{
LastError = LOG_LAST_ERROR(L"Failed to set adapter %u description", Adapter->DevInfoData.DevInst);
- goto cleanupNetDevRegKey;
+ goto cleanupDevice;
}
- for (int Tries = 0; Tries < 1000; ++Tries)
+ if (!WaitForInterface(Adapter->DevInfo, &Adapter->DevInfoData))
{
DEVPROPTYPE PropertyType = 0;
NTSTATUS NtStatus = 0;
INT32 ProblemCode = 0;
-
if (!SetupDiGetDevicePropertyW(
Adapter->DevInfo,
&Adapter->DevInfoData,
@@ -1540,72 +1688,32 @@ WireGuardCreateAdapter(LPCWSTR Pool, LPCWSTR Name, const GUID *RequestedGUID)
0) ||
(PropertyType != DEVPROP_TYPE_INT32 && PropertyType != DEVPROP_TYPE_UINT32))
ProblemCode = 0;
- if (NtStatus == STATUS_PNP_DEVICE_CONFIGURATION_PENDING && Tries < 999)
- {
- Sleep(10);
- continue;
- }
- if (NT_SUCCESS(NtStatus) && !ProblemCode)
- break;
LastError = RtlNtStatusToDosError(NtStatus);
if (LastError == ERROR_SUCCESS)
- LastError = ERROR_NOT_READY;
- LOG_ERROR(
- LastError,
- L"Failed to setup adapter (problem code: 0x%x, ntstatus: 0x%x)",
- ProblemCode,
- NtStatus);
- goto cleanupNetDevRegKey;
- }
-
- /* 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. */
- LPWSTR DummyStr = RegistryQueryStringWait(NetDevRegKey, L"NetCfgInstanceId", WAIT_FOR_REGISTRY_TIMEOUT);
- if (!DummyStr)
- {
- WCHAR RegPath[MAX_REG_PATH];
- LoggerGetRegistryKeyPath(NetDevRegKey, RegPath);
- LastError = LOG(WIREGUARD_LOG_ERR, L"Failed to get %.*s\\NetCfgInstanceId", MAX_REG_PATH, RegPath);
- goto cleanupNetDevRegKey;
- }
- Free(DummyStr);
- DWORD DummyDWORD;
- if (!RegistryQueryDWORDWait(NetDevRegKey, L"NetLuidIndex", WAIT_FOR_REGISTRY_TIMEOUT, &DummyDWORD))
- {
- WCHAR RegPath[MAX_REG_PATH];
- LoggerGetRegistryKeyPath(NetDevRegKey, RegPath);
- LastError = LOG(WIREGUARD_LOG_ERR, L"Failed to get %.*s\\NetLuidIndex", MAX_REG_PATH, RegPath);
- goto cleanupNetDevRegKey;
- }
- if (!RegistryQueryDWORDWait(NetDevRegKey, L"*IfType", WAIT_FOR_REGISTRY_TIMEOUT, &DummyDWORD))
- {
- WCHAR RegPath[MAX_REG_PATH];
- LoggerGetRegistryKeyPath(NetDevRegKey, RegPath);
- LastError = LOG(WIREGUARD_LOG_ERR, L"Failed to get %.*s\\*IfType", MAX_REG_PATH, RegPath);
- goto cleanupNetDevRegKey;
+ LastError = ERROR_DEVICE_NOT_AVAILABLE;
+ LOG_ERROR(LastError, L"Failed to setup adapter (problem code: 0x%x, ntstatus: 0x%x)", ProblemCode, NtStatus);
+ goto cleanupDevice;
}
if (!PopulateAdapterData(Adapter, Pool))
{
LastError = LOG(WIREGUARD_LOG_ERR, L"Failed to populate adapter %u data", Adapter->DevInfoData.DevInst);
- goto cleanupNetDevRegKey;
+ goto cleanupDevice;
}
if (!WireGuardSetAdapterName(Adapter, Name))
{
LastError = LOG(WIREGUARD_LOG_ERR, L"Failed to set adapter name %s", Name);
- goto cleanupNetDevRegKey;
+ goto cleanupDevice;
}
if (!EnsureDeviceObject(Adapter->DevInstanceID))
{
LastError = LOG_LAST_ERROR(L"Device object file did not appear");
- goto cleanupNetDevRegKey;
+ goto cleanupDevice;
}
LastError = ERROR_SUCCESS;
-cleanupNetDevRegKey:
- RegCloseKey(NetDevRegKey);
cleanupDevice:
if (LastError != ERROR_SUCCESS)
{
diff --git a/api/api.vcxproj b/api/api.vcxproj
index d805826..0c75dc8 100644
--- a/api/api.vcxproj
+++ b/api/api.vcxproj
@@ -34,8 +34,8 @@
<PreprocessorDefinitions Condition="'$(Platform)'=='ARM'">WANT_ARM64_WOW64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
- <DelayLoadDLLs>advapi32.dll;bcrypt.dll;cfgmgr32.dll;iphlpapi.dll;ole32.dll;nci.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll</DelayLoadDLLs>
- <AdditionalDependencies>Bcrypt.lib;Cfgmgr32.lib;Iphlpapi.lib;$(IntDir)nci.lib;ntdll.lib;Setupapi.lib;shlwapi.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <DelayLoadDLLs>advapi32.dll;api-ms-win-devices-query-l1-1-0.dll;bcrypt.dll;cfgmgr32.dll;iphlpapi.dll;ole32.dll;nci.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll</DelayLoadDLLs>
+ <AdditionalDependencies>Bcrypt.lib;Cfgmgr32.lib;Iphlpapi.lib;onecore.lib;$(IntDir)nci.lib;ntdll.lib;Setupapi.lib;shlwapi.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
<SubSystem>Windows</SubSystem>
</Link>
diff --git a/api/main.c b/api/main.c
index 7e4e2c9..c51f185 100644
--- a/api/main.c
+++ b/api/main.c
@@ -21,7 +21,7 @@ HANDLE ModuleHeap;
SECURITY_ATTRIBUTES SecurityAttributes = { .nLength = sizeof(SECURITY_ATTRIBUTES) };
BOOL IsLocalSystem;
USHORT NativeMachine = IMAGE_FILE_PROCESS;
-BOOL IsWindows10;
+BOOL IsWindows10, IsWindows7;
static FARPROC WINAPI
DelayedLoadLibraryHook(unsigned dliNotify, PDelayLoadInfo pdli)
@@ -72,9 +72,10 @@ cleanupProcessToken:
static void EnvInit(VOID)
{
- DWORD MajorVersion;
- RtlGetNtVersionNumbers(&MajorVersion, NULL, NULL);
+ DWORD MajorVersion, MinorVersion;
+ RtlGetNtVersionNumbers(&MajorVersion, &MinorVersion, NULL);
IsWindows10 = MajorVersion >= 10;
+ IsWindows7 = MajorVersion == 6 && MinorVersion == 1;
#ifdef MAYBE_WOW64
typedef BOOL(WINAPI * IsWow64Process2_t)(
diff --git a/api/main.h b/api/main.h
index 5d3ebb1..e39459a 100644
--- a/api/main.h
+++ b/api/main.h
@@ -24,4 +24,4 @@ extern HANDLE ModuleHeap;
extern SECURITY_ATTRIBUTES SecurityAttributes;
extern BOOL IsLocalSystem;
extern USHORT NativeMachine;
-extern BOOL IsWindows10; \ No newline at end of file
+extern BOOL IsWindows10, IsWindows7; \ No newline at end of file
diff --git a/api/ntdll.h b/api/ntdll.h
index 3782a30..2eb2786 100644
--- a/api/ntdll.h
+++ b/api/ntdll.h
@@ -39,7 +39,6 @@ typedef struct _KEY_NAME_INFORMATION
} KEY_NAME_INFORMATION, *PKEY_NAME_INFORMATION;
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) // TODO: #include <ntstatus.h> instead of this
-#define STATUS_PNP_DEVICE_CONFIGURATION_PENDING ((NTSTATUS)0xC0000495L)
/* We can't use RtlGetVersion, because appcompat's aclayers.dll shims it to report Vista
* when run from legacy contexts. So, we instead use the undocumented RtlGetNtVersionNumbers.
diff --git a/api/registry.c b/api/registry.c
index 05a62a6..245d72f 100644
--- a/api/registry.c
+++ b/api/registry.c
@@ -10,100 +10,6 @@
#include <stdlib.h>
#include <strsafe.h>
-_Must_inspect_result_
-static _Return_type_success_(return != NULL)
-_Post_maybenull_
-HKEY
-OpenKeyWait(_In_ HKEY Key, _Inout_z_ LPWSTR Path, _In_ DWORD Access, _In_ ULONGLONG Deadline)
-{
- DWORD LastError;
- LPWSTR PathNext = wcschr(Path, L'\\');
- if (PathNext)
- *PathNext = 0;
-
- HANDLE Event = CreateEventW(NULL, FALSE, FALSE, NULL);
- if (!Event)
- {
- LOG_LAST_ERROR(L"Failed to create event");
- return NULL;
- }
- for (;;)
- {
- LastError = RegNotifyChangeKeyValue(Key, FALSE, REG_NOTIFY_CHANGE_NAME, Event, TRUE);
- if (LastError != ERROR_SUCCESS)
- {
- WCHAR RegPath[MAX_REG_PATH];
- LoggerGetRegistryKeyPath(Key, RegPath);
- LOG_ERROR(LastError, L"Failed to setup registry key %.*s notification", MAX_REG_PATH, RegPath);
- break;
- }
-
- HKEY Subkey;
- LastError = RegOpenKeyExW(Key, Path, 0, PathNext ? KEY_NOTIFY : Access, &Subkey);
- if (LastError == ERROR_SUCCESS)
- {
- if (PathNext)
- {
- HKEY KeyOut = OpenKeyWait(Subkey, PathNext + 1, Access, Deadline);
- if (KeyOut)
- {
- RegCloseKey(Subkey);
- CloseHandle(Event);
- return KeyOut;
- }
- LastError = GetLastError();
- break;
- }
- else
- {
- CloseHandle(Event);
- return Subkey;
- }
- }
- if (LastError != ERROR_FILE_NOT_FOUND && LastError != ERROR_PATH_NOT_FOUND)
- {
- WCHAR RegPath[MAX_REG_PATH];
- LoggerGetRegistryKeyPath(Key, RegPath);
- LOG_ERROR(LastError, L"Failed to open registry key %.*s\\%s", MAX_REG_PATH, RegPath, Path);
- break;
- }
-
- LONGLONG TimeLeft = Deadline - GetTickCount64();
- if (TimeLeft < 0)
- TimeLeft = 0;
- DWORD Result = WaitForSingleObject(Event, (DWORD)TimeLeft);
- if (Result != WAIT_OBJECT_0)
- {
- WCHAR RegPath[MAX_REG_PATH];
- LoggerGetRegistryKeyPath(Key, RegPath);
- LOG(WIREGUARD_LOG_ERR,
- L"Timeout waiting for registry key %.*s\\%s (status: 0x%x)",
- MAX_REG_PATH,
- RegPath,
- Path,
- Result);
- break;
- }
- }
- CloseHandle(Event);
- SetLastError(LastError);
- return NULL;
-}
-
-_Use_decl_annotations_
-HKEY
-RegistryOpenKeyWait(HKEY Key, LPCWSTR Path, DWORD Access, DWORD Timeout)
-{
- WCHAR Buf[MAX_REG_PATH];
- if (wcsncpy_s(Buf, _countof(Buf), Path, _TRUNCATE) == STRUNCATE)
- {
- LOG(WIREGUARD_LOG_ERR, L"Registry path too long: %s", Path);
- SetLastError(ERROR_INVALID_PARAMETER);
- return NULL;
- }
- return OpenKeyWait(Key, Buf, Access, GetTickCount64() + Timeout);
-}
-
_Use_decl_annotations_
BOOL
RegistryGetString(LPWSTR *Buf, DWORD Len, DWORD ValueType)
@@ -257,59 +163,6 @@ RegistryQueryString(HKEY Key, LPCWSTR Name, BOOL Log)
}
_Use_decl_annotations_
-LPWSTR
-RegistryQueryStringWait(HKEY Key, LPCWSTR Name, DWORD Timeout)
-{
- DWORD LastError;
- ULONGLONG Deadline = GetTickCount64() + Timeout;
- HANDLE Event = CreateEventW(NULL, FALSE, FALSE, NULL);
- if (!Event)
- {
- LOG_LAST_ERROR(L"Failed to create event");
- return NULL;
- }
- for (;;)
- {
- LastError = RegNotifyChangeKeyValue(Key, FALSE, REG_NOTIFY_CHANGE_LAST_SET, Event, TRUE);
- if (LastError != ERROR_SUCCESS)
- {
- WCHAR RegPath[MAX_REG_PATH];
- LoggerGetRegistryKeyPath(Key, RegPath);
- LOG_ERROR(LastError, L"Failed to setup registry key %.*s notification", MAX_REG_PATH, RegPath);
- break;
- }
- LPWSTR Value = RegistryQueryString(Key, Name, FALSE);
- if (Value)
- {
- CloseHandle(Event);
- return Value;
- }
- LastError = GetLastError();
- if (LastError != ERROR_FILE_NOT_FOUND && LastError != ERROR_PATH_NOT_FOUND)
- break;
- LONGLONG TimeLeft = Deadline - GetTickCount64();
- if (TimeLeft < 0)
- TimeLeft = 0;
- DWORD Result = WaitForSingleObject(Event, (DWORD)TimeLeft);
- if (Result != WAIT_OBJECT_0)
- {
- WCHAR RegPath[MAX_REG_PATH];
- LoggerGetRegistryKeyPath(Key, RegPath);
- LOG(WIREGUARD_LOG_ERR,
- L"Timeout waiting for registry value %.*s\\%s (status: 0x%x)",
- MAX_REG_PATH,
- RegPath,
- Name,
- Result);
- break;
- }
- }
- CloseHandle(Event);
- SetLastError(LastError);
- return NULL;
-}
-
-_Use_decl_annotations_
BOOL
RegistryQueryDWORD(HKEY Key, LPCWSTR Name, DWORD *Value, BOOL Log)
{
@@ -344,55 +197,3 @@ RegistryQueryDWORD(HKEY Key, LPCWSTR Name, DWORD *Value, BOOL Log)
}
return TRUE;
}
-
-_Use_decl_annotations_
-BOOL
-RegistryQueryDWORDWait(HKEY Key, LPCWSTR Name, DWORD Timeout, DWORD *Value)
-{
- DWORD LastError;
- ULONGLONG Deadline = GetTickCount64() + Timeout;
- HANDLE Event = CreateEventW(NULL, FALSE, FALSE, NULL);
- if (!Event)
- {
- LOG_LAST_ERROR(L"Failed to create event");
- return FALSE;
- }
- for (;;)
- {
- LastError = RegNotifyChangeKeyValue(Key, FALSE, REG_NOTIFY_CHANGE_LAST_SET, Event, TRUE);
- if (LastError != ERROR_SUCCESS)
- {
- WCHAR RegPath[MAX_REG_PATH];
- LoggerGetRegistryKeyPath(Key, RegPath);
- LOG_ERROR(LastError, L"Failed to setup registry key %.*s notification", MAX_REG_PATH, RegPath);
- break;
- }
- if (RegistryQueryDWORD(Key, Name, Value, FALSE))
- {
- CloseHandle(Event);
- return TRUE;
- }
- LastError = GetLastError();
- if (LastError != ERROR_FILE_NOT_FOUND && LastError != ERROR_PATH_NOT_FOUND)
- break;
- LONGLONG TimeLeft = Deadline - GetTickCount64();
- if (TimeLeft < 0)
- TimeLeft = 0;
- DWORD Result = WaitForSingleObject(Event, (DWORD)TimeLeft);
- if (Result != WAIT_OBJECT_0)
- {
- WCHAR RegPath[MAX_REG_PATH];
- LoggerGetRegistryKeyPath(Key, RegPath);
- LOG(WIREGUARD_LOG_ERR,
- L"Timeout waiting registry value %.*s\\%s (status: 0x%x)",
- MAX_REG_PATH,
- RegPath,
- Name,
- Result);
- break;
- }
- }
- CloseHandle(Event);
- SetLastError(LastError);
- return FALSE;
-}
diff --git a/api/registry.h b/api/registry.h
index 40fc7c7..9f9429d 100644
--- a/api/registry.h
+++ b/api/registry.h
@@ -13,26 +13,6 @@
https://support.microsoft.com/en-us/help/256986/windows-registry-information-for-advanced-users */
/**
- * Opens the specified registry key. It waits for the registry key to become available.
- *
- * @param Key Handle of the parent registry key. Must be opened with notify access.
- *
- * @param Path Subpath of the registry key to open. Zero-terminated string of up to MAX_REG_PATH-1 characters.
- *
- * @param Access A mask that specifies the desired access rights to the key to be opened.
- *
- * @param Timeout Timeout to wait for the value in milliseconds.
- *
- * @return Key handle on success. If the function fails, the return value is zero. To get extended error information,
- * call GetLastError.
- */
-_Must_inspect_result_
-_Return_type_success_(return != NULL)
-_Post_maybenull_
-HKEY
-RegistryOpenKeyWait(_In_ HKEY Key, _In_z_ LPCWSTR Path, _In_ DWORD Access, _In_ DWORD Timeout);
-
-/**
* Validates and/or sanitizes string value read from registry.
*
* @param Buf On input, it contains a pointer to pointer where the data is stored. The data must be allocated
@@ -97,27 +77,6 @@ LPWSTR
RegistryQueryString(_In_ HKEY Key, _In_opt_z_ LPCWSTR Name, _In_ BOOL Log);
/**
- * Reads string value from registry key. It waits for the registry value to become available.
- *
- * @param Key Handle of the registry key to read from. Must be opened with read and notify access.
- *
- * @param Name Name of the value to read.
- *
- * @param Timeout Timeout to wait for the value in milliseconds.
- *
- * @return Registry value. If the value type is REG_EXPAND_SZ the value is expanded using ExpandEnvironmentStrings(). If
- * the value type is REG_MULTI_SZ, only the first string from the multi-string is returned. The string must be
- * released with HeapFree(ModuleHeap, 0, Value) after use. If the function fails, the return value is zero. To
- * get extended error information, call GetLastError. Possible errors include the following:
- * ERROR_INVALID_DATATYPE when the registry value is not a string
- */
-_Must_inspect_result_
-_Return_type_success_(return != NULL)
-_Post_maybenull_
-LPWSTR
-RegistryQueryStringWait(_In_ HKEY Key, _In_opt_z_ LPCWSTR Name, _In_ DWORD Timeout);
-
-/**
* Reads a 32-bit DWORD value from registry key.
*
* @param Key Handle of the registry key to read from. Must be opened with read access.
@@ -137,24 +96,3 @@ _Must_inspect_result_
_Return_type_success_(return != FALSE)
BOOL
RegistryQueryDWORD(_In_ HKEY Key, _In_opt_z_ LPCWSTR Name, _Out_ DWORD *Value, _In_ BOOL Log);
-
-/**
- * Reads a 32-bit DWORD value from registry key. It waits for the registry value to become available.
- *
- * @param Key Handle of the registry key to read from. Must be opened with read access.
- *
- * @param Name Name of the value to read.
- *
- * @param Timeout Timeout to wait for the value in milliseconds.
- *
- * @param Value Pointer to DWORD to retrieve registry value.
- *
- * @return If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To
- * get extended error information, call GetLastError. Possible errors include the following:
- * ERROR_INVALID_DATATYPE when registry value exist but not REG_DWORD type;
- * ERROR_INVALID_DATA when registry value size is not 4 bytes
- */
-_Must_inspect_result_
-_Return_type_success_(return != FALSE)
-BOOL
-RegistryQueryDWORDWait(_In_ HKEY Key, _In_opt_z_ LPCWSTR Name, _In_ DWORD Timeout, _Out_ DWORD *Value);