- 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:
Aleksey Bragin
2008-08-28 10:16:48 +00:00
parent a66715b036
commit dea8ec1229
2 changed files with 132 additions and 3 deletions
+131 -2
View File
@@ -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
+1 -1
View File
@@ -184,7 +184,7 @@ CmpQueryKeyName(IN PVOID ObjectBody,
_SEH_END;
/* Free the buffer allocated by CmpConstructName */
ExFreePool(KeyName->Buffer);
ExFreePool(KeyName);
return Status;
}