+NTSTATUS
+CmpQuerySecurityDescriptor(IN PCM_KEY_BODY KeyBody,
+ IN SECURITY_INFORMATION SecurityInformation,
+ OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
+ IN OUT PULONG BufferLength)
+{
+ PISECURITY_DESCRIPTOR_RELATIVE RelSd;
+ PUCHAR Current;
+ ULONG SidSize;
+ ULONG SdSize;
+ NTSTATUS Status;
+
+ DBG_UNREFERENCED_PARAMETER(KeyBody);
+
+ if (SecurityInformation == 0)
+ {
+ return STATUS_ACCESS_DENIED;
+ }
+
+ SidSize = RtlLengthSid(SeWorldSid);
+ SdSize = sizeof(*RelSd) + 2 * SidSize;
+ RelSd = SecurityDescriptor;
+
+ if (*BufferLength < SdSize)
+ {
+ *BufferLength = SdSize;
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+
+ *BufferLength = SdSize;
+
+ Status = RtlCreateSecurityDescriptorRelative(RelSd,
+ SECURITY_DESCRIPTOR_REVISION);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ Current = (PUCHAR)(RelSd + 1);
+ ASSERT((ULONG_PTR)Current - (ULONG_PTR)RelSd <= SdSize);
+
+ if (SecurityInformation & OWNER_SECURITY_INFORMATION)
+ {
+ RtlCopyMemory(Current, SeWorldSid, SidSize);
+ RelSd->Owner = Current - (PUCHAR)RelSd;
+ Current += SidSize;
+ ASSERT((ULONG_PTR)Current - (ULONG_PTR)RelSd <= SdSize);
+ }
+
+ if (SecurityInformation & GROUP_SECURITY_INFORMATION)
+ {
+ RtlCopyMemory(Current, SeWorldSid, SidSize);
+ RelSd->Group = Current - (PUCHAR)RelSd;
+ Current += SidSize;
+ ASSERT((ULONG_PTR)Current - (ULONG_PTR)RelSd <= SdSize);
+ }
+
+ if (SecurityInformation & DACL_SECURITY_INFORMATION)
+ {
+ RelSd->Control |= SE_DACL_PRESENT;
+ }
+
+ if (SecurityInformation & SACL_SECURITY_INFORMATION)
+ {
+ RelSd->Control |= SE_SACL_PRESENT;
+ }
+
+ return STATUS_SUCCESS;
+}
+