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?... ============================================================================== --- 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?... ============================================================================== --- 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; }