[ros-diffs] [ion] 26781: - Implement CmpFindSubKeyByNumber and CmpDoFindSubKeyByNumber. - Make NtEnumerateKey a simpler wrapper around CmEnumerateKey. - Implement CmEnumerateKey by using the same API as previously, CmpQueryKeyData instead of duplicating code like the previous version did. Use CmpFindSubKeyByNumber to convert from index to key node. - Remove CmiGetValueFromKeyByIndex, CmiGetKeyFromHashByIndex, CmiCopyPackedName: deprecated.

ion at svn.reactos.org ion at svn.reactos.org
Mon May 14 21:35:58 CEST 2007


Author: ion
Date: Mon May 14 23:35:58 2007
New Revision: 26781

URL: http://svn.reactos.org/svn/reactos?rev=26781&view=rev
Log:
- Implement CmpFindSubKeyByNumber and CmpDoFindSubKeyByNumber.
- Make NtEnumerateKey a simpler wrapper around CmEnumerateKey.
- Implement CmEnumerateKey by using the same API as previously, CmpQueryKeyData instead of duplicating code like the previous version did. Use CmpFindSubKeyByNumber to convert from index to key node.
- Remove CmiGetValueFromKeyByIndex, CmiGetKeyFromHashByIndex, CmiCopyPackedName: deprecated.

Modified:
    trunk/reactos/ntoskrnl/cm/cm.h
    trunk/reactos/ntoskrnl/cm/ntfunc.c
    trunk/reactos/ntoskrnl/cm/regfile.c
    trunk/reactos/ntoskrnl/config/cm.h
    trunk/reactos/ntoskrnl/config/cmapi.c
    trunk/reactos/ntoskrnl/config/cmindex.c

Modified: trunk/reactos/ntoskrnl/cm/cm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/cm.h?rev=26781&r1=26780&r2=26781&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/cm/cm.h (original)
+++ trunk/reactos/ntoskrnl/cm/cm.h Mon May 14 23:35:58 2007
@@ -163,39 +163,6 @@
 NTSTATUS STDCALL
 CmUnRegisterCallback(IN LARGE_INTEGER    Cookie);
 
-NTSTATUS STDCALL
-CmpParseKey(IN PVOID ParsedObject,
-               IN PVOID ObjectType,
-               IN OUT PACCESS_STATE AccessState,
-               IN KPROCESSOR_MODE AccessMode,
-               IN ULONG Attributes,
-               IN OUT PUNICODE_STRING FullPath,
-               IN OUT PUNICODE_STRING RemainingName,
-               IN OUT PVOID Context OPTIONAL,
-               IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
-               OUT PVOID *NextObject);
-
-VOID STDCALL
-CmpDeleteKeyObject(PVOID  DeletedObject);
-
-NTSTATUS STDCALL
-CmpSecurityMethod(PVOID ObjectBody,
-		  SECURITY_OPERATION_CODE OperationCode,
-		  PSECURITY_INFORMATION SecurityInformation,
-		  PSECURITY_DESCRIPTOR SecurityDescriptor,
-		  PULONG BufferLength,
-		  PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
-		  POOL_TYPE PoolType,
-		  PGENERIC_MAPPING GenericMapping);
-
-NTSTATUS STDCALL
-CmpQueryKeyName (PVOID ObjectBody,
-                    IN BOOLEAN HasObjectName,
-		    POBJECT_NAME_INFORMATION ObjectNameInfo,
-		    ULONG Length,
-		    PULONG ReturnLength,
-            IN KPROCESSOR_MODE PreviousMode);
-
 VOID
 CmiAddKeyToList(IN PKEY_OBJECT ParentKey,
 		IN PKEY_OBJECT NewKey);
@@ -265,12 +232,6 @@
 		   OUT HCELL_INDEX *VBOffset);
 
 NTSTATUS
-CmiGetValueFromKeyByIndex(IN PEREGISTRY_HIVE RegistryHive,
-			  IN PCM_KEY_NODE KeyCell,
-			  IN ULONG Index,
-			  OUT PCM_KEY_VALUE *ValueCell);
-
-NTSTATUS
 NTAPI
 CmDeleteValueKey(IN PKEY_OBJECT KeyControlBlock,
                  IN UNICODE_STRING ValueName);
@@ -310,16 +271,20 @@
            IN PULONG ResultLength);
 
 NTSTATUS
