Author: ion
Date: Mon May 14 10:40:40 2007
New Revision: 26778
URL:
http://svn.reactos.org/svn/reactos?rev=26778&view=rev
Log:
- Implement NtEnumerateValueKey as a simpler wrapper.
- Implement CmEnumerateValueKey. Simply calls already-existing Value Cache routines
(CmpGetValueListFromCache, CmpGetValueKeyFromCache and CmpQueryKeyValueData) to do all the
work.
Modified:
trunk/reactos/ntoskrnl/cm/cm.h
trunk/reactos/ntoskrnl/cm/ntfunc.c
trunk/reactos/ntoskrnl/config/cm.h
trunk/reactos/ntoskrnl/config/cmapi.c
Modified: trunk/reactos/ntoskrnl/cm/cm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/cm.h?rev=26778…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/cm.h (original)
+++ trunk/reactos/ntoskrnl/cm/cm.h Mon May 14 10:40:40 2007
@@ -285,6 +285,23 @@
IN PULONG ResultLength);
NTSTATUS
+NTAPI
+CmEnumerateValueKey(IN PKEY_OBJECT KeyObject,
+ IN ULONG Index,
+ IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
+ IN PVOID KeyValueInformation,
+ IN ULONG Length,
+ IN PULONG ResultLength);
+
+NTSTATUS
+NTAPI
+CmSetValueKey(IN PKEY_OBJECT KeyObject,
+ IN PUNICODE_STRING ValueName,
+ IN ULONG Type,
+ IN PVOID Data,
+ IN ULONG DataSize);
+
+NTSTATUS
CmiAllocateHashTableCell(IN PEREGISTRY_HIVE RegistryHive,
OUT PHASH_TABLE_CELL *HashBlock,
OUT HCELL_INDEX *HBOffset,
@@ -303,14 +320,6 @@
HV_STORAGE_TYPE StorageType,
PCM_KEY_NODE NewKeyCell,
HCELL_INDEX NKBOffset);
-
-NTSTATUS
-NTAPI
-CmSetValueKey(IN PKEY_OBJECT KeyObject,
- IN PUNICODE_STRING ValueName,
- IN ULONG Type,
- IN PVOID Data,
- IN ULONG DataSize);
NTSTATUS
CmiRemoveKeyFromHashTable(PEREGISTRY_HIVE RegistryHive,
Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/ntfunc.c?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/ntfunc.c (original)
+++ trunk/reactos/ntoskrnl/cm/ntfunc.c Mon May 14 10:40:40 2007
@@ -830,276 +830,60 @@
return(Status);
}
-
-NTSTATUS STDCALL
+NTSTATUS
+NTAPI
NtEnumerateValueKey(IN HANDLE KeyHandle,
- IN ULONG Index,
- IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
- OUT PVOID KeyValueInformation,
- IN ULONG Length,
- OUT PULONG ResultLength)
-{
- NTSTATUS Status;
- PKEY_OBJECT KeyObject;
- PEREGISTRY_HIVE RegistryHive;
- PCM_KEY_NODE KeyCell;
- PCM_KEY_VALUE ValueCell;
- PVOID DataCell;
- ULONG NameSize, DataSize;
- REG_ENUMERATE_VALUE_KEY_INFORMATION EnumerateValueKeyInfo;
- REG_POST_OPERATION_INFORMATION PostOperationInfo;
- PKEY_VALUE_BASIC_INFORMATION ValueBasicInformation;
- PKEY_VALUE_PARTIAL_INFORMATION ValuePartialInformation;
- PKEY_VALUE_FULL_INFORMATION ValueFullInformation;
-
- PAGED_CODE();
-
- DPRINT("KH 0x%p I %d KVIC %x KVI 0x%p L %d RL 0x%p\n",
- KeyHandle,
- Index,
- KeyValueInformationClass,
- KeyValueInformation,
- Length,
- ResultLength);
-
- /* Verify that the handle is valid and is a registry key */
- Status = ObReferenceObjectByHandle(KeyHandle,
- KEY_QUERY_VALUE,
- CmpKeyObjectType,
- ExGetPreviousMode(),
- (PVOID *) &KeyObject,
- NULL);
-
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
- PostOperationInfo.Object = (PVOID)KeyObject;
- EnumerateValueKeyInfo.Object = (PVOID)KeyObject;
- EnumerateValueKeyInfo.Index = Index;
- EnumerateValueKeyInfo.KeyValueInformationClass = KeyValueInformationClass;
- EnumerateValueKeyInfo.KeyValueInformation = KeyValueInformation;
- EnumerateValueKeyInfo.Length = Length;
- EnumerateValueKeyInfo.ResultLength = ResultLength;
-
- Status = CmiCallRegisteredCallbacks(RegNtPreEnumerateValueKey,
&EnumerateValueKeyInfo);
- if (!NT_SUCCESS(Status))
- {
- PostOperationInfo.Status = Status;
- CmiCallRegisteredCallbacks(RegNtPostEnumerateValueKey, &PostOperationInfo);
- ObDereferenceObject(KeyObject);
- return Status;
- }
-
- /* Acquire hive lock */
- KeEnterCriticalRegion();
- ExAcquireResourceSharedLite(&CmpRegistryLock, TRUE);
-
- VERIFY_KEY_OBJECT(KeyObject);
-
- /* Get pointer to KeyCell */
- KeyCell = KeyObject->KeyCell;
- RegistryHive = KeyObject->RegistryHive;
-
- /* Get Value block of interest */
- Status = CmiGetValueFromKeyByIndex(RegistryHive,
- KeyCell,
- Index,
- &ValueCell);
-
- if (!NT_SUCCESS(Status))
- {
- ExReleaseResourceLite(&CmpRegistryLock);
- KeLeaveCriticalRegion();
- ObDereferenceObject(KeyObject);
- PostOperationInfo.Status = Status;
- CmiCallRegisteredCallbacks(RegNtPostEnumerateValueKey, &PostOperationInfo);
- return Status;
- }
-
- if (ValueCell != NULL)
- {
- switch (KeyValueInformationClass)
- {
- case KeyValueBasicInformation:
- NameSize = ValueCell->NameSize;
- if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
- {
- NameSize *= sizeof(WCHAR);
- }
-
- *ResultLength = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name[0]) + NameSize;
-
- if (Length < FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name[0]))
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- }
- else
- {
- ValueBasicInformation = (PKEY_VALUE_BASIC_INFORMATION)
- KeyValueInformation;
- ValueBasicInformation->TitleIndex = 0;
- ValueBasicInformation->Type = ValueCell->DataType;
- ValueBasicInformation->NameLength = NameSize;
-
- if (Length - FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name[0]) <
- NameSize)
- {
- NameSize = Length - FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name[0]);
- Status = STATUS_BUFFER_OVERFLOW;
- CHECKPOINT;
- }
-
- if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
- {
- CmiCopyPackedName(ValueBasicInformation->Name,
- ValueCell->Name,
- NameSize / sizeof(WCHAR));
- }
- else
- {
- RtlCopyMemory(ValueBasicInformation->Name,
- ValueCell->Name,
- NameSize);
- }
- }
- break;
-
- case KeyValuePartialInformation:
- DataSize = ValueCell->DataSize & REG_DATA_SIZE_MASK;
-
- *ResultLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]) +
- DataSize;
-
- if (Length < FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]))
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- }
- else
- {
- ValuePartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION)
- KeyValueInformation;
- ValuePartialInformation->TitleIndex = 0;
- ValuePartialInformation->Type = ValueCell->DataType;
- ValuePartialInformation->DataLength = ValueCell->DataSize &
REG_DATA_SIZE_MASK;
-
- if (Length - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]) <
- DataSize)
- {
- DataSize = Length - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,
Data[0]);
- Status = STATUS_BUFFER_OVERFLOW;
- CHECKPOINT;
- }
-
- if (!(ValueCell->DataSize & REG_DATA_IN_OFFSET))
- {
- DataCell = HvGetCell (&RegistryHive->Hive,
ValueCell->DataOffset);
- RtlCopyMemory(ValuePartialInformation->Data,
- DataCell,
- DataSize);
- }
- else
- {
- RtlCopyMemory(ValuePartialInformation->Data,
- &ValueCell->DataOffset,
- DataSize);
- }
- }
- break;
-
- case KeyValueFullInformation:
- NameSize = ValueCell->NameSize;
- if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
- {
- NameSize *= sizeof(WCHAR);
- }
- DataSize = ValueCell->DataSize & REG_DATA_SIZE_MASK;
-
- *ResultLength = ROUND_UP(FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION,
- Name[0]) + NameSize, sizeof(PVOID)) + DataSize;
-
- if (Length < FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name[0]))
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- }
- else
- {
- ValueFullInformation = (PKEY_VALUE_FULL_INFORMATION)
- KeyValueInformation;
- ValueFullInformation->TitleIndex = 0;
- ValueFullInformation->Type = ValueCell->DataType;
- ValueFullInformation->NameLength = NameSize;
- ValueFullInformation->DataOffset =
- (ULONG_PTR)ValueFullInformation->Name -
- (ULONG_PTR)ValueFullInformation +
- ValueFullInformation->NameLength;
- ValueFullInformation->DataOffset =
- ROUND_UP(ValueFullInformation->DataOffset, sizeof(PVOID));
- ValueFullInformation->DataLength = ValueCell->DataSize &
REG_DATA_SIZE_MASK;
-
- if (Length < ValueFullInformation->DataOffset)
- {
- NameSize = Length - FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name[0]);
- DataSize = 0;
- Status = STATUS_BUFFER_OVERFLOW;
- CHECKPOINT;
- }
- else if (Length - ValueFullInformation->DataOffset < DataSize)
- {
- DataSize = Length - ValueFullInformation->DataOffset;
- Status = STATUS_BUFFER_OVERFLOW;
- CHECKPOINT;
- }
-
- if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
- {
- CmiCopyPackedName(ValueFullInformation->Name,
- ValueCell->Name,
- NameSize / sizeof(WCHAR));
- }
- else
- {
- RtlCopyMemory(ValueFullInformation->Name,
- ValueCell->Name,
- NameSize);
- }
-
- if (!(ValueCell->DataSize & REG_DATA_IN_OFFSET))
- {
- DataCell = HvGetCell (&RegistryHive->Hive,
ValueCell->DataOffset);
- RtlCopyMemory((PCHAR) ValueFullInformation
- + ValueFullInformation->DataOffset,
- DataCell, DataSize);
- }
- else
- {
- RtlCopyMemory((PCHAR) ValueFullInformation
- + ValueFullInformation->DataOffset,
- &ValueCell->DataOffset, DataSize);
- }
- }
- break;
-
- default:
- DPRINT1("Not handling 0x%x\n", KeyValueInformationClass);
- break;
- }
- }
- else
- {
- Status = STATUS_UNSUCCESSFUL;
- }
-
- ExReleaseResourceLite(&CmpRegistryLock);
- KeLeaveCriticalRegion();
- ObDereferenceObject(KeyObject);
- PostOperationInfo.Status = Status;
- CmiCallRegisteredCallbacks(RegNtPostEnumerateValueKey, &PostOperationInfo);
-
- return Status;
-}
-
+ IN ULONG Index,
+ IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
+ OUT PVOID KeyValueInformation,
+ IN ULONG Length,
+ OUT PULONG ResultLength)
+{
+ NTSTATUS Status;
+ PKEY_OBJECT KeyObject;
+ REG_ENUMERATE_VALUE_KEY_INFORMATION EnumerateValueKeyInfo;
+ REG_POST_OPERATION_INFORMATION PostOperationInfo;
+ PAGED_CODE();
+
+ /* Verify that the handle is valid and is a registry key */
+ Status = ObReferenceObjectByHandle(KeyHandle,
+ KEY_QUERY_VALUE,
+ CmpKeyObjectType,
+ ExGetPreviousMode(),
+ (PVOID *)&KeyObject,
+ NULL);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Setup the callback */
+ PostOperationInfo.Object = (PVOID)KeyObject;
+ EnumerateValueKeyInfo.Object = (PVOID)KeyObject;
+ EnumerateValueKeyInfo.Index = Index;
+ EnumerateValueKeyInfo.KeyValueInformationClass = KeyValueInformationClass;
+ EnumerateValueKeyInfo.KeyValueInformation = KeyValueInformation;
+ EnumerateValueKeyInfo.Length = Length;
+ EnumerateValueKeyInfo.ResultLength = ResultLength;
+
+ /* Do the callback */
+ Status = CmiCallRegisteredCallbacks(RegNtPreEnumerateValueKey,
+ &EnumerateValueKeyInfo);
+ if (NT_SUCCESS(Status))
+ {
+ /* Call the internal API */
+ Status = CmEnumerateValueKey(KeyObject,
+ Index,
+ KeyValueInformationClass,
+ KeyValueInformation,
+ Length,
+ ResultLength);
+
+ /* Do the post callback */
+ PostOperationInfo.Status = Status;
+ CmiCallRegisteredCallbacks(RegNtPostEnumerateValueKey, &PostOperationInfo);
+ }
+
+ ObDereferenceObject(KeyObject);
+ return Status;
+}
NTSTATUS STDCALL
NtFlushKey(IN HANDLE KeyHandle)
Modified: trunk/reactos/ntoskrnl/config/cm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cm.h?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cm.h (original)
+++ trunk/reactos/ntoskrnl/config/cm.h Mon May 14 10:40:40 2007
@@ -769,6 +769,28 @@
OUT PNTSTATUS Status
);
+VALUE_SEARCH_RETURN_TYPE
+NTAPI
+CmpGetValueListFromCache(
+ IN PKEY_OBJECT KeyObject,
+ OUT PCELL_DATA *CellData,
+ OUT BOOLEAN *IndexIsCached,
+ OUT PHCELL_INDEX ValueListToRelease
+);
+
+VALUE_SEARCH_RETURN_TYPE
+NTAPI
+CmpGetValueKeyFromCache(
+ IN PKEY_OBJECT KeyObject,
+ IN PCELL_DATA CellData,
+ IN ULONG Index,
+ OUT PCM_CACHED_VALUE **CachedValue,
+ OUT PCM_KEY_VALUE *Value,
+ IN BOOLEAN IndexIsCached,
+ OUT BOOLEAN *ValueIsCached,
+ OUT PHCELL_INDEX CellToRelease
+);
+
//
// Registry Validation Functions
//
Modified: trunk/reactos/ntoskrnl/config/cmapi.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmapi.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmapi.c (original)
+++ trunk/reactos/ntoskrnl/config/cmapi.c Mon May 14 10:40:40 2007
@@ -519,3 +519,108 @@
KeLeaveCriticalRegion();
return Status;
}
+
+NTSTATUS
+NTAPI
+CmEnumerateValueKey(IN PKEY_OBJECT KeyObject,
+ IN ULONG Index,
+ IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
+ IN PVOID KeyValueInformation,
+ IN ULONG Length,
+ IN PULONG ResultLength)
+{
+ NTSTATUS Status;
+ PHHIVE Hive;
+ PCM_KEY_NODE Parent;
+ HCELL_INDEX CellToRelease = HCELL_NIL, CellToRelease2 = HCELL_NIL;
+ VALUE_SEARCH_RETURN_TYPE Result;
+ BOOLEAN IndexIsCached, ValueIsCached = FALSE;
+ PCELL_DATA CellData;
+ PCM_CACHED_VALUE *CachedValue;
+ PCM_KEY_VALUE ValueData;
+ PAGED_CODE();
+
+ /* Acquire hive lock */
+ KeEnterCriticalRegion();
+ ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
+
+ /* Get the hive and parent */
+ Hive = &KeyObject->RegistryHive->Hive;
+ Parent = (PCM_KEY_NODE)HvGetCell(Hive, KeyObject->KeyCellOffset);
+ if (!Parent)
+ {
+ /* Fail */
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto Quickie;
+ }
+
+ /* Make sure the index is valid */
+ //if (Index >= KeyObject->ValueCache.Count)
+ if (Index >= KeyObject->KeyCell->ValueList.Count)
+ {
+ /* Release the cell and fail */
+ HvReleaseCell(Hive, KeyObject->KeyCellOffset);
+ Status = STATUS_NO_MORE_ENTRIES;
+ goto Quickie;
+ }
+
+ /* Find the value list */
+ Result = CmpGetValueListFromCache(KeyObject,
+ &CellData,
+ &IndexIsCached,
+ &CellToRelease);
+ if (Result != SearchSuccess)
+ {
+ /* Sanity check */
+ ASSERT(CellData == NULL);
+
+ /* Release the cell and fail */
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto Quickie;
+ }
+
+ /* Now get the key value */
+ Result = CmpGetValueKeyFromCache(KeyObject,
+ CellData,
+ Index,
+ &CachedValue,
+ &ValueData,
+ IndexIsCached,
+ &ValueIsCached,
+ &CellToRelease2);
+ if (Result != SearchSuccess)
+ {
+ /* Sanity check */
+ ASSERT(CellToRelease2 == HCELL_NIL);
+
+ /* Release the cells and fail */
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto Quickie;
+ }
+
+ /* Query the information requested */
+ Result = CmpQueryKeyValueData(KeyObject,
+ CachedValue,
+ ValueData,
+ ValueIsCached,
+ KeyValueInformationClass,
+ KeyValueInformation,
+ Length,
+ ResultLength,
+ &Status);
+
+Quickie:
+ /* If we have a cell to release, do so */
+ if (CellToRelease != HCELL_NIL) HvReleaseCell(Hive, CellToRelease);
+
+ /* Release the parent cell */
+ HvReleaseCell(Hive, KeyObject->KeyCellOffset);
+
+ /* If we have a cell to release, do so */
+ if (CellToRelease2 != HCELL_NIL) HvReleaseCell(Hive, CellToRelease2);
+
+ /* Release hive lock */
+ ExReleaseResourceLite(&CmpRegistryLock);
+ KeLeaveCriticalRegion();
+ return Status;
+}