[ros-diffs] [ion] 26780: - Make CmiGetMaxClassLength, CmiGetMaxNameLength, CmiGetMaxValueDataLength, CmiGetMaxValueNameLength use PHHIVE and PCM_KEY_NODE instead of PKEY_OBJECT or PERGSITRY_HIVE/PCM_KEY_NDOE so they're consistent. - Implement NtQueryKey as a simple wrapper around CmQueryKey. - Implement CmQueryKey based on previous code, and handle only the classes that the previous code handled, through CmpQueryKeyData. - The CmiGetMax* routines will be depreated soon since they're a perf hit and we should be reading the key node's values instead.

ion at svn.reactos.org ion at svn.reactos.org
Mon May 14 20:12:58 CEST 2007


Author: ion
Date: Mon May 14 22:12:57 2007
New Revision: 26780

URL: http://svn.reactos.org/svn/reactos?rev=26780&view=rev
Log:
- Make CmiGetMaxClassLength, CmiGetMaxNameLength, CmiGetMaxValueDataLength, CmiGetMaxValueNameLength use PHHIVE and PCM_KEY_NODE instead of PKEY_OBJECT or PERGSITRY_HIVE/PCM_KEY_NDOE so they're consistent.
- Implement NtQueryKey as a simple wrapper around CmQueryKey.
- Implement CmQueryKey based on previous code, and handle only the classes that the previous code handled, through CmpQueryKeyData.
- The CmiGetMax* routines will be depreated soon since they're a perf hit and we should be reading the key node's values instead.

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

Modified: trunk/reactos/ntoskrnl/cm/cm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/cm.h?rev=26780&r1=26779&r2=26780&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/cm/cm.h (original)
+++ trunk/reactos/ntoskrnl/cm/cm.h Mon May 14 22:12:57 2007
@@ -221,17 +221,17 @@
 CmiGetNumberOfSubKeys(PKEY_OBJECT KeyObject);
 
 ULONG
-CmiGetMaxNameLength(IN PKEY_OBJECT KeyObject);
+CmiGetMaxNameLength(IN PHHIVE RegistryHive, IN PCM_KEY_NODE KeyCell);
 
 ULONG
-CmiGetMaxClassLength(IN PKEY_OBJECT KeyObject);
+CmiGetMaxClassLength(IN PHHIVE RegistryHive, IN PCM_KEY_NODE KeyCell);
 
 ULONG
-CmiGetMaxValueNameLength(IN PEREGISTRY_HIVE RegistryHive,
+CmiGetMaxValueNameLength(IN PHHIVE RegistryHive,
 			 IN PCM_KEY_NODE KeyCell);
 
 ULONG
-CmiGetMaxValueDataLength(IN PEREGISTRY_HIVE RegistryHive,
+CmiGetMaxValueDataLength(IN PHHIVE RegistryHive,
 			 IN PCM_KEY_NODE KeyCell);
 
 NTSTATUS
@@ -300,6 +300,14 @@
               IN ULONG Type,
               IN PVOID Data,
               IN ULONG DataSize);
+
+NTSTATUS
+NTAPI
+CmQueryKey(IN PKEY_OBJECT KeyObject,
+           IN KEY_INFORMATION_CLASS KeyInformationClass,
+           IN PVOID KeyInformation,
+           IN ULONG Length,
+           IN PULONG ResultLength);
 
 NTSTATUS
 CmiAllocateHashTableCell(IN PEREGISTRY_HIVE RegistryHive,

Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/ntfunc.c?rev=26780&r1=26779&r2=26780&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/cm/ntfunc.c (original)
+++ trunk/reactos/ntoskrnl/cm/ntfunc.c Mon May 14 22:12:57 2007
@@ -786,13 +786,13 @@
 	      sizeof(WCHAR);
 	    FullInformation->ClassLength = SubKeyCell->ClassSize;
 	    FullInformation->SubKeys = CmiGetNumberOfSubKeys(KeyObject); //SubKeyCell->SubKeyCounts;
-	    FullInformation->MaxNameLen = CmiGetMaxNameLength(KeyObject);
-	    FullInformation->MaxClassLen = CmiGetMaxClassLength(KeyObject);
+	    FullInformation->MaxNameLen = CmiGetMaxNameLength(&RegistryHive->Hive, SubKeyCell);
+	    FullInformation->MaxClassLen = CmiGetMaxClassLength(&RegistryHive->Hive, SubKeyCell);
 	    FullInformation->Values = SubKeyCell->ValueList.Count;
 	    FullInformation->MaxValueNameLen =
-	      CmiGetMaxValueNameLength(RegistryHive, SubKeyCell);
+	      CmiGetMaxValueNameLength(&RegistryHive->Hive, SubKeyCell);
 	    FullInformation->MaxValueDataLen =
-	      CmiGetMaxValueDataLength(RegistryHive, SubKeyCell);
+	      CmiGetMaxValueDataLength(&RegistryHive->Hive, SubKeyCell);
 
 	    if (Length - FIELD_OFFSET(KEY_FULL_INFORMATION, Class[0]) < ClassSize)
 	      {
@@ -1094,232 +1094,58 @@
   return Status;
 }
 
-
-NTSTATUS STDCALL
+NTSTATUS
+NTAPI
 NtQueryKey(IN HANDLE KeyHandle,
-	   IN KEY_INFORMATION_CLASS KeyInformationClass,
-	   OUT PVOID KeyInformation,
-	   IN ULONG Length,
-	   OUT PULONG ResultLength)
-{
-  PKEY_BASIC_INFORMATION BasicInformation;
-  PKEY_NODE_INFORMATION NodeInformation;
-  PKEY_FULL_INFORMATION FullInformation;
-  PEREGISTRY_HIVE RegistryHive;
-  PVOID ClassCell;
-  PKEY_OBJECT KeyObject;
-  PCM_KEY_NODE KeyCell;
-  ULONG NameSize, ClassSize;
-  NTSTATUS Status;
-  REG_QUERY_KEY_INFORMATION QueryKeyInfo;
-  REG_POST_OPERATION_INFORMATION PostOperationInfo;
-
-  PAGED_CODE();
-
-  DPRINT("NtQueryKey(KH 0x%p  KIC %x  KI 0x%p  L %d  RL 0x%p)\n",
-	 KeyHandle,
-	 KeyInformationClass,
-	 KeyInformation,
-	 Length,
-	 ResultLength);
-
-  /* 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;
-    }
-
-  PostOperationInfo.Object = (PVOID)KeyObject;
-  QueryKeyInfo.Object = (PVOID)KeyObject;
-  QueryKeyInfo.KeyInformationClass = KeyInformationClass;
-  QueryKeyInfo.KeyInformation = KeyInformation;
-  QueryKeyInfo.Length = Length;
-  QueryKeyInfo.ResultLength = ResultLength;
-  
-  Status = CmiCallRegisteredCallbacks(RegNtPreQueryKey, &QueryKeyInfo);
-  if (!NT_SUCCESS(Status))
-    {
-      PostOperationInfo.Status = Status;
-      CmiCallRegisteredCallbacks(RegNtPostQueryKey, &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;
-
-  Status = STATUS_SUCCESS;
-  switch (KeyInformationClass)
-    {
-      case KeyBasicInformation:
-        NameSize = KeyObject->Name.Length;
-
-	*ResultLength = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);
-
-	/* Check size of buffer */
-	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 = KeyCell->LastWriteTime.u.LowPart;
-	    BasicInformation->LastWriteTime.u.HighPart = KeyCell->LastWriteTime.u.HighPart;
-	    BasicInformation->TitleIndex = 0;
-	    BasicInformation->NameLength = KeyObject->Name.Length;
-
-	    if (Length - FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]) <
-	        NameSize)
-	      {
-	        NameSize = Length - FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);
-	        Status = STATUS_BUFFER_OVERFLOW;
-	        CHECKPOINT;
-	      }
-
-	    RtlCopyMemory(BasicInformation->Name,
-			  KeyObject->Name.Buffer,
-			  NameSize);
-	  }
-	break;
-
-      case KeyNodeInformation:
-        NameSize = KeyObject->Name.Length;
-        ClassSize = KeyCell->ClassSize;
-
-	*ResultLength = FIELD_OFFSET(KEY_NODE_INFORMATION, Name[0]) +
-	  NameSize + ClassSize;
-
-	/* Check size of buffer */
-	if (Length < *ResultLength)
-	  {
-	    Status = STATUS_BUFFER_TOO_SMALL;
-	  }
-	else
-	  {
-	    /* Fill buffer with requested info */
-	    NodeInformation = (PKEY_NODE_INFORMATION) KeyInformation;
-	    NodeInformation->LastWriteTime.u.LowPart = KeyCell->LastWriteTime.u.LowPart;
-	    NodeInformation->LastWriteTime.u.HighPart = KeyCell->LastWriteTime.u.HighPart;
-	    NodeInformation->TitleIndex = 0;
-	    NodeInformation->ClassOffset = sizeof(KEY_NODE_INFORMATION) +
-	      KeyObject->Name.Length;
-	    NodeInformation->ClassLength = KeyCell->ClassSize;
-	    NodeInformation->NameLength = KeyObject->Name.Length;
-
-	    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;
-	      }
-
-	    RtlCopyMemory(NodeInformation->Name,
-			  KeyObject->Name.Buffer,
-			  NameSize);
-
-	    if (ClassSize != 0)
-	      {
-		ClassCell = HvGetCell (&KeyObject->RegistryHive->Hive,
-		                       KeyCell->ClassNameOffset);
-		RtlCopyMemory (NodeInformation->Name + KeyObject->Name.Length,
-			       ClassCell,
-			       ClassSize);
-	      }
-	  }
-	break;
-
-      case KeyFullInformation:
-        ClassSize = KeyCell->ClassSize;
-
-	*ResultLength = FIELD_OFFSET(KEY_FULL_INFORMATION, Class) +
-	  ClassSize;
-
-	/* Check size of buffer */
-	if (Length < FIELD_OFFSET(KEY_FULL_INFORMATION, Class))
-	  {
-	    Status = STATUS_BUFFER_TOO_SMALL;
-	  }
-	else
-	  {
-	    /* Fill buffer with requested info */
-	    FullInformation = (PKEY_FULL_INFORMATION) KeyInformation;
-	    FullInformation->LastWriteTime.u.LowPart = KeyCell->LastWriteTime.u.LowPart;
-	    FullInformation->LastWriteTime.u.HighPart = KeyCell->LastWriteTime.u.HighPart;
-	    FullInformation->TitleIndex = 0;
-	    FullInformation->ClassOffset = sizeof(KEY_FULL_INFORMATION) - sizeof(WCHAR);
-	    FullInformation->ClassLength = KeyCell->ClassSize;
-	    FullInformation->SubKeys = CmiGetNumberOfSubKeys(KeyObject); //KeyCell->SubKeyCounts;
-	    FullInformation->MaxNameLen = CmiGetMaxNameLength(KeyObject);
-	    FullInformation->MaxClassLen = CmiGetMaxClassLength(KeyObject);
-	    FullInformation->Values = KeyCell->ValueList.Count;
-	    FullInformation->MaxValueNameLen =
-	      CmiGetMaxValueNameLength(RegistryHive, KeyCell);
-	    FullInformation->MaxValueDataLen =
-	      CmiGetMaxValueDataLength(RegistryHive, KeyCell);
-
-	    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)
-	      {
-		ClassCell = HvGetCell (&KeyObject->RegistryHive->Hive,
-		                       KeyCell->ClassNameOffset);
-		RtlCopyMemory (FullInformation->Class,
-			       ClassCell, ClassSize);
-	      }
-	  }
-	break;
-
-      case KeyNameInformation:
-      case KeyCachedInformation:
-      case KeyFlagsInformation:
-        DPRINT1("Key information class 0x%x not yet implemented!\n", KeyInformationClass);
-        Status = STATUS_NOT_IMPLEMENTED;
-        break;
-
-      default:
-	DPRINT1("Not handling 0x%x\n", KeyInformationClass);
-	Status = STATUS_INVALID_INFO_CLASS;
-	break;
-    }
-
-  ExReleaseResourceLite(&CmpRegistryLock);
-  KeLeaveCriticalRegion();
-
-  PostOperationInfo.Status = Status;
-  CmiCallRegisteredCallbacks(RegNtPostQueryKey, &PostOperationInfo);
-
-  ObDereferenceObject(KeyObject);
-
-  return(Status);
+           IN KEY_INFORMATION_CLASS KeyInformationClass,
+           OUT PVOID KeyInformation,
+           IN ULONG Length,
+           OUT PULONG ResultLength)
+{
+    NTSTATUS Status;
+    PKEY_OBJECT KeyObject;
+    REG_QUERY_KEY_INFORMATION QueryKeyInfo;
+    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;
+    QueryKeyInfo.Object = (PVOID)KeyObject;
+    QueryKeyInfo.KeyInformationClass = KeyInformationClass;
+    QueryKeyInfo.KeyInformation = KeyInformation;
+    QueryKeyInfo.Length = Length;
+    QueryKeyInfo.ResultLength = ResultLength;
+
+    /* Do the callback */
+    Status = CmiCallRegisteredCallbacks(RegNtPreQueryKey, &QueryKeyInfo);
+    if (NT_SUCCESS(Status))
+    {
+        /* Call the internal API */
+        Status = CmQueryKey(KeyObject,
+                            KeyInformationClass,
+                            KeyInformation,
+                            Length,
+                            ResultLength);
+
+        /* Do the post callback */
+        PostOperationInfo.Status = Status;
+        CmiCallRegisteredCallbacks(RegNtPostQueryKey, &PostOperationInfo);
+    }
+
+    /* Dereference and return status */
+    ObDereferenceObject(KeyObject);
+    return Status;
 }
 
 NTSTATUS
@@ -1371,6 +1197,7 @@
         CmiCallRegisteredCallbacks(RegNtPostQueryValueKey, &PostOperationInfo);
     }
 
+    /* Dereference and return status */
     ObDereferenceObject(KeyObject);
     return Status;
 }

Modified: trunk/reactos/ntoskrnl/cm/regfile.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/regfile.c?rev=26780&r1=26779&r2=26780&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/cm/regfile.c (original)
+++ trunk/reactos/ntoskrnl/cm/regfile.c Mon May 14 22:12:57 2007
@@ -124,32 +124,27 @@
 
 
 ULONG
-CmiGetMaxNameLength(PKEY_OBJECT KeyObject)
+CmiGetMaxNameLength(PHHIVE Hive,
+                    PCM_KEY_NODE KeyCell)
 {
   PHASH_TABLE_CELL HashBlock;
   PCM_KEY_NODE CurSubKeyCell;
-  PCM_KEY_NODE KeyCell;
   ULONG MaxName;
   ULONG NameSize;
   ULONG i;
   ULONG Storage;
 
-  VERIFY_KEY_OBJECT(KeyObject);
-
-  KeyCell = KeyObject->KeyCell;
-  VERIFY_KEY_CELL(KeyCell);
-
   MaxName = 0;
   for (Storage = HvStable; Storage < HvMaxStorageType; Storage++)
     {
       if (KeyCell->SubKeyLists[Storage] != HCELL_NULL)
         {
-          HashBlock = HvGetCell (&KeyObject->RegistryHive->Hive, KeyCell->SubKeyLists[Storage]);
+          HashBlock = HvGetCell (Hive, KeyCell->SubKeyLists[Storage]);
           ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID);
 
           for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
             {
-              CurSubKeyCell = HvGetCell (&KeyObject->RegistryHive->Hive,
+              CurSubKeyCell = HvGetCell (Hive,
                                          HashBlock->Table[i].KeyOffset);
               NameSize = CurSubKeyCell->NameSize;
               if (CurSubKeyCell->Flags & REG_KEY_NAME_PACKED)
@@ -167,32 +162,27 @@
 
 
 ULONG
-CmiGetMaxClassLength(PKEY_OBJECT  KeyObject)
+CmiGetMaxClassLength(PHHIVE Hive,
+                     PCM_KEY_NODE KeyCell)
 {
   PHASH_TABLE_CELL HashBlock;
   PCM_KEY_NODE CurSubKeyCell;
-  PCM_KEY_NODE KeyCell;
   ULONG MaxClass;
   ULONG i;
   ULONG Storage;
 
-  VERIFY_KEY_OBJECT(KeyObject);
-
-  KeyCell = KeyObject->KeyCell;
-  VERIFY_KEY_CELL(KeyCell);
-
   MaxClass = 0;
   for (Storage = HvStable; Storage < HvMaxStorageType; Storage++)
     {
       if (KeyCell->SubKeyLists[Storage] != HCELL_NULL)
         {
-          HashBlock = HvGetCell (&KeyObject->RegistryHive->Hive,
+          HashBlock = HvGetCell (Hive,
                                  KeyCell->SubKeyLists[Storage]);
           ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID);
 
           for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
             {
-              CurSubKeyCell = HvGetCell (&KeyObject->RegistryHive->Hive,
+              CurSubKeyCell = HvGetCell (Hive,
                                          HashBlock->Table[i].KeyOffset);
 
               if (MaxClass < CurSubKeyCell->ClassSize)
@@ -208,7 +198,7 @@
 
 
 ULONG
-CmiGetMaxValueNameLength(PEREGISTRY_HIVE RegistryHive,
+CmiGetMaxValueNameLength(PHHIVE Hive,
 			 PCM_KEY_NODE KeyCell)
 {
   PVALUE_LIST_CELL ValueListCell;
@@ -225,12 +215,12 @@
     }
 
   MaxValueName = 0;
-  ValueListCell = HvGetCell (&RegistryHive->Hive,
+  ValueListCell = HvGetCell (Hive,
 			     KeyCell->ValueList.List);
 
   for (i = 0; i < KeyCell->ValueList.Count; i++)
     {
-      CurValueCell = HvGetCell (&RegistryHive->Hive,
+      CurValueCell = HvGetCell (Hive,
 				ValueListCell->ValueOffset[i]);
       if (CurValueCell == NULL)
 	{
@@ -256,7 +246,7 @@
 
 
 ULONG
-CmiGetMaxValueDataLength(PEREGISTRY_HIVE RegistryHive,
+CmiGetMaxValueDataLength(PHHIVE Hive,
 			 PCM_KEY_NODE KeyCell)
 {
   PVALUE_LIST_CELL ValueListCell;
@@ -272,11 +262,11 @@
     }
 
   MaxValueData = 0;
-  ValueListCell = HvGetCell (&RegistryHive->Hive, KeyCell->ValueList.List);
+  ValueListCell = HvGetCell (Hive, KeyCell->ValueList.List);
 
   for (i = 0; i < KeyCell->ValueList.Count; i++)
     {
-      CurValueCell = HvGetCell (&RegistryHive->Hive,
+      CurValueCell = HvGetCell (Hive,
                                 ValueListCell->ValueOffset[i]);
       if ((MaxValueData < (LONG)(CurValueCell->DataSize & REG_DATA_SIZE_MASK)))
         {

Modified: trunk/reactos/ntoskrnl/config/cm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cm.h?rev=26780&r1=26779&r2=26780&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/config/cm.h (original)
+++ trunk/reactos/ntoskrnl/config/cm.h Mon May 14 22:12:57 2007
@@ -675,6 +675,16 @@
     };
 } KEY_VALUE_INFORMATION, *PKEY_VALUE_INFORMATION;
 
+typedef struct _KEY_INFORMATION
+{
+    union
+    {
+        KEY_BASIC_INFORMATION KeyBasicInformation;
+        KEY_FULL_INFORMATION KeyFullInformation;
+        KEY_NODE_INFORMATION KeyNodeInformation;
+    };
+} KEY_INFORMATION, *PKEY_INFORMATION;
+
 ///////////////////////////////////////////////////////////////////////////////
 //
 // BUGBUG Old Hive Stuff for Temporary Support
@@ -718,6 +728,10 @@
 VOID NTAPI CmiWorkerThread(IN PVOID Param);
 PVOID NTAPI CmpRosGetHardwareHive(OUT PULONG Length);
 NTSTATUS CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1, IN PVOID Argument2);
+ULONG CmiGetMaxNameLength(IN PHHIVE RegistryHive, IN PCM_KEY_NODE KeyCell);
+ULONG CmiGetMaxClassLength(IN PHHIVE RegistryHive, IN PCM_KEY_NODE KeyCell);
+ULONG CmiGetMaxValueNameLength(IN PHHIVE RegistryHive, IN PCM_KEY_NODE KeyCell);
+ULONG CmiGetMaxValueDataLength(IN PHHIVE RegistryHive, IN PCM_KEY_NODE KeyCell);
 VOID CmiSyncHives(VOID);
 #define HIVE_NO_FILE    0x00000002
 ///////////////////////////////////////////////////////////////////////////////

Modified: trunk/reactos/ntoskrnl/config/cmapi.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmapi.c?rev=26780&r1=26779&r2=26780&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmapi.c (original)
+++ trunk/reactos/ntoskrnl/config/cmapi.c Mon May 14 22:12:57 2007
@@ -624,3 +624,296 @@
     KeLeaveCriticalRegion();
     return Status;
 }
+
+NTSTATUS
+NTAPI
+CmpQueryKeyData(IN PHHIVE Hive,
+                IN PCM_KEY_NODE Node,
+                IN KEY_INFORMATION_CLASS KeyInformationClass,
+                IN OUT PVOID KeyInformation,
+                IN ULONG Length,
+                IN OUT PULONG ResultLength)
+{
+    NTSTATUS Status;
+    ULONG Size, SizeLeft, MinimumSize;
+    PKEY_INFORMATION Info = (PKEY_INFORMATION)KeyInformation;
+    USHORT NameLength;
+
+    /* Check if the value is compressed */
+    if (Node->Flags & VALUE_COMP_NAME)
+    {
+        /* Get the compressed name size */
+        NameLength = CmpCompressedNameSize(Node->Name, Node->NameLength);
+    }
+    else
+    {
+        /* Get the real size */
+        NameLength = Node->NameLength;
+    }
+
+    /* Check what kind of information is being requested */
+    switch (KeyInformationClass)
+    {
+        /* Basic information */
+        case KeyBasicInformation:
+
+            /* This is the size we need */
+            Size = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) + NameLength;
+
+            /* And this is the minimum we can work with */
+            MinimumSize = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name);
+
+            /* Let the caller know and assume success */
+            *ResultLength = Size;
+            Status = STATUS_SUCCESS;
+
+            /* Check if the bufer we got is too small */
+            if (Length < MinimumSize)
+            {
+                /* Let the caller know and fail */
+                Status = STATUS_BUFFER_TOO_SMALL;
+                break;
+            }
+
+            /* Copy the basic information */
+            Info->KeyBasicInformation.LastWriteTime = Node->LastWriteTime;
+            Info->KeyBasicInformation.TitleIndex = 0;
+            Info->KeyBasicInformation.NameLength = NameLength;
+
+            /* Only the name is left */
+            SizeLeft = Length - MinimumSize;
+            Size = NameLength;
+
+            /* Check if we don't have enough space for the name */
+            if (SizeLeft < Size)
+            {
+                /* Truncate the name we'll return, and tell the caller */
+                Size = SizeLeft;
+                Status = STATUS_BUFFER_OVERFLOW;
+            }
+
+            /* Check if this is a compressed key */
+            if (Node->Flags & KEY_COMP_NAME)
+            {
+                /* Copy the compressed name */
+                CmpCopyCompressedName(Info->KeyBasicInformation.Name,
+                                      SizeLeft,
+                                      Node->Name,
+                                      Node->NameLength);
+            }
+            else
+            {
+                /* Otherwise, copy the raw name */
+                RtlCopyMemory(Info->KeyBasicInformation.Name,
+                              Node->Name,
+                              Size);
+            }
+            break;
+
+        /* Node information */
+        case KeyNodeInformation:
+
+            /* Calculate the size we need */
+            Size = FIELD_OFFSET(KEY_NODE_INFORMATION, Name) +
+                   NameLength +
+                   Node->ClassLength;
+
+            /* And the minimum size we can support */
+            MinimumSize = FIELD_OFFSET(KEY_NODE_INFORMATION, Name);
+
+            /* Return the size to the caller and assume succes */
+            *ResultLength = Size;
+            Status = STATUS_SUCCESS;
+
+            /* Check if the caller's buffer is too small */
+            if (Length < MinimumSize)
+            {
+                /* Let them know, and fail */
+                Status = STATUS_BUFFER_TOO_SMALL;
+                break;
+            }
+
+            /* Copy the basic information */
+            Info->KeyNodeInformation.LastWriteTime = Node->LastWriteTime;
+            Info->KeyNodeInformation.TitleIndex = 0;
+            Info->KeyNodeInformation.ClassLength = Node->ClassLength;
+            Info->KeyNodeInformation.NameLength = NameLength;
+
+            /* Now the name is left */
+            SizeLeft = Length - MinimumSize;
+            Size = NameLength;
+
+            /* Check if the name can fit entirely */
+            if (SizeLeft < Size)
+            {
+                /* It can't, we'll have to truncate. Tell the caller */
+                Size = SizeLeft;
+                Status = STATUS_BUFFER_OVERFLOW;
+            }
+
+            /* Check if the key node name is compressed */
+            if (Node->Flags & KEY_COMP_NAME)
+            {
+                /* Copy the compressed name */
+                CmpCopyCompressedName(Info->KeyNodeInformation.Name,
+                                      SizeLeft,
+                                      Node->Name,
+                                      Node->NameLength);
+            }
+            else
+            {
+                /* It isn't, so copy the raw name */
+                RtlCopyMemory(Info->KeyNodeInformation.Name,
+                              Node->Name,
+                              Size);
+            }
+
+            /* Check if the node has a class */
+            if (Node->ClassLength > 0)
+            {
+                /* It does. We don't support these yet */
+                ASSERTMSG("Classes not supported\n", FALSE);
+            }
+            else
+            {
+                /* It doesn't, so set offset to -1, not 0! */
+                Info->KeyNodeInformation.ClassOffset = 0xFFFFFFFF;
+            }
+            break;
+
+        /* Full information requsted */
+        case KeyFullInformation:
+
+            /* This is the size we need */
+            Size = FIELD_OFFSET(KEY_FULL_INFORMATION, Class) +
+                   Node->ClassLength;
+
+            /* This is what we can work with */
+            MinimumSize = FIELD_OFFSET(KEY_FULL_INFORMATION, Class);
+
+            /* Return it to caller and assume success */
+            *ResultLength = Size;
+            Status = STATUS_SUCCESS;
+
+            /* Check if the caller's buffer is to small */
+            if (Length < MinimumSize)
+            {
+                /* Let them know and fail */
+                Status = STATUS_BUFFER_TOO_SMALL;
+                break;
+            }
+
+            /* Now copy all the basic information */
+            Info->KeyFullInformation.LastWriteTime = Node->LastWriteTime;
+            Info->KeyFullInformation.TitleIndex = 0;
+            Info->KeyFullInformation.ClassLength = Node->ClassLength;
+            Info->KeyFullInformation.SubKeys = Node->SubKeyCounts[HvStable] +
+                                               Node->SubKeyCounts[HvVolatile];
+            Info->KeyFullInformation.Values = Node->ValueList.Count;
+            Info->KeyFullInformation.MaxNameLen = CmiGetMaxNameLength(Hive, Node);
+            Info->KeyFullInformation.MaxClassLen = CmiGetMaxClassLength(Hive, Node);
+            Info->KeyFullInformation.MaxValueNameLen = CmiGetMaxValueNameLength(Hive, Node);
+            Info->KeyFullInformation.MaxValueDataLen = CmiGetMaxValueDataLength(Hive, Node);
+            DPRINT("%d %d %d %d\n",
+                   CmiGetMaxNameLength(Hive, Node),
+                   CmiGetMaxValueDataLength(Hive, Node),
+                   CmiGetMaxValueNameLength(Hive, Node),
+                   CmiGetMaxClassLength(Hive, Node));
+            //Info->KeyFullInformation.MaxNameLen = Node->MaxNameLen;
+            //Info->KeyFullInformation.MaxClassLen = Node->MaxClassLen;
+            //Info->KeyFullInformation.MaxValueNameLen = Node->MaxValueNameLen;
+            //Info->KeyFullInformation.MaxValueDataLen = Node->MaxValueDataLen;
+
+            /* Check if we have a class */
+            if (Node->ClassLength > 0)
+            {
+                /* We do, but we currently don't support this */
+                ASSERTMSG("Classes not supported\n", FALSE);
+            }
+            else
+            {
+                /* We don't have a class, so set offset to -1, not 0! */
+                Info->KeyNodeInformation.ClassOffset = 0xFFFFFFFF;
+            }
+            break;
+
+        /* Any other class that got sent here is invalid! */
+        default:
+
+            /* Set failure code */
+            Status = STATUS_INVALID_PARAMETER;
+            break;
+    }
+
+    /* Return status */
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+CmQueryKey(IN PKEY_OBJECT KeyObject,
+           IN KEY_INFORMATION_CLASS KeyInformationClass,
+           IN PVOID KeyInformation,
+           IN ULONG Length,
+           IN PULONG ResultLength)
+{
+    NTSTATUS Status;
+    PHHIVE Hive;
+    PCM_KEY_NODE Parent;
+
+    /* 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;
+    }
+
+    /* Check what class we got */
+    switch (KeyInformationClass)
+    {
+        /* Typical information */
+        case KeyFullInformation:
+        case KeyBasicInformation:
+        case KeyNodeInformation:
+
+            /* Call the internal API */
+            Status = CmpQueryKeyData(Hive,
+                                     Parent,
+                                     KeyInformationClass,
+                                     KeyInformation,
+                                     Length,
+                                     ResultLength);
+            break;
+
+        /* Unsupported classes for now */
+        case KeyNameInformation:
+        case KeyCachedInformation:
+        case KeyFlagsInformation:
+
+            /* Print message and fail */
+            DPRINT1("Unsupported class: %d!\n", KeyInformationClass);
+            Status = STATUS_NOT_IMPLEMENTED;
+            break;
+
+        /* Illegal classes */
+        default:
+
+            /* Print message and fail */
+            DPRINT1("Unsupported class: %d!\n", KeyInformationClass);
+            Status = STATUS_INVALID_INFO_CLASS;
+            break;
+    }
+
+Quickie:
+    /* Release hive lock */
+    ExReleaseResourceLite(&CmpRegistryLock);
+    KeLeaveCriticalRegion();
+    return Status;
+}




More information about the Ros-diffs mailing list