+NTAPI
+CmEnumerateKey(IN PKEY_OBJECT KeyObject,
+               IN ULONG Index,
+               IN KEY_INFORMATION_CLASS KeyInformationClass,
+               IN PVOID KeyInformation,
+               IN ULONG Length,
+               IN PULONG ResultLength);
+
+NTSTATUS
 CmiAllocateHashTableCell(IN PEREGISTRY_HIVE RegistryHive,
 			 OUT PHASH_TABLE_CELL *HashBlock,
 			 OUT HCELL_INDEX *HBOffset,
 			 IN ULONG HashTableSize,
 			 IN HV_STORAGE_TYPE Storage);
-
-PCM_KEY_NODE
-CmiGetKeyFromHashByIndex(PEREGISTRY_HIVE RegistryHive,
-			 PHASH_TABLE_CELL HashBlock,
-			 ULONG Index);
 
 NTSTATUS
 CmiAddKeyToHashTable(PEREGISTRY_HIVE RegistryHive,
@@ -363,16 +328,7 @@
 );
 
 VOID
-CmiCopyPackedName(PWCHAR NameBuffer,
-		  PUCHAR PackedNameBuffer,
-		  ULONG PackedNameSize);
-
-VOID
 CmiSyncHives(VOID);
-
-
-NTSTATUS
-CmiCreateTempHive(PEREGISTRY_HIVE *RegistryHive);
 
 NTSTATUS
 CmiSaveTempHive (PEREGISTRY_HIVE Hive,
@@ -389,45 +345,6 @@
     IN PACCESS_STATE AccessState,
     IN PVOID ParseContext
 );
-PVOID CMAPI
-CmpAllocate(
-   ULONG Size,
-   BOOLEAN Paged);
-
-VOID CMAPI
-CmpFree(
-   PVOID Ptr);
-
-BOOLEAN CMAPI
-CmpFileRead(
-   PHHIVE RegistryHive,
-   ULONG FileType,
-   ULONGLONG FileOffset,
-   PVOID Buffer,
-   SIZE_T BufferLength);
-
-BOOLEAN CMAPI
-CmpFileWrite(
-   PHHIVE RegistryHive,
-   ULONG FileType,
-   ULONGLONG FileOffset,
-   PVOID Buffer,
-   SIZE_T BufferLength);
-
-BOOLEAN CMAPI
-CmpFileSetSize(
-   PHHIVE RegistryHive,
-   ULONG FileType,
-   ULONGLONG FileSize);
-
-BOOLEAN CMAPI
-CmpFileFlush(
-   PHHIVE RegistryHive,
-   ULONG FileType);
-
-VOID
-CmiCheckKey(BOOLEAN Verbose,
-  HANDLE Key);
 
 NTSTATUS
 NTAPI
@@ -449,31 +366,6 @@
                     OUT PEREGISTRY_HIVE *Hive,
                     IN OUT PBOOLEAN New,
                     IN ULONG CheckFlags);
-
-#if 0
-static __inline PVOID xHvGetCell(char *file, int line, PHHIVE Hive, HCELL_INDEX Cell)
-{
-   DPRINT1("xHvGetCell @ %s:%d %x @ %x\n", file, line, Cell, Hive);
-   return HvGetCell(Hive, Cell);
-}
-
-static __inline VOID xHvFreeCell(char *file, int line, PHHIVE Hive, HCELL_INDEX Cell)
-{
-   DPRINT1("xHvFreeCell @ %s:%d %x @ %x\n", file, line, Cell, Hive);
-   HvFreeCell(Hive, Cell);
-}
-
-static __inline HCELL_INDEX xHvAllocateCell(char *file, int line, PHHIVE Hive, SIZE_T Size)
-{
-   HCELL_INDEX Offset = HvAllocateCell(Hive, Size);
-   DPRINT1("xHvAllocateCell @ %s:%d (%x) %x @ %x\n", file, line, Size, Offset, Hive);
-   return Offset;
-}
-
-#define HvGetCell(hive, cell) xHvGetCell(__FILE__, __LINE__, hive, cell)
-#define HvFreeCell(hive, cell) xHvFreeCell(__FILE__, __LINE__, hive, cell)
-#define HvAllocateCell(hive, size) xHvAllocateCell(__FILE__, __LINE__, hive, size)
-#endif
 
 // Some Ob definitions for debug messages in Cm
 #define ObGetObjectPointerCount(x) OBJECT_TO_OBJECT_HEADER(x)->PointerCount

Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/ntfunc.c?rev=26781&r1=26780&r2=26781&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/cm/ntfunc.c (original)
+++ trunk/reactos/ntoskrnl/cm/ntfunc.c Mon May 14 23:35:58 2007
@@ -525,309 +525,60 @@
   return Status;
 }
 
-
-NTSTATUS STDCALL
+NTSTATUS
+NTAPI
 NtEnumerateKey(IN HANDLE KeyHandle,
-	       IN ULONG Index,
-	       IN KEY_INFORMATION_CLASS KeyInformationClass,
-	       OUT PVOID KeyInformation,
-	       IN ULONG Length,
-	       OUT PULONG ResultLength)
-{
-  PKEY_OBJECT KeyObject;
-  PEREGISTRY_HIVE  RegistryHive;
-  PCM_KEY_NODE  KeyCell, SubKeyCell;
-  PHASH_TABLE_CELL  HashTableBlock;
-  PKEY_BASIC_INFORMATION  BasicInformation;
-  PKEY_NODE_INFORMATION  NodeInformation;
-  PKEY_FULL_INFORMATION  FullInformation;
-  PVOID ClassCell;
-  ULONG NameSize, ClassSize;
-  KPROCESSOR_MODE PreviousMode;
-  NTSTATUS Status;
-  REG_ENUMERATE_KEY_INFORMATION EnumerateKeyInfo;
-  REG_POST_OPERATION_INFORMATION PostOperationInfo;
-  HV_STORAGE_TYPE Storage;
-  ULONG BaseIndex;
-
-  PAGED_CODE();
-
-  PreviousMode = ExGetPreviousMode();
-
-  DPRINT("KH 0x%p  I %d  KIC %x KI 0x%p  L %d  RL 0x%p\n",
-	 KeyHandle,
-	 Index,
-	 KeyInformationClass,
-	 KeyInformation,
-	 Length,
-	 ResultLength);
-
-  /* Verify that the handle is valid and is a registry key */
-  Status = ObReferenceObjectByHandle(KeyHandle,
-		KEY_ENUMERATE_SUB_KEYS,
-		CmpKeyObjectType,
-		PreviousMode,
-		(PVOID *) &KeyObject,
-		NULL);
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT("ObReferenceObjectByHandle() failed with status %x\n", Status);
-      return(Status);
-    }
-
-  PostOperationInfo.Object = (PVOID)KeyObject;
-  EnumerateKeyInfo.Object = (PVOID)KeyObject;
-  EnumerateKeyInfo.Index = Index;
-  EnumerateKeyInfo.KeyInformationClass = KeyInformationClass;
-  EnumerateKeyInfo.Length = Length;
-  EnumerateKeyInfo.ResultLength = ResultLength;
-
-  Status = CmiCallRegisteredCallbacks(RegNtPreEnumerateKey, &EnumerateKeyInfo);
-  if (!NT_SUCCESS(Status))
-    {
-      PostOperationInfo.Status = Status;
-      CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &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;
-
-  /* Check for hightest possible sub key index */
-  if (Index >= KeyCell->SubKeyCounts[HvStable] +
-               KeyCell->SubKeyCounts[HvVolatile])
-    {
-      ExReleaseResourceLite(&CmpRegistryLock);
-      KeLeaveCriticalRegion();
-      PostOperationInfo.Status = STATUS_NO_MORE_ENTRIES;
-      CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo);
-      ObDereferenceObject(KeyObject);
-      DPRINT("No more volatile entries\n");
-      return STATUS_NO_MORE_ENTRIES;
-    }
-
-  /* Get pointer to SubKey */
-  if (Index >= KeyCell->SubKeyCounts[HvStable])
-    {
-      Storage = HvVolatile;
-      BaseIndex = Index - KeyCell->SubKeyCounts[HvStable];
-    }
-  else
-    {
-      Storage = HvStable;
-      BaseIndex = Index;
-    }
-
-  if (KeyCell->SubKeyLists[Storage] == HCELL_NULL)
-    {
-      ExReleaseResourceLite(&CmpRegistryLock);
-      KeLeaveCriticalRegion();
-      PostOperationInfo.Status = STATUS_NO_MORE_ENTRIES;
-      CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo);
-      ObDereferenceObject(KeyObject);
-      return STATUS_NO_MORE_ENTRIES;
-    }
-
-  ASSERT(KeyCell->SubKeyLists[Storage] != HCELL_NULL);
-  HashTableBlock = HvGetCell (&RegistryHive->Hive, KeyCell->SubKeyLists[Storage]);
-
-  SubKeyCell = CmiGetKeyFromHashByIndex(RegistryHive,
-                                        HashTableBlock,
-                                        BaseIndex);
-
-  Status = STATUS_SUCCESS;
-  switch (KeyInformationClass)
-    {
-      case KeyBasicInformation:
-	/* Check size of buffer */
-	NameSize = SubKeyCell->NameSize;
-	if (SubKeyCell->Flags & REG_KEY_NAME_PACKED)
-	  {
-	    NameSize *= sizeof(WCHAR);
-	  }
-
-	*ResultLength = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]) + NameSize;
-
-	/*
-	 * NOTE: It's perfetly valid to call NtEnumerateKey to get
-         * all the information but name. Actually the NT4 sound
-         * framework does that while querying parameters from registry.
-         * -- Filip Navara, 19/07/2004
-         */
-	if (Length < FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]))
-	  {
-	    Status = STATUS_BUFFER_TOO_SMALL;
-	  }
-	else
-	  {
-	    /* Fill buffer with requested info */
-	    BasicInformation = (PKEY_BASIC_INFORMATION) KeyInformation;
-	    BasicInformation->LastWriteTime.u.LowPart = SubKeyCell->LastWriteTime.u.LowPart;
-	    BasicInformation->LastWriteTime.u.HighPart = SubKeyCell->LastWriteTime.u.HighPart;
-	    BasicInformation->TitleIndex = Index;
-	    BasicInformation->NameLength = NameSize;
-
-	    if (Length - FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]) < NameSize)
-	      {
-	        NameSize = Length - FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);
-	        Status = STATUS_BUFFER_OVERFLOW;
-	        CHECKPOINT;
-	      }
-
-	    if (SubKeyCell->Flags & REG_KEY_NAME_PACKED)
-	      {
-	        CmiCopyPackedName(BasicInformation->Name,
-	                          SubKeyCell->Name,
-	                          NameSize / sizeof(WCHAR));
-	      }
-	    else
-	      {
-	        RtlCopyMemory(BasicInformation->Name,
-	                      SubKeyCell->Name,
-	                      NameSize);
-	      }
-	  }
-	break;
-
-      case KeyNodeInformation:
-	/* Check size of buffer */
-	NameSize = SubKeyCell->NameSize;
-	if (SubKeyCell->Flags & REG_KEY_NAME_PACKED)
-	  {
-	    NameSize *= sizeof(WCHAR);
-	  }
-	ClassSize = SubKeyCell->ClassSize;
-
-	*ResultLength = FIELD_OFFSET(KEY_NODE_INFORMATION, Name[0]) +
-	  NameSize + ClassSize;
-
-	if (Length < FIELD_OFFSET(KEY_NODE_INFORMATION, Name[0]))
-	  {
-	    Status = STATUS_BUFFER_TOO_SMALL;
-	  }
-	else
-	  {
-	    /* Fill buffer with requested info */
-	    NodeInformation = (PKEY_NODE_INFORMATION) KeyInformation;
-	    NodeInformation->LastWriteTime.u.LowPart = SubKeyCell->LastWriteTime.u.LowPart;
-	    NodeInformation->LastWriteTime.u.HighPart = SubKeyCell->LastWriteTime.u.HighPart;
-	    NodeInformation->TitleIndex = Index;
-	    NodeInformation->ClassOffset = sizeof(KEY_NODE_INFORMATION) + NameSize;
-	    NodeInformation->ClassLength = SubKeyCell->ClassSize;
-	    NodeInformation->NameLength = NameSize;
-
-	    if (Length - FIELD_OFFSET(KEY_NODE_INFORMATION, Name[0]) < NameSize)
-	      {
-	        NameSize = Length - FIELD_OFFSET(KEY_NODE_INFORMATION, Name[0]);
-	        ClassSize = 0;
-	        Status = STATUS_BUFFER_OVERFLOW;
-	        CHECKPOINT;
-	      }
-	    else if (Length - FIELD_OFFSET(KEY_NODE_INFORMATION, Name[0]) -
-	             NameSize < ClassSize)
-	      {
-	        ClassSize = Length - FIELD_OFFSET(KEY_NODE_INFORMATION, Name[0]) -
-	                    NameSize;
-	        Status = STATUS_BUFFER_OVERFLOW;
-	        CHECKPOINT;
-	      }
-
-	    if (SubKeyCell->Flags & REG_KEY_NAME_PACKED)
-	      {
-	        CmiCopyPackedName(NodeInformation->Name,
-	                          SubKeyCell->Name,
-	                          NameSize / sizeof(WCHAR));
-	      }
-	    else
-	      {
-	        RtlCopyMemory(NodeInformation->Name,
-	                      SubKeyCell->Name,
-	                      NameSize);
-       	      }
-
-	    if (ClassSize != 0)
-	      {
-		ClassCell = HvGetCell (&KeyObject->RegistryHive->Hive,
-		                       SubKeyCell->ClassNameOffset);
-		RtlCopyMemory (NodeInformation->Name + SubKeyCell->NameSize,
-			       ClassCell,
-			       ClassSize);
-	      }
-	  }
-	break;
-
-      case KeyFullInformation:
-	ClassSize = SubKeyCell->ClassSize;
-
-	*ResultLength = FIELD_OFFSET(KEY_FULL_INFORMATION, Class[0]) +
-	  ClassSize;
-
-	/* Check size of buffer */
-	if (Length < FIELD_OFFSET(KEY_FULL_INFORMATION, Class[0]))
-	  {
-	    Status = STATUS_BUFFER_TOO_SMALL;
-	  }
-	else
-	  {
-	    /* Fill buffer with requested info */
-	    FullInformation = (PKEY_FULL_INFORMATION) KeyInformation;
-	    FullInformation->LastWriteTime.u.LowPart = SubKeyCell->LastWriteTime.u.LowPart;
-	    FullInformation->LastWriteTime.u.HighPart = SubKeyCell->LastWriteTime.u.HighPart;
-	    FullInformation->TitleIndex = Index;
-	    FullInformation->ClassOffset = sizeof(KEY_FULL_INFORMATION) -
-	      sizeof(WCHAR);
-	    FullInformation->ClassLength = SubKeyCell->ClassSize;
-	    FullInformation->SubKeys = CmiGetNumberOfSubKeys(KeyObject); //SubKeyCell->SubKeyCounts;
-	    FullInformation->MaxNameLen = CmiGetMaxNameLength(&RegistryHive->Hive, SubKeyCell);
-	    FullInformation->MaxClassLen = CmiGetMaxClassLength(&RegistryHive->Hive, SubKeyCell);
-	    FullInformation->Values = SubKeyCell->ValueList.Count;
-	    FullInformation->MaxValueNameLen =
-	      CmiGetMaxValueNameLength(&RegistryHive->Hive, SubKeyCell);
-	    FullInformation->MaxValueDataLen =
-	      CmiGetMaxValueDataLength(&RegistryHive->Hive, SubKeyCell);
-
-	    if (Length - FIELD_OFFSET(KEY_FULL_INFORMATION, Class[0]) < ClassSize)
-	      {
-	        ClassSize = Length - FIELD_OFFSET(KEY_FULL_INFORMATION, Class[0]);
-	        Status = STATUS_BUFFER_OVERFLOW;
-	        CHECKPOINT;
-	      }
-
-	    if (ClassSize != 0)
-	      {
-		ClassCell = HvGetCell (&KeyObject->RegistryHive->Hive,
-		                       SubKeyCell->ClassNameOffset);
-		RtlCopyMemory (FullInformation->Class,
-			       ClassCell,
-			       ClassSize);
-	      }
-	  }
-	break;
-
-      default:
-	DPRINT1("Not handling 0x%x\n", KeyInformationClass);
-	break;
-    }
-
-  ExReleaseResourceLite(&CmpRegistryLock);
-  KeLeaveCriticalRegion();
-
-  PostOperationInfo.Status = Status;
-  CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo);
-
-  ObDereferenceObject(KeyObject);
-
-  DPRINT("Returning status %x\n", Status);
-
-  return(Status);
+               IN ULONG Index,
+               IN KEY_INFORMATION_CLASS KeyInformationClass,
+               OUT PVOID KeyInformation,
+               IN ULONG Length,
+               OUT PULONG ResultLength)
+{
+    NTSTATUS Status;
+    PKEY_OBJECT KeyObject;
+    REG_ENUMERATE_KEY_INFORMATION EnumerateKeyInfo;
+    REG_POST_OPERATION_INFORMATION PostOperationInfo;
+    PAGED_CODE();
+
+    /* Verify that the handle is valid and is a registry key */
+    Status = ObReferenceObjectByHandle(KeyHandle,
+                                       (KeyInformationClass !=
+                                        KeyNameInformation) ?
+                                       KEY_QUERY_VALUE : 0,
+                                       CmpKeyObjectType,
+                                       ExGetPreviousMode(),
+                                       (PVOID *)&KeyObject,
+                                       NULL);
+    if (!NT_SUCCESS(Status)) return Status;
+
+    /* Setup the callback */
+    PostOperationInfo.Object = (PVOID)KeyObject;
+    EnumerateKeyInfo.Object = (PVOID)KeyObject;
+    EnumerateKeyInfo.Index = Index;
+    EnumerateKeyInfo.KeyInformationClass = KeyInformationClass;
+    EnumerateKeyInfo.Length = Length;
+    EnumerateKeyInfo.ResultLength = ResultLength;
+
+    /* Do the callback */
+    Status = CmiCallRegisteredCallbacks(RegNtPreEnumerateKey, &EnumerateKeyInfo);
+    if (NT_SUCCESS(Status))
+    {
+        /* Call the internal API */
+        Status = CmEnumerateKey(KeyObject,
+                                Index,
+                                KeyInformationClass,
+                                KeyInformation,
+                                Length,
+                                ResultLength);
+
+        /* Do the post callback */
+        PostOperationInfo.Status = Status;
+        CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo);
+    }
+
+    /* Dereference and return status */
+    ObDereferenceObject(KeyObject);
+    return Status;
 }
 
 NTSTATUS

Modified: trunk/reactos/ntoskrnl/cm/regfile.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/regfile.c?rev=26781&r1=26780&r2=26781&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/cm/regfile.c (original)
+++ trunk/reactos/ntoskrnl/cm/regfile.c Mon May 14 23:35:58 2007
@@ -621,39 +621,6 @@
 }
 
 NTSTATUS
-CmiGetValueFromKeyByIndex(IN PEREGISTRY_HIVE RegistryHive,
-			  IN PCM_KEY_NODE KeyCell,
-			  IN ULONG Index,
-			  OUT PCM_KEY_VALUE *ValueCell)
-{
-  PVALUE_LIST_CELL ValueListCell;
-  PCM_KEY_VALUE CurValueCell;
-
-  *ValueCell = NULL;
-
-  if (KeyCell->ValueList.List == (HCELL_INDEX)-1)
-    {
-      return STATUS_NO_MORE_ENTRIES;
-    }
-
-  if (Index >= KeyCell->ValueList.Count)
-    {
-      return STATUS_NO_MORE_ENTRIES;
-    }
-
-
-  ValueListCell = HvGetCell (&RegistryHive->Hive, KeyCell->ValueList.List);
-
-  VERIFY_VALUE_LIST_CELL(ValueListCell);
-
-  CurValueCell = HvGetCell (&RegistryHive->Hive, ValueListCell->ValueOffset[Index]);
-
-  *ValueCell = CurValueCell;
-
-  return STATUS_SUCCESS;
-}
-
-NTSTATUS
 CmiAllocateHashTableCell (IN PEREGISTRY_HIVE RegistryHive,
 	OUT PHASH_TABLE_CELL *HashBlock,
 	OUT HCELL_INDEX *HBOffset,
@@ -684,20 +651,6 @@
     }
 
   return Status;
-}
-
-PCM_KEY_NODE
-CmiGetKeyFromHashByIndex(PEREGISTRY_HIVE RegistryHive,
-			 PHASH_TABLE_CELL HashBlock,
-			 ULONG Index)
-{
-  HCELL_INDEX KeyOffset;
-  PCM_KEY_NODE KeyCell;
-
-  KeyOffset =  HashBlock->Table[Index].KeyOffset;
-  KeyCell = HvGetCell (&RegistryHive->Hive, KeyOffset);
-
-  return KeyCell;
 }
 
 NTSTATUS
@@ -744,17 +697,6 @@
   return STATUS_UNSUCCESSFUL;
 }
 
-VOID
-CmiCopyPackedName(PWCHAR NameBuffer,
-		  PUCHAR PackedNameBuffer,
-		  ULONG PackedNameSize)
-{
-  ULONG i;
-
-  for (i = 0; i < PackedNameSize; i++)
-    NameBuffer[i] = (WCHAR)PackedNameBuffer[i];
-}
-
 NTSTATUS
 CmiSaveTempHive (PEREGISTRY_HIVE Hive,
 		 HANDLE FileHandle)

Modified: trunk/reactos/ntoskrnl/config/cm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cm.h?rev=26781&r1=26780&r2=26781&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/config/cm.h (original)
+++ trunk/reactos/ntoskrnl/config/cm.h Mon May 14 23:35:58 2007
@@ -1115,6 +1115,14 @@
     IN PUNICODE_STRING SearchName
 );
 
+HCELL_INDEX
+NTAPI
+CmpFindSubKeyByNumber(
+    IN PHHIVE Hive,
+    IN PCM_KEY_NODE Node,
+    IN ULONG Number
+);
+
 ULONG
 NTAPI
 CmpComputeHashKey(

Modified: trunk/reactos/ntoskrnl/config/cmapi.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmapi.c?rev=26781&r1=26780&r2=26781&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmapi.c (original)
+++ trunk/reactos/ntoskrnl/config/cmapi.c Mon May 14 23:35:58 2007
@@ -640,7 +640,7 @@
     USHORT NameLength;
 
     /* Check if the value is compressed */
-    if (Node->Flags & VALUE_COMP_NAME)
+    if (Node->Flags & KEY_COMP_NAME)
     {
         /* Get the compressed name size */
         NameLength = CmpCompressedNameSize(Node->Name, Node->NameLength);
@@ -917,3 +917,69 @@
     KeLeaveCriticalRegion();
     return Status;
 }
+
+NTSTATUS
+NTAPI
+CmEnumerateKey(IN PKEY_OBJECT KeyObject,
+               IN ULONG Index,
+               IN KEY_INFORMATION_CLASS KeyInformationClass,
+               IN PVOID KeyInformation,
+               IN ULONG Length,
+               IN PULONG ResultLength)
+{
+    NTSTATUS Status;
+    PHHIVE Hive;
+    PCM_KEY_NODE Parent, Child;
+    HCELL_INDEX ChildCell;
+
+    /* 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;
+    }
+
+    /* Get the child cell */
+    ChildCell = CmpFindSubKeyByNumber(Hive, Parent, Index);
+
+    /* Release the parent cell */
+    HvReleaseCell(Hive, KeyObject->KeyCellOffset);
+
+    /* Check if we found the child */
+    if (ChildCell == HCELL_NIL)
+    {
+        /* We didn't, fail */
+        Status = STATUS_NO_MORE_ENTRIES;
+        goto Quickie;
+    }
+
+    /* Now get the actual child node */
+    Child = (PCM_KEY_NODE)HvGetCell(Hive, ChildCell);
+    if (!Child)
+    {
+        /* Fail */
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto Quickie;
+    }
+
+    /* Query the data requested */
+    Status = CmpQueryKeyData(Hive,
+                             Child,
+                             KeyInformationClass,
+                             KeyInformation,
+                             Length,
+                             ResultLength);
+
+Quickie:
+    /* Release hive lock */
+    ExReleaseResourceLite(&CmpRegistryLock);
+    KeLeaveCriticalRegion();
+    return Status;
+}

Modified: trunk/reactos/ntoskrnl/config/cmindex.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmindex.c?rev=26781&r1=26780&r2=26781&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmindex.c (original)
+++ trunk/reactos/ntoskrnl/config/cmindex.c Mon May 14 23:35:58 2007
@@ -516,6 +516,139 @@
 
 HCELL_INDEX
 NTAPI
+CmpDoFindSubKeyByNumber(IN PHHIVE Hive,
+                        IN PCM_KEY_INDEX Index,
+                        IN ULONG Number)
+{
+    ULONG i;
+    HCELL_INDEX LeafCell = 0;
+    PCM_KEY_INDEX Leaf = NULL;
+    PCM_KEY_FAST_INDEX FastIndex;
+    HCELL_INDEX Result;
+
+    /* Check if this is a root */
+    if (Index->Signature == CM_KEY_INDEX_ROOT)
+    {
+        /* Loop the index */
+        for (i = 0; i < Index->Count; i++)
+        {
+            /* Check if this isn't the first iteration */
+            if (i)
+            {
+                /* Make sure we had something valid, and release it */
+                ASSERT(Leaf != NULL );
+                ASSERT(LeafCell == Index->List[i - 1]);
+                HvReleaseCell(Hive, LeafCell);
+            }
+
+            /* Get the leaf cell and the leaf for this index */
+            LeafCell = Index->List[i];
+            Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell);
+            if (!Leaf) return HCELL_NIL;
+
+            /* Check if the index may be inside it */
+            if (Number < Leaf->Count)
+            {
+                /* Check if this is a fast or hash leaf */
+                if ((Leaf->Signature == CM_KEY_FAST_LEAF) ||
+                    (Leaf->Signature == CM_KEY_HASH_LEAF))
+                {
+                    /* Get the fast index */
+                    FastIndex = (PCM_KEY_FAST_INDEX)Leaf;
+
+                    /* Look inside the list to get our actual cell */
+                    Result = FastIndex->List[Number].Cell;
+                    HvReleaseCell(Hive, LeafCell);
+                    return Result;
+                }
+                else
+                {
+                    /* Regular leaf, so just use the index directly */
+                    Result = Leaf->List[Number];
+
+                    /*  Release and return it */
+                    HvReleaseCell(Hive,LeafCell);
+                    return Result;
+                }
+            }
+            else
+            {
+                /* Otherwise, skip this leaf */
+                Number = Number - Leaf->Count;
+            }
+        }
+
+        /* Should never get here */
+        ASSERT(FALSE);
+    }
+
+    /* If we got here, then the cell is in this index */
+    ASSERT(Number < Index->Count);
+
+    /* Check if we're a fast or hash leaf */
+    if ((Index->Signature == CM_KEY_FAST_LEAF) ||
+        (Index->Signature == CM_KEY_HASH_LEAF))
+    {
+        /* We are, get the fast index and get the cell from the list */
+        FastIndex = (PCM_KEY_FAST_INDEX)Index;
+        return FastIndex->List[Number].Cell;
+    }
+    else
+    {
+        /* We aren't, so use the index directly to grab the cell */
+        return Index->List[Number];
+    }
+}
+
+HCELL_INDEX
+NTAPI
+CmpFindSubKeyByNumber(IN PHHIVE Hive,
+                      IN PCM_KEY_NODE Node,
+                      IN ULONG Number)
+{
+    PCM_KEY_INDEX Index;
+    HCELL_INDEX Result = HCELL_NIL;
+
+    /* Check if it's in the stable list */
+    if (Number < Node->SubKeyCounts[HvStable])
+    {
+        /* Get the actual key index */
+        Index = (PCM_KEY_INDEX)HvGetCell(Hive, Node->SubKeyLists[HvStable]);
+        if (!Index) return HCELL_NIL;
+
+        /* Do a search inside it */
+        Result = CmpDoFindSubKeyByNumber(Hive, Index, Number);
+
+        /* Release the cell and return the result */
+        HvReleaseCell(Hive, Node->SubKeyLists[HvStable]);
+        return Result;
+    }
+    else if (Hive->StorageTypeCount > HvVolatile)
+    {
+        /* It's in the volatile list */
+        Number = Number - Node->SubKeyCounts[HvStable];
+        if (Number < Node->SubKeyCounts[HvVolatile])
+        {
+            /* Get the actual key index */
+            Index = (PCM_KEY_INDEX)HvGetCell(Hive,
+                                             Node->SubKeyLists[HvVolatile]);
+            if (!Index) return HCELL_NIL;
+
+            /* Do a search inside it */
+            Result = CmpDoFindSubKeyByNumber(Hive, Index, Number);
+
+            /* Release the cell and return the result */
+            HvReleaseCell(Hive, Node->SubKeyLists[HvVolatile]);
+            return Result;
+        }
+    }
+
+    /* Nothing was found */
+    return HCELL_NIL;
+}
+
+HCELL_INDEX
+NTAPI
 CmpFindSubKeyByHash(IN PHHIVE Hive,
                     IN PCM_KEY_FAST_INDEX FastIndex,
                     IN PUNICODE_STRING SearchName)




More information about the Ros-diffs mailing list