--- trunk/reactos/lib/ntdll/rtl/registry.c 2005-01-18 04:25:27 UTC (rev 13112)
+++ trunk/reactos/lib/ntdll/rtl/registry.c 2005-01-18 04:33:31 UTC (rev 13113)
@@ -1,1125 +0,0 @@
-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * PURPOSE: Rtl registry functions
- * FILE: lib/ntdll/rtl/registry.c
- * PROGRAMER: Eric Kohl
- * REVISION HISTORY:
- * 2000/08/11: Created
- */
-
-/*
- * TODO:
- * - finish RtlQueryRegistryValues()
- * - support RTL_QUERY_REGISTRY_DELETE
- */
-
-/* INCLUDES ****************************************************************/
-
-#include <ddk/ntddk.h>
-#include <ntdll/rtl.h>
-#include <ntos/minmax.h>
-
-#define NDEBUG
-#include <ntdll/ntdll.h>
-
-
-/* FUNCTIONS ***************************************************************/
-
-static NTSTATUS
-RtlpGetRegistryHandle(ULONG RelativeTo,
- PWSTR Path,
- BOOLEAN Create,
- PHANDLE KeyHandle)
-{
- UNICODE_STRING KeyPath;
- UNICODE_STRING KeyName;
- WCHAR KeyBuffer[MAX_PATH];
- OBJECT_ATTRIBUTES ObjectAttributes;
- NTSTATUS Status;
-
- DPRINT("RtlpGetRegistryHandle()\n");
-
- if (RelativeTo & RTL_REGISTRY_HANDLE)
- {
- Status = NtDuplicateObject(NtCurrentProcess(),
- (HANDLE)Path,
- NtCurrentProcess(),
- KeyHandle,
- 0,
- FALSE,
- DUPLICATE_SAME_ACCESS);
- return(Status);
- }
-
- if (RelativeTo & RTL_REGISTRY_OPTIONAL)
- RelativeTo &= ~RTL_REGISTRY_OPTIONAL;
-
- if (RelativeTo >= RTL_REGISTRY_MAXIMUM)
- return(STATUS_INVALID_PARAMETER);
-
- KeyName.Length = 0;
- KeyName.MaximumLength = MAX_PATH;
- KeyName.Buffer = KeyBuffer;
- KeyBuffer[0] = 0;
-
- switch (RelativeTo)
- {
- case RTL_REGISTRY_ABSOLUTE:
- RtlAppendUnicodeToString(&KeyName,
- L"\\");
- break;
-
- case RTL_REGISTRY_SERVICES:
- RtlAppendUnicodeToString(&KeyName,
- L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
- break;
-
- case RTL_REGISTRY_CONTROL:
- RtlAppendUnicodeToString(&KeyName,
- L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\");
- break;
-
- case RTL_REGISTRY_WINDOWS_NT:
- RtlAppendUnicodeToString(&KeyName,
- L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\");
- break;
-
- case RTL_REGISTRY_DEVICEMAP:
- RtlAppendUnicodeToString(&KeyName,
- L"\\Registry\\Machine\\Hardware\\DeviceMap\\");
- break;
-
- case RTL_REGISTRY_USER:
- Status = RtlFormatCurrentUserKeyPath (&KeyPath);
- if (!NT_SUCCESS(Status))
- return(Status);
- RtlAppendUnicodeStringToString (&KeyName,
- &KeyPath);
- RtlFreeUnicodeString (&KeyPath);
- RtlAppendUnicodeToString (&KeyName,
- L"\\");
- break;
-
- /* ReactOS specific */
- case RTL_REGISTRY_ENUM:
- RtlAppendUnicodeToString(&KeyName,
- L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
- break;
- }
-
- DPRINT("KeyName %wZ\n", &KeyName);
-
- if (Path[0] == L'\\' && RelativeTo != RTL_REGISTRY_ABSOLUTE)
- {
- Path++;
- }
- RtlAppendUnicodeToString(&KeyName,
- Path);
-
- DPRINT("KeyName %wZ\n", &KeyName);
-
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
- NULL,
- NULL);
-
- if (Create == TRUE)
- {
- Status = NtCreateKey(KeyHandle,
- KEY_ALL_ACCESS,
- &ObjectAttributes,
- 0,
- NULL,
- 0,
- NULL);
- }
- else
- {
- Status = NtOpenKey(KeyHandle,
- KEY_ALL_ACCESS,
- &ObjectAttributes);
- }
-
- return(Status);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlCheckRegistryKey(IN ULONG RelativeTo,
- IN PWSTR Path)
-{
- HANDLE KeyHandle;
- NTSTATUS Status;
-
- Status = RtlpGetRegistryHandle(RelativeTo,
- Path,
- FALSE,
- &KeyHandle);
- if (!NT_SUCCESS(Status))
- return(Status);
-
- NtClose(KeyHandle);
-
- return(STATUS_SUCCESS);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlCreateRegistryKey(IN ULONG RelativeTo,
- IN PWSTR Path)
-{
- HANDLE KeyHandle;
- NTSTATUS Status;
-
- Status = RtlpGetRegistryHandle(RelativeTo,
- Path,
- TRUE,
- &KeyHandle);
- if (!NT_SUCCESS(Status))
- return(Status);
-
- NtClose(KeyHandle);
-
- return(STATUS_SUCCESS);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlDeleteRegistryValue(IN ULONG RelativeTo,
- IN PCWSTR Path,
- IN PCWSTR ValueName)
-{
- HANDLE KeyHandle;
- NTSTATUS Status;
- UNICODE_STRING Name;
-
- Status = RtlpGetRegistryHandle(RelativeTo,
- (PWSTR)Path,
- FALSE,
- &KeyHandle);
- if (!NT_SUCCESS(Status))
- return(Status);
-
- RtlInitUnicodeString(&Name,
- ValueName);
-
- Status = NtDeleteValueKey(KeyHandle,
- &Name);
-
- NtClose(KeyHandle);
-
- return(Status);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlFormatCurrentUserKeyPath (OUT PUNICODE_STRING KeyPath)
-{
- HANDLE TokenHandle;
- UCHAR Buffer[256];
- PSID_AND_ATTRIBUTES SidBuffer;
- ULONG Length;
- UNICODE_STRING SidString;
- NTSTATUS Status;
-
- DPRINT ("RtlFormatCurrentUserKeyPath() called\n");
-
- Status = NtOpenThreadToken (NtCurrentThread (),
- TOKEN_READ,
- TRUE,
- &TokenHandle);
- if (!NT_SUCCESS (Status))
- {
- if (Status != STATUS_NO_TOKEN)
- {
- DPRINT1 ("NtOpenThreadToken() failed (Status %lx)\n", Status);
- return Status;
- }
-
- Status = NtOpenProcessToken (NtCurrentProcess (),
- TOKEN_READ,
- &TokenHandle);
- if (!NT_SUCCESS (Status))
- {
- DPRINT1 ("NtOpenProcessToken() failed (Status %lx)\n", Status);
- return Status;
- }
- }
-
- SidBuffer = (PSID_AND_ATTRIBUTES)Buffer;
- Status = NtQueryInformationToken (TokenHandle,
- TokenUser,
- (PVOID)SidBuffer,
- 256,
- &Length);
- NtClose (TokenHandle);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1 ("NtQueryInformationToken() failed (Status %lx)\n", Status);
- return Status;
- }
-
- Status = RtlConvertSidToUnicodeString (&SidString,
- SidBuffer[0].Sid,
- TRUE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1 ("RtlConvertSidToUnicodeString() failed (Status %lx)\n", Status);
- return Status;
- }
-
- DPRINT ("SidString: '%wZ'\n", &SidString);
-
- Length = SidString.Length + sizeof(L"\\Registry\\User\\");
- DPRINT ("Length: %lu\n", Length);
-
- KeyPath->Length = 0;
- KeyPath->MaximumLength = Length;
- KeyPath->Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
- 0,
- KeyPath->MaximumLength);
- if (KeyPath->Buffer == NULL)
- {
- DPRINT1 ("RtlAllocateHeap() failed\n");
- RtlFreeUnicodeString (&SidString);
- return STATUS_NO_TOKEN;
- }
-
- RtlAppendUnicodeToString (KeyPath,
- L"\\Registry\\User\\");
- RtlAppendUnicodeStringToString (KeyPath,
- &SidString);
- RtlFreeUnicodeString (&SidString);
-
- return STATUS_SUCCESS;
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlOpenCurrentUser(IN ACCESS_MASK DesiredAccess,
- OUT PHANDLE KeyHandle)
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING KeyPath;
- NTSTATUS Status;
-
- Status = RtlFormatCurrentUserKeyPath(&KeyPath);
- if (NT_SUCCESS(Status))
- {
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyPath,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
- Status = NtOpenKey(KeyHandle,
- DesiredAccess,
- &ObjectAttributes);
- RtlFreeUnicodeString(&KeyPath);
- if (NT_SUCCESS(Status))
- {
- return STATUS_SUCCESS;
- }
- }
-
- RtlInitUnicodeString (&KeyPath,
- L"\\Registry\\User\\.Default");
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyPath,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
- Status = NtOpenKey(KeyHandle,
- DesiredAccess,
- &ObjectAttributes);
-
- return Status;
-}
-
-
-/*
- * @unimplemented
- */
-NTSTATUS STDCALL
-RtlQueryRegistryValues(IN ULONG RelativeTo,
- IN PCWSTR Path,
- IN PRTL_QUERY_REGISTRY_TABLE QueryTable,
- IN PVOID Context,
- IN PVOID Environment)
-{
- NTSTATUS Status;
- HANDLE BaseKeyHandle;
- HANDLE CurrentKeyHandle;
- PRTL_QUERY_REGISTRY_TABLE QueryEntry;
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING KeyName;
- PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
- PKEY_VALUE_FULL_INFORMATION FullValueInfo;
- ULONG BufferSize;
- ULONG ResultSize;
- ULONG Index;
- ULONG StringLen;
- ULONG ValueNameSize;
- PWSTR StringPtr;
- PWSTR ExpandBuffer;
- PWSTR ValueName;
- UNICODE_STRING EnvValue;
- UNICODE_STRING EnvExpandedValue;
-
- DPRINT("RtlQueryRegistryValues() called\n");
-
- Status = RtlpGetRegistryHandle(RelativeTo,
- (PWSTR)Path,
- FALSE,
- &BaseKeyHandle);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("RtlpGetRegistryHandle() failed (Status %lx)\n", Status);
- return(Status);
- }
-
- CurrentKeyHandle = BaseKeyHandle;
- QueryEntry = QueryTable;
- while ((QueryEntry->QueryRoutine != NULL) ||
- (QueryEntry->Name != NULL))
- {
- if (((QueryEntry->Flags & (RTL_QUERY_REGISTRY_SUBKEY | RTL_QUERY_REGISTRY_TOPKEY)) != 0) &&
- (BaseKeyHandle != CurrentKeyHandle))
- {
- NtClose(CurrentKeyHandle);
- CurrentKeyHandle = BaseKeyHandle;
- }
-
- if (QueryEntry->Flags & RTL_QUERY_REGISTRY_SUBKEY)
- {
- DPRINT("Open new subkey: %S\n", QueryEntry->Name);
-
- RtlInitUnicodeString(&KeyName,
- QueryEntry->Name);
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- BaseKeyHandle,
- NULL);
- Status = NtOpenKey(&CurrentKeyHandle,
- KEY_ALL_ACCESS,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- break;
- }
- else if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DIRECT)
- {
- DPRINT("Query value directly: %S\n", QueryEntry->Name);
-
- RtlInitUnicodeString(&KeyName,
- QueryEntry->Name);
-
- BufferSize = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + 4096;
- ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(),
- 0,
- BufferSize);
- if (ValueInfo == NULL)
- {
- Status = STATUS_NO_MEMORY;
- break;
- }
-
- Status = NtQueryValueKey(CurrentKeyHandle,
- &KeyName,
- KeyValuePartialInformation,
- ValueInfo,
- BufferSize,
- &ResultSize);
- if (!NT_SUCCESS(Status))
- {
- if (QueryEntry->Flags & RTL_QUERY_REGISTRY_REQUIRED)
- {
- RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
- Status = STATUS_OBJECT_NAME_NOT_FOUND;
- break;
- }
-
- if (QueryEntry->DefaultType == REG_SZ)
- {
- PUNICODE_STRING ValueString;
- PUNICODE_STRING SourceString;
-
- SourceString = (PUNICODE_STRING)QueryEntry->DefaultData;
- ValueString = (PUNICODE_STRING)QueryEntry->EntryContext;
- if (ValueString->Buffer == NULL)
- {
- ValueString->Length = SourceString->Length;
- ValueString->MaximumLength = SourceString->MaximumLength;
- ValueString->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
- 0,
- ValueString->MaximumLength);
- if (!ValueString->Buffer)
- break;
- ValueString->Buffer[0] = 0;
- memcpy(ValueString->Buffer,
- SourceString->Buffer,
- SourceString->MaximumLength);
- }
- else
- {
- ValueString->Length = min(SourceString->Length,
- ValueString->MaximumLength - sizeof(WCHAR));
- memcpy(ValueString->Buffer,
- SourceString->Buffer,
- ValueString->Length);
- ((PWSTR)ValueString->Buffer)[ValueString->Length / sizeof(WCHAR)] = 0;
- }
- }
- else
- {
- memcpy(QueryEntry->EntryContext,
- QueryEntry->DefaultData,
- QueryEntry->DefaultLength);
- }
- Status = STATUS_SUCCESS;
- }
- else
- {
- if ((ValueInfo->Type == REG_SZ) ||
- (ValueInfo->Type == REG_MULTI_SZ) ||
- (ValueInfo->Type == REG_EXPAND_SZ && (QueryEntry->Flags & RTL_QUERY_REGISTRY_NOEXPAND)))
- {
- PUNICODE_STRING ValueString;
-
- ValueString = (PUNICODE_STRING)QueryEntry->EntryContext;
- if (ValueString->Buffer == NULL)
- {
- ValueString->MaximumLength = ValueInfo->DataLength;
- ValueString->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
- 0,
- ValueString->MaximumLength);
- if (ValueString->Buffer == NULL)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- break;
- }
- ValueString->Buffer[0] = 0;
- }
- ValueString->Length = min(ValueInfo->DataLength,
- ValueString->MaximumLength) - sizeof(WCHAR);
- memcpy(ValueString->Buffer,
- ValueInfo->Data,
- ValueString->Length);
- ((PWSTR)ValueString->Buffer)[ValueString->Length / sizeof(WCHAR)] = 0;
- }
- else if (ValueInfo->Type == REG_EXPAND_SZ)
- {
- PUNICODE_STRING ValueString;
-
- DPRINT("Expand REG_EXPAND_SZ type\n");
-
- ValueString = (PUNICODE_STRING)QueryEntry->EntryContext;
-
- ExpandBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
- 0,
- ValueInfo->DataLength * 2);
- if (ExpandBuffer == NULL)
- {
- Status = STATUS_NO_MEMORY;
- break;
- }
-
- RtlInitUnicodeString(&EnvValue,
- (PWSTR)ValueInfo->Data);
- EnvExpandedValue.Length = 0;
- EnvExpandedValue.MaximumLength = ValueInfo->DataLength * 2;
- EnvExpandedValue.Buffer = ExpandBuffer;
- *ExpandBuffer = 0;
-
- RtlExpandEnvironmentStrings_U(Environment,
- &EnvValue,
- &EnvExpandedValue,
- &StringLen);
-
- if (ValueString->Buffer == NULL)
- {
- ValueString->MaximumLength = EnvExpandedValue.Length + sizeof(WCHAR);
- ValueString->Length = EnvExpandedValue.Length;
- ValueString->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
- 0,
- ValueString->MaximumLength);
- if (ValueString->Buffer == NULL)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- break;
- }
- }
- else
- {
- ValueString->Length = min(EnvExpandedValue.Length,
- ValueString->MaximumLength - sizeof(WCHAR));
- }
-
- memcpy(ValueString->Buffer,
- EnvExpandedValue.Buffer,
- ValueString->Length);
- ((PWSTR)ValueString->Buffer)[ValueString->Length / sizeof(WCHAR)] = 0;
-
- RtlFreeHeap(RtlGetProcessHeap(),
- 0,
- ExpandBuffer);
- }
- else
- {
- memcpy(QueryEntry->EntryContext,
- ValueInfo->Data,
- ValueInfo->DataLength);
- }
- }
-
- if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DELETE)
- {
- DPRINT1("FIXME: Delete value: %S\n", QueryEntry->Name);
-
- }
-
- RtlFreeHeap(RtlGetProcessHeap(),
- 0,
- ValueInfo);
- }
- else
- {
- DPRINT("Query value via query routine: %S\n", QueryEntry->Name);
- if (QueryEntry->Name != NULL)
- {
- RtlInitUnicodeString(&KeyName,
- QueryEntry->Name);
-
- BufferSize = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + 4096;
- ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(),
- 0,
- BufferSize);
- if (ValueInfo == NULL)
- {
- Status = STATUS_NO_MEMORY;
- break;
- }
-
- Status = NtQueryValueKey(CurrentKeyHandle,
- &KeyName,
- KeyValuePartialInformation,
- ValueInfo,
- BufferSize,
- &ResultSize);
- if (!NT_SUCCESS(Status))
- {
- if (!(QueryEntry->Flags & RTL_QUERY_REGISTRY_REQUIRED))
- {
- Status = QueryEntry->QueryRoutine(QueryEntry->Name,
- QueryEntry->DefaultType,
- QueryEntry->DefaultData,
- QueryEntry->DefaultLength,
- Context,
- QueryEntry->EntryContext);
- }
- }
- else if ((ValueInfo->Type == REG_MULTI_SZ) &&
- !(QueryEntry->Flags & RTL_QUERY_REGISTRY_NOEXPAND))
- {
- DPRINT("Expand REG_MULTI_SZ type\n");
- StringPtr = (PWSTR)ValueInfo->Data;
- while (*StringPtr != 0)
- {
- StringLen = (wcslen(StringPtr) + 1) * sizeof(WCHAR);
- Status = QueryEntry->QueryRoutine(QueryEntry->Name,
- REG_SZ,
- (PVOID)StringPtr,
- StringLen,
- Context,
- QueryEntry->EntryContext);
- if(!NT_SUCCESS(Status))
- break;
- StringPtr = (PWSTR)((PUCHAR)StringPtr + StringLen);
- }
- }
- else if ((ValueInfo->Type == REG_EXPAND_SZ) &&
- !(QueryEntry->Flags & RTL_QUERY_REGISTRY_NOEXPAND))
- {
- DPRINT("Expand REG_EXPAND_SZ type\n");
-
- ExpandBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
- 0,
- ValueInfo->DataLength * 2);
- if (ExpandBuffer == NULL)
- {
- Status = STATUS_NO_MEMORY;
- break;
- }
-
- RtlInitUnicodeString(&EnvValue,
- (PWSTR)ValueInfo->Data);
- EnvExpandedValue.Length = 0;
- EnvExpandedValue.MaximumLength = ValueInfo->DataLength * 2 * sizeof(WCHAR);
- EnvExpandedValue.Buffer = ExpandBuffer;
- *ExpandBuffer = 0;
-
- RtlExpandEnvironmentStrings_U(Environment,
- &EnvValue,
- &EnvExpandedValue,
- &StringLen);
-
- StringLen = (wcslen(ExpandBuffer) + 1) * sizeof(WCHAR);
- Status = QueryEntry->QueryRoutine(QueryEntry->Name,
- REG_SZ,
- (PVOID)ExpandBuffer,
- StringLen,
- Context,
- QueryEntry->EntryContext);
-
- RtlFreeHeap(RtlGetProcessHeap(),
- 0,
- ExpandBuffer);
- }
- else
- {
- Status = QueryEntry->QueryRoutine(QueryEntry->Name,
- ValueInfo->Type,
- ValueInfo->Data,
- ValueInfo->DataLength,
- Context,
- QueryEntry->EntryContext);
- }
-
- if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DELETE)
- {
- DPRINT1("FIXME: Delete value: %S\n", QueryEntry->Name);
-
- }
-
- RtlFreeHeap(RtlGetProcessHeap(),
- 0,
- ValueInfo);
- if (!NT_SUCCESS(Status))
- break;
- }
- else if (QueryEntry->Flags & RTL_QUERY_REGISTRY_NOVALUE)
- {
- DPRINT("Simple callback\n");
- Status = QueryEntry->QueryRoutine(NULL,
- REG_NONE,
- NULL,
- 0,
- Context,
- QueryEntry->EntryContext);
- if (!NT_SUCCESS(Status))
- break;
- }
- else
- {
- DPRINT("Enumerate values\n");
-
- BufferSize = sizeof(KEY_VALUE_FULL_INFORMATION) + 4096;
- FullValueInfo = RtlAllocateHeap(RtlGetProcessHeap(),
- 0,
- BufferSize);
- if (FullValueInfo == NULL)
- {
- Status = STATUS_NO_MEMORY;
- break;
- }
- ValueNameSize = 256 * sizeof(WCHAR);
- ValueName = RtlAllocateHeap(RtlGetProcessHeap(),
- 0,
- ValueNameSize);
- if (ValueName == NULL)
- {
- Status = STATUS_NO_MEMORY;
- break;
- }
- Index = 0;
- while (TRUE)
- {
- Status = NtEnumerateValueKey(CurrentKeyHandle,
- Index,
- KeyValueFullInformation,
- FullValueInfo,
- BufferSize,
- &ResultSize);
- if (!NT_SUCCESS(Status))
- {
- if ((Status == STATUS_NO_MORE_ENTRIES) &&
- (Index == 0) &&
- (QueryEntry->Flags & RTL_QUERY_REGISTRY_REQUIRED))
- {
- Status = STATUS_OBJECT_NAME_NOT_FOUND;
- }
- else if (Status == STATUS_NO_MORE_ENTRIES)
- {
- Status = STATUS_SUCCESS;
- }
- break;
- }
-
- if (FullValueInfo->NameLength > ValueNameSize - sizeof(WCHAR))
- {
- /* Should not happen, because the name length is limited to 255 characters */
- RtlFreeHeap(RtlGetProcessHeap(),
- 0,
- ValueName);
- ValueNameSize = FullValueInfo->NameLength + sizeof(WCHAR);
- ValueName = RtlAllocateHeap(RtlGetProcessHeap(),
- 0,
- ValueNameSize);
- if (ValueName == NULL)
- {
- Status = STATUS_NO_MEMORY;
- break;
- }
- }
-
- memcpy(ValueName,
- FullValueInfo->Name,
- FullValueInfo->NameLength);
- ValueName[FullValueInfo->NameLength / sizeof(WCHAR)] = 0;
-
- DPRINT("FullValueInfo->Type: %lu\n", FullValueInfo->Type);
- if ((FullValueInfo->Type == REG_MULTI_SZ) &&
- !(QueryEntry->Flags & RTL_QUERY_REGISTRY_NOEXPAND))
- {
- DPRINT("Expand REG_MULTI_SZ type\n");
- StringPtr = (PWSTR)((PVOID)FullValueInfo + FullValueInfo->DataOffset);
- while (*StringPtr != 0)
- {
- StringLen = (wcslen(StringPtr) + 1) * sizeof(WCHAR);
- Status = QueryEntry->QueryRoutine(ValueName,
- REG_SZ,
- (PVOID)StringPtr,
- StringLen,
- Context,
- QueryEntry->EntryContext);
- if(!NT_SUCCESS(Status))
- break;
- StringPtr = (PWSTR)((PUCHAR)StringPtr + StringLen);
- }
- }
- else if ((FullValueInfo->Type == REG_EXPAND_SZ) &&
- !(QueryEntry->Flags & RTL_QUERY_REGISTRY_NOEXPAND))
- {
- DPRINT("Expand REG_EXPAND_SZ type\n");
-
- StringPtr = (PWSTR)((PVOID)FullValueInfo + FullValueInfo->DataOffset);
- ExpandBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
- 0,
- FullValueInfo->DataLength * 2);
- if (ExpandBuffer == NULL)
- {
- Status = STATUS_NO_MEMORY;
- break;
- }
-
- RtlInitUnicodeString(&EnvValue,
- StringPtr);
- EnvExpandedValue.Length = 0;
- EnvExpandedValue.MaximumLength = FullValueInfo->DataLength * 2;
- EnvExpandedValue.Buffer = ExpandBuffer;
- *ExpandBuffer = 0;
-
- RtlExpandEnvironmentStrings_U(Environment,
- &EnvValue,
- &EnvExpandedValue,
- &StringLen);
-
- StringLen = (wcslen(ExpandBuffer) + 1) * sizeof(WCHAR);
- Status = QueryEntry->QueryRoutine(ValueName,
- REG_SZ,
- (PVOID)ExpandBuffer,
- StringLen,
- Context,
- QueryEntry->EntryContext);
-
- RtlFreeHeap(RtlGetProcessHeap(),
- 0,
- ExpandBuffer);
- }
- else
- {
- Status = QueryEntry->QueryRoutine(ValueName,
- FullValueInfo->Type,
- (PVOID)FullValueInfo + FullValueInfo->DataOffset,
- FullValueInfo->DataLength,
- Context,
- QueryEntry->EntryContext);
- }
-
- if (!NT_SUCCESS(Status))
- break;
-
- /* FIXME: How will these be deleted? */
-
- Index++;
- }
-
- RtlFreeHeap(RtlGetProcessHeap(),
- 0,
- FullValueInfo);
- RtlFreeHeap(RtlGetProcessHeap(),
- 0,
- ValueName);
- if (!NT_SUCCESS(Status))
- break;
- }
- }
-
- QueryEntry++;
- }
-
- if (CurrentKeyHandle != BaseKeyHandle)
- NtClose(CurrentKeyHandle);
-
- NtClose(BaseKeyHandle);
-
- return(Status);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlWriteRegistryValue(IN ULONG RelativeTo,
- IN PCWSTR Path,
- IN PCWSTR ValueName,
- IN ULONG ValueType,
- IN PVOID ValueData,
- IN ULONG ValueLength)
-{
- HANDLE KeyHandle;
- NTSTATUS Status;
- UNICODE_STRING Name;
-
- Status = RtlpGetRegistryHandle(RelativeTo,
- (PWSTR)Path,
- TRUE,
- &KeyHandle);
- if (!NT_SUCCESS(Status))
- return(Status);
-
- RtlInitUnicodeString(&Name,
- ValueName);
-
- Status = NtSetValueKey(KeyHandle,
- &Name,
- 0,
- ValueType,
- ValueData,
- ValueLength);
- if (NT_SUCCESS(Status))
- NtClose(KeyHandle);
-
- return(Status);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlpNtCreateKey(OUT HANDLE KeyHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN ULONG Unused1,
- OUT PULONG Disposition,
- IN ULONG Unused2)
-{
- if (ObjectAttributes != NULL)
- ObjectAttributes->Attributes &= ~(OBJ_PERMANENT | OBJ_EXCLUSIVE);
-
- return(NtCreateKey(KeyHandle,
- DesiredAccess,
- ObjectAttributes,
- 0,
- NULL,
- 0,
- Disposition));
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlpNtEnumerateSubKey(IN HANDLE KeyHandle,
- OUT PUNICODE_STRING SubKeyName,
- IN ULONG Index,
- IN ULONG Unused)
-{
- PKEY_BASIC_INFORMATION KeyInfo = NULL;
- ULONG BufferLength = 0;
- ULONG ReturnedLength;
- NTSTATUS Status;
-
- if (SubKeyName->MaximumLength != 0)
- {
- BufferLength = SubKeyName->MaximumLength +
- sizeof(KEY_BASIC_INFORMATION);
- KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(),
- 0,
- BufferLength);
- if (KeyInfo == NULL)
- return(STATUS_NO_MEMORY);
- }
-
[truncated at 1000 lines; 2023 more skipped]