- don't close handles of keys in RegDeleteTree() that were deleted
- implemented RegConnectRegistryA()
Modified: trunk/reactos/lib/advapi32/reg/reg.c

Modified: trunk/reactos/lib/advapi32/reg/reg.c
--- trunk/reactos/lib/advapi32/reg/reg.c	2005-08-28 15:43:00 UTC (rev 17588)
+++ trunk/reactos/lib/advapi32/reg/reg.c	2005-08-29 13:54:05 UTC (rev 17589)
@@ -320,21 +320,6 @@
 
 
 /************************************************************************
- *  RegConnectRegistryA
- *
- * @unimplemented
- */
-LONG STDCALL
-RegConnectRegistryA (LPCSTR lpMachineName,
-		     HKEY hKey,
-		     PHKEY phkResult)
-{
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return ERROR_CALL_NOT_IMPLEMENTED;
-}
-
-
-/************************************************************************
  *  RegCopyTreeW
  *
  * @unimplemented
@@ -446,6 +431,41 @@
 
 
 /************************************************************************
+ *  RegConnectRegistryA
+ *
+ * @implemented
+ */
+LONG STDCALL
+RegConnectRegistryA (IN LPCSTR lpMachineName,
+                     IN HKEY hKey,
+                     OUT PHKEY phkResult)
+{
+    UNICODE_STRING MachineName;
+    LONG Ret;
+    
+    if (lpMachineName != NULL)
+    {
+        if (!RtlCreateUnicodeStringFromAsciiz(&MachineName,
+                                              (LPSTR)lpMachineName))
+        {
+            return ERROR_NOT_ENOUGH_MEMORY;
+        }
+    }
+    else
+        RtlInitUnicodeString(&MachineName,
+                             NULL);
+
+    Ret = RegConnectRegistryW(MachineName.Buffer,
+                              hKey,
+                              phkResult);
+
+    RtlFreeUnicodeString(&MachineName);
+    
+    return Ret;
+}
+
+
+/************************************************************************
  *  RegConnectRegistryW
  *
  * @unimplemented
@@ -971,7 +991,8 @@
 
 
 static NTSTATUS
-RegpDeleteTree(IN HKEY hKey)
+RegpDeleteTree(IN HKEY hKey,
+               OUT PBOOLEAN KeysDeleted)
 {
     typedef struct
     {
@@ -980,7 +1001,7 @@
     } REGP_DEL_KEYS, *PREG_DEL_KEYS;
 
     LIST_ENTRY delQueueHead;
-    PREG_DEL_KEYS delKeys = NULL, newDelKeys;
+    PREG_DEL_KEYS delKeys, newDelKeys;
     HANDLE ProcessHeap;
     ULONG BufferSize;
     PKEY_BASIC_INFORMATION BasicInfo;
@@ -988,6 +1009,8 @@
     NTSTATUS Status = STATUS_SUCCESS;
     NTSTATUS Status2 = STATUS_SUCCESS;
     
+    *KeysDeleted = FALSE;
+    
     InitializeListHead(&delQueueHead);
     
     ProcessHeap = RtlGetProcessHeap();
@@ -1105,10 +1128,13 @@
                         Status2 = STATUS_INSUFFICIENT_RESOURCES;
                     }
                 }
+
 SubKeyFailure:
+                ASSERT(newDelKeys != NULL);
                 RtlFreeHeap(ProcessHeap,
                             0,
                             newDelKeys);
+
 SubKeyFailureNoFree:
                 /* don't break, let's try to delete as many keys as possible */
                 if (Status2 != STATUS_NO_MORE_ENTRIES && NT_SUCCESS(Status))
@@ -1134,6 +1160,8 @@
                         0,
                         delKeys);
         } while (!IsListEmpty(&delQueueHead));
+        
+        *KeysDeleted = TRUE;
     }
     else
         Status = STATUS_INSUFFICIENT_RESOURCES;
@@ -1151,6 +1179,7 @@
 RegDeleteTreeW(IN HKEY hKey,
                IN LPCWSTR lpSubKey  OPTIONAL)
 {
+    BOOLEAN KeysDeleted;
     HANDLE KeyHandle, CurKey, SubKeyHandle = NULL;
     NTSTATUS Status;
 
@@ -1188,15 +1217,20 @@
     else
         CurKey = KeyHandle;
 
-    Status = RegpDeleteTree(CurKey);
+    Status = RegpDeleteTree(CurKey,
+                            &KeysDeleted);
 
-    if (SubKeyHandle != NULL)
+    if (!KeysDeleted)
     {
-        NtClose(SubKeyHandle);
-    }
+        /* only close handles of keys that weren't deleted! */
+        if (SubKeyHandle != NULL)
+        {
+            NtClose(SubKeyHandle);
+        }
 
 Cleanup:
-    CloseDefaultKey(KeyHandle);
+        CloseDefaultKey(KeyHandle);
+    }
 
     if (!NT_SUCCESS(Status))
     {