From 3ad56b6c40ebf8b5c0694fc42fd7b231f74272ea Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sun, 26 Oct 2008 15:40:44 +0000 Subject: [PATCH] - Port RegDeleteTreeW from Wine, and remove previous implementation (fixes registry regtests). That previous implementation was better due to the fact it was not recursive, however it's buggy and noone managed to fix it since the commit's date (revision ~17000). It's wrapped into #if0-#endif now so the code doesn't get lost. svn path=/trunk/; revision=36994 --- reactos/dll/win32/advapi32/reg/reg.c | 97 +++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/reactos/dll/win32/advapi32/reg/reg.c b/reactos/dll/win32/advapi32/reg/reg.c index 57f8885db0e..171d9b0b453 100644 --- a/reactos/dll/win32/advapi32/reg/reg.c +++ b/reactos/dll/win32/advapi32/reg/reg.c @@ -1427,7 +1427,8 @@ RegDeleteKeyValueA(IN HKEY hKey, return Ret; } - +#if 0 +// Non-recursive RegDeleteTreeW implementation by Thomas, however it needs bugfixing static NTSTATUS RegpDeleteTree(IN HKEY hKey) { @@ -1705,6 +1706,100 @@ Cleanup: return RtlNtStatusToDosError(Status); } } +#endif + +/************************************************************************ + * RegDeleteTreeW + * + * @implemented + */ +LSTATUS +WINAPI +RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey) +{ + LONG ret; + DWORD dwMaxSubkeyLen, dwMaxValueLen; + DWORD dwMaxLen, dwSize; + NTSTATUS Status; + HANDLE KeyHandle; + HKEY hSubKey; + WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf; + + TRACE("(hkey=%p,%p %s)\n", hKey, lpszSubKey, debugstr_w(lpszSubKey)); + + Status = MapDefaultKey(&KeyHandle, + hKey); + if (!NT_SUCCESS(Status)) + { + return RtlNtStatusToDosError(Status); + } + + hSubKey = KeyHandle; + + if(lpszSubKey) + { + ret = RegOpenKeyExW(KeyHandle, lpszSubKey, 0, KEY_READ, &hSubKey); + if (ret) + { + ClosePredefKey(KeyHandle); + return ret; + } + } + + /* Get highest length for keys, values */ + ret = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL, + &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL); + if (ret) goto cleanup; + + dwMaxSubkeyLen++; + dwMaxValueLen++; + dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen); + if (dwMaxLen > sizeof(szNameBuf)/sizeof(WCHAR)) + { + /* Name too big: alloc a buffer for it */ + if (!(lpszName = RtlAllocateHeap( RtlGetProcessHeap(), 0, dwMaxLen*sizeof(WCHAR)))) + { + ret = ERROR_NOT_ENOUGH_MEMORY; + goto cleanup; + } + } + + + /* Recursively delete all the subkeys */ + while (TRUE) + { + dwSize = dwMaxLen; + if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL, + NULL, NULL, NULL)) break; + + ret = RegDeleteTreeW(hSubKey, lpszName); + if (ret) goto cleanup; + } + + if (lpszSubKey) + ret = RegDeleteKeyW(KeyHandle, lpszSubKey); + else + while (TRUE) + { + dwSize = dwMaxLen; + if (RegEnumValueW(KeyHandle, 0, lpszName, &dwSize, + NULL, NULL, NULL, NULL)) break; + + ret = RegDeleteValueW(KeyHandle, lpszName); + if (ret) goto cleanup; + } + +cleanup: + /* Free buffer if allocated */ + if (lpszName != szNameBuf) + RtlFreeHeap( RtlGetProcessHeap(), 0, lpszName); + if(lpszSubKey) + RegCloseKey(hSubKey); + + ClosePredefKey(KeyHandle); + + return ret; +} /************************************************************************