Author: fireball
Date: Sun Oct 26 10:40:44 2008
New Revision: 36994
URL:
http://svn.reactos.org/svn/reactos?rev=36994&view=rev
Log:
- 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.
Modified:
trunk/reactos/dll/win32/advapi32/reg/reg.c
Modified: trunk/reactos/dll/win32/advapi32/reg/reg.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/reg/reg…
==============================================================================
--- trunk/reactos/dll/win32/advapi32/reg/reg.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/advapi32/reg/reg.c [iso-8859-1] Sun Oct 26 10:40:44 2008
@@ -1427,7 +1427,8 @@
return Ret;
}
-
+#if 0
+// Non-recursive RegDeleteTreeW implementation by Thomas, however it needs bugfixing
static NTSTATUS
RegpDeleteTree(IN HKEY hKey)
{
@@ -1704,6 +1705,100 @@
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;
}