* FILE: lib/advapi32/reg/reg.c
* PURPOSE: Registry functions
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
+ * Thomas Weidenmueller <w3seek@reactos.com>
* UPDATE HISTORY:
* Created 01/11/98
* 19990309 EA Stubs
#define REG_MAX_NAME_SIZE 256
#define REG_MAX_DATA_SIZE 2048
-/* FIXME: should go into msvcrt.h header? */
-#define offsetof(s,m) (size_t)&(((s*)NULL)->m)
-
/* GLOBALS ******************************************************************/
static RTL_CRITICAL_SECTION HandleTableCS;
static NTSTATUS MapDefaultKey (PHANDLE ParentKey, HKEY Key);
static VOID CloseDefaultKeys(VOID);
-#define CloseDefaultKey(Handle) \
+#define ClosePredefKey(Handle) \
if ((ULONG_PTR)Handle & 0x1) { \
NtClose(Handle); \
}
+#define IsPredefKey(HKey) \
+ (((ULONG)(HKey) & 0xF0000000) == 0x80000000)
+#define GetPredefKeyIndex(HKey) \
+ ((ULONG)(HKey) & 0x0FFFFFFF)
static NTSTATUS OpenClassesRootKey(PHANDLE KeyHandle);
static NTSTATUS OpenLocalMachineKey (PHANDLE KeyHandle);
/* FUNCTIONS ****************************************************************/
/* check if value type needs string conversion (Ansi<->Unicode) */
-inline static int is_string( DWORD type )
+__inline static int is_string( DWORD type )
{
return (type == REG_SZ) || (type == REG_EXPAND_SZ) || (type == REG_MULTI_SZ);
}
}
+static NTSTATUS
+OpenPredefinedKey(IN ULONG Index,
+ OUT HANDLE Handle)
+{
+ NTSTATUS Status;
+
+ switch (Index)
+ {
+ case 0: /* HKEY_CLASSES_ROOT */
+ Status = OpenClassesRootKey (Handle);
+ break;
+
+ case 1: /* HKEY_CURRENT_USER */
+ Status = RtlOpenCurrentUser (MAXIMUM_ALLOWED,
+ Handle);
+ break;
+
+ case 2: /* HKEY_LOCAL_MACHINE */
+ Status = OpenLocalMachineKey (Handle);
+ break;
+
+ case 3: /* HKEY_USERS */
+ Status = OpenUsersKey (Handle);
+ break;
+#if 0
+ case 4: /* HKEY_PERFORMANCE_DATA */
+ Status = OpenPerformanceDataKey (Handle);
+ break;
+#endif
+
+ case 5: /* HKEY_CURRENT_CONFIG */
+ Status = OpenCurrentConfigKey (Handle);
+ break;
+
+ case 6: /* HKEY_DYN_DATA */
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ default:
+ WARN("MapDefaultHandle() no handle creator\n");
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ return Status;
+}
+
+
static NTSTATUS
MapDefaultKey (OUT PHANDLE RealKey,
IN HKEY Key)
TRACE("MapDefaultKey (Key %x)\n", Key);
- if (((ULONG)Key & 0xF0000000) != 0x80000000)
+ if (!IsPredefKey(Key))
{
*RealKey = (HANDLE)((ULONG_PTR)Key & ~0x1);
return STATUS_SUCCESS;
}
/* Handle special cases here */
- Index = (ULONG)Key & 0x0FFFFFFF;
+ Index = GetPredefKeyIndex(Key);
if (Index >= MAX_DEFAULT_HANDLES)
{
return STATUS_INVALID_PARAMETER;
if (DoOpen)
{
/* create/open the default handle */
- switch (Index)
- {
- case 0: /* HKEY_CLASSES_ROOT */
- Status = OpenClassesRootKey (Handle);
- break;
-
- case 1: /* HKEY_CURRENT_USER */
- Status = RtlOpenCurrentUser (MAXIMUM_ALLOWED,
- Handle);
- break;
-
- case 2: /* HKEY_LOCAL_MACHINE */
- Status = OpenLocalMachineKey (Handle);
- break;
-
- case 3: /* HKEY_USERS */
- Status = OpenUsersKey (Handle);
- break;
-#if 0
- case 4: /* HKEY_PERFORMANCE_DATA */
- Status = OpenPerformanceDataKey (Handle);
- break;
-#endif
- case 5: /* HKEY_CURRENT_CONFIG */
- Status = OpenCurrentConfigKey (Handle);
- break;
-
- case 6: /* HKEY_DYN_DATA */
- Status = STATUS_NOT_IMPLEMENTED;
- break;
-
- default:
- WARN("MapDefaultHandle() no handle creator\n");
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
+ Status = OpenPredefinedKey(Index,
+ Handle);
}
if (NT_SUCCESS(Status))
}
+/************************************************************************
+ * RegOverridePredefKey
+ *
+ * @implemented
+ */
+LONG STDCALL
+RegOverridePredefKey(IN HKEY hKey,
+ IN HKEY hNewHKey OPTIONAL)
+{
+ LONG ErrorCode = ERROR_SUCCESS;
+
+ if ((hKey == HKEY_CLASSES_ROOT ||
+ hKey == HKEY_CURRENT_CONFIG ||
+ hKey == HKEY_CURRENT_USER ||
+ hKey == HKEY_LOCAL_MACHINE ||
+ hKey == HKEY_PERFORMANCE_DATA ||
+ hKey == HKEY_USERS) &&
+ !IsPredefKey(hNewHKey))
+ {
+ PHANDLE Handle;
+ ULONG Index;
+
+ Index = GetPredefKeyIndex(hKey);
+ Handle = &DefaultHandleTable[Index];
+
+ if (hNewHKey == NULL)
+ {
+ /* restore the default mapping */
+ NTSTATUS Status = OpenPredefinedKey(Index,
+ &hNewHKey);
+ if (!NT_SUCCESS(Status))
+ {
+ return RtlNtStatusToDosError(Status);
+ }
+
+ ASSERT(hNewHKey != NULL);
+ }
+
+ RtlEnterCriticalSection (&HandleTableCS);
+
+ /* close the currently mapped handle if existing */
+ if (*Handle != NULL)
+ {
+ NtClose(*Handle);
+ }
+
+ /* update the mapping */
+ *Handle = hNewHKey;
+
+ RtlLeaveCriticalSection (&HandleTableCS);
+ }
+ else
+ ErrorCode = ERROR_INVALID_HANDLE;
+
+ return ErrorCode;
+}
+
+
/************************************************************************
* RegCloseKey
*
}
+static NTSTATUS
+RegpCopyTree(IN HKEY hKeySrc,
+ IN HKEY hKeyDest)
+{
+ typedef struct
+ {
+ LIST_ENTRY ListEntry;
+ HANDLE hKeySrc;
+ HANDLE hKeyDest;
+ } REGP_COPY_KEYS, *PREGP_COPY_KEYS;
+
+ LIST_ENTRY copyQueueHead;
+ PREGP_COPY_KEYS copyKeys, newCopyKeys;
+ union
+ {
+ KEY_VALUE_FULL_INFORMATION *KeyValue;
+ KEY_NODE_INFORMATION *KeyNode;
+ PVOID Buffer;
+ } Info;
+ ULONG Index, BufferSizeRequired, BufferSize = 0x200;
+ NTSTATUS Status = STATUS_SUCCESS;
+ NTSTATUS Status2 = STATUS_SUCCESS;
+
+ InitializeListHead(©QueueHead);
+
+ Info.Buffer = RtlAllocateHeap(ProcessHeap,
+ 0,
+ BufferSize);
+ if (Info.Buffer == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ copyKeys = RtlAllocateHeap(ProcessHeap,
+ 0,
+ sizeof(REGP_COPY_KEYS));
+ if (copyKeys != NULL)
+ {
+ copyKeys->hKeySrc = hKeySrc;
+ copyKeys->hKeyDest = hKeyDest;
+ InsertHeadList(©QueueHead,
+ ©Keys->ListEntry);
+
+ /* FIXME - copy security from hKeySrc to hKeyDest or just for the subkeys? */
+
+ do
+ {
+ copyKeys = CONTAINING_RECORD(copyQueueHead.Flink,
+ REGP_COPY_KEYS,
+ ListEntry);
+
+ /* enumerate all values and copy them */
+ Index = 0;
+ for (;;)
+ {
+ Status2 = NtEnumerateValueKey(copyKeys->hKeySrc,
+ Index,
+ KeyValueFullInformation,
+ Info.KeyValue,
+ BufferSize,
+ &BufferSizeRequired);
+ if (NT_SUCCESS(Status2))
+ {
+ UNICODE_STRING ValueName;
+ PVOID Data;
+
+ /* don't use RtlInitUnicodeString as the string is not NULL-terminated! */
+ ValueName.Length = Info.KeyValue->NameLength;
+ ValueName.MaximumLength = ValueName.Length;
+ ValueName.Buffer = Info.KeyValue->Name;
+
+ Data = (PVOID)((ULONG_PTR)Info.KeyValue + Info.KeyValue->DataOffset);
+
+ Status2 = NtSetValueKey(copyKeys->hKeyDest,
+ &ValueName,
+ Info.KeyValue->TitleIndex,
+ Info.KeyValue->Type,
+ Data,
+ Info.KeyValue->DataLength);
+
+ /* don't break, let's try to copy as many values as possible */
+ if (!NT_SUCCESS(Status2) && NT_SUCCESS(Status))
+ {
+ Status = Status2;
+ }
+
+ Index++;
+ }
+ else if (Status2 == STATUS_BUFFER_OVERFLOW)
+ {
+ PVOID Buffer;
+
+ ASSERT(BufferSize < BufferSizeRequired);
+
+ Buffer = RtlReAllocateHeap(ProcessHeap,
+ 0,
+ Info.Buffer,
+ BufferSizeRequired);
+ if (Buffer != NULL)
+ {
+ Info.Buffer = Buffer;
+ /* try again */
+ }
+ else
+ {
+ /* don't break, let's try to copy as many values as possible */
+ Status2 = STATUS_INSUFFICIENT_RESOURCES;
+ Index++;
+
+ if (NT_SUCCESS(Status))
+ {
+ Status = Status2;
+ }
+ }
+ }
+ else
+ {
+ /* break to avoid an infinite loop in case of denied access or
+ other errors! */
+ if (Status2 != STATUS_NO_MORE_ENTRIES && NT_SUCCESS(Status))
+ {
+ Status = Status2;
+ }
+
+ break;
+ }
+ }
+
+ /* enumerate all subkeys and open and enqueue them */
+ Index = 0;
+ for (;;)
+ {
+ Status2 = NtEnumerateKey(copyKeys->hKeySrc,
+ Index,
+ KeyNodeInformation,
+ Info.KeyNode,
+ BufferSize,
+ &BufferSizeRequired);
+ if (NT_SUCCESS(Status2))
+ {
+ HANDLE KeyHandle, NewKeyHandle;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING SubKeyName, ClassName;
+
+ /* don't use RtlInitUnicodeString as the string is not NULL-terminated! */
+ SubKeyName.Length = Info.KeyNode->NameLength;
+ SubKeyName.MaximumLength = SubKeyName.Length;
+ SubKeyName.Buffer = Info.KeyNode->Name;
+ ClassName.Length = Info.KeyNode->ClassLength;
+ ClassName.MaximumLength = ClassName.Length;
+ ClassName.Buffer = (PWSTR)((ULONG_PTR)Info.KeyNode + Info.KeyNode->ClassOffset);
+
+ /* open the subkey with sufficient rights */
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &SubKeyName,
+ OBJ_CASE_INSENSITIVE,
+ copyKeys->hKeySrc,
+ NULL);
+
+ Status2 = NtOpenKey(&KeyHandle,
+ KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
+ &ObjectAttributes);
+ if (NT_SUCCESS(Status2))
+ {
+ /* FIXME - attempt to query the security information */
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &SubKeyName,
+ OBJ_CASE_INSENSITIVE,
+ copyKeys->hKeyDest,
+ NULL);
+
+ Status2 = NtCreateKey(&NewKeyHandle,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes,
+ Info.KeyNode->TitleIndex,
+ &ClassName,
+ 0,
+ NULL);
+ if (NT_SUCCESS(Status2))
+ {
+ newCopyKeys = RtlAllocateHeap(ProcessHeap,
+ 0,
+ sizeof(REGP_COPY_KEYS));
+ if (newCopyKeys != NULL)
+ {
+ /* save the handles and enqueue the subkey */
+ newCopyKeys->hKeySrc = KeyHandle;
+ newCopyKeys->hKeyDest = NewKeyHandle;
+ InsertTailList(©QueueHead,
+ &newCopyKeys->ListEntry);
+ }
+ else
+ {
+ NtClose(KeyHandle);
+ NtClose(NewKeyHandle);
+
+ Status2 = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+ else
+ {
+ NtClose(KeyHandle);
+ }
+ }
+
+ if (!NT_SUCCESS(Status2) && NT_SUCCESS(Status))
+ {
+ Status = Status2;
+ }
+
+ Index++;
+ }
+ else if (Status2 == STATUS_BUFFER_OVERFLOW)
+ {
+ PVOID Buffer;
+
+ ASSERT(BufferSize < BufferSizeRequired);
+
+ Buffer = RtlReAllocateHeap(ProcessHeap,
+ 0,
+ Info.Buffer,
+ BufferSizeRequired);
+ if (Buffer != NULL)
+ {
+ Info.Buffer = Buffer;
+ /* try again */
+ }
+ else
+ {
+ /* don't break, let's try to copy as many keys as possible */
+ Status2 = STATUS_INSUFFICIENT_RESOURCES;
+ Index++;
+
+ if (NT_SUCCESS(Status))
+ {
+ Status = Status2;
+ }
+ }
+ }
+ else
+ {
+ /* break to avoid an infinite loop in case of denied access or
+ other errors! */
+ if (Status2 != STATUS_NO_MORE_ENTRIES && NT_SUCCESS(Status))
+ {
+ Status = Status2;
+ }
+
+ break;
+ }
+ }
+
+ /* close the handles and remove the entry from the list */
+ if (copyKeys->hKeySrc != hKeySrc)
+ {
+ NtClose(copyKeys->hKeySrc);
+ }
+ if (copyKeys->hKeyDest != hKeyDest)
+ {
+ NtClose(copyKeys->hKeyDest);
+ }
+
+ RemoveEntryList(©Keys->ListEntry);
+
+ RtlFreeHeap(ProcessHeap,
+ 0,
+ copyKeys);
+ } while (!IsListEmpty(©QueueHead));
+ }
+ else
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+
+ RtlFreeHeap(ProcessHeap,
+ 0,
+ Info.Buffer);
+
+ return Status;
+}
+
+
/************************************************************************
* RegCopyTreeW
*
- * @unimplemented
+ * @implemented
*/
LONG STDCALL
RegCopyTreeW(IN HKEY hKeySrc,
NULL);
Status = NtOpenKey(&SubKeyHandle,
- KEY_READ,
+ KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
else
CurKey = KeyHandle;
- /* FIXME - copy all keys and values recursively */
- Status = STATUS_NOT_IMPLEMENTED;
+ Status = RegpCopyTree(CurKey,
+ hKeyDest);
if (SubKeyHandle != NULL)
{
}
Cleanup:
- CloseDefaultKey(DestKeyHandle);
+ ClosePredefKey(DestKeyHandle);
Cleanup2:
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
if (!NT_SUCCESS(Status))
{
IN LPCSTR lpSubKey OPTIONAL,
IN HKEY hKeyDest)
{
- UNICODE_STRING SubKeyName;
+ UNICODE_STRING SubKeyName = {0};
LONG Ret;
- if (lpSubKey != NULL)
+ if (lpSubKey != NULL &&
+ !RtlCreateUnicodeStringFromAsciiz(&SubKeyName,
+ (LPSTR)lpSubKey))
{
- if (!RtlCreateUnicodeStringFromAsciiz(&SubKeyName,
- (LPSTR)lpSubKey))
- {
- return ERROR_NOT_ENOUGH_MEMORY;
- }
+ return ERROR_NOT_ENOUGH_MEMORY;
}
- else
- RtlInitUnicodeString(&SubKeyName,
- NULL);
Ret = RegCopyTreeW(hKeySrc,
SubKeyName.Buffer,
IN HKEY hKey,
OUT PHKEY phkResult)
{
- UNICODE_STRING MachineName;
+ UNICODE_STRING MachineName = {0};
LONG Ret;
- if (lpMachineName != NULL)
+ if (lpMachineName != NULL &&
+ !RtlCreateUnicodeStringFromAsciiz(&MachineName,
+ (LPSTR)lpMachineName))
{
- if (!RtlCreateUnicodeStringFromAsciiz(&MachineName,
- (LPSTR)lpMachineName))
- {
- return ERROR_NOT_ENOUGH_MEMORY;
- }
+ return ERROR_NOT_ENOUGH_MEMORY;
}
- else
- RtlInitUnicodeString(&MachineName,
- NULL);
Ret = RegConnectRegistryW(MachineName.Buffer,
hKey,
RtlFreeUnicodeString (&ClassString);
}
- CloseDefaultKey(ParentKey);
+ ClosePredefKey(ParentKey);
TRACE("Status %x\n", Status);
if (!NT_SUCCESS(Status))
samDesired,
lpdwDisposition);
- CloseDefaultKey(ParentKey);
+ ClosePredefKey(ParentKey);
TRACE("Status %x\n", Status);
if (!NT_SUCCESS(Status))
NtClose (TargetKey);
Cleanup:
- CloseDefaultKey(ParentKey);
+ ClosePredefKey(ParentKey);
if (!NT_SUCCESS(Status))
{
NtClose (TargetKey);
Cleanup:
- CloseDefaultKey(ParentKey);
+ ClosePredefKey(ParentKey);
if (!NT_SUCCESS(Status))
{
}
Cleanup:
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
if (!NT_SUCCESS(Status))
{
IN LPCSTR lpSubKey OPTIONAL,
IN LPCSTR lpValueName OPTIONAL)
{
- UNICODE_STRING SubKey, ValueName;
+ UNICODE_STRING SubKey = {0}, ValueName = {0};
LONG Ret;
- if (lpSubKey != NULL)
+ if (lpSubKey != NULL &&
+ !RtlCreateUnicodeStringFromAsciiz(&SubKey,
+ (LPSTR)lpSubKey))
{
- if (!RtlCreateUnicodeStringFromAsciiz(&SubKey,
- (LPSTR)lpSubKey))
- {
- return ERROR_NOT_ENOUGH_MEMORY;
- }
+ return ERROR_NOT_ENOUGH_MEMORY;
}
- else
- RtlInitUnicodeString(&SubKey,
- NULL);
- if (lpValueName != NULL)
+ if (lpValueName != NULL &&
+ !RtlCreateUnicodeStringFromAsciiz(&ValueName,
+ (LPSTR)lpValueName))
{
- if (!RtlCreateUnicodeStringFromAsciiz(&ValueName,
- (LPSTR)lpValueName))
- {
- RtlFreeUnicodeString(&SubKey);
- return ERROR_NOT_ENOUGH_MEMORY;
- }
+ RtlFreeUnicodeString(&SubKey);
+ return ERROR_NOT_ENOUGH_MEMORY;
}
- else
- RtlInitUnicodeString(&ValueName,
- NULL);
Ret = RegDeleteKeyValueW(hKey,
SubKey.Buffer,
static NTSTATUS
-RegpDeleteTree(IN HKEY hKey,
- OUT PBOOLEAN KeysDeleted)
+RegpDeleteTree(IN HKEY hKey)
{
typedef struct
{
NTSTATUS Status = STATUS_SUCCESS;
NTSTATUS Status2 = STATUS_SUCCESS;
- *KeysDeleted = FALSE;
-
InitializeListHead(&delQueueHead);
ProcessHeap = RtlGetProcessHeap();
/* open the subkey */
Status2 = NtOpenKey(&newDelKeys->KeyHandle,
- DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
+ DELETE | KEY_ENUMERATE_SUB_KEYS,
&ObjectAttributes);
if (!NT_SUCCESS(Status2))
{
Status2 = STATUS_INSUFFICIENT_RESOURCES;
}
}
+ else if (Status2 == STATUS_NO_MORE_ENTRIES)
+ {
+ /* in some race conditions where another thread would delete
+ the same tree at the same time, newDelKeys could actually
+ be != NULL! */
+ if (newDelKeys != NULL)
+ {
+ RtlFreeHeap(ProcessHeap,
+ 0,
+ newDelKeys);
+ }
+ break;
+ }
SubKeyFailure:
- ASSERT(newDelKeys != NULL);
- RtlFreeHeap(ProcessHeap,
- 0,
- newDelKeys);
+ /* newDelKeys can be NULL here when NtEnumerateKey returned an
+ error other than STATUS_BUFFER_TOO_SMALL or STATUS_BUFFER_OVERFLOW! */
+ if (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))
+ if (NT_SUCCESS(Status))
{
Status = Status2;
}
/* 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 */
0,
delKeys);
} while (!IsListEmpty(&delQueueHead));
-
- *KeysDeleted = TRUE;
}
else
Status = STATUS_INSUFFICIENT_RESOURCES;
-
+
return Status;
}
RegDeleteTreeW(IN HKEY hKey,
IN LPCWSTR lpSubKey OPTIONAL)
{
- BOOLEAN KeysDeleted;
HANDLE KeyHandle, CurKey, SubKeyHandle = NULL;
NTSTATUS Status;
NULL);
Status = NtOpenKey(&SubKeyHandle,
- DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
+ DELETE | KEY_ENUMERATE_SUB_KEYS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
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)
+ {
+ ClosePredefKey(KeyHandle);
+ }
+
+ return ERROR_SUCCESS;
+ }
+ else
+ {
+ /* make sure we close all handles we created! */
if (SubKeyHandle != NULL)
{
NtClose(SubKeyHandle);
}
Cleanup:
- CloseDefaultKey(KeyHandle);
- }
-
- if (!NT_SUCCESS(Status))
- {
+ ClosePredefKey(KeyHandle);
+
return RtlNtStatusToDosError(Status);
}
-
- return ERROR_SUCCESS;
}
RegDeleteTreeA(IN HKEY hKey,
IN LPCSTR lpSubKey OPTIONAL)
{
- UNICODE_STRING SubKeyName;
+ UNICODE_STRING SubKeyName = {0};
LONG Ret;
- if (lpSubKey != NULL)
+ if (lpSubKey != NULL &&
+ !RtlCreateUnicodeStringFromAsciiz(&SubKeyName,
+ (LPSTR)lpSubKey))
{
- if (!RtlCreateUnicodeStringFromAsciiz(&SubKeyName,
- (LPSTR)lpSubKey))
- {
- return ERROR_NOT_ENOUGH_MEMORY;
- }
+ return ERROR_NOT_ENOUGH_MEMORY;
}
- else
- RtlInitUnicodeString(&SubKeyName,
- NULL);
Ret = RegDeleteTreeW(hKey,
SubKeyName.Buffer);
}
Cleanup:
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
return Ret;
}
}
Cleanup:
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
return Ret;
}
&ValueName);
RtlFreeUnicodeString (&ValueName);
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
if (!NT_SUCCESS(Status))
{
Status = NtDeleteValueKey (KeyHandle,
&ValueName);
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
if (!NT_SUCCESS(Status))
{
KeyInfo);
Cleanup:
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
return ErrorCode;
}
KeyInfo);
Cleanup:
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
return ErrorCode;
}
DWORD total_size;
char buffer[256], *buf_ptr = buffer;
KEY_VALUE_FULL_INFORMATION *info = (KEY_VALUE_FULL_INFORMATION *)buffer;
- static const int info_size = offsetof( KEY_VALUE_FULL_INFORMATION, Name );
+ static const int info_size = FIELD_OFFSET( KEY_VALUE_FULL_INFORMATION, Name );
//TRACE("(%p,%ld,%p,%p,%p,%p,%p,%p)\n",
// hkey, index, value, val_count, reserved, type, data, count );
done:
if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
return RtlNtStatusToDosError(status);
}
DWORD total_size;
char buffer[256], *buf_ptr = buffer;
KEY_VALUE_FULL_INFORMATION *info = (KEY_VALUE_FULL_INFORMATION *)buffer;
- static const int info_size = offsetof( KEY_VALUE_FULL_INFORMATION, Name );
+ static const int info_size = FIELD_OFFSET( KEY_VALUE_FULL_INFORMATION, Name );
//TRACE("(%p,%ld,%p,%p,%p,%p,%p,%p)\n",
// hkey, index, value, val_count, reserved, type, data, count );
done:
if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
return RtlNtStatusToDosError(status);
}
Status = NtFlushKey (KeyHandle);
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
if (!NT_SUCCESS(Status))
{
TRACE("MapDefaultKey() failed (Status %lx)\n", Status);
return RtlNtStatusToDosError (Status);
}
-
+#ifndef __REACTOS__
Status = NtQuerySecurityObject(KeyHandle,
SecurityInformation,
pSecurityDescriptor,
*lpcbSecurityDescriptor,
lpcbSecurityDescriptor);
+#endif
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
}
- if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFile,
+ if (!RtlDosPathNameToNtPathName_U (lpFile,
&FileName,
NULL,
NULL))
}
Cleanup:
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
return ErrorCode;
}
ErrorCode = RtlNtStatusToDosError (Status);
}
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
return ErrorCode;
}
ErrorCode = RtlNtStatusToDosError (Status);
}
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
return ErrorCode;
}
ErrorCode = RtlNtStatusToDosError (Status);
}
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
return ErrorCode;
}
{
*lpcbMaxValueLen = FullInfo->MaxValueDataLen;
}
-
+#ifndef __REACTOS__
if (lpcbSecurityDescriptor != NULL)
{
Status = NtQuerySecurityObject(KeyHandle,
goto Cleanup;
}
}
+#endif
if (lpftLastWriteTime != NULL)
{
}
Cleanup:
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
return ErrorCode;
}
ValueInfo);
Cleanup:
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
return ErrorCode;
}
}
Cleanup:
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
return ErrorCode;
}
}
/* Convert new file name */
- if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpNewFile,
+ if (!RtlDosPathNameToNtPathName_U (lpNewFile,
&NewFileName,
NULL,
NULL))
NULL);
/* Convert old file name */
- if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpOldFile,
+ if (!RtlDosPathNameToNtPathName_U (lpOldFile,
&OldFileName,
NULL,
NULL))
}
Cleanup:
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
return ErrorCode;
}
return RtlNtStatusToDosError (Status);
}
- if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFile,
+ if (!RtlDosPathNameToNtPathName_U (lpFile,
&FileName,
NULL,
NULL))
NtClose (FileHandle);
Cleanup:
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
}
- if (!RtlDosPathNameToNtPathName_U ((PWSTR)lpFile,
+ if (!RtlDosPathNameToNtPathName_U (lpFile,
&FileName,
NULL,
NULL))
NtClose (FileHandle);
Cleanup:
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
if (!NT_SUCCESS(Status))
{
SecurityInformation,
pSecurityDescriptor);
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
if (!NT_SUCCESS(Status))
{
(PVOID)lpData,
(ULONG)cbData);
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
if (!NT_SUCCESS(Status))
{
}
Cleanup:
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
return ErrorCode;
}
Status = NtUnloadKey (&ObjectAttributes);
- CloseDefaultKey(KeyHandle);
+ ClosePredefKey(KeyHandle);
if (!NT_SUCCESS(Status))
{