From baaf29305f36bcd22c0eed0503628a1bf8ec36d3 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 20 Mar 2004 15:56:00 +0000 Subject: [PATCH] Fully implement RtlFormatCurrentUserKeyPath(). svn path=/trunk/; revision=8813 --- reactos/lib/ntdll/rtl/registry.c | 130 ++++++++++++++++++++++++------- reactos/ntoskrnl/cm/rtlfunc.c | 96 ++++++++++++++++++++--- 2 files changed, 191 insertions(+), 35 deletions(-) diff --git a/reactos/lib/ntdll/rtl/registry.c b/reactos/lib/ntdll/rtl/registry.c index a2c6b4ebc36..a3bc3219f44 100644 --- a/reactos/lib/ntdll/rtl/registry.c +++ b/reactos/lib/ntdll/rtl/registry.c @@ -1,4 +1,4 @@ -/* $Id: registry.c,v 1.27 2003/11/17 02:12:50 hyperion Exp $ +/* $Id: registry.c,v 1.28 2004/03/20 15:56:00 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -13,15 +13,12 @@ * TODO: * - finish RtlQueryRegistryValues() * - support RTL_QUERY_REGISTRY_DELETE - * - * - finish RtlFormatCurrentUserKeyPath() */ /* INCLUDES ****************************************************************/ #include #include -#include #include #define NDEBUG @@ -36,6 +33,7 @@ RtlpGetRegistryHandle(ULONG RelativeTo, BOOLEAN Create, PHANDLE KeyHandle) { + UNICODE_STRING KeyPath; UNICODE_STRING KeyName; WCHAR KeyBuffer[MAX_PATH]; OBJECT_ATTRIBUTES ObjectAttributes; @@ -94,9 +92,14 @@ RtlpGetRegistryHandle(ULONG RelativeTo, break; case RTL_REGISTRY_USER: - Status = RtlFormatCurrentUserKeyPath(&KeyName); + Status = RtlFormatCurrentUserKeyPath (&KeyPath); if (!NT_SUCCESS(Status)) return(Status); + RtlAppendUnicodeStringToString (&KeyName, + &KeyPath); + RtlFreeUnicodeString (&KeyPath); + RtlAppendUnicodeToString (&KeyName, + L"\\"); break; /* ReactOS specific */ @@ -222,17 +225,88 @@ RtlDeleteRegistryValue(IN ULONG RelativeTo, /* - * @unimplemented + * @implemented */ NTSTATUS STDCALL -RtlFormatCurrentUserKeyPath(PUNICODE_STRING KeyPath) +RtlFormatCurrentUserKeyPath (OUT PUNICODE_STRING KeyPath) { - /* FIXME: !!! */ -#if 0 - RtlCreateUnicodeString(KeyPath, - L"\\Registry\\User\\.Default"); -#endif - return(STATUS_SUCCESS); + 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; } @@ -244,8 +318,8 @@ RtlOpenCurrentUser(IN ACCESS_MASK DesiredAccess, OUT PHANDLE KeyHandle) { OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyPath; NTSTATUS Status; - UNICODE_STRING KeyPath = ROS_STRING_INITIALIZER(L"\\Registry\\User\\.Default"); Status = RtlFormatCurrentUserKeyPath(&KeyPath); if (NT_SUCCESS(Status)) @@ -258,11 +332,15 @@ RtlOpenCurrentUser(IN ACCESS_MASK DesiredAccess, Status = NtOpenKey(KeyHandle, DesiredAccess, &ObjectAttributes); - if (NT_SUCCESS(Status)) { - RtlFreeUnicodeString(&KeyPath); - return(STATUS_SUCCESS); - } + RtlFreeUnicodeString(&KeyPath); + if (NT_SUCCESS(Status)) + { + return STATUS_SUCCESS; + } } + + RtlInitUnicodeString (&KeyPath, + L"\\Registry\\User\\.Default"); InitializeObjectAttributes(&ObjectAttributes, &KeyPath, OBJ_CASE_INSENSITIVE, @@ -271,8 +349,8 @@ RtlOpenCurrentUser(IN ACCESS_MASK DesiredAccess, Status = NtOpenKey(KeyHandle, DesiredAccess, &ObjectAttributes); - RtlFreeUnicodeString(&KeyPath); - return(Status); + + return Status; } @@ -656,7 +734,7 @@ RtlQueryRegistryValues(IN ULONG RelativeTo, FullValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize); - if (FullValueInfo == NULL) + if (FullValueInfo == NULL) { Status = STATUS_NO_MEMORY; break; @@ -670,7 +748,7 @@ RtlQueryRegistryValues(IN ULONG RelativeTo, Status = STATUS_NO_MEMORY; break; } - Index = 0; + Index = 0; while (TRUE) { Status = NtEnumerateValueKey(CurrentKeyHandle, @@ -701,9 +779,9 @@ RtlQueryRegistryValues(IN ULONG RelativeTo, 0, ValueName); ValueNameSize = FullValueInfo->NameLength + sizeof(WCHAR); - ValueName = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - ValueNameSize); + ValueName = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + ValueNameSize); if (ValueName == NULL) { Status = STATUS_NO_MEMORY; @@ -712,7 +790,7 @@ RtlQueryRegistryValues(IN ULONG RelativeTo, } memcpy(ValueName, - FullValueInfo->Name, + FullValueInfo->Name, FullValueInfo->NameLength); ValueName[FullValueInfo->NameLength / sizeof(WCHAR)] = 0; diff --git a/reactos/ntoskrnl/cm/rtlfunc.c b/reactos/ntoskrnl/cm/rtlfunc.c index ae19f6fd4ee..c6bd9696221 100644 --- a/reactos/ntoskrnl/cm/rtlfunc.c +++ b/reactos/ntoskrnl/cm/rtlfunc.c @@ -29,6 +29,7 @@ RtlpGetRegistryHandle(ULONG RelativeTo, BOOLEAN Create, PHANDLE KeyHandle) { + UNICODE_STRING KeyPath; UNICODE_STRING KeyName; WCHAR KeyBuffer[MAX_PATH]; OBJECT_ATTRIBUTES ObjectAttributes; @@ -80,10 +81,14 @@ RtlpGetRegistryHandle(ULONG RelativeTo, break; case RTL_REGISTRY_USER: - Status = RtlFormatCurrentUserKeyPath(&KeyName); + Status = RtlFormatCurrentUserKeyPath (&KeyPath); if (!NT_SUCCESS(Status)) return(Status); - RtlAppendUnicodeToString(&KeyName, L"\\"); + RtlAppendUnicodeStringToString (&KeyName, + &KeyPath); + RtlFreeUnicodeString (&KeyPath); + RtlAppendUnicodeToString (&KeyName, + L"\\"); break; /* ReactOS specific */ @@ -207,16 +212,87 @@ RtlDeleteRegistryValue(IN ULONG RelativeTo, /* - * @unimplemented + * @implemented */ NTSTATUS STDCALL -RtlFormatCurrentUserKeyPath(IN OUT PUNICODE_STRING KeyPath) +RtlFormatCurrentUserKeyPath (OUT PUNICODE_STRING KeyPath) { - /* FIXME: !!! */ - KeyPath->Length = 0; - RtlAppendUnicodeToString(KeyPath, L"\\Registry\\User\\.Default"); + HANDLE TokenHandle; + UCHAR Buffer[256]; + PSID_AND_ATTRIBUTES SidBuffer; + ULONG Length; + UNICODE_STRING SidString; + NTSTATUS Status; - return(STATUS_SUCCESS); + 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 = ExAllocatePool (NonPagedPool, + 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; } @@ -225,7 +301,7 @@ RtlOpenCurrentUser(IN ACCESS_MASK DesiredAccess, OUT PHANDLE KeyHandle) { OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING KeyPath = ROS_STRING_INITIALIZER(L"\\Registry\\User\\.Default"); + UNICODE_STRING KeyPath; NTSTATUS Status; Status = RtlFormatCurrentUserKeyPath(&KeyPath); @@ -244,6 +320,8 @@ RtlOpenCurrentUser(IN ACCESS_MASK DesiredAccess, return(STATUS_SUCCESS); } + RtlInitUnicodeString (&KeyPath, + L"\\Registry\\User\\.Default"); InitializeObjectAttributes(&ObjectAttributes, &KeyPath, OBJ_CASE_INSENSITIVE,