mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Implemented value enumeration in RtlQueryRegistryValues().
svn path=/trunk/; revision=2603
This commit is contained in:
parent
5d67a14618
commit
916157c159
2 changed files with 779 additions and 569 deletions
File diff suppressed because it is too large
Load diff
|
@ -133,151 +133,258 @@ RtlQueryRegistryValues(IN ULONG RelativeTo,
|
|||
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;
|
||||
ULONG BufferSize;
|
||||
ULONG ResultSize;
|
||||
|
||||
DPRINT("RtlQueryRegistryValues() called\n");
|
||||
|
||||
Status = RtlpGetRegistryHandle(RelativeTo,
|
||||
Path,
|
||||
FALSE,
|
||||
&BaseKeyHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
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;
|
||||
|
||||
DPRINT("RtlQueryRegistryValues() called\n");
|
||||
|
||||
Status = RtlpGetRegistryHandle(RelativeTo,
|
||||
Path,
|
||||
FALSE,
|
||||
&BaseKeyHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("RtlpGetRegistryHandle() failed with status %x\n", Status);
|
||||
return Status;
|
||||
return(Status);
|
||||
}
|
||||
|
||||
CurrentKeyHandle = BaseKeyHandle;
|
||||
QueryEntry = QueryTable;
|
||||
while ((QueryEntry->QueryRoutine != NULL) ||
|
||||
(QueryEntry->Name != NULL))
|
||||
{
|
||||
//CSH: Was:
|
||||
//if ((QueryEntry->QueryRoutine == NULL) &&
|
||||
// ((QueryEntry->Flags & (RTL_QUERY_REGISTRY_SUBKEY | RTL_QUERY_REGISTRY_DIRECT)) != 0))
|
||||
// Which is more correct?
|
||||
if ((QueryEntry->QueryRoutine == NULL) &&
|
||||
((QueryEntry->Flags & RTL_QUERY_REGISTRY_SUBKEY) != 0))
|
||||
{
|
||||
DPRINT("Bad parameters\n");
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
CurrentKeyHandle = BaseKeyHandle;
|
||||
QueryEntry = QueryTable;
|
||||
while ((QueryEntry->QueryRoutine != NULL) ||
|
||||
(QueryEntry->Name != NULL))
|
||||
{
|
||||
//CSH: Was:
|
||||
//if ((QueryEntry->QueryRoutine == NULL) &&
|
||||
// ((QueryEntry->Flags & (RTL_QUERY_REGISTRY_SUBKEY | RTL_QUERY_REGISTRY_DIRECT)) != 0))
|
||||
// Which is more correct?
|
||||
if ((QueryEntry->QueryRoutine == NULL) &&
|
||||
((QueryEntry->Flags & RTL_QUERY_REGISTRY_SUBKEY) != 0))
|
||||
{
|
||||
DPRINT("Bad parameters\n");
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
DPRINT("Name: %S\n", QueryEntry->Name);
|
||||
DPRINT("Name: %S\n", QueryEntry->Name);
|
||||
|
||||
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 | 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 = ExAllocatePool(PagedPool, BufferSize);
|
||||
if (ValueInfo == NULL)
|
||||
{
|
||||
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 = ExAllocatePool(PagedPool, BufferSize);
|
||||
if (ValueInfo == NULL)
|
||||
{
|
||||
Status = STATUS_NO_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
Status = ZwQueryValueKey(CurrentKeyHandle,
|
||||
&KeyName,
|
||||
KeyValuePartialInformation,
|
||||
ValueInfo,
|
||||
BufferSize,
|
||||
&ResultSize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwQueryValueKey() failed with status %x\n", Status);
|
||||
ExFreePool(ValueInfo);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ValueInfo->Type == REG_SZ)
|
||||
{
|
||||
PUNICODE_STRING ValueString;
|
||||
|
||||
ValueString = (PUNICODE_STRING)QueryEntry->EntryContext;
|
||||
if (ValueString->Buffer == 0)
|
||||
{
|
||||
RtlInitUnicodeString(ValueString,
|
||||
NULL);
|
||||
ValueString->MaximumLength = 256 * sizeof(WCHAR);
|
||||
ValueString->Buffer = ExAllocatePool(PagedPool,
|
||||
ValueString->MaximumLength);
|
||||
if (!ValueString->Buffer)
|
||||
break;
|
||||
ValueString->Buffer[0] = 0;
|
||||
}
|
||||
ValueString->Length = RtlMin(ValueInfo->DataLength,
|
||||
ValueString->MaximumLength - sizeof(WCHAR));
|
||||
memcpy(ValueString->Buffer,
|
||||
ValueInfo->Data,
|
||||
ValueInfo->DataLength);
|
||||
((PWSTR)ValueString->Buffer)[ValueString->Length / sizeof(WCHAR)] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(QueryEntry->EntryContext,
|
||||
ValueInfo->Data,
|
||||
ValueInfo->DataLength);
|
||||
}
|
||||
}
|
||||
|
||||
ExFreePool(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 = ExAllocatePool(PagedPool,
|
||||
BufferSize);
|
||||
if (ValueInfo == NULL)
|
||||
{
|
||||
Status = STATUS_NO_MEMORY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Status = ZwQueryValueKey(CurrentKeyHandle,
|
||||
&KeyName,
|
||||
KeyValuePartialInformation,
|
||||
ValueInfo,
|
||||
BufferSize,
|
||||
&ResultSize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwQueryValueKey() failed with status %x\n", Status);
|
||||
ExFreePool(ValueInfo);
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ValueInfo->Type == REG_SZ)
|
||||
}
|
||||
|
||||
Index = 0;
|
||||
while (TRUE)
|
||||
{
|
||||
Status = NtEnumerateValueKey(CurrentKeyHandle,
|
||||
Index,
|
||||
KeyValueFullInformation,
|
||||
FullValueInfo,
|
||||
BufferSize,
|
||||
&ResultSize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
PUNICODE_STRING ValueString;
|
||||
ValueString = (PUNICODE_STRING)QueryEntry->EntryContext;
|
||||
if (ValueString->Buffer == 0)
|
||||
{
|
||||
RtlInitUnicodeString(ValueString, NULL);
|
||||
ValueString->MaximumLength = 256 * sizeof(WCHAR);
|
||||
ValueString->Buffer = ExAllocatePool(PagedPool, ValueString->MaximumLength);
|
||||
if (!ValueString->Buffer)
|
||||
break;
|
||||
ValueString->Buffer[0] = 0;
|
||||
}
|
||||
ValueString->Length = RtlMin(ValueInfo->DataLength,
|
||||
ValueString->MaximumLength - sizeof(WCHAR));
|
||||
memcpy(ValueString->Buffer,
|
||||
ValueInfo->Data,
|
||||
ValueInfo->DataLength);
|
||||
((PWSTR)ValueString->Buffer)[ValueString->Length / sizeof(WCHAR)] = 0;
|
||||
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(QueryEntry->EntryContext,
|
||||
ValueInfo->Data,
|
||||
ValueInfo->DataLength);
|
||||
}
|
||||
}
|
||||
|
||||
ExFreePool (ValueInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Query value via query routine: %S\n", QueryEntry->Name);
|
||||
|
||||
}
|
||||
Status = QueryEntry->QueryRoutine(FullValueInfo->Name,
|
||||
FullValueInfo->Type,
|
||||
(PVOID)FullValueInfo + FullValueInfo->DataOffset,
|
||||
FullValueInfo->DataLength,
|
||||
Context,
|
||||
QueryEntry->EntryContext);
|
||||
if (!NT_SUCCESS(Status))
|
||||
break;
|
||||
|
||||
if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DELETE)
|
||||
{
|
||||
DPRINT("Delete value: %S\n", QueryEntry->Name);
|
||||
|
||||
}
|
||||
Index++;
|
||||
}
|
||||
|
||||
QueryEntry++;
|
||||
}
|
||||
ExFreePool(ValueInfo);
|
||||
|
||||
if (CurrentKeyHandle != BaseKeyHandle)
|
||||
NtClose(CurrentKeyHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NtClose(BaseKeyHandle);
|
||||
if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DELETE)
|
||||
{
|
||||
DPRINT1("FIXME: Delete value: %S\n", QueryEntry->Name);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
QueryEntry++;
|
||||
}
|
||||
|
||||
if (CurrentKeyHandle != BaseKeyHandle)
|
||||
NtClose(CurrentKeyHandle);
|
||||
|
||||
NtClose(BaseKeyHandle);
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
|
@ -289,40 +396,41 @@ RtlWriteRegistryValue(IN ULONG RelativeTo,
|
|||
IN PVOID ValueData,
|
||||
IN ULONG ValueLength)
|
||||
{
|
||||
HANDLE KeyHandle;
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING Name;
|
||||
HANDLE KeyHandle;
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING Name;
|
||||
|
||||
Status = RtlpGetRegistryHandle(RelativeTo,
|
||||
Path,
|
||||
TRUE,
|
||||
&KeyHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
Status = RtlpGetRegistryHandle(RelativeTo,
|
||||
Path,
|
||||
TRUE,
|
||||
&KeyHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return(Status);
|
||||
|
||||
RtlInitUnicodeString(&Name,
|
||||
ValueName);
|
||||
RtlInitUnicodeString(&Name,
|
||||
ValueName);
|
||||
|
||||
NtSetValueKey(KeyHandle,
|
||||
&Name,
|
||||
0,
|
||||
ValueType,
|
||||
ValueData,
|
||||
ValueLength);
|
||||
NtSetValueKey(KeyHandle,
|
||||
&Name,
|
||||
0,
|
||||
ValueType,
|
||||
ValueData,
|
||||
ValueLength);
|
||||
|
||||
NtClose(KeyHandle);
|
||||
NtClose(KeyHandle);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
RtlFormatCurrentUserKeyPath(IN OUT PUNICODE_STRING KeyPath)
|
||||
{
|
||||
/* FIXME: !!! */
|
||||
RtlCreateUnicodeString(KeyPath,
|
||||
L"\\Registry\\User\\.Default");
|
||||
/* FIXME: !!! */
|
||||
RtlCreateUnicodeString(KeyPath,
|
||||
L"\\Registry\\User\\.Default");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
/* ------------------------------------------ Private Implementation */
|
||||
|
|
Loading…
Reference in a new issue