Author: tkreuzer Date: Fri Jan 17 21:45:53 2014 New Revision: 61658
URL: http://svn.reactos.org/svn/reactos?rev=61658&view=rev Log: [NTOSKRNL] Implement querying class data in CmpQueryKeyData
Modified: trunk/reactos/ntoskrnl/config/cmapi.c
Modified: trunk/reactos/ntoskrnl/config/cmapi.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmapi.c?rev... ============================================================================== --- trunk/reactos/ntoskrnl/config/cmapi.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/config/cmapi.c [iso-8859-1] Fri Jan 17 21:45:53 2014 @@ -380,9 +380,10 @@ IN OUT PULONG ResultLength) { NTSTATUS Status; - ULONG Size, SizeLeft, MinimumSize; + ULONG Size, SizeLeft, MinimumSize, Offset; PKEY_INFORMATION Info = (PKEY_INFORMATION)KeyInformation; USHORT NameLength; + PVOID ClassData;
/* Check if the value is compressed */ if (Node->Flags & KEY_COMP_NAME) @@ -516,8 +517,36 @@ /* Check if the node has a class */ if (Node->ClassLength > 0) { - /* It does. We don't support these yet */ - ASSERTMSG("Classes not supported\n", FALSE); + /* Set the class offset */ + Offset = FIELD_OFFSET(KEY_NODE_INFORMATION, Name) + NameLength; + Offset = ALIGN_UP_BY(Offset, sizeof(ULONG)); + Info->KeyNodeInformation.ClassOffset = Offset; + + /* Get the class data */ + ClassData = HvGetCell(Hive, Node->Class); + if (ClassData == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + break; + } + + /* Check if we can copy anything */ + if (Length > Offset) + { + /* Copy the class data */ + RtlCopyMemory((PUCHAR)Info + Offset, + ClassData, + min(Node->ClassLength, Length - Offset)); + } + + /* Check if the buffer was large enough */ + if (Length < Offset + Node->ClassLength) + { + Status = STATUS_BUFFER_OVERFLOW; + } + + /* Release the class cell */ + HvReleaseCell(Hive, Node->Class); } else { @@ -563,13 +592,37 @@ /* Check if we have a class */ if (Node->ClassLength > 0) { - /* We do, but we currently don't support this */ - ASSERTMSG("Classes not supported\n", FALSE); + /* Set the class offset */ + Offset = FIELD_OFFSET(KEY_FULL_INFORMATION, Class); + Info->KeyFullInformation.ClassOffset = Offset; + + /* Get the class data */ + ClassData = HvGetCell(Hive, Node->Class); + if (ClassData == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + break; + } + + /* Copy the class data */ + NT_ASSERT(Length > Offset); + RtlCopyMemory(Info->KeyFullInformation.Class, + ClassData, + min(Node->ClassLength, Length - Offset)); + + /* Check if the buffer was large enough */ + if (Length < Offset + Node->ClassLength) + { + Status = STATUS_BUFFER_OVERFLOW; + } + + /* Release the class cell */ + HvReleaseCell(Hive, Node->Class); } else { /* We don't have a class, so set offset to -1, not 0! */ - Info->KeyNodeInformation.ClassOffset = 0xFFFFFFFF; + Info->KeyFullInformation.ClassOffset = 0xFFFFFFFF; } break;