From 1d0d9fbf9f22a4e947771dc9bfe5d150b1b72d28 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Wed, 6 Feb 2002 01:23:10 +0000 Subject: [PATCH] Implemented [Nt/Zw]QueryMultipleValueKey(). svn path=/trunk/; revision=2607 --- reactos/include/ddk/cmtypes.h | 21 +++- reactos/include/ddk/zw.h | 34 +++--- reactos/ntoskrnl/cm/ntfunc.c | 203 ++++++++++++++++++++++++---------- 3 files changed, 175 insertions(+), 83 deletions(-) diff --git a/reactos/include/ddk/cmtypes.h b/reactos/include/ddk/cmtypes.h index 46b1f0aa940..b44d83d8f92 100644 --- a/reactos/include/ddk/cmtypes.h +++ b/reactos/include/ddk/cmtypes.h @@ -14,7 +14,7 @@ typedef enum _KEY_INFORMATION_CLASS KeyFullInformation } KEY_INFORMATION_CLASS; -typedef struct _KEY_BASIC_INFORMATION +typedef struct _KEY_BASIC_INFORMATION { LARGE_INTEGER LastWriteTime; ULONG TitleIndex; @@ -22,7 +22,7 @@ typedef struct _KEY_BASIC_INFORMATION WCHAR Name[1]; } KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION; -typedef struct _KEY_FULL_INFORMATION +typedef struct _KEY_FULL_INFORMATION { LARGE_INTEGER LastWriteTime; ULONG TitleIndex; @@ -37,7 +37,7 @@ typedef struct _KEY_FULL_INFORMATION WCHAR Class[1]; } KEY_FULL_INFORMATION, *PKEY_FULL_INFORMATION; -typedef struct _KEY_NODE_INFORMATION +typedef struct _KEY_NODE_INFORMATION { LARGE_INTEGER LastWriteTime; ULONG TitleIndex; @@ -61,7 +61,7 @@ typedef enum _KEY_VALUE_INFORMATION_CLASS KeyValuePartialInformation } KEY_VALUE_INFORMATION_CLASS; -typedef struct _KEY_VALUE_BASIC_INFORMATION +typedef struct _KEY_VALUE_BASIC_INFORMATION { ULONG TitleIndex; ULONG Type; @@ -69,7 +69,7 @@ typedef struct _KEY_VALUE_BASIC_INFORMATION WCHAR Name[1]; } KEY_VALUE_BASIC_INFORMATION, *PKEY_VALUE_BASIC_INFORMATION; -typedef struct _KEY_VALUE_FULL_INFORMATION +typedef struct _KEY_VALUE_FULL_INFORMATION { ULONG TitleIndex; ULONG Type; @@ -79,7 +79,7 @@ typedef struct _KEY_VALUE_FULL_INFORMATION WCHAR Name[1]; } KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION; -typedef struct _KEY_VALUE_PARTIAL_INFORMATION +typedef struct _KEY_VALUE_PARTIAL_INFORMATION { ULONG TitleIndex; ULONG Type; @@ -91,4 +91,13 @@ typedef struct _KEY_VALUE_PARTIAL_INFORMATION #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; diff --git a/reactos/include/ddk/zw.h b/reactos/include/ddk/zw.h index 5eab0b0eca9..fbe6760f8eb 100644 --- a/reactos/include/ddk/zw.h +++ b/reactos/include/ddk/zw.h @@ -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 * PROJECT: ReactOS kernel @@ -3075,7 +3075,7 @@ NtQueryKey( IN KEY_INFORMATION_CLASS KeyInformationClass, OUT PVOID KeyInformation, IN ULONG Length, - OUT PULONG ResultLength + OUT PULONG ResultLength ); NTSTATUS @@ -3085,7 +3085,7 @@ ZwQueryKey( IN KEY_INFORMATION_CLASS KeyInformationClass, OUT PVOID KeyInformation, IN ULONG Length, - OUT PULONG ResultLength + OUT PULONG ResultLength ); @@ -3094,24 +3094,24 @@ ZwQueryKey( NTSTATUS STDCALL NtQueryMultipleValueKey( - HANDLE KeyHandle, - PWVALENT ListOfValuesToQuery, - ULONG NumberOfItems, - PVOID MultipleValueInformation, - ULONG Length, - PULONG ReturnLength -); + IN HANDLE KeyHandle, + IN OUT PKEY_VALUE_ENTRY ValueList, + IN ULONG NumberOfValues, + OUT PVOID Buffer, + IN OUT PULONG Length, + OUT PULONG ReturnLength + ); NTSTATUS STDCALL ZwQueryMultipleValueKey( - HANDLE KeyHandle, - PWVALENT ListOfValuesToQuery, - ULONG NumberOfItems, - PVOID MultipleValueInformation, - ULONG Length, - PULONG ReturnLength -); + IN HANDLE KeyHandle, + IN OUT PKEY_VALUE_ENTRY ValueList, + IN ULONG NumberOfValues, + OUT PVOID Buffer, + IN OUT PULONG Length, + OUT PULONG ReturnLength + ); /* * FUNCTION: Queries the information of a mutant object. diff --git a/reactos/ntoskrnl/cm/ntfunc.c b/reactos/ntoskrnl/cm/ntfunc.c index e961a7869fb..cf1c5a312eb 100644 --- a/reactos/ntoskrnl/cm/ntfunc.c +++ b/reactos/ntoskrnl/cm/ntfunc.c @@ -704,15 +704,12 @@ DPRINT("NTOpenKey2 : after ObFindObject\n"); } -NTSTATUS -STDCALL -NtQueryKey ( - IN HANDLE KeyHandle, - IN KEY_INFORMATION_CLASS KeyInformationClass, - OUT PVOID KeyInformation, - IN ULONG Length, - OUT PULONG ResultLength - ) +NTSTATUS STDCALL +NtQueryKey(IN HANDLE KeyHandle, + IN KEY_INFORMATION_CLASS KeyInformationClass, + OUT PVOID KeyInformation, + IN ULONG Length, + OUT PULONG ResultLength) { NTSTATUS Status; PKEY_OBJECT KeyObject; @@ -1136,19 +1133,17 @@ NtSetValueKey ( return Status; } -NTSTATUS -STDCALL -NtDeleteValueKey ( - IN HANDLE KeyHandle, - IN PUNICODE_STRING ValueName - ) + +NTSTATUS STDCALL +NtDeleteValueKey(IN HANDLE KeyHandle, + IN PUNICODE_STRING ValueName) { - NTSTATUS Status; - PKEY_OBJECT KeyObject; - PREGISTRY_FILE RegistryFile; - PKEY_BLOCK KeyBlock; - char ValueName2[MAX_PATH]; -// KIRQL OldIrql; + NTSTATUS Status; + PKEY_OBJECT KeyObject; + PREGISTRY_FILE RegistryFile; + PKEY_BLOCK KeyBlock; + char ValueName2[MAX_PATH]; +// KIRQL OldIrql; wcstombs(ValueName2,ValueName->Buffer,ValueName->Length>>1); ValueName2[ValueName->Length>>1]=0; @@ -1178,26 +1173,21 @@ NtDeleteValueKey ( return Status; } -NTSTATUS -STDCALL -NtLoadKey ( - PHANDLE KeyHandle, - POBJECT_ATTRIBUTES ObjectAttributes - ) + +NTSTATUS STDCALL +NtLoadKey(PHANDLE KeyHandle, + POBJECT_ATTRIBUTES ObjectAttributes) { - return NtLoadKey2(KeyHandle, - ObjectAttributes, - 0); + return(NtLoadKey2(KeyHandle, + ObjectAttributes, + 0)); } -NTSTATUS -STDCALL -NtLoadKey2 ( - PHANDLE KeyHandle, - POBJECT_ATTRIBUTES ObjectAttributes, - ULONG Unknown3 - ) +NTSTATUS STDCALL +NtLoadKey2(IN PHANDLE KeyHandle, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG Flags) { UNIMPLEMENTED; } @@ -1222,18 +1212,118 @@ NtNotifyChangeKey ( } -NTSTATUS -STDCALL -NtQueryMultipleValueKey ( - IN HANDLE KeyHandle, - IN PWVALENT ListOfValuesToQuery, - IN ULONG NumberOfItems, - OUT PVOID MultipleValueInformation, - IN ULONG Length, - OUT PULONG ReturnLength - ) +NTSTATUS STDCALL +NtQueryMultipleValueKey(IN HANDLE KeyHandle, + IN OUT PKEY_VALUE_ENTRY ValueList, + IN ULONG NumberOfValues, + OUT PVOID Buffer, + IN OUT PULONG 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 -STDCALL -NtUnloadKey ( - HANDLE KeyHandle - ) +NTSTATUS STDCALL +NtUnloadKey(IN HANDLE KeyHandle) { UNIMPLEMENTED; } -NTSTATUS -STDCALL -NtInitializeRegistry ( - BOOLEAN SetUpBoot - ) +NTSTATUS STDCALL +NtInitializeRegistry(IN BOOLEAN SetUpBoot) { -// UNIMPLEMENTED; - return STATUS_SUCCESS; + return(STATUS_SUCCESS); } -- 2.17.1