fixed some handle leaks in RegDeleteTree() in some failure cases
Modified: trunk/reactos/lib/advapi32/reg/reg.c

Modified: trunk/reactos/lib/advapi32/reg/reg.c
--- trunk/reactos/lib/advapi32/reg/reg.c	2005-09-21 22:55:37 UTC (rev 17977)
+++ trunk/reactos/lib/advapi32/reg/reg.c	2005-09-21 23:56:52 UTC (rev 17978)
@@ -991,8 +991,7 @@
 
 
 static NTSTATUS
-RegpDeleteTree(IN HKEY hKey,
-               OUT PBOOLEAN KeysDeleted)
+RegpDeleteTree(IN HKEY hKey)
 {
     typedef struct
     {
@@ -1009,8 +1008,6 @@
     NTSTATUS Status = STATUS_SUCCESS;
     NTSTATUS Status2 = STATUS_SUCCESS;
     
-    *KeysDeleted = FALSE;
-    
     InitializeListHead(&delQueueHead);
     
     ProcessHeap = RtlGetProcessHeap();
@@ -1147,10 +1144,22 @@
             
             /* NOTE: do NOT close the handle anymore, it's invalid already! */
 
-            if (!NT_SUCCESS(Status2) && NT_SUCCESS(Status))
+            if (!NT_SUCCESS(Status2))
             {
-                /* don't break, let's try to delete as many keys as possible */
-                Status = Status2;
+                /* close the key handle so we don't leak handles for keys we were
+                   unable to delete. But only do this for handles not supplied
+                   by the caller! */
+
+                if (delKeys->KeyHandle != hKey)
+                {
+                    NtClose(delKeys->KeyHandle);
+                }
+
+                if (!NT_SUCCESS(Status))
+                {
+                    /* don't break, let's try to delete as many keys as possible */
+                    Status = Status2;
+                }
             }
             
             /* remove the entry from the list */
@@ -1160,8 +1169,6 @@
                         0,
                         delKeys);
         } while (!IsListEmpty(&delQueueHead));
-        
-        *KeysDeleted = TRUE;
     }
     else
         Status = STATUS_INSUFFICIENT_RESOURCES;
@@ -1179,7 +1186,6 @@
 RegDeleteTreeW(IN HKEY hKey,
                IN LPCWSTR lpSubKey  OPTIONAL)
 {
-    BOOLEAN KeysDeleted;
     HANDLE KeyHandle, CurKey, SubKeyHandle = NULL;
     NTSTATUS Status;
 
@@ -1217,12 +1223,22 @@
     else
         CurKey = KeyHandle;
 
-    Status = RegpDeleteTree(CurKey,
-                            &KeysDeleted);
+    Status = RegpDeleteTree(CurKey);
 
-    if (!KeysDeleted)
+    if (NT_SUCCESS(Status))
     {
-        /* only close handles of keys that weren't deleted! */
+        /* make sure we only close hKey (KeyHandle) when the caller specified a
+           subkey, because the handle would be invalid already! */
+        if (CurKey != KeyHandle)
+        {
+            CloseDefaultKey(KeyHandle);
+        }
+        
+        return ERROR_SUCCESS;
+    }
+    else
+    {
+        /* make sure we close all handles we created! */
         if (SubKeyHandle != NULL)
         {
             NtClose(SubKeyHandle);
@@ -1230,14 +1246,9 @@
 
 Cleanup:
         CloseDefaultKey(KeyHandle);
-    }
-
-    if (!NT_SUCCESS(Status))
-    {
+        
         return RtlNtStatusToDosError(Status);
     }
-
-    return ERROR_SUCCESS;
 }