static RTL_CRITICAL_SECTION HandleTableCS;
static HANDLE DefaultHandleTable[MAX_DEFAULT_HANDLES];
static HANDLE ProcessHeap;
+static BOOLEAN DefaultHandlesDisabled = FALSE;
/* PROTOTYPES ***************************************************************/
static NTSTATUS MapDefaultKey (PHANDLE ParentKey, HKEY Key);
static VOID CloseDefaultKeys(VOID);
+#define CloseDefaultKey(Handle) \
+ if ((ULONG_PTR)Handle & 0x1) { \
+ NtClose(Handle); \
+ }
static NTSTATUS OpenClassesRootKey(PHANDLE KeyHandle);
static NTSTATUS OpenLocalMachineKey (PHANDLE KeyHandle);
static NTSTATUS
-MapDefaultKey (PHANDLE RealKey,
- HKEY Key)
+MapDefaultKey (OUT PHANDLE RealKey,
+ IN HKEY Key)
{
PHANDLE Handle;
ULONG Index;
+ BOOLEAN DoOpen;
NTSTATUS Status = STATUS_SUCCESS;
TRACE("MapDefaultKey (Key %x)\n", Key);
if (((ULONG)Key & 0xF0000000) != 0x80000000)
{
- *RealKey = (HANDLE)Key;
+ *RealKey = (HANDLE)((ULONG_PTR)Key & ~0x1);
return STATUS_SUCCESS;
}
}
RtlEnterCriticalSection (&HandleTableCS);
- Handle = &DefaultHandleTable[Index];
- if (*Handle == NULL)
+
+ if (!DefaultHandlesDisabled)
+ {
+ Handle = &DefaultHandleTable[Index];
+ DoOpen = (*Handle == NULL);
+ }
+ else
+ {
+ Handle = RealKey;
+ DoOpen = TRUE;
+ }
+
+ if (DoOpen)
{
/* create/open the default handle */
switch (Index)
default:
WARN("MapDefaultHandle() no handle creator\n");
Status = STATUS_INVALID_PARAMETER;
+ break;
}
}
- RtlLeaveCriticalSection (&HandleTableCS);
- if (NT_SUCCESS(Status))
- {
- *RealKey = *Handle;
- }
+ if (NT_SUCCESS(Status))
+ {
+ if (!DefaultHandlesDisabled)
+ *RealKey = *Handle;
+ else
+ *(PULONG_PTR)Handle |= 0x1;
+ }
+
+ RtlLeaveCriticalSection (&HandleTableCS);
return Status;
}
}
+/************************************************************************
+ * RegDisablePredefinedCacheEx
+ *
+ * @implemented
+ */
+LONG STDCALL
+RegDisablePredefinedCacheEx(VOID)
+{
+ RtlEnterCriticalSection (&HandleTableCS);
+ DefaultHandlesDisabled = TRUE;
+ RtlLeaveCriticalSection (&HandleTableCS);
+ return ERROR_SUCCESS;
+}
+
+
/************************************************************************
* RegCloseKey
*
IN LPCWSTR lpSubKey OPTIONAL,
IN HKEY hKeyDest)
{
- HANDLE DestKeyHandle, KeyHandle, SubKeyHandle = NULL;
+ HANDLE DestKeyHandle, KeyHandle, CurKey, SubKeyHandle = NULL;
NTSTATUS Status;
Status = MapDefaultKey(&KeyHandle,
hKeyDest);
if (!NT_SUCCESS(Status))
{
- return RtlNtStatusToDosError(Status);
+ goto Cleanup2;
}
if (lpSubKey != NULL)
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
- return RtlNtStatusToDosError(Status);
+ goto Cleanup;
}
+
+ CurKey = SubKeyHandle;
}
+ else
+ CurKey = KeyHandle;
/* FIXME - copy all keys and values recursively */
Status = STATUS_NOT_IMPLEMENTED;
NtClose(SubKeyHandle);
}
+Cleanup:
+ CloseDefaultKey(DestKeyHandle);
+Cleanup2:
+ CloseDefaultKey(KeyHandle);
+
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError(Status);
/* get the real parent key */
Status = MapDefaultKey (&ParentKey,
- hKey);
+ hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
RtlFreeUnicodeString (&ClassString);
}
+ CloseDefaultKey(ParentKey);
+
TRACE("Status %x\n", Status);
if (!NT_SUCCESS(Status))
{
/* get the real parent key */
Status = MapDefaultKey (&ParentKey,
- hKey);
+ hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError(Status);
dwOptions,
samDesired,
lpdwDisposition);
+
+ CloseDefaultKey(ParentKey);
+
TRACE("Status %x\n", Status);
if (!NT_SUCCESS(Status))
{
NTSTATUS Status;
Status = MapDefaultKey (&ParentKey,
- hKey);
+ hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
RtlFreeUnicodeString (&SubKeyName);
if (!NT_SUCCESS(Status))
{
- return RtlNtStatusToDosError (Status);
+ goto Cleanup;
}
Status = NtDeleteKey (TargetKey);
NtClose (TargetKey);
+
+Cleanup:
+ CloseDefaultKey(ParentKey);
+
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError(Status);
NTSTATUS Status;
Status = MapDefaultKey (&ParentKey,
- hKey);
+ hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
- return RtlNtStatusToDosError (Status);
+ goto Cleanup;
}
Status = NtDeleteKey (TargetKey);
NtClose (TargetKey);
+
+Cleanup:
+ CloseDefaultKey(ParentKey);
+
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
IN LPCWSTR lpValueName OPTIONAL)
{
UNICODE_STRING ValueName;
- HANDLE KeyHandle, SubKeyHandle = NULL;
+ HANDLE KeyHandle, CurKey, SubKeyHandle = NULL;
NTSTATUS Status;
Status = MapDefaultKey(&KeyHandle,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
- return RtlNtStatusToDosError(Status);
+ goto Cleanup;
}
+
+ CurKey = SubKeyHandle;
}
+ else
+ CurKey = KeyHandle;
RtlInitUnicodeString(&ValueName,
(LPWSTR)lpValueName);
- Status = NtDeleteValueKey((SubKeyHandle != NULL) ? SubKeyHandle : KeyHandle,
+ Status = NtDeleteValueKey(CurKey,
&ValueName);
if (SubKeyHandle != NULL)
{
NtClose(SubKeyHandle);
}
+
+Cleanup:
+ CloseDefaultKey(KeyHandle);
if (!NT_SUCCESS(Status))
{
}
+static NTSTATUS
+RegpDeleteTree(IN HKEY hKey)
+{
+ typedef struct
+ {
+ LIST_ENTRY ListEntry;
+ HANDLE KeyHandle;
+ } REGP_DEL_KEYS, *PREG_DEL_KEYS;
+
+ LIST_ENTRY delQueueHead;
+ PREG_DEL_KEYS delKeys = NULL, newDelKeys;
+ HANDLE ProcessHeap;
+ ULONG BufferSize;
+ PKEY_BASIC_INFORMATION BasicInfo;
+ PREG_DEL_KEYS KeyDelRoot;
+ NTSTATUS Status = STATUS_SUCCESS;
+ NTSTATUS Status2 = STATUS_SUCCESS;
+
+ InitializeListHead(&delQueueHead);
+
+ ProcessHeap = RtlGetProcessHeap();
+
+ /* NOTE: no need to allocate enough memory for an additional KEY_BASIC_INFORMATION
+ structure for the root key, we only do that for subkeys as we need to
+ allocate REGP_DEL_KEYS structures anyway! */
+ KeyDelRoot = RtlAllocateHeap(ProcessHeap,
+ 0,
+ sizeof(REGP_DEL_KEYS));
+ if (KeyDelRoot != NULL)
+ {
+ KeyDelRoot->KeyHandle = hKey;
+ InsertTailList(&delQueueHead,
+ &KeyDelRoot->ListEntry);
+
+ do
+ {
+ delKeys = CONTAINING_RECORD(delQueueHead.Flink,
+ REGP_DEL_KEYS,
+ ListEntry);
+
+ BufferSize = 0;
+ BasicInfo = NULL;
+ newDelKeys = NULL;
+
+ReadFirstSubKey:
+ /* check if this key contains subkeys and delete them first by queuing
+ them at the head of the list */
+ Status2 = NtEnumerateKey(delKeys->KeyHandle,
+ 0,
+ KeyBasicInformation,
+ BasicInfo,
+ BufferSize,
+ &BufferSize);
+
+ if (NT_SUCCESS(Status2))
+ {
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING SubKeyName;
+
+ ASSERT(newDelKeys != NULL);
+ ASSERT(BasicInfo != NULL);
+
+ /* don't use RtlInitUnicodeString as the string is not NULL-terminated! */
+ SubKeyName.Length = BasicInfo->NameLength;
+ SubKeyName.MaximumLength = BasicInfo->NameLength;
+ SubKeyName.Buffer = BasicInfo->Name;
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &SubKeyName,
+ OBJ_CASE_INSENSITIVE,
+ delKeys->KeyHandle,
+ NULL);
+
+ /* open the subkey */
+ Status2 = NtOpenKey(&newDelKeys->KeyHandle,
+ DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status2))
+ {
+ goto SubKeyFailure;
+ }
+
+ /* enqueue this key to the head of the deletion queue */
+ InsertHeadList(&delQueueHead,
+ &newDelKeys->ListEntry);
+
+ /* try again from the head of the list */
+ continue;
+ }
+ else
+ {
+ if (Status2 == STATUS_BUFFER_TOO_SMALL)
+ {
+ newDelKeys = RtlAllocateHeap(ProcessHeap,
+ 0,
+ BufferSize + sizeof(REGP_DEL_KEYS));
+ if (newDelKeys != NULL)
+ {
+ BasicInfo = (PKEY_BASIC_INFORMATION)(newDelKeys + 1);
+
+ /* try again */
+ goto ReadFirstSubKey;
+ }
+ else
+ {
+ /* don't break, let's try to delete as many keys as possible */
+ Status2 = STATUS_INSUFFICIENT_RESOURCES;
+ goto SubKeyFailureNoFree;
+ }
+ }
+ else if (Status2 == STATUS_BUFFER_OVERFLOW)
+ {
+ PREG_DEL_KEYS newDelKeys2;
+
+ ASSERT(newDelKeys != NULL);
+
+ /* we need more memory to query the key name */
+ newDelKeys2 = RtlReAllocateHeap(ProcessHeap,
+ 0,
+ newDelKeys,
+ BufferSize + sizeof(REGP_DEL_KEYS));
+ if (newDelKeys2 != NULL)
+ {
+ newDelKeys = newDelKeys2;
+ BasicInfo = (PKEY_BASIC_INFORMATION)(newDelKeys + 1);
+
+ /* try again */
+ goto ReadFirstSubKey;
+ }
+ else
+ {
+ /* don't break, let's try to delete as many keys as possible */
+ Status2 = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+SubKeyFailure:
+ 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))
+ {
+ Status = Status2;
+ }
+ }
+
+ Status2 = NtDeleteKey(delKeys->KeyHandle);
+
+ /* NOTE: do NOT close the handle anymore, it's invalid already! */
+
+ if (!NT_SUCCESS(Status2) && NT_SUCCESS(Status))
+ {
+ /* don't break, let's try to delete as many keys as possible */
+ Status = Status2;
+ }
+
+ /* remove the entry from the list */
+ RemoveEntryList(&delKeys->ListEntry);
+
+ RtlFreeHeap(ProcessHeap,
+ 0,
+ delKeys);
+ } while (!IsListEmpty(&delQueueHead));
+ }
+ else
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+
+ return Status;
+}
+
+
/************************************************************************
* RegDeleteTreeW
*
- * @unimplemented
+ * @implemented
*/
LONG STDCALL
RegDeleteTreeW(IN HKEY hKey,
IN LPCWSTR lpSubKey OPTIONAL)
{
- HANDLE KeyHandle, SubKeyHandle = NULL;
+ HANDLE KeyHandle, CurKey, SubKeyHandle = NULL;
NTSTATUS Status;
Status = MapDefaultKey(&KeyHandle,
NULL);
Status = NtOpenKey(&SubKeyHandle,
- KEY_READ,
+ DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
- return RtlNtStatusToDosError(Status);
+ goto Cleanup;
}
+
+ CurKey = SubKeyHandle;
}
+ else
+ CurKey = KeyHandle;
- /* FIXME - delete all keys recursively */
- Status = STATUS_NOT_IMPLEMENTED;
+ Status = RegpDeleteTree(CurKey);
if (SubKeyHandle != NULL)
{
NtClose(SubKeyHandle);
}
+Cleanup:
+ CloseDefaultKey(KeyHandle);
+
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError(Status);
IN LPCVOID lpData OPTIONAL,
IN DWORD cbData)
{
- HANDLE KeyHandle, SubKeyHandle = NULL;
+ HANDLE KeyHandle, CurKey, SubKeyHandle = NULL;
NTSTATUS Status;
LONG Ret;
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
- return RtlNtStatusToDosError(Status);
+ Ret = RtlNtStatusToDosError(Status);
+ goto Cleanup;
}
+
+ CurKey = SubKeyHandle;
}
+ else
+ CurKey = KeyHandle;
- Ret = RegSetValueExW((SubKeyHandle != NULL) ? SubKeyHandle : KeyHandle,
+ Ret = RegSetValueExW(CurKey,
lpValueName,
0,
dwType,
{
NtClose(SubKeyHandle);
}
+
+Cleanup:
+ CloseDefaultKey(KeyHandle);
return Ret;
}
IN LPCVOID lpData OPTIONAL,
IN DWORD cbData)
{
- HANDLE KeyHandle, SubKeyHandle = NULL;
+ HANDLE KeyHandle, CurKey, SubKeyHandle = NULL;
NTSTATUS Status;
LONG Ret;
if (!RtlCreateUnicodeStringFromAsciiz(&SubKeyName,
(LPSTR)lpSubKey))
{
- return ERROR_NOT_ENOUGH_MEMORY;
+ Ret = ERROR_NOT_ENOUGH_MEMORY;
+ goto Cleanup;
}
InitializeObjectAttributes(&ObjectAttributes,
if (!NT_SUCCESS(Status))
{
- return RtlNtStatusToDosError(Status);
+ Ret = RtlNtStatusToDosError(Status);
+ goto Cleanup;
}
+
+ CurKey = SubKeyHandle;
}
+ else
+ CurKey = KeyHandle;
- Ret = RegSetValueExA((SubKeyHandle != NULL) ? SubKeyHandle : KeyHandle,
+ Ret = RegSetValueExA(CurKey,
lpValueName,
0,
dwType,
{
NtClose(SubKeyHandle);
}
+
+Cleanup:
+ CloseDefaultKey(KeyHandle);
return Ret;
}
NTSTATUS Status;
Status = MapDefaultKey (&KeyHandle,
- hKey);
+ hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
Status = NtDeleteValueKey (KeyHandle,
&ValueName);
RtlFreeUnicodeString (&ValueName);
+
+ CloseDefaultKey(KeyHandle);
+
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
HANDLE KeyHandle;
Status = MapDefaultKey (&KeyHandle,
- hKey);
+ hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
Status = NtDeleteValueKey (KeyHandle,
&ValueName);
+
+ CloseDefaultKey(KeyHandle);
+
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
KeyInfo = RtlAllocateHeap (ProcessHeap, 0, BufferSize);
if (KeyInfo == NULL)
{
- return ERROR_OUTOFMEMORY;
+ ErrorCode = ERROR_OUTOFMEMORY;
+ goto Cleanup;
}
Status = NtEnumerateKey (KeyHandle,
0,
KeyInfo);
- return ErrorCode;
+Cleanup:
+ CloseDefaultKey(KeyHandle);
+
+ return ErrorCode;
}
NTSTATUS Status;
Status = MapDefaultKey(&KeyHandle,
- hKey);
+ hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
BufferSize);
if (KeyInfo == NULL)
{
- return ERROR_OUTOFMEMORY;
+ ErrorCode = ERROR_OUTOFMEMORY;
+ goto Cleanup;
}
Status = NtEnumerateKey (KeyHandle,
0,
KeyInfo);
+Cleanup:
+ CloseDefaultKey(KeyHandle);
+
return ErrorCode;
}
{
if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
if (!(buf_ptr = HeapAlloc( GetProcessHeap(), 0, total_size )))
- return ERROR_NOT_ENOUGH_MEMORY;
+ {
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ goto done;
+ }
info = (KEY_VALUE_FULL_INFORMATION *)buf_ptr;
status = NtEnumerateValueKey( KeyHandle, index, KeyValueFullInformation,
buf_ptr, total_size, &total_size );
done:
if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+ CloseDefaultKey(KeyHandle);
return RtlNtStatusToDosError(status);
}
{
if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
if (!(buf_ptr = HeapAlloc( GetProcessHeap(), 0, total_size )))
- return ERROR_NOT_ENOUGH_MEMORY;
+ {
+ status = ERROR_NOT_ENOUGH_MEMORY;
+ goto done;
+ }
info = (KEY_VALUE_FULL_INFORMATION *)buf_ptr;
status = NtEnumerateValueKey( KeyHandle, index, KeyValueFullInformation,
buf_ptr, total_size, &total_size );
done:
if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+ CloseDefaultKey(KeyHandle);
return RtlNtStatusToDosError(status);
}
}
Status = MapDefaultKey (&KeyHandle,
- hKey);
+ hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
}
Status = NtFlushKey (KeyHandle);
+
+ CloseDefaultKey(KeyHandle);
+
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
}
Status = MapDefaultKey(&KeyHandle,
- hKey);
+ hKey);
if (!NT_SUCCESS(Status))
{
TRACE("MapDefaultKey() failed (Status %lx)\n", Status);
pSecurityDescriptor,
*lpcbSecurityDescriptor,
lpcbSecurityDescriptor);
+
+ CloseDefaultKey(KeyHandle);
+
if (!NT_SUCCESS(Status))
{
WARN("NtQuerySecurityObject() failed (Status %lx)\n", Status);
UNICODE_STRING KeyName;
HANDLE KeyHandle;
NTSTATUS Status;
+ LONG ErrorCode = ERROR_SUCCESS;
if (hKey == HKEY_PERFORMANCE_DATA)
{
}
Status = MapDefaultKey (&KeyHandle,
- hKey);
+ hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
NULL,
NULL))
{
- return ERROR_BAD_PATHNAME;
+ ErrorCode = ERROR_BAD_PATHNAME;
+ goto Cleanup;
}
InitializeObjectAttributes (&FileObjectAttributes,
if (!NT_SUCCESS(Status))
{
- return RtlNtStatusToDosError (Status);
+ ErrorCode = RtlNtStatusToDosError (Status);
+ goto Cleanup;
}
- return ERROR_SUCCESS;
+Cleanup:
+ CloseDefaultKey(KeyHandle);
+
+ return ErrorCode;
}
IO_STATUS_BLOCK IoStatusBlock;
HANDLE KeyHandle;
NTSTATUS Status;
+ LONG ErrorCode = ERROR_SUCCESS;
if (hKey == HKEY_PERFORMANCE_DATA)
{
}
Status = MapDefaultKey (&KeyHandle,
- hKey);
+ hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
fAsynchronous);
if (!NT_SUCCESS(Status) && Status != STATUS_TIMEOUT)
{
- return RtlNtStatusToDosError (Status);
+ ErrorCode = RtlNtStatusToDosError (Status);
}
- return ERROR_SUCCESS;
+ CloseDefaultKey(KeyHandle);
+
+ return ErrorCode;
}
UNICODE_STRING SubKeyString;
HANDLE KeyHandle;
NTSTATUS Status;
+ LONG ErrorCode = ERROR_SUCCESS;
TRACE("RegOpenKeyExA hKey 0x%x lpSubKey %s ulOptions 0x%x samDesired 0x%x phkResult %p\n",
hKey, lpSubKey, ulOptions, samDesired, phkResult);
RtlFreeUnicodeString (&SubKeyString);
if (!NT_SUCCESS(Status))
{
- return RtlNtStatusToDosError (Status);
+ ErrorCode = RtlNtStatusToDosError (Status);
}
+
+ CloseDefaultKey(KeyHandle);
- return ERROR_SUCCESS;
+ return ErrorCode;
}
UNICODE_STRING SubKeyString;
HANDLE KeyHandle;
NTSTATUS Status;
+ LONG ErrorCode = ERROR_SUCCESS;
TRACE("RegOpenKeyExW hKey 0x%x lpSubKey %S ulOptions 0x%x samDesired 0x%x phkResult %p\n",
hKey, lpSubKey, ulOptions, samDesired, phkResult);
if (!NT_SUCCESS(Status))
{
- return RtlNtStatusToDosError (Status);
+ ErrorCode = RtlNtStatusToDosError (Status);
}
+
+ CloseDefaultKey(KeyHandle);
- return ERROR_SUCCESS;
+ return ErrorCode;
}
ULONG RequiredLength;
UNICODE_STRING UserSidString, UserClassesKeyRoot;
OBJECT_ATTRIBUTES ObjectAttributes;
- LONG ErrorCode;
NTSTATUS Status;
/* check parameters */
/* NOTE - as opposed to all other registry functions windows does indeed
change the last error code in case the caller supplied a invalid
handle for example! */
- ErrorCode = RtlNtStatusToDosError (Status);
- return ErrorCode;
+ return RtlNtStatusToDosError (Status);
}
TokenUserData = RtlAllocateHeap(ProcessHeap,
/* NOTE - as opposed to all other registry functions windows does indeed
change the last error code in case the caller supplied a invalid
handle for example! */
- ErrorCode = RtlNtStatusToDosError (Status);
- return ErrorCode;
+ return RtlNtStatusToDosError (Status);
}
/*
FullInfoSize);
if (FullInfo == NULL)
{
- return ERROR_OUTOFMEMORY;
+ ErrorCode = ERROR_OUTOFMEMORY;
+ goto Cleanup;
}
FullInfo->ClassLength = ClassLength;
FullInfo);
}
- return RtlNtStatusToDosError (Status);
+ ErrorCode = RtlNtStatusToDosError (Status);
+ goto Cleanup;
}
TRACE("SubKeys %d\n", FullInfo->SubKeys);
FullInfo);
}
- return RtlNtStatusToDosError (Status);
+ ErrorCode = RtlNtStatusToDosError (Status);
+ goto Cleanup;
}
}
FullInfo);
}
+Cleanup:
+ CloseDefaultKey(KeyHandle);
+
return ErrorCode;
}
if (lpData != NULL && lpcbData == NULL)
{
- return ERROR_INVALID_PARAMETER;
+ ErrorCode = ERROR_INVALID_PARAMETER;
+ goto Cleanup;
}
RtlInitUnicodeString (&ValueName,
BufferSize);
if (ValueInfo == NULL)
{
- return ERROR_OUTOFMEMORY;
+ ErrorCode = ERROR_OUTOFMEMORY;
+ goto Cleanup;
}
Status = NtQueryValueKey (KeyHandle,
0,
ValueInfo);
+Cleanup:
+ CloseDefaultKey(KeyHandle);
+
return ErrorCode;
}
hKey, lpSubKey, lpValue, lpcbValue ? *lpcbValue : 0);
Status = MapDefaultKey (&KeyHandle,
- hKey);
+ hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
- return RtlNtStatusToDosError (Status);
+ ErrorCode = RtlNtStatusToDosError (Status);
+ goto Cleanup;
}
CloseRealKey = TRUE;
}
NtClose (RealKey);
}
+Cleanup:
+ CloseDefaultKey(KeyHandle);
+
return ErrorCode;
}
HANDLE RealKeyHandle;
HANDLE KeyHandle;
NTSTATUS Status;
+ LONG ErrorCode = ERROR_SUCCESS;
if (hKey == HKEY_PERFORMANCE_DATA)
{
}
Status = MapDefaultKey (&KeyHandle,
- hKey);
+ hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
&KeyObjectAttributes);
if (!NT_SUCCESS(Status))
{
- return RtlNtStatusToDosError (Status);
+ ErrorCode = RtlNtStatusToDosError (Status);
+ goto Cleanup;
}
CloseRealKey = TRUE;
}
{
NtClose (RealKeyHandle);
}
- return ERROR_INVALID_PARAMETER;
+ ErrorCode = ERROR_INVALID_PARAMETER;
+ goto Cleanup;
}
InitializeObjectAttributes (&NewObjectAttributes,
{
NtClose (RealKeyHandle);
}
- return ERROR_INVALID_PARAMETER;
+ ErrorCode = ERROR_INVALID_PARAMETER;
+ goto Cleanup;
}
InitializeObjectAttributes (&OldObjectAttributes,
return RtlNtStatusToDosError (Status);
}
- return ERROR_SUCCESS;
+Cleanup:
+ CloseDefaultKey(KeyHandle);
+
+ return ErrorCode;
}
}
Status = MapDefaultKey (&KeyHandle,
- hKey);
+ hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
NULL,
NULL))
{
- return ERROR_INVALID_PARAMETER;
+ Status = STATUS_INVALID_PARAMETER;
+ goto Cleanup;
}
InitializeObjectAttributes (&ObjectAttributes,
RtlFreeUnicodeString (&FileName);
if (!NT_SUCCESS(Status))
{
- return RtlNtStatusToDosError (Status);
+ goto Cleanup;
}
Status = NtRestoreKey (KeyHandle,
FileHandle,
(ULONG)dwFlags);
NtClose (FileHandle);
+
+Cleanup:
+ CloseDefaultKey(KeyHandle);
+
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
NTSTATUS Status;
Status = MapDefaultKey (&KeyHandle,
- hKey);
+ hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
NULL,
NULL))
{
- return ERROR_INVALID_PARAMETER;
+ Status = STATUS_INVALID_PARAMETER;
+ goto Cleanup;
}
if (lpSecurityAttributes != NULL)
RtlFreeUnicodeString (&FileName);
if (!NT_SUCCESS(Status))
{
- return RtlNtStatusToDosError (Status);
+ goto Cleanup;
}
Status = NtSaveKey (KeyHandle,
FileHandle);
NtClose (FileHandle);
+
+Cleanup:
+ CloseDefaultKey(KeyHandle);
+
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
}
Status = MapDefaultKey (&KeyHandle,
- hKey);
+ hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
Status = NtSetSecurityObject (KeyHandle,
SecurityInformation,
pSecurityDescriptor);
+
+ CloseDefaultKey(KeyHandle);
+
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
NTSTATUS Status;
Status = MapDefaultKey (&KeyHandle,
- hKey);
+ hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
dwType,
(PVOID)lpData,
(ULONG)cbData);
+
+ CloseDefaultKey(KeyHandle);
+
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
LONG ErrorCode;
Status = MapDefaultKey (&KeyHandle,
- hKey);
+ hKey);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
- return RtlNtStatusToDosError (Status);
+ ErrorCode = RtlNtStatusToDosError (Status);
+ goto Cleanup;
}
CloseRealKey = TRUE;
}
NtClose (RealKey);
}
+Cleanup:
+ CloseDefaultKey(KeyHandle);
+
return ErrorCode;
}
NULL);
Status = NtUnloadKey (&ObjectAttributes);
+
+ CloseDefaultKey(KeyHandle);
if (!NT_SUCCESS(Status))
{
return ERROR_SUCCESS;
}
+
+/************************************************************************
+ * RegLoadMUIStringW
+ *
+ * @unimplemented
+ */
+LONG STDCALL
+RegLoadMUIStringW(IN HKEY hKey,
+ IN LPCWSTR pszValue OPTIONAL,
+ OUT LPWSTR pszOutBuf,
+ IN ULONG cbOutBuf,
+ IN ULONG Reserved,
+ IN LPCWSTR pszDirectory OPTIONAL)
+{
+ DPRINT1("RegLoadMUIStringW(0x%p, 0x%p, 0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
+ hKey, pszValue, pszOutBuf, cbOutBuf, Reserved, pszDirectory);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/************************************************************************
+ * RegLoadMUIStringA
+ *
+ * @unimplemented
+ */
+LONG STDCALL
+RegLoadMUIStringA(IN HKEY hKey,
+ IN LPCSTR pszValue OPTIONAL,
+ OUT LPSTR pszOutBuf,
+ IN ULONG cbOutBuf,
+ IN ULONG Reserved,
+ IN LPCSTR pszDirectory OPTIONAL)
+{
+ DPRINT1("RegLoadMUIStringA(0x%p, 0x%p, 0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
+ hKey, pszValue, pszOutBuf, cbOutBuf, Reserved, pszDirectory);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
/* EOF */