[ros-diffs] [fireball] 35727: - Implement CmpConstructName (builds a full name of the given key). - Fix freeing of the buffer returned by CmpConstructName in CmpQueryKeyName routine. - Fixes bug 3616 and related query-routines. See issue #3616 for more details.

fireball at svn.reactos.org fireball at svn.reactos.org
Thu Aug 28 12:16:49 CEST 2008


Author: fireball
Date: Thu Aug 28 05:16:48 2008
New Revision: 35727

URL: http://svn.reactos.org/svn/reactos?rev=35727&view=rev
Log:
- Implement CmpConstructName (builds a full name of the given key).
- Fix freeing of the buffer returned by CmpConstructName in CmpQueryKeyName routine.
- Fixes bug 3616 and related query-routines.
See issue #3616 for more details.

Modified:
    trunk/reactos/ntoskrnl/config/cmkcbncb.c
    trunk/reactos/ntoskrnl/config/cmsysini.c

Modified: trunk/reactos/ntoskrnl/config/cmkcbncb.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmkcbncb.c?rev=35727&r1=35726&r2=35727&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmkcbncb.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/config/cmkcbncb.c [iso-8859-1] Thu Aug 28 05:16:48 2008
@@ -890,8 +890,137 @@
 NTAPI
 CmpConstructName(IN PCM_KEY_CONTROL_BLOCK Kcb)
 {
-    UNIMPLEMENTED;
-    return NULL;
+    PUNICODE_STRING KeyName;
+    ULONG NameLength, i;
+    PCM_KEY_CONTROL_BLOCK MyKcb;
+    PCM_KEY_NODE KeyNode;
+    BOOLEAN DeletedKey = FALSE;
+    PWCHAR TargetBuffer, CurrentNameW;
+    PUCHAR CurrentName;
+
+     /* Calculate how much size our key name is going to occupy */
+    NameLength = 0;
+    MyKcb = Kcb;
+
+    while (MyKcb)
+    {
+        /* Add length of the name */
+        if (!MyKcb->NameBlock->Compressed)
+            NameLength += MyKcb->NameBlock->NameLength;
+        else
+            NameLength += MyKcb->NameBlock->NameLength * sizeof(WCHAR);
+
+        /* Sum up the separator also */
+        NameLength += sizeof(WCHAR);
+
+        /* Go to the parent KCB */
+        MyKcb = MyKcb->ParentKcb;
+    }
+
+    /* Allocate the unicode string now */
+    KeyName = ExAllocatePoolWithTag(PagedPool, NameLength + sizeof(UNICODE_STRING), TAG_CM);
+
+    if (!KeyName) return NULL;
+
+    KeyName->Buffer = (PWSTR)(KeyName + 1);
+    KeyName->Length = NameLength;
+    KeyName->MaximumLength = NameLength;
+
+    /* Loop the keys again, now adding names */
+    NameLength = 0;
+    MyKcb = Kcb;
+
+    while (MyKcb)
+    {
+        /* Sanity checks for deleted keys */
+        if ((!MyKcb->KeyCell && !MyKcb->Delete) ||
+            !MyKcb->KeyHive ||
+            MyKcb->ExtFlags & CM_KCB_KEY_NON_EXIST)
+        {
+            /* Failure */
+            ExFreePool(KeyName);
+            return NULL;
+        }
+
+        /* Try to get the name from the keynode,
+           if the key is not deleted */
+        if (!DeletedKey && !MyKcb->Delete)
+        {
+            KeyNode = HvGetCell(MyKcb->KeyHive, MyKcb->KeyCell);
+
+            if (!KeyNode)
+            {
+                /* Failure */
+                ExFreePool(KeyName);
+                return NULL;
+            }
+        }
+        else
+        {
+            /* The key was deleted */
+            KeyNode = NULL;
+            DeletedKey = TRUE;
+        }
+
+        /* Get the pointer to the beginning of the current key name */
+        NameLength += (MyKcb->NameBlock->NameLength + 1) * sizeof(WCHAR);
+        TargetBuffer = &KeyName->Buffer[(KeyName->Length - NameLength) / sizeof(WCHAR)];
+
+        /* Add a separator */
+        TargetBuffer[0] = OBJ_NAME_PATH_SEPARATOR;
+
+        /* Add the name, but remember to go from the end to the beginning */
+        if (!MyKcb->NameBlock->Compressed)
+        {
+            /* Get the pointer to the name (from the keynode, if possible) */
+            if ((MyKcb->Flags & (KEY_HIVE_ENTRY | KEY_HIVE_EXIT)) ||
+                !KeyNode)
+            {
+                CurrentNameW = MyKcb->NameBlock->Name;
+            }
+            else
+            {
+                CurrentNameW = KeyNode->Name;
+            }
+
+            /* Copy the name */
+            for (i=0; i < MyKcb->NameBlock->NameLength; i++)
+            {
+                TargetBuffer[i+1] = *CurrentNameW;
+                CurrentNameW++;
+            }
+        }
+        else
+        {
+            /* Get the pointer to the name (from the keynode, if possible) */
+            if ((MyKcb->Flags & (KEY_HIVE_ENTRY | KEY_HIVE_EXIT)) ||
+                !KeyNode)
+            {
+                CurrentName = (PUCHAR)MyKcb->NameBlock->Name;
+            }
+            else
+            {
+                CurrentName = (PUCHAR)KeyNode->Name;
+            }
+
+            /* Copy the name */
+            for (i=0; i < MyKcb->NameBlock->NameLength; i++)
+            {
+                TargetBuffer[i+1] = (WCHAR)*CurrentName;
+                CurrentName++;
+            }
+        }
+
+        /* Release the cell, if needed */
+        if (KeyNode) HvReleaseCell(MyKcb->KeyHive, MyKcb->KeyCell);
+
+        /* Go to the parent KCB */
+        MyKcb = MyKcb->ParentKcb;
+    }
+
+    /* Return resulting buffer (both UNICODE_STRING and
+       its buffer following it) */
+    return KeyName;
 }
 
 VOID

Modified: trunk/reactos/ntoskrnl/config/cmsysini.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmsysini.c?rev=35727&r1=35726&r2=35727&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmsysini.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/config/cmsysini.c [iso-8859-1] Thu Aug 28 05:16:48 2008
@@ -184,7 +184,7 @@
     _SEH_END;
 
     /* Free the buffer allocated by CmpConstructName */
-    ExFreePool(KeyName->Buffer);
+    ExFreePool(KeyName);
 
     return Status;
 }



More information about the Ros-diffs mailing list