mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 04:13:34 +00:00
- 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. svn path=/trunk/; revision=35727
This commit is contained in:
@@ -890,8 +890,137 @@ PUNICODE_STRING
|
||||
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
|
||||
|
||||
@@ -184,7 +184,7 @@ CmpQueryKeyName(IN PVOID ObjectBody,
|
||||
_SEH_END;
|
||||
|
||||
/* Free the buffer allocated by CmpConstructName */
|
||||
ExFreePool(KeyName->Buffer);
|
||||
ExFreePool(KeyName);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user