aboutsummaryrefslogtreecommitdiffstats
path: root/api/registry.c
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2021-05-04 18:46:59 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2021-05-05 11:17:39 +0200
commit747ba7121d1d94dac982b9148076d7006e2c170f (patch)
tree960900a770c9887c16613f7d02e8479451c12883 /api/registry.c
parentapi: don't pass bogus previous buffer size argument (diff)
downloadwintun-747ba7121d1d94dac982b9148076d7006e2c170f.tar.xz
wintun-747ba7121d1d94dac982b9148076d7006e2c170f.zip
api: clean up NetSetup2 GUIDs
Recent versions of Windows fail to tidy up, causing issues when reusing GUIDs. Check to see if a GUID might be orphaned, and forcibly clear out the registry state if so. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'api/registry.c')
-rw-r--r--api/registry.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/api/registry.c b/api/registry.c
index 94ae8d4..7cb7cf2 100644
--- a/api/registry.c
+++ b/api/registry.c
@@ -8,6 +8,7 @@
#include "registry.h"
#include <Windows.h>
#include <wchar.h>
+#include <strsafe.h>
static _Return_type_success_(return != NULL) HKEY
OpenKeyWait(_In_ HKEY Key, _Inout_z_ WCHAR *Path, _In_ DWORD Access, _In_ ULONGLONG Deadline)
@@ -397,3 +398,73 @@ _Return_type_success_(return != FALSE) BOOL
SetLastError(LastError);
return FALSE;
}
+
+_Return_type_success_(return != FALSE) static BOOL
+ DeleteNodeRecurse(_In_ HKEY Key, _In_z_ WCHAR *Name)
+{
+ LSTATUS Ret;
+ DWORD Size;
+ SIZE_T Len;
+ WCHAR SubName[MAX_REG_PATH], *End;
+ HKEY SubKey;
+
+ Len = wcslen(Name);
+ if (Len >= MAX_REG_PATH || !Len)
+ return TRUE;
+
+ if (RegDeleteKeyW(Key, Name) == ERROR_SUCCESS)
+ return TRUE;
+
+ Ret = RegOpenKeyEx(Key, Name, 0, KEY_READ, &SubKey);
+ if (Ret != ERROR_SUCCESS)
+ {
+ if (Ret == ERROR_FILE_NOT_FOUND)
+ return TRUE;
+ SetLastError(Ret);
+ return FALSE;
+ }
+
+ End = Name + Len;
+ if (End[-1] != L'\\')
+ {
+ *(End++) = L'\\';
+ *End = L'\0';
+ }
+ Size = MAX_REG_PATH;
+ Ret = RegEnumKeyEx(SubKey, 0, SubName, &Size, NULL, NULL, NULL, NULL);
+ if (Ret == ERROR_SUCCESS)
+ {
+ do
+ {
+ End[0] = L'\0';
+ StringCchCatW(Name, MAX_REG_PATH * 2, SubName);
+ if (!DeleteNodeRecurse(Key, Name))
+ break;
+ Size = MAX_REG_PATH;
+ Ret = RegEnumKeyEx(SubKey, 0, SubName, &Size, NULL, NULL, NULL, NULL);
+ } while (Ret == ERROR_SUCCESS);
+ }
+ else
+ {
+ SetLastError(Ret);
+ *(--End) = L'\0';
+ RegCloseKey(SubKey);
+ return FALSE;
+ }
+ *(--End) = L'\0';
+ RegCloseKey(SubKey);
+
+ Ret = RegDeleteKey(Key, Name);
+ if (Ret == ERROR_SUCCESS)
+ return TRUE;
+ SetLastError(Ret);
+ return FALSE;
+}
+
+_Return_type_success_(return != FALSE) BOOL
+RegistryDeleteKeyRecursive(_In_ HKEY Key, _In_z_ const WCHAR *Name)
+{
+ WCHAR NameBuf[(MAX_REG_PATH + 2) * 2] = { 0 };
+ StringCchCopyW(NameBuf, MAX_REG_PATH * 2, Name);
+ return DeleteNodeRecurse(Key, NameBuf);
+} \ No newline at end of file