Implemented value enumeration in RtlQueryRegistryValues().

svn path=/trunk/; revision=2603
This commit is contained in:
Eric Kohl 2002-02-05 15:42:41 +00:00
parent 5d67a14618
commit 916157c159
2 changed files with 779 additions and 569 deletions

View file

@ -1,4 +1,4 @@
/* $Id: registry.c,v 1.8 2001/09/16 13:19:31 chorns Exp $ /* $Id: registry.c,v 1.9 2002/02/05 15:42:41 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -15,7 +15,7 @@
* - finish RtlFormatCurrentUserKeyPath() * - finish RtlFormatCurrentUserKeyPath()
*/ */
/* INCLUDES *****************************************************************/ /* INCLUDES ****************************************************************/
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <ntdll/registry.h> #include <ntdll/registry.h>
@ -39,11 +39,11 @@ RtlCheckRegistryKey(IN ULONG RelativeTo,
FALSE, FALSE,
&KeyHandle); &KeyHandle);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return Status; return(Status);
NtClose(KeyHandle); NtClose(KeyHandle);
return STATUS_SUCCESS; return(STATUS_SUCCESS);
} }
@ -59,11 +59,11 @@ RtlCreateRegistryKey(IN ULONG RelativeTo,
TRUE, TRUE,
&KeyHandle); &KeyHandle);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return Status; return(Status);
NtClose(KeyHandle); NtClose(KeyHandle);
return STATUS_SUCCESS; return(STATUS_SUCCESS);
} }
@ -81,17 +81,17 @@ RtlDeleteRegistryValue(IN ULONG RelativeTo,
FALSE, FALSE,
&KeyHandle); &KeyHandle);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return Status; return(Status);
RtlInitUnicodeString(&Name, RtlInitUnicodeString(&Name,
ValueName); ValueName);
NtDeleteValueKey(KeyHandle, Status = NtDeleteValueKey(KeyHandle,
&Name); &Name);
NtClose(KeyHandle); NtClose(KeyHandle);
return STATUS_SUCCESS; return(Status);
} }
@ -101,7 +101,7 @@ RtlFormatCurrentUserKeyPath(PUNICODE_STRING KeyPath)
/* FIXME: !!! */ /* FIXME: !!! */
RtlCreateUnicodeString(KeyPath, RtlCreateUnicodeString(KeyPath,
L"\\Registry\\User\\.Default"); L"\\Registry\\User\\.Default");
return STATUS_SUCCESS; return(STATUS_SUCCESS);
} }
@ -126,7 +126,7 @@ RtlOpenCurrentUser(IN ACCESS_MASK DesiredAccess,
&ObjectAttributes); &ObjectAttributes);
RtlFreeUnicodeString(&KeyPath); RtlFreeUnicodeString(&KeyPath);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
return STATUS_SUCCESS; return(STATUS_SUCCESS);
} }
RtlInitUnicodeString(&KeyPath, RtlInitUnicodeString(&KeyPath,
@ -158,8 +158,10 @@ RtlQueryRegistryValues(IN ULONG RelativeTo,
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName; UNICODE_STRING KeyName;
PKEY_VALUE_PARTIAL_INFORMATION ValueInfo; PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
PKEY_VALUE_FULL_INFORMATION FullValueInfo;
ULONG BufferSize; ULONG BufferSize;
ULONG ResultSize; ULONG ResultSize;
ULONG Index;
DPRINT("RtlQueryRegistryValues() called\n"); DPRINT("RtlQueryRegistryValues() called\n");
@ -168,7 +170,7 @@ RtlQueryRegistryValues(IN ULONG RelativeTo,
FALSE, FALSE,
&BaseKeyHandle); &BaseKeyHandle);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return Status; return(Status);
CurrentKeyHandle = BaseKeyHandle; CurrentKeyHandle = BaseKeyHandle;
QueryEntry = QueryTable; QueryEntry = QueryTable;
@ -241,10 +243,12 @@ RtlQueryRegistryValues(IN ULONG RelativeTo,
if (ValueInfo->Type == REG_SZ) if (ValueInfo->Type == REG_SZ)
{ {
PUNICODE_STRING ValueString; PUNICODE_STRING ValueString;
ValueString = (PUNICODE_STRING)QueryEntry->EntryContext; ValueString = (PUNICODE_STRING)QueryEntry->EntryContext;
if (ValueString->Buffer == 0) if (ValueString->Buffer == 0)
{ {
RtlInitUnicodeString(ValueString, NULL); RtlInitUnicodeString(ValueString,
NULL);
ValueString->MaximumLength = 256 * sizeof(WCHAR); ValueString->MaximumLength = 256 * sizeof(WCHAR);
ValueString->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), ValueString->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
0, 0,
@ -268,17 +272,124 @@ RtlQueryRegistryValues(IN ULONG RelativeTo,
} }
} }
RtlFreeHeap (RtlGetProcessHeap(), 0, ValueInfo); RtlFreeHeap(RtlGetProcessHeap(),
0,
ValueInfo);
} }
else else
{ {
DPRINT("Query value via query routine: %S\n", QueryEntry->Name); 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))
{
Status = QueryEntry->QueryRoutine(QueryEntry->Name,
QueryEntry->DefaultType,
QueryEntry->DefaultData,
QueryEntry->DefaultLength,
Context,
QueryEntry->EntryContext);
}
else
{
Status = QueryEntry->QueryRoutine(QueryEntry->Name,
ValueInfo->Type,
ValueInfo->Data,
ValueInfo->DataLength,
Context,
QueryEntry->EntryContext);
}
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 (ValueInfo == 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)
Status = STATUS_SUCCESS;
break;
}
Status = QueryEntry->QueryRoutine(FullValueInfo->Name,
FullValueInfo->Type,
(PVOID)FullValueInfo + FullValueInfo->DataOffset,
FullValueInfo->DataLength,
Context,
QueryEntry->EntryContext);
if (!NT_SUCCESS(Status))
break;
Index++;
}
RtlFreeHeap(RtlGetProcessHeap(),
0,
ValueInfo);
if (!NT_SUCCESS(Status))
break;
}
} }
if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DELETE) if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DELETE)
{ {
DPRINT("Delete value: %S\n", QueryEntry->Name); DPRINT1("FIXME: Delete value: %S\n", QueryEntry->Name);
} }
@ -290,7 +401,7 @@ RtlQueryRegistryValues(IN ULONG RelativeTo,
NtClose(BaseKeyHandle); NtClose(BaseKeyHandle);
return Status; return(Status);
} }
@ -311,21 +422,21 @@ RtlWriteRegistryValue(IN ULONG RelativeTo,
TRUE, TRUE,
&KeyHandle); &KeyHandle);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return Status; return(Status);
RtlInitUnicodeString(&Name, RtlInitUnicodeString(&Name,
ValueName); ValueName);
NtSetValueKey(KeyHandle, Status = NtSetValueKey(KeyHandle,
&Name, &Name,
0, 0,
ValueType, ValueType,
ValueData, ValueData,
ValueLength); ValueLength);
if (NT_SUCCESS(Status))
NtClose(KeyHandle); NtClose(KeyHandle);
return STATUS_SUCCESS; return(Status);
} }
@ -338,8 +449,7 @@ RtlpNtCreateKey(OUT HANDLE KeyHandle,
IN ULONG Unused2) IN ULONG Unused2)
{ {
if (ObjectAttributes != NULL) if (ObjectAttributes != NULL)
ObjectAttributes->Attributes &= ObjectAttributes->Attributes &= ~(OBJ_PERMANENT | OBJ_EXCLUSIVE);
~(OBJ_PERMANENT | OBJ_EXCLUSIVE);
return(NtCreateKey(KeyHandle, return(NtCreateKey(KeyHandle,
DesiredAccess, DesiredAccess,
@ -419,8 +529,7 @@ RtlpNtOpenKey(OUT HANDLE KeyHandle,
IN ULONG Unused) IN ULONG Unused)
{ {
if (ObjectAttributes != NULL) if (ObjectAttributes != NULL)
ObjectAttributes->Attributes &= ObjectAttributes->Attributes &= ~(OBJ_PERMANENT | OBJ_EXCLUSIVE);
~(OBJ_PERMANENT | OBJ_EXCLUSIVE);
return(NtOpenKey(KeyHandle, return(NtOpenKey(KeyHandle,
DesiredAccess, DesiredAccess,
@ -502,6 +611,7 @@ RtlpNtSetValueKey(IN HANDLE KeyHandle,
DataLength)); DataLength));
} }
/* INTERNAL FUNCTIONS ******************************************************/ /* INTERNAL FUNCTIONS ******************************************************/
NTSTATUS NTSTATUS
@ -519,15 +629,14 @@ RtlpGetRegistryHandle(ULONG RelativeTo,
if (RelativeTo & RTL_REGISTRY_HANDLE) if (RelativeTo & RTL_REGISTRY_HANDLE)
{ {
Status = NtDuplicateObject( Status = NtDuplicateObject(NtCurrentProcess(),
NtCurrentProcess(),
(HANDLE)Path, (HANDLE)Path,
NtCurrentProcess(), NtCurrentProcess(),
KeyHandle, KeyHandle,
0, 0,
FALSE, FALSE,
DUPLICATE_SAME_ACCESS); DUPLICATE_SAME_ACCESS);
return Status; return(Status);
} }
if (RelativeTo & RTL_REGISTRY_OPTIONAL) if (RelativeTo & RTL_REGISTRY_OPTIONAL)
@ -579,20 +688,14 @@ RtlpGetRegistryHandle(ULONG RelativeTo,
RtlAppendUnicodeToString(&KeyName, RtlAppendUnicodeToString(&KeyName,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\"); L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
break; break;
} }
if ((RelativeTo == RTL_REGISTRY_ABSOLUTE) || (Path[0] != L'\\')) if (Path[0] == L'\\')
{
RtlAppendUnicodeToString(&KeyName,
Path);
}
else
{ {
Path++; Path++;
}
RtlAppendUnicodeToString(&KeyName, RtlAppendUnicodeToString(&KeyName,
Path); Path);
}
DPRINT("KeyName %wZ\n", &KeyName); DPRINT("KeyName %wZ\n", &KeyName);
@ -619,8 +722,7 @@ RtlpGetRegistryHandle(ULONG RelativeTo,
&ObjectAttributes); &ObjectAttributes);
} }
return Status; return(Status);
} }
/* EOF */ /* EOF */

View file

@ -140,8 +140,10 @@ RtlQueryRegistryValues(IN ULONG RelativeTo,
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName; UNICODE_STRING KeyName;
PKEY_VALUE_PARTIAL_INFORMATION ValueInfo; PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
PKEY_VALUE_FULL_INFORMATION FullValueInfo;
ULONG BufferSize; ULONG BufferSize;
ULONG ResultSize; ULONG ResultSize;
ULONG Index;
DPRINT("RtlQueryRegistryValues() called\n"); DPRINT("RtlQueryRegistryValues() called\n");
@ -152,7 +154,7 @@ RtlQueryRegistryValues(IN ULONG RelativeTo,
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("RtlpGetRegistryHandle() failed with status %x\n", Status); DPRINT("RtlpGetRegistryHandle() failed with status %x\n", Status);
return Status; return(Status);
} }
CurrentKeyHandle = BaseKeyHandle; CurrentKeyHandle = BaseKeyHandle;
@ -205,7 +207,7 @@ RtlQueryRegistryValues(IN ULONG RelativeTo,
RtlInitUnicodeString(&KeyName, RtlInitUnicodeString(&KeyName,
QueryEntry->Name); QueryEntry->Name);
BufferSize = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + 4096; BufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 4096;
ValueInfo = ExAllocatePool(PagedPool, BufferSize); ValueInfo = ExAllocatePool(PagedPool, BufferSize);
if (ValueInfo == NULL) if (ValueInfo == NULL)
{ {
@ -230,12 +232,15 @@ RtlQueryRegistryValues(IN ULONG RelativeTo,
if (ValueInfo->Type == REG_SZ) if (ValueInfo->Type == REG_SZ)
{ {
PUNICODE_STRING ValueString; PUNICODE_STRING ValueString;
ValueString = (PUNICODE_STRING)QueryEntry->EntryContext; ValueString = (PUNICODE_STRING)QueryEntry->EntryContext;
if (ValueString->Buffer == 0) if (ValueString->Buffer == 0)
{ {
RtlInitUnicodeString(ValueString, NULL); RtlInitUnicodeString(ValueString,
NULL);
ValueString->MaximumLength = 256 * sizeof(WCHAR); ValueString->MaximumLength = 256 * sizeof(WCHAR);
ValueString->Buffer = ExAllocatePool(PagedPool, ValueString->MaximumLength); ValueString->Buffer = ExAllocatePool(PagedPool,
ValueString->MaximumLength);
if (!ValueString->Buffer) if (!ValueString->Buffer)
break; break;
ValueString->Buffer[0] = 0; ValueString->Buffer[0] = 0;
@ -255,17 +260,119 @@ RtlQueryRegistryValues(IN ULONG RelativeTo,
} }
} }
ExFreePool (ValueInfo); ExFreePool(ValueInfo);
} }
else else
{ {
DPRINT("Query value via query routine: %S\n", QueryEntry->Name); 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 = ExAllocatePool(PagedPool,
BufferSize);
if (ValueInfo == NULL)
{
Status = STATUS_NO_MEMORY;
break;
}
Status = NtQueryValueKey(CurrentKeyHandle,
&KeyName,
KeyValuePartialInformation,
ValueInfo,
BufferSize,
&ResultSize);
if (!NT_SUCCESS(Status))
{
Status = QueryEntry->QueryRoutine(QueryEntry->Name,
QueryEntry->DefaultType,
QueryEntry->DefaultData,
QueryEntry->DefaultLength,
Context,
QueryEntry->EntryContext);
}
else
{
Status = QueryEntry->QueryRoutine(QueryEntry->Name,
ValueInfo->Type,
ValueInfo->Data,
ValueInfo->DataLength,
Context,
QueryEntry->EntryContext);
}
ExFreePool(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 = ExAllocatePool(PagedPool,
BufferSize);
if (ValueInfo == 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)
Status = STATUS_SUCCESS;
break;
}
Status = QueryEntry->QueryRoutine(FullValueInfo->Name,
FullValueInfo->Type,
(PVOID)FullValueInfo + FullValueInfo->DataOffset,
FullValueInfo->DataLength,
Context,
QueryEntry->EntryContext);
if (!NT_SUCCESS(Status))
break;
Index++;
}
ExFreePool(ValueInfo);
if (!NT_SUCCESS(Status))
break;
}
} }
if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DELETE) if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DELETE)
{ {
DPRINT("Delete value: %S\n", QueryEntry->Name); DPRINT1("FIXME: Delete value: %S\n", QueryEntry->Name);
} }
@ -277,7 +384,7 @@ RtlQueryRegistryValues(IN ULONG RelativeTo,
NtClose(BaseKeyHandle); NtClose(BaseKeyHandle);
return Status; return(Status);
} }
@ -298,7 +405,7 @@ RtlWriteRegistryValue(IN ULONG RelativeTo,
TRUE, TRUE,
&KeyHandle); &KeyHandle);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return Status; return(Status);
RtlInitUnicodeString(&Name, RtlInitUnicodeString(&Name,
ValueName); ValueName);
@ -312,9 +419,10 @@ RtlWriteRegistryValue(IN ULONG RelativeTo,
NtClose(KeyHandle); NtClose(KeyHandle);
return STATUS_SUCCESS; return(STATUS_SUCCESS);
} }
NTSTATUS STDCALL NTSTATUS STDCALL
RtlFormatCurrentUserKeyPath(IN OUT PUNICODE_STRING KeyPath) RtlFormatCurrentUserKeyPath(IN OUT PUNICODE_STRING KeyPath)
{ {
@ -322,7 +430,7 @@ RtlFormatCurrentUserKeyPath(IN OUT PUNICODE_STRING KeyPath)
RtlCreateUnicodeString(KeyPath, RtlCreateUnicodeString(KeyPath,
L"\\Registry\\User\\.Default"); L"\\Registry\\User\\.Default");
return STATUS_SUCCESS; return(STATUS_SUCCESS);
} }
/* ------------------------------------------ Private Implementation */ /* ------------------------------------------ Private Implementation */