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 Context,
|
||||||
IN PVOID Environment)
|
IN PVOID Environment)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
HANDLE BaseKeyHandle;
|
HANDLE BaseKeyHandle;
|
||||||
HANDLE CurrentKeyHandle;
|
HANDLE CurrentKeyHandle;
|
||||||
PRTL_QUERY_REGISTRY_TABLE QueryEntry;
|
PRTL_QUERY_REGISTRY_TABLE QueryEntry;
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
UNICODE_STRING KeyName;
|
UNICODE_STRING KeyName;
|
||||||
PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
|
PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
|
||||||
ULONG BufferSize;
|
PKEY_VALUE_FULL_INFORMATION FullValueInfo;
|
||||||
ULONG ResultSize;
|
ULONG BufferSize;
|
||||||
|
ULONG ResultSize;
|
||||||
DPRINT("RtlQueryRegistryValues() called\n");
|
ULONG Index;
|
||||||
|
|
||||||
Status = RtlpGetRegistryHandle(RelativeTo,
|
DPRINT("RtlQueryRegistryValues() called\n");
|
||||||
Path,
|
|
||||||
FALSE,
|
Status = RtlpGetRegistryHandle(RelativeTo,
|
||||||
&BaseKeyHandle);
|
Path,
|
||||||
if (!NT_SUCCESS(Status))
|
FALSE,
|
||||||
|
&BaseKeyHandle);
|
||||||
|
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;
|
||||||
QueryEntry = QueryTable;
|
QueryEntry = QueryTable;
|
||||||
while ((QueryEntry->QueryRoutine != NULL) ||
|
while ((QueryEntry->QueryRoutine != NULL) ||
|
||||||
(QueryEntry->Name != NULL))
|
(QueryEntry->Name != NULL))
|
||||||
{
|
{
|
||||||
//CSH: Was:
|
//CSH: Was:
|
||||||
//if ((QueryEntry->QueryRoutine == NULL) &&
|
//if ((QueryEntry->QueryRoutine == NULL) &&
|
||||||
// ((QueryEntry->Flags & (RTL_QUERY_REGISTRY_SUBKEY | RTL_QUERY_REGISTRY_DIRECT)) != 0))
|
// ((QueryEntry->Flags & (RTL_QUERY_REGISTRY_SUBKEY | RTL_QUERY_REGISTRY_DIRECT)) != 0))
|
||||||
// Which is more correct?
|
// Which is more correct?
|
||||||
if ((QueryEntry->QueryRoutine == NULL) &&
|
if ((QueryEntry->QueryRoutine == NULL) &&
|
||||||
((QueryEntry->Flags & RTL_QUERY_REGISTRY_SUBKEY) != 0))
|
((QueryEntry->Flags & RTL_QUERY_REGISTRY_SUBKEY) != 0))
|
||||||
{
|
{
|
||||||
DPRINT("Bad parameters\n");
|
DPRINT("Bad parameters\n");
|
||||||
Status = STATUS_INVALID_PARAMETER;
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
break;
|
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) &&
|
if (((QueryEntry->Flags & (RTL_QUERY_REGISTRY_SUBKEY | RTL_QUERY_REGISTRY_TOPKEY)) != 0) &&
|
||||||
(BaseKeyHandle != CurrentKeyHandle))
|
(BaseKeyHandle != CurrentKeyHandle))
|
||||||
{
|
{
|
||||||
NtClose(CurrentKeyHandle);
|
NtClose(CurrentKeyHandle);
|
||||||
CurrentKeyHandle = BaseKeyHandle;
|
CurrentKeyHandle = BaseKeyHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (QueryEntry->Flags & RTL_QUERY_REGISTRY_SUBKEY)
|
if (QueryEntry->Flags & RTL_QUERY_REGISTRY_SUBKEY)
|
||||||
{
|
{
|
||||||
DPRINT("Open new subkey: %S\n", QueryEntry->Name);
|
DPRINT("Open new subkey: %S\n", QueryEntry->Name);
|
||||||
|
|
||||||
RtlInitUnicodeString(&KeyName,
|
RtlInitUnicodeString(&KeyName,
|
||||||
QueryEntry->Name);
|
QueryEntry->Name);
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
&KeyName,
|
&KeyName,
|
||||||
OBJ_CASE_INSENSITIVE,
|
OBJ_CASE_INSENSITIVE,
|
||||||
BaseKeyHandle,
|
BaseKeyHandle,
|
||||||
NULL);
|
NULL);
|
||||||
Status = NtOpenKey(&CurrentKeyHandle,
|
Status = NtOpenKey(&CurrentKeyHandle,
|
||||||
KEY_ALL_ACCESS,
|
KEY_ALL_ACCESS,
|
||||||
&ObjectAttributes);
|
&ObjectAttributes);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DIRECT)
|
else if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DIRECT)
|
||||||
{
|
{
|
||||||
DPRINT("Query value directly: %S\n", QueryEntry->Name);
|
DPRINT("Query value directly: %S\n", QueryEntry->Name);
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
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;
|
Status = STATUS_NO_MEMORY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ZwQueryValueKey(CurrentKeyHandle,
|
Status = NtQueryValueKey(CurrentKeyHandle,
|
||||||
&KeyName,
|
&KeyName,
|
||||||
KeyValuePartialInformation,
|
KeyValuePartialInformation,
|
||||||
ValueInfo,
|
ValueInfo,
|
||||||
BufferSize,
|
BufferSize,
|
||||||
&ResultSize);
|
&ResultSize);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("ZwQueryValueKey() failed with status %x\n", Status);
|
Status = QueryEntry->QueryRoutine(QueryEntry->Name,
|
||||||
ExFreePool(ValueInfo);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
Index = 0;
|
||||||
if (ValueInfo->Type == REG_SZ)
|
while (TRUE)
|
||||||
|
{
|
||||||
|
Status = NtEnumerateValueKey(CurrentKeyHandle,
|
||||||
|
Index,
|
||||||
|
KeyValueFullInformation,
|
||||||
|
FullValueInfo,
|
||||||
|
BufferSize,
|
||||||
|
&ResultSize);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
PUNICODE_STRING ValueString;
|
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||||
ValueString = (PUNICODE_STRING)QueryEntry->EntryContext;
|
Status = STATUS_SUCCESS;
|
||||||
if (ValueString->Buffer == 0)
|
break;
|
||||||
{
|
|
||||||
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);
|
Status = QueryEntry->QueryRoutine(FullValueInfo->Name,
|
||||||
}
|
FullValueInfo->Type,
|
||||||
else
|
(PVOID)FullValueInfo + FullValueInfo->DataOffset,
|
||||||
{
|
FullValueInfo->DataLength,
|
||||||
DPRINT("Query value via query routine: %S\n", QueryEntry->Name);
|
Context,
|
||||||
|
QueryEntry->EntryContext);
|
||||||
}
|
if (!NT_SUCCESS(Status))
|
||||||
|
break;
|
||||||
|
|
||||||
if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DELETE)
|
Index++;
|
||||||
{
|
}
|
||||||
DPRINT("Delete value: %S\n", QueryEntry->Name);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryEntry++;
|
ExFreePool(ValueInfo);
|
||||||
}
|
|
||||||
|
|
||||||
if (CurrentKeyHandle != BaseKeyHandle)
|
if (!NT_SUCCESS(Status))
|
||||||
NtClose(CurrentKeyHandle);
|
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 PVOID ValueData,
|
||||||
IN ULONG ValueLength)
|
IN ULONG ValueLength)
|
||||||
{
|
{
|
||||||
HANDLE KeyHandle;
|
HANDLE KeyHandle;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
UNICODE_STRING Name;
|
UNICODE_STRING Name;
|
||||||
|
|
||||||
Status = RtlpGetRegistryHandle(RelativeTo,
|
Status = RtlpGetRegistryHandle(RelativeTo,
|
||||||
Path,
|
Path,
|
||||||
TRUE,
|
TRUE,
|
||||||
&KeyHandle);
|
&KeyHandle);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
return Status;
|
return(Status);
|
||||||
|
|
||||||
RtlInitUnicodeString(&Name,
|
RtlInitUnicodeString(&Name,
|
||||||
ValueName);
|
ValueName);
|
||||||
|
|
||||||
NtSetValueKey(KeyHandle,
|
NtSetValueKey(KeyHandle,
|
||||||
&Name,
|
&Name,
|
||||||
0,
|
0,
|
||||||
ValueType,
|
ValueType,
|
||||||
ValueData,
|
ValueData,
|
||||||
ValueLength);
|
ValueLength);
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
/* FIXME: !!! */
|
/* FIXME: !!! */
|
||||||
RtlCreateUnicodeString(KeyPath,
|
RtlCreateUnicodeString(KeyPath,
|
||||||
L"\\Registry\\User\\.Default");
|
L"\\Registry\\User\\.Default");
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------ Private Implementation */
|
/* ------------------------------------------ Private Implementation */
|
||||||
|
|
Loading…
Reference in a new issue