implemented RtlSelfRelativeToAbsoluteSD2 for 32 and 64 bit builds
Modified: trunk/reactos/lib/rtl/sd.c
_____
Modified: trunk/reactos/lib/rtl/sd.c
--- trunk/reactos/lib/rtl/sd.c 2005-11-01 20:30:17 UTC (rev 18937)
+++ trunk/reactos/lib/rtl/sd.c 2005-11-01 21:53:36 UTC (rev 18938)
@@ -726,14 +726,157 @@
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS NTAPI
RtlSelfRelativeToAbsoluteSD2(PISECURITY_DESCRIPTOR
SelfRelativeSecurityDescriptor,
PULONG BufferSize)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PISECURITY_DESCRIPTOR AbsSD = SelfRelativeSecurityDescriptor;
+ PISECURITY_DESCRIPTOR_RELATIVE RelSD =
(PISECURITY_DESCRIPTOR_RELATIVE)SelfRelativeSecurityDescriptor;
+#ifdef _WIN64
+ PVOID DataStart;
+ ULONG DataSize;
+ ULONG OwnerLength;
+ ULONG GroupLength;
+ ULONG DaclLength;
+ ULONG SaclLength;
+#endif
+ PSID pOwner;
+ PSID pGroup;
+ PACL pDacl;
+ PACL pSacl;
+
+ PAGED_CODE_RTL();
+
+ if (SelfRelativeSecurityDescriptor == NULL)
+ {
+ return STATUS_INVALID_PARAMETER_1;
+ }
+ if (BufferSize == NULL)
+ {
+ return STATUS_INVALID_PARAMETER_2;
+ }
+
+ if (RelSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
+ {
+ return STATUS_UNKNOWN_REVISION;
+ }
+ if (!(RelSD->Control & SE_SELF_RELATIVE))
+ {
+ return STATUS_BAD_DESCRIPTOR_FORMAT;
+ }
+
+ ASSERT(FIELD_OFFSET(SECURITY_DESCRIPTOR, Owner) ==
+ FIELD_OFFSET(SECURITY_DESCRIPTOR_RELATIVE, Owner));
+
+#ifdef _WIN64
+
+ RtlpQuerySecurityDescriptor(SelfRelativeSecurityDescriptor,
+ &pOwner,
+ &OwnerLength,
+ &pGroup,
+ &GroupLength,
+ &pDacl,
+ &DaclLength,
+ &pSacl,
+ &SaclLength);
+
+ ASSERT(sizeof(SECURITY_DESCRIPTOR) >
sizeof(SECURITY_DESCRIPTOR_RELATIVE));
+
+ DataSize = OwnerLength + GroupLength + DaclLength + SaclLength;
+ if (*BufferSize < sizeof(SECURITY_DESCRIPTOR) + DataSize)
+ {
+ *BufferSize = sizeof(SECURITY_DESCRIPTOR) + DataSize;
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+
+ if (DataSize != 0)
+ {
+ /* calculate the start of the data area, we simply just move
the data by
+ the difference between the size of the relative and absolute
security
+ descriptor structure */
+ DataStart = pOwner;
+ if ((pGroup != NULL && (ULONG_PTR)pGroup <
(ULONG_PTR)DataStart) || DataStart == NULL)
+ DataStart = pGroup;
+ if ((pDacl != NULL && (ULONG_PTR)pDacl < (ULONG_PTR)DataStart)
|| DataStart == NULL)
+ DataStart = pDacl;
+ if ((pSacl != NULL && (ULONG_PTR)pSacl < (ULONG_PTR)DataStart)
|| DataStart == NULL)
+ DataStart = pSacl;
+
+ /* if DataSize != 0 ther must be at least one SID or ACL in the
security
+ descriptor! Also the data area must be located somewhere
after the
+ end of the SECURITY_DESCRIPTOR_RELATIVE structure */
+ ASSERT(DataStart != NULL);
+ ASSERT((ULONG_PTR)DataStart >= (ULONG_PTR)(RelSD + 1));
+
+ /* it's time to move the data */
+ RtlMoveMemory((PVOID)(AbsSD + 1),
+ DataStart,
+ DataSize);
+
+ /* adjust the pointers if neccessary */
+ if (pOwner != NULL)
+ AbsSD->Owner = (PSID)((ULONG_PTR)pOwner +
+ sizeof(SECURITY_DESCRIPTOR) -
sizeof(SECURITY_DESCRIPTOR_RELATIVE));
+ else
+ AbsSD->Owner = NULL;
+
+ if (pGroup != NULL)
+ AbsSD->Group = (PSID)((ULONG_PTR)pGroup +
+ sizeof(SECURITY_DESCRIPTOR) -
sizeof(SECURITY_DESCRIPTOR_RELATIVE));
+ else
+ AbsSD->Group = NULL;
+
+ if (pSacl != NULL)
+ AbsSD->Sacl = (PACL)((ULONG_PTR)pSacl +
+ sizeof(SECURITY_DESCRIPTOR) -
sizeof(SECURITY_DESCRIPTOR_RELATIVE));
+ else
+ AbsSD->Sacl = NULL;
+
+ if (pDacl != NULL)
+ AbsSD->Dacl = (PACL)((ULONG_PTR)pDacl +
+ sizeof(SECURITY_DESCRIPTOR) -
sizeof(SECURITY_DESCRIPTOR_RELATIVE));
+ else
+ AbsSD->Dacl = NULL;
+ }
+ else
+ {
+ /* all pointers must be NULL! */
+ ASSERT(pOwner == NULL);
+ ASSERT(pGroup == NULL);
+ ASSERT(pSacl == NULL);
+ ASSERT(pDacl == NULL);
+
+ AbsSD->Owner = NULL;
+ AbsSD->Group = NULL;
+ AbsSD->Dacl = NULL;
+ AbsSD->Sacl = NULL;
+ }
+
+ /* clear the self-relative flag */
+ AbsSD->Control &= ~SE_SELF_RELATIVE;
+
+#else
+
+ RtlpQuerySecurityDescriptorPointers(SelfRelativeSecurityDescriptor,
+ &pOwner,
+ &pGroup,
+ &pSacl,
+ &pDacl);
+
+ ASSERT(sizeof(SECURITY_DESCRIPTOR) ==
sizeof(SECURITY_DESCRIPTOR_RELATIVE));
+
+ /* clear the self-relative flag and simply convert the offsets to
pointers */
+ AbsSD->Control &= ~SE_SELF_RELATIVE;
+ AbsSD->Owner = pOwner;
+ AbsSD->Group = pGroup;
+ AbsSD->Sacl = pDacl;
+ AbsSD->Dacl = pSacl;
+
+#endif
+
+ return STATUS_SUCCESS;
}