+ ULONG OwnerLength;
+ ULONG GroupLength;
+ ULONG DaclLength;
+ ULONG SaclLength;
+ PSID pOwner;
+ PSID pGroup;
+ PACL pDacl;
+ PACL pSacl;
+
+ if (!(RelSD->Control & SE_SELF_RELATIVE))
+ return STATUS_BAD_DESCRIPTOR_FORMAT;
+
+ RtlpQuerySecurityDescriptor (RelSD,
+ &pOwner,
+ &OwnerLength,
+ &pGroup,
+ &GroupLength,
+ &pDacl,
+ &DaclLength,
+ &pSacl,
+ &SaclLength);
+
+ if (OwnerLength > *OwnerSize ||
+ GroupLength > *GroupSize ||
+ DaclLength > *DaclSize ||
+ SaclLength > *SaclSize)
+ return STATUS_BUFFER_TOO_SMALL;
+
+ memmove (Owner, pOwner, OwnerLength);
+ memmove (Group, pGroup, GroupLength);
+ memmove (Dacl, pDacl, DaclLength);
+ memmove (Sacl, pSacl, SaclLength);
+
+ memmove (AbsSD, RelSD, sizeof (SECURITY_DESCRIPTOR));
+
+ AbsSD->Control &= ~SE_SELF_RELATIVE;
+ AbsSD->Owner = Owner;
+ AbsSD->Group = Group;
+ AbsSD->Dacl = Dacl;
+ AbsSD->Sacl = Sacl;
+
+ *OwnerSize = OwnerLength;
+ *GroupSize = GroupLength;
+ *DaclSize = DaclLength;
+ *SaclSize = SaclLength;
+
+ return STATUS_SUCCESS;