[ros-diffs] [ion] 26778: - Implement NtEnumerateValueKey as a simpler wrapper. - Implement CmEnumerateValueKey. Simply calls already-existing Value Cache routines (CmpGetValueListFromCache, CmpGetValueKeyFromCache and CmpQueryKeyValueData) to do all the work.

ion at svn.reactos.org ion at svn.reactos.org
Mon May 14 08:40:40 CEST 2007


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&r1=26777&r2=26778&view=diff
==============================================================================
--- 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=26778&r1=26777&r2=26778&view=diff
==============================================================================
--- 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=26778&r1=26777&r2=26778&view=diff
==============================================================================
--- 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?rev=26778&r1=26777&r2=26778&view=diff
==============================================================================
--- 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;
+}




More information about the Ros-diffs mailing list