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; }