- don't close handles of keys in RegDeleteTree() that were deleted

- implemented RegConnectRegistryA()

svn path=/trunk/; revision=17589
This commit is contained in:
Thomas Bluemel 2005-08-29 13:54:05 +00:00
parent 37315f15ba
commit 13115c5ce3

View file

@ -319,21 +319,6 @@ RegCloseKey (HKEY hKey)
} }
/************************************************************************
* RegConnectRegistryA
*
* @unimplemented
*/
LONG STDCALL
RegConnectRegistryA (LPCSTR lpMachineName,
HKEY hKey,
PHKEY phkResult)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
/************************************************************************ /************************************************************************
* RegCopyTreeW * RegCopyTreeW
* *
@ -445,6 +430,41 @@ RegCopyTreeA(IN HKEY hKeySrc,
} }
/************************************************************************
* 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 * RegConnectRegistryW
* *
@ -971,7 +991,8 @@ RegDeleteKeyValueA(IN HKEY hKey,
static NTSTATUS static NTSTATUS
RegpDeleteTree(IN HKEY hKey) RegpDeleteTree(IN HKEY hKey,
OUT PBOOLEAN KeysDeleted)
{ {
typedef struct typedef struct
{ {
@ -980,7 +1001,7 @@ RegpDeleteTree(IN HKEY hKey)
} REGP_DEL_KEYS, *PREG_DEL_KEYS; } REGP_DEL_KEYS, *PREG_DEL_KEYS;
LIST_ENTRY delQueueHead; LIST_ENTRY delQueueHead;
PREG_DEL_KEYS delKeys = NULL, newDelKeys; PREG_DEL_KEYS delKeys, newDelKeys;
HANDLE ProcessHeap; HANDLE ProcessHeap;
ULONG BufferSize; ULONG BufferSize;
PKEY_BASIC_INFORMATION BasicInfo; PKEY_BASIC_INFORMATION BasicInfo;
@ -988,6 +1009,8 @@ RegpDeleteTree(IN HKEY hKey)
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
NTSTATUS Status2 = STATUS_SUCCESS; NTSTATUS Status2 = STATUS_SUCCESS;
*KeysDeleted = FALSE;
InitializeListHead(&delQueueHead); InitializeListHead(&delQueueHead);
ProcessHeap = RtlGetProcessHeap(); ProcessHeap = RtlGetProcessHeap();
@ -1105,10 +1128,13 @@ ReadFirstSubKey:
Status2 = STATUS_INSUFFICIENT_RESOURCES; Status2 = STATUS_INSUFFICIENT_RESOURCES;
} }
} }
SubKeyFailure: SubKeyFailure:
ASSERT(newDelKeys != NULL);
RtlFreeHeap(ProcessHeap, RtlFreeHeap(ProcessHeap,
0, 0,
newDelKeys); newDelKeys);
SubKeyFailureNoFree: SubKeyFailureNoFree:
/* don't break, let's try to delete as many keys as possible */ /* don't break, let's try to delete as many keys as possible */
if (Status2 != STATUS_NO_MORE_ENTRIES && NT_SUCCESS(Status)) if (Status2 != STATUS_NO_MORE_ENTRIES && NT_SUCCESS(Status))
@ -1134,6 +1160,8 @@ SubKeyFailureNoFree:
0, 0,
delKeys); delKeys);
} while (!IsListEmpty(&delQueueHead)); } while (!IsListEmpty(&delQueueHead));
*KeysDeleted = TRUE;
} }
else else
Status = STATUS_INSUFFICIENT_RESOURCES; Status = STATUS_INSUFFICIENT_RESOURCES;
@ -1151,6 +1179,7 @@ LONG STDCALL
RegDeleteTreeW(IN HKEY hKey, RegDeleteTreeW(IN HKEY hKey,
IN LPCWSTR lpSubKey OPTIONAL) IN LPCWSTR lpSubKey OPTIONAL)
{ {
BOOLEAN KeysDeleted;
HANDLE KeyHandle, CurKey, SubKeyHandle = NULL; HANDLE KeyHandle, CurKey, SubKeyHandle = NULL;
NTSTATUS Status; NTSTATUS Status;
@ -1188,15 +1217,20 @@ RegDeleteTreeW(IN HKEY hKey,
else else
CurKey = KeyHandle; 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: Cleanup:
CloseDefaultKey(KeyHandle); CloseDefaultKey(KeyHandle);
}
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {