Share duplicated Rtl code. I've taken care to use the most recent code, so now ntoskrnl can also do environment string expansion. Modified: trunk/reactos/lib/ntdll/makefile Deleted: trunk/reactos/lib/ntdll/rtl/registry.c Modified: trunk/reactos/lib/rtl/makefile Added: trunk/reactos/lib/rtl/registry.c Modified: trunk/reactos/ntoskrnl/Makefile Deleted: trunk/reactos/ntoskrnl/cm/rtlfunc.c _____
Modified: trunk/reactos/lib/ntdll/makefile --- trunk/reactos/lib/ntdll/makefile 2005-01-18 04:25:27 UTC (rev 13112) +++ trunk/reactos/lib/ntdll/makefile 2005-01-18 04:33:31 UTC (rev 13113) @@ -77,7 +77,6 @@
rtl/process.o \ rtl/propvar.o \ rtl/rangelist.o \ - rtl/registry.o \ rtl/resource.o \ rtl/teb.o \ rtl/thread.o \ _____
Deleted: trunk/reactos/lib/ntdll/rtl/registry.c --- 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]
ion@svn.reactos.com wrote:
Share duplicated Rtl code. I've taken care to use the most recent code, so now ntoskrnl can also do environment string expansion.
I also tried merging the two once. It seemed they both had stuff impl. that the other hadnt. Did you merge or did you take the best one?
And env. str. exp. crash in kmode Windows, at least with NULL Environment. This is because the system process has no PEB. It could work when passing something in Environment, but have never seen it done. Env. str. exp. is said to be of no use in kmode anyways...
G.