Implemented [Nt/Zw]QueryMultipleValueKey().

svn path=/trunk/; revision=2607
This commit is contained in:
Eric Kohl 2002-02-06 01:23:10 +00:00
parent 52d2359910
commit 1d0d9fbf9f
3 changed files with 175 additions and 83 deletions

View file

@ -91,4 +91,13 @@ typedef struct _KEY_VALUE_PARTIAL_INFORMATION
#define REG_OPTION_BACKUP_RESTORE 0x00000004 #define REG_OPTION_BACKUP_RESTORE 0x00000004
/* used by [Nt/Zw]QueryMultipleValueKey */
typedef struct _KEY_VALUE_ENTRY
{
PUNICODE_STRING ValueName;
ULONG DataLength;
ULONG DataOffset;
ULONG Type;
} KEY_VALUE_ENTRY, *PKEY_VALUE_ENTRY;

View file

@ -1,5 +1,5 @@
/* $Id: zw.h,v 1.48 2001/11/20 02:29:43 dwelch Exp $ /* $Id: zw.h,v 1.49 2002/02/06 01:22:32 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -3094,24 +3094,24 @@ ZwQueryKey(
NTSTATUS NTSTATUS
STDCALL STDCALL
NtQueryMultipleValueKey( NtQueryMultipleValueKey(
HANDLE KeyHandle, IN HANDLE KeyHandle,
PWVALENT ListOfValuesToQuery, IN OUT PKEY_VALUE_ENTRY ValueList,
ULONG NumberOfItems, IN ULONG NumberOfValues,
PVOID MultipleValueInformation, OUT PVOID Buffer,
ULONG Length, IN OUT PULONG Length,
PULONG ReturnLength OUT PULONG ReturnLength
); );
NTSTATUS NTSTATUS
STDCALL STDCALL
ZwQueryMultipleValueKey( ZwQueryMultipleValueKey(
HANDLE KeyHandle, IN HANDLE KeyHandle,
PWVALENT ListOfValuesToQuery, IN OUT PKEY_VALUE_ENTRY ValueList,
ULONG NumberOfItems, IN ULONG NumberOfValues,
PVOID MultipleValueInformation, OUT PVOID Buffer,
ULONG Length, IN OUT PULONG Length,
PULONG ReturnLength OUT PULONG ReturnLength
); );
/* /*
* FUNCTION: Queries the information of a mutant object. * FUNCTION: Queries the information of a mutant object.

View file

@ -704,15 +704,12 @@ DPRINT("NTOpenKey2 : after ObFindObject\n");
} }
NTSTATUS NTSTATUS STDCALL
STDCALL NtQueryKey(IN HANDLE KeyHandle,
NtQueryKey (
IN HANDLE KeyHandle,
IN KEY_INFORMATION_CLASS KeyInformationClass, IN KEY_INFORMATION_CLASS KeyInformationClass,
OUT PVOID KeyInformation, OUT PVOID KeyInformation,
IN ULONG Length, IN ULONG Length,
OUT PULONG ResultLength OUT PULONG ResultLength)
)
{ {
NTSTATUS Status; NTSTATUS Status;
PKEY_OBJECT KeyObject; PKEY_OBJECT KeyObject;
@ -1136,12 +1133,10 @@ NtSetValueKey (
return Status; return Status;
} }
NTSTATUS
STDCALL NTSTATUS STDCALL
NtDeleteValueKey ( NtDeleteValueKey(IN HANDLE KeyHandle,
IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName)
IN PUNICODE_STRING ValueName
)
{ {
NTSTATUS Status; NTSTATUS Status;
PKEY_OBJECT KeyObject; PKEY_OBJECT KeyObject;
@ -1178,26 +1173,21 @@ NtDeleteValueKey (
return Status; return Status;
} }
NTSTATUS
STDCALL NTSTATUS STDCALL
NtLoadKey ( NtLoadKey(PHANDLE KeyHandle,
PHANDLE KeyHandle, POBJECT_ATTRIBUTES ObjectAttributes)
POBJECT_ATTRIBUTES ObjectAttributes
)
{ {
return NtLoadKey2(KeyHandle, return(NtLoadKey2(KeyHandle,
ObjectAttributes, ObjectAttributes,
0); 0));
} }
NTSTATUS NTSTATUS STDCALL
STDCALL NtLoadKey2(IN PHANDLE KeyHandle,
NtLoadKey2 ( IN POBJECT_ATTRIBUTES ObjectAttributes,
PHANDLE KeyHandle, IN ULONG Flags)
POBJECT_ATTRIBUTES ObjectAttributes,
ULONG Unknown3
)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }
@ -1222,18 +1212,118 @@ NtNotifyChangeKey (
} }
NTSTATUS NTSTATUS STDCALL
STDCALL NtQueryMultipleValueKey(IN HANDLE KeyHandle,
NtQueryMultipleValueKey ( IN OUT PKEY_VALUE_ENTRY ValueList,
IN HANDLE KeyHandle, IN ULONG NumberOfValues,
IN PWVALENT ListOfValuesToQuery, OUT PVOID Buffer,
IN ULONG NumberOfItems, IN OUT PULONG Length,
OUT PVOID MultipleValueInformation, OUT PULONG ReturnLength)
IN ULONG Length,
OUT PULONG ReturnLength
)
{ {
UNIMPLEMENTED; PKEY_OBJECT KeyObject;
PREGISTRY_FILE RegistryFile;
PKEY_BLOCK KeyBlock;
PVALUE_BLOCK ValueBlock;
PDATA_BLOCK DataBlock;
UCHAR ValueName[MAX_PATH];
PUCHAR DataPtr;
ULONG BufferLength;
ULONG i;
NTSTATUS Status;
/* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle,
KEY_QUERY_VALUE,
CmiKeyType,
UserMode,
(PVOID *)&KeyObject,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT("ObReferenceObjectByHandle() failed with status %x\n", Status);
return(Status);
}
/* Get pointer to KeyBlock */
KeyBlock = KeyObject->KeyBlock;
RegistryFile = KeyObject->RegistryFile;
DataPtr = (PUCHAR)Buffer;
for (i = 0; i < NumberOfValues; i++)
{
wcstombs(ValueName,
ValueList[i].ValueName->Buffer,
ValueList[i].ValueName->Length >> 1);
ValueName[ValueList[i].ValueName->Length >> 1] = 0;
DPRINT("ValueName: '%s'\n", ValueName);
/* Get Value block of interest */
Status = CmiScanKeyForValue(RegistryFile,
KeyBlock,
ValueName,
&ValueBlock,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT("CmiScanKeyForValue() failed with status %x\n", Status);
break;
}
else if (ValueBlock == NULL)
{
Status = STATUS_OBJECT_NAME_NOT_FOUND;
break;
}
BufferLength = (BufferLength + 3) & 0xfffffffc;
if (BufferLength + (ValueBlock->DataSize & LONG_MAX) <= *Length)
{
DataPtr = (PUCHAR)(((ULONG)DataPtr + 3) & 0xfffffffc);
ValueList[i].Type = ValueBlock->DataType;
ValueList[i].DataLength = ValueBlock->DataSize & LONG_MAX;
ValueList[i].DataOffset = (ULONG)DataPtr - (ULONG)Buffer;
if (ValueBlock->DataSize >0)
{
DataBlock = CmiGetBlock(RegistryFile,
ValueBlock->DataOffset,
NULL);
RtlCopyMemory(DataPtr,
DataBlock->Data,
ValueBlock->DataSize & LONG_MAX);
CmiReleaseBlock(RegistryFile,
DataBlock);
}
else
{
RtlCopyMemory(DataPtr,
&ValueBlock->DataOffset,
ValueBlock->DataSize & LONG_MAX);
}
DataPtr += ValueBlock->DataSize & LONG_MAX;
}
else
{
Status = STATUS_BUFFER_TOO_SMALL;
}
BufferLength += ValueBlock->DataSize & LONG_MAX;
}
if (NT_SUCCESS(Status))
*Length = BufferLength;
*ReturnLength = BufferLength;
ObDereferenceObject(KeyObject);
DPRINT("Return Status 0x%X\n", Status);
return(Status);
} }
@ -1285,22 +1375,15 @@ NtSetInformationKey (
} }
NTSTATUS NTSTATUS STDCALL
STDCALL NtUnloadKey(IN HANDLE KeyHandle)
NtUnloadKey (
HANDLE KeyHandle
)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }
NTSTATUS NTSTATUS STDCALL
STDCALL NtInitializeRegistry(IN BOOLEAN SetUpBoot)
NtInitializeRegistry (
BOOLEAN SetUpBoot
)
{ {
// UNIMPLEMENTED; return(STATUS_SUCCESS);
return STATUS_SUCCESS;
} }