diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-05-04 18:46:59 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-05-05 11:17:39 +0200 |
commit | 747ba7121d1d94dac982b9148076d7006e2c170f (patch) | |
tree | 960900a770c9887c16613f7d02e8479451c12883 /api/registry.c | |
parent | api: don't pass bogus previous buffer size argument (diff) | |
download | wintun-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.c | 71 |
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 |