[NTOS/CM]

- Add NtQueryKey(KeyNameInformation) implementation.
CORE-8581 #resolve

svn path=/trunk/; revision=64396
This commit is contained in:
Jérôme Gardou 2014-09-29 16:27:16 +00:00
parent ea57e45a4b
commit 4d394c076a

View file

@ -1514,13 +1514,103 @@ CmpQueryFlagsInformation(
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static
NTSTATUS
CmpQueryNameInformation(
_In_ PCM_KEY_CONTROL_BLOCK Kcb,
_Out_opt_ PKEY_NAME_INFORMATION KeyNameInfo,
_In_ ULONG Length,
_Out_ PULONG ResultLength)
{
ULONG NeededLength;
PCM_KEY_CONTROL_BLOCK CurrentKcb;
NeededLength = 0;
CurrentKcb = Kcb;
/* Count the needed buffer size */
while (CurrentKcb)
{
if (CurrentKcb->NameBlock->Compressed)
NeededLength += CmpCompressedNameSize(CurrentKcb->NameBlock->Name, CurrentKcb->NameBlock->NameLength);
else
NeededLength += CurrentKcb->NameBlock->NameLength;
NeededLength += sizeof(OBJ_NAME_PATH_SEPARATOR);
CurrentKcb = CurrentKcb->ParentKcb;
}
_SEH2_TRY
{
*ResultLength = NeededLength + FIELD_OFFSET(KEY_NAME_INFORMATION, Name[0]);
if (Length < *ResultLength)
return STATUS_BUFFER_TOO_SMALL;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
return _SEH2_GetExceptionCode();
}
_SEH2_END;
/* Do the real copy */
KeyNameInfo->NameLength = 0;
CurrentKcb = Kcb;
while (CurrentKcb)
{
ULONG NameLength;
_SEH2_TRY
{
if (CurrentKcb->NameBlock->Compressed)
{
NameLength = CmpCompressedNameSize(CurrentKcb->NameBlock->Name, CurrentKcb->NameBlock->NameLength);
/* Copy the compressed name */
CmpCopyCompressedName(&KeyNameInfo->Name[(NeededLength - NameLength)/sizeof(WCHAR)],
NameLength,
CurrentKcb->NameBlock->Name,
CurrentKcb->NameBlock->NameLength);
}
else
{
NameLength = CurrentKcb->NameBlock->NameLength;
/* Otherwise, copy the raw name */
RtlCopyMemory(&KeyNameInfo->Name[(NeededLength - NameLength)/sizeof(WCHAR)],
CurrentKcb->NameBlock->Name,
NameLength);
}
NeededLength -= NameLength;
NeededLength -= sizeof(OBJ_NAME_PATH_SEPARATOR);
/* Add path separator */
KeyNameInfo->Name[NeededLength/sizeof(WCHAR)] = OBJ_NAME_PATH_SEPARATOR;
KeyNameInfo->NameLength += NameLength + sizeof(OBJ_NAME_PATH_SEPARATOR);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
return _SEH2_GetExceptionCode();
}
_SEH2_END;
CurrentKcb = CurrentKcb->ParentKcb;
}
/* Make sure we copied everything */
ASSERT(NeededLength == 0);
ASSERT(KeyNameInfo->Name[0] == OBJ_NAME_PATH_SEPARATOR);
/* We're done */
return STATUS_SUCCESS;
}
NTSTATUS NTSTATUS
NTAPI NTAPI
CmQueryKey(IN PCM_KEY_CONTROL_BLOCK Kcb, CmQueryKey(_In_ PCM_KEY_CONTROL_BLOCK Kcb,
IN KEY_INFORMATION_CLASS KeyInformationClass, _In_ KEY_INFORMATION_CLASS KeyInformationClass,
IN PVOID KeyInformation, _Out_opt_ PVOID KeyInformation,
IN ULONG Length, _In_ ULONG Length,
IN PULONG ResultLength) _Out_ PULONG ResultLength)
{ {
NTSTATUS Status; NTSTATUS Status;
PHHIVE Hive; PHHIVE Hive;
@ -1588,12 +1678,12 @@ CmQueryKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
ResultLength); ResultLength);
break; break;
/* Unsupported class for now */
case KeyNameInformation: case KeyNameInformation:
/* Call the internal API */
/* Print message and fail */ Status = CmpQueryNameInformation(Kcb,
DPRINT1("Unsupported class: %d!\n", KeyInformationClass); KeyInformation,
Status = STATUS_NOT_IMPLEMENTED; Length,
ResultLength);
break; break;
/* Illegal classes */ /* Illegal classes */