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

@ -14,7 +14,7 @@ typedef enum _KEY_INFORMATION_CLASS
KeyFullInformation KeyFullInformation
} KEY_INFORMATION_CLASS; } KEY_INFORMATION_CLASS;
typedef struct _KEY_BASIC_INFORMATION typedef struct _KEY_BASIC_INFORMATION
{ {
LARGE_INTEGER LastWriteTime; LARGE_INTEGER LastWriteTime;
ULONG TitleIndex; ULONG TitleIndex;
@ -22,7 +22,7 @@ typedef struct _KEY_BASIC_INFORMATION
WCHAR Name[1]; WCHAR Name[1];
} KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION; } KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION;
typedef struct _KEY_FULL_INFORMATION typedef struct _KEY_FULL_INFORMATION
{ {
LARGE_INTEGER LastWriteTime; LARGE_INTEGER LastWriteTime;
ULONG TitleIndex; ULONG TitleIndex;
@ -37,7 +37,7 @@ typedef struct _KEY_FULL_INFORMATION
WCHAR Class[1]; WCHAR Class[1];
} KEY_FULL_INFORMATION, *PKEY_FULL_INFORMATION; } KEY_FULL_INFORMATION, *PKEY_FULL_INFORMATION;
typedef struct _KEY_NODE_INFORMATION typedef struct _KEY_NODE_INFORMATION
{ {
LARGE_INTEGER LastWriteTime; LARGE_INTEGER LastWriteTime;
ULONG TitleIndex; ULONG TitleIndex;
@ -61,7 +61,7 @@ typedef enum _KEY_VALUE_INFORMATION_CLASS
KeyValuePartialInformation KeyValuePartialInformation
} KEY_VALUE_INFORMATION_CLASS; } KEY_VALUE_INFORMATION_CLASS;
typedef struct _KEY_VALUE_BASIC_INFORMATION typedef struct _KEY_VALUE_BASIC_INFORMATION
{ {
ULONG TitleIndex; ULONG TitleIndex;
ULONG Type; ULONG Type;
@ -69,7 +69,7 @@ typedef struct _KEY_VALUE_BASIC_INFORMATION
WCHAR Name[1]; WCHAR Name[1];
} KEY_VALUE_BASIC_INFORMATION, *PKEY_VALUE_BASIC_INFORMATION; } KEY_VALUE_BASIC_INFORMATION, *PKEY_VALUE_BASIC_INFORMATION;
typedef struct _KEY_VALUE_FULL_INFORMATION typedef struct _KEY_VALUE_FULL_INFORMATION
{ {
ULONG TitleIndex; ULONG TitleIndex;
ULONG Type; ULONG Type;
@ -79,7 +79,7 @@ typedef struct _KEY_VALUE_FULL_INFORMATION
WCHAR Name[1]; WCHAR Name[1];
} KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION; } KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION;
typedef struct _KEY_VALUE_PARTIAL_INFORMATION typedef struct _KEY_VALUE_PARTIAL_INFORMATION
{ {
ULONG TitleIndex; ULONG TitleIndex;
ULONG Type; ULONG Type;
@ -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
@ -3075,7 +3075,7 @@ NtQueryKey(
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 NTSTATUS
@ -3085,7 +3085,7 @@ ZwQueryKey(
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
); );
@ -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 KEY_INFORMATION_CLASS KeyInformationClass,
IN HANDLE KeyHandle, OUT PVOID KeyInformation,
IN KEY_INFORMATION_CLASS KeyInformationClass, IN ULONG Length,
OUT PVOID KeyInformation, OUT PULONG ResultLength)
IN ULONG Length,
OUT PULONG ResultLength
)
{ {
NTSTATUS Status; NTSTATUS Status;
PKEY_OBJECT KeyObject; PKEY_OBJECT KeyObject;
@ -1136,19 +1133,17 @@ 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;
PREGISTRY_FILE RegistryFile; PREGISTRY_FILE RegistryFile;
PKEY_BLOCK KeyBlock; PKEY_BLOCK KeyBlock;
char ValueName2[MAX_PATH]; char ValueName2[MAX_PATH];
// KIRQL OldIrql; // KIRQL OldIrql;
wcstombs(ValueName2,ValueName->Buffer,ValueName->Length>>1); wcstombs(ValueName2,ValueName->Buffer,ValueName->Length>>1);
ValueName2[ValueName->Length>>1]=0; ValueName2[ValueName->Length>>1]=0;
@ -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;
} }