mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 02:25:17 +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
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in a new issue