The structure layout of self-relative security descriptors may be different from absolute security descriptors depending on the platform. Self-relative security descriptors always use 32 bit offsets while absolute security descriptors use pointers which could be 64 bits.
Modified: trunk/reactos/include/ntos/rtl.h
Modified: trunk/reactos/include/ntos/security.h
Modified: trunk/reactos/lib/advapi32/sec/sec.c
Modified: trunk/reactos/lib/rtl/sd.c
Modified: trunk/reactos/ntoskrnl/se/sd.c
Modified: trunk/reactos/w32api/include/ddk/ntifs.h
Modified: trunk/reactos/w32api/include/ddk/winddk.h
Modified: trunk/reactos/w32api/include/winnt.h

Modified: trunk/reactos/include/ntos/rtl.h
--- trunk/reactos/include/ntos/rtl.h	2005-02-12 09:17:51 UTC (rev 13501)
+++ trunk/reactos/include/ntos/rtl.h	2005-02-12 11:47:03 UTC (rev 13502)
@@ -521,7 +521,7 @@
 
 NTSTATUS STDCALL
 RtlAbsoluteToSelfRelativeSD (PSECURITY_DESCRIPTOR AbsSD,
-			     PSECURITY_DESCRIPTOR RelSD,
+			     PSECURITY_DESCRIPTOR_RELATIVE RelSD,
 			     PULONG BufferLength);
 
 NTSTATUS STDCALL
@@ -852,6 +852,10 @@
 RtlCreateSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor,
 			     ULONG Revision);
 
+NTSTATUS STDCALL
+RtlCreateSecurityDescriptorRelative (PSECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor,
+			             ULONG Revision);
+
 NTSTATUS
 STDCALL
 RtlCreateSystemVolumeInformationFolder(
@@ -1999,7 +2003,7 @@
 
 NTSTATUS STDCALL
 RtlMakeSelfRelativeSD (PSECURITY_DESCRIPTOR AbsSD,
-		       PSECURITY_DESCRIPTOR RelSD,
+		       PSECURITY_DESCRIPTOR_RELATIVE RelSD,
 		       PULONG BufferLength);
 
 VOID STDCALL
@@ -2261,7 +2265,7 @@
 			   PLARGE_INTEGER Time);
 
 NTSTATUS STDCALL
-RtlSelfRelativeToAbsoluteSD (PSECURITY_DESCRIPTOR RelSD,
+RtlSelfRelativeToAbsoluteSD (PSECURITY_DESCRIPTOR_RELATIVE RelSD,
 			     PSECURITY_DESCRIPTOR AbsSD,
 			     PULONG AbsSDSize,
 			     PACL Dacl,
@@ -2276,7 +2280,7 @@
 NTSTATUS
 STDCALL
 RtlSelfRelativeToAbsoluteSD2(
-	PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
+	PSECURITY_DESCRIPTOR_RELATIVE SelfRelativeSecurityDescriptor,
 	PULONG BufferSize
 	);
 
@@ -2659,7 +2663,7 @@
 BOOLEAN
 STDCALL
 RtlValidRelativeSecurityDescriptor (
-	IN PSECURITY_DESCRIPTOR SecurityDescriptorInput,
+	IN PSECURITY_DESCRIPTOR_RELATIVE SecurityDescriptorInput,
 	IN ULONG SecurityDescriptorLength,
 	IN SECURITY_INFORMATION RequiredInformation
 	);

Modified: trunk/reactos/include/ntos/security.h
--- trunk/reactos/include/ntos/security.h	2005-02-12 09:17:51 UTC (rev 13501)
+++ trunk/reactos/include/ntos/security.h	2005-02-12 11:47:03 UTC (rev 13502)
@@ -283,6 +283,17 @@
   PACL Dacl;
 } SECURITY_DESCRIPTOR, *PSECURITY_DESCRIPTOR;
 
+typedef struct _SECURITY_DESCRIPTOR_RELATIVE
+{
+  UCHAR  Revision;
+  UCHAR  Sbz1;
+  SECURITY_DESCRIPTOR_CONTROL Control;
+  ULONG Owner;
+  ULONG Group;
+  ULONG Sacl;
+  ULONG Dacl;
+} SECURITY_DESCRIPTOR_RELATIVE, *PSECURITY_DESCRIPTOR_RELATIVE;
+
 typedef struct _LUID_AND_ATTRIBUTES
 {
   LUID  Luid;

Modified: trunk/reactos/lib/advapi32/sec/sec.c
--- trunk/reactos/lib/advapi32/sec/sec.c	2005-02-12 09:17:51 UTC (rev 13501)
+++ trunk/reactos/lib/advapi32/sec/sec.c	2005-02-12 11:47:03 UTC (rev 13502)
@@ -258,7 +258,7 @@
 {
 	NTSTATUS Status;
 
-	Status = RtlSelfRelativeToAbsoluteSD (pSelfRelativeSecurityDescriptor,
+	Status = RtlSelfRelativeToAbsoluteSD ((PSECURITY_DESCRIPTOR_RELATIVE)pSelfRelativeSecurityDescriptor,
 	                                      pAbsoluteSecurityDescriptor,
 	                                      lpdwAbsoluteSecurityDescriptorSize,
 	                                      pDacl,
@@ -293,7 +293,7 @@
 	NTSTATUS Status;
 
 	Status = RtlAbsoluteToSelfRelativeSD (pAbsoluteSecurityDescriptor,
-	                                      pSelfRelativeSecurityDescriptor,
+	                                      (PSECURITY_DESCRIPTOR_RELATIVE)pSelfRelativeSecurityDescriptor,
 	                                      (PULONG)lpdwBufferLength);
 	if (!NT_SUCCESS(Status))
 	{

Modified: trunk/reactos/lib/rtl/sd.c
--- trunk/reactos/lib/rtl/sd.c	2005-02-12 09:17:51 UTC (rev 13501)
+++ trunk/reactos/lib/rtl/sd.c	2005-02-12 11:47:03 UTC (rev 13502)
@@ -17,6 +17,95 @@
 
 /* FUNCTIONS ***************************************************************/
 
+
+static VOID
+RtlpQuerySecurityDescriptorPointers(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
+                                    OUT PSID *Owner  OPTIONAL,
+                                    OUT PSID *Group  OPTIONAL,
+                                    OUT PACL *Sacl  OPTIONAL,
+                                    OUT PACL *Dacl  OPTIONAL)
+{
+  if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
+  {
+    PSECURITY_DESCRIPTOR_RELATIVE RelSD = (PSECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
+    if(Owner != NULL)
+    {
+      *Owner = ((RelSD->Owner != 0) ? (PSID)((ULONG_PTR)RelSD + RelSD->Owner) : NULL);
+    }
+    if(Group != NULL)
+    {
+      *Group = ((RelSD->Group != 0) ? (PSID)((ULONG_PTR)RelSD + RelSD->Group) : NULL);
+    }
+    if(Sacl != NULL)
+    {
+      *Sacl = (((RelSD->Control & SE_SACL_PRESENT) && (RelSD->Sacl != 0)) ?
+              (PSID)((ULONG_PTR)RelSD + RelSD->Sacl) : NULL);
+    }
+    if(Dacl != NULL)
+    {
+      *Dacl = (((RelSD->Control & SE_DACL_PRESENT) && (RelSD->Dacl != 0)) ?
+              (PSID)((ULONG_PTR)RelSD + RelSD->Dacl) : NULL);
+    }
+  }
+  else
+  {
+    if(Owner != NULL)
+    {
+      *Owner = SecurityDescriptor->Owner;
+    }
+    if(Group != NULL)
+    {
+      *Group = SecurityDescriptor->Group;
+    }
+    if(Sacl != NULL)
+    {
+      *Sacl = ((SecurityDescriptor->Control & SE_SACL_PRESENT) ? SecurityDescriptor->Sacl : NULL);
+    }
+    if(Dacl != NULL)
+    {
+      *Dacl = ((SecurityDescriptor->Control & SE_DACL_PRESENT) ? SecurityDescriptor->Dacl : NULL);
+    }
+  }
+}
+
+static VOID
+RtlpQuerySecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
+                            PSID* Owner,
+                            PULONG OwnerLength,
+                            PSID* Group,
+                            PULONG GroupLength,
+                            PACL* Dacl,
+                            PULONG DaclLength,
+                            PACL* Sacl,
+                            PULONG SaclLength)
+{
+   RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
+                                       Owner,
+                                       Group,
+                                       Sacl,
+                                       Dacl);
+
+   if (Owner != NULL)
+   {
+      *OwnerLength = ((*Owner != NULL) ? ROUND_UP(RtlLengthSid(*Owner), 4) : 0);
+   }
+   
+   if (Group != NULL)
+   {
+      *GroupLength = ((*Group != NULL) ? ROUND_UP(RtlLengthSid(*Group), 4) : 0);
+   }
+   
+   if (Dacl != NULL)
+   {
+      *DaclLength = ((*Dacl != NULL) ? ROUND_UP((*Dacl)->AclSize, 4) : 0);
+   }
+   
+   if (Sacl != NULL)
+   {
+      *SaclLength = ((*Sacl != NULL) ? ROUND_UP((*Sacl)->AclSize, 4) : 0);
+   }
+}
+
 /*
 * @implemented
 */
@@ -41,54 +130,61 @@
 }
 
 
+NTSTATUS STDCALL
+RtlCreateSecurityDescriptorRelative (PSECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor,
+			             ULONG Revision)
+{
+   if (Revision != SECURITY_DESCRIPTOR_REVISION1)
+   {
+      return STATUS_UNKNOWN_REVISION;
+   }
+
+   SecurityDescriptor->Revision = Revision;
+   SecurityDescriptor->Sbz1 = 0;
+   SecurityDescriptor->Control = SE_SELF_RELATIVE;
+   SecurityDescriptor->Owner = 0;
+   SecurityDescriptor->Group = 0;
+   SecurityDescriptor->Sacl = 0;
+   SecurityDescriptor->Dacl = 0;
+
+   return STATUS_SUCCESS;
+}
+
+
 /*
  * @implemented
  */
 ULONG STDCALL
 RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor)
 {
+   PSID Owner, Group;
+   PACL Sacl, Dacl;
    ULONG Length = sizeof(SECURITY_DESCRIPTOR);
+   
+   RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
+                                       &Owner,
+                                       &Group,
+                                       &Sacl,
+                                       &Dacl);
 
-   if (SecurityDescriptor->Owner != NULL)
+   if (Owner != NULL)
    {
-      PSID Owner = SecurityDescriptor->Owner;
-      if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
-      {
-         Owner = (PSID)((ULONG_PTR)Owner + (ULONG_PTR)SecurityDescriptor);
-      }
-      Length = Length + ROUND_UP(RtlLengthSid(Owner), 4);
+      Length += ROUND_UP(RtlLengthSid(Owner), 4);
    }
 
-   if (SecurityDescriptor->Group != NULL)
+   if (Group != NULL)
    {
-      PSID Group = SecurityDescriptor->Group;
-      if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
-      {
-         Group = (PSID)((ULONG_PTR)Group + (ULONG_PTR)SecurityDescriptor);
-      }
-      Length = Length + ROUND_UP(RtlLengthSid(Group), 4);
+      Length += ROUND_UP(RtlLengthSid(Group), 4);
    }
 
-   if (SecurityDescriptor->Control & SE_DACL_PRESENT &&
-         SecurityDescriptor->Dacl != NULL)
+   if (Dacl != NULL)
    {
-      PACL Dacl = SecurityDescriptor->Dacl;
-      if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
-      {
-         Dacl = (PACL)((ULONG_PTR)Dacl + (ULONG_PTR)SecurityDescriptor);
-      }
-      Length = Length + ROUND_UP(Dacl->AclSize, 4);
+      Length += ROUND_UP(Dacl->AclSize, 4);
    }
 
-   if (SecurityDescriptor->Control & SE_SACL_PRESENT &&
-         SecurityDescriptor->Sacl != NULL)
+   if (Sacl != NULL)
    {
-      PACL Sacl = SecurityDescriptor->Sacl;
-      if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
-      {
-         Sacl = (PACL)((ULONG_PTR)Sacl + (ULONG_PTR)SecurityDescriptor);
-      }
-      Length = Length + ROUND_UP(Sacl->AclSize, 4);
+      Length += ROUND_UP(Sacl->AclSize, 4);
    }
 
    return Length;
@@ -116,27 +212,13 @@
    }
    *DaclPresent = TRUE;
 
-   if (SecurityDescriptor->Dacl == NULL)
-   {
-      *Dacl = NULL;
-   }
-   else
-   {
-      *Dacl = SecurityDescriptor->Dacl;
-      if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
-      {
-         *Dacl = (PACL)((ULONG_PTR)*Dacl + (ULONG_PTR)SecurityDescriptor);
-      }
-   }
+   RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
+                                       NULL,
+                                       NULL,
+                                       NULL,
+                                       Dacl);
 
-   if (SecurityDescriptor->Control & SE_DACL_DEFAULTED)
-   {
-      *DaclDefaulted = TRUE;
-   }
-   else
-   {
-      *DaclDefaulted = FALSE;
-   }
+   *DaclDefaulted = ((SecurityDescriptor->Control & SE_DACL_DEFAULTED) ? TRUE : FALSE);
 
    return STATUS_SUCCESS;
 }
@@ -186,69 +268,28 @@
 BOOLEAN STDCALL
 RtlValidSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor)
 {
+   PSID Owner, Group;
+   PACL Sacl, Dacl;
+
    if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
    {
       return FALSE;
    }
+   
+   RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
+                                       &Owner,
+                                       &Group,
+                                       &Sacl,
+                                       &Dacl);
 
-   if (SecurityDescriptor->Owner != NULL)
+   if ((Owner != NULL && !RtlValidSid(Owner)) ||
+       (Group != NULL && !RtlValidSid(Group)) ||
+       (Sacl != NULL && !RtlValidAcl(Sacl)) ||
+       (Dacl != NULL && !RtlValidAcl(Dacl)))
    {
-      PSID Owner = SecurityDescriptor->Owner;
-      if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
-      {
-         Owner = (PSID)((ULONG_PTR)Owner + (ULONG_PTR)SecurityDescriptor);
-      }
-
-      if (!RtlValidSid(Owner))
-      {
-         return FALSE;
-      }
+      return FALSE;
    }
 
-   if (SecurityDescriptor->Group != NULL)
-   {
-      PSID Group = SecurityDescriptor->Group;
-      if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
-      {
-         Group = (PSID)((ULONG_PTR)Group + (ULONG_PTR)SecurityDescriptor);
-      }
-
-      if (!RtlValidSid(Group))
-      {
-         return FALSE;
-      }
-   }
-
-   if (SecurityDescriptor->Control & SE_DACL_PRESENT &&
-       SecurityDescriptor->Dacl != NULL)
-   {
-      PACL Dacl = SecurityDescriptor->Dacl;
-      if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
-      {
-         Dacl = (PACL)((ULONG_PTR)Dacl + (ULONG_PTR)SecurityDescriptor);
-      }
-
-      if (!RtlValidAcl(Dacl))
-      {
-         return FALSE;
-      }
-   }
-
-   if (SecurityDescriptor->Control & SE_SACL_PRESENT &&
-       SecurityDescriptor->Sacl != NULL)
-   {
-      PACL Sacl = SecurityDescriptor->Sacl;
-      if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
-      {
-         Sacl = (PACL)((ULONG_PTR)Sacl + (ULONG_PTR)SecurityDescriptor);
-      }
-
-      if (!RtlValidAcl(Sacl))
-      {
-         return FALSE;
-      }
-   }
-
    return TRUE;
 }
 
@@ -296,27 +337,13 @@
       return STATUS_UNKNOWN_REVISION;
    }
 
-   if (SecurityDescriptor->Owner != NULL)
-   {
-      *Owner = SecurityDescriptor->Owner;
-      if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
-      {
-         *Owner = (PSID)((ULONG_PTR)*Owner + (ULONG_PTR)SecurityDescriptor);
-      }
-   }
-   else
-   {
-      *Owner = NULL;
-   }
+   RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
+                                       Owner,
+                                       NULL,
+                                       NULL,
+                                       NULL);
 
-   if (SecurityDescriptor->Control & SE_OWNER_DEFAULTED)
-   {
-      *OwnerDefaulted = TRUE;
-   }
-   else
-   {
-      *OwnerDefaulted = FALSE;
-   }
+   *OwnerDefaulted = ((SecurityDescriptor->Control & SE_OWNER_DEFAULTED) ? TRUE : FALSE);
 
    return STATUS_SUCCESS;
 }
@@ -364,142 +391,25 @@
       return STATUS_UNKNOWN_REVISION;
    }
 
-   if (SecurityDescriptor->Group != NULL)
-   {
-      *Group = SecurityDescriptor->Group;
-      if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
-      {
-         *Group = (PSID)((ULONG_PTR)*Group + (ULONG_PTR)SecurityDescriptor);
-      }
-   }
-   else
-   {
-      *Group = NULL;
-   }
+   RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
+                                       NULL,
+                                       Group,
+                                       NULL,
+                                       NULL);
 
-   if (SecurityDescriptor->Control & SE_GROUP_DEFAULTED)
-   {
-      *GroupDefaulted = TRUE;
-   }
-   else
-   {
-      *GroupDefaulted = FALSE;
-   }
+   *GroupDefaulted = ((SecurityDescriptor->Control & SE_GROUP_DEFAULTED) ? TRUE : FALSE);
 
    return STATUS_SUCCESS;
 }
 
 
-static VOID
-RtlpQuerySecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
-                            PSID* Owner,
-                            PULONG OwnerLength,
-                            PSID* Group,
-                            PULONG GroupLength,
-                            PACL* Dacl,
-                            PULONG DaclLength,
-                            PACL* Sacl,
-                            PULONG SaclLength)
-{
-   if (SecurityDescriptor->Owner != NULL)
-   {
-      *Owner = SecurityDescriptor->Owner;
-      if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
-      {
-         *Owner = (PSID)((ULONG_PTR)*Owner + (ULONG_PTR)SecurityDescriptor);
-      }
-   }
-   else
-   {
-      *Owner = NULL;
-   }
-
-   if (*Owner != NULL)
-   {
-      *OwnerLength = ROUND_UP(RtlLengthSid(*Owner), 4);
-   }
-   else
-   {
-      *OwnerLength = 0;
-   }
-
-   if ((SecurityDescriptor->Control & SE_DACL_PRESENT) &&
-         SecurityDescriptor->Dacl != NULL)
-   {
-      *Dacl = SecurityDescriptor->Dacl;
-      if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
-      {
-         *Dacl = (PACL)((ULONG_PTR)*Dacl + (ULONG_PTR)SecurityDescriptor);
-      }
-   }
-   else
-   {
-      *Dacl = NULL;
-   }
-
-   if (*Dacl != NULL)
-   {
-      *DaclLength = ROUND_UP((*Dacl)->AclSize, 4);
-   }
-   else
-   {
-      *DaclLength = 0;
-   }
-
-   if (SecurityDescriptor->Group != NULL)
-   {
-      *Group = SecurityDescriptor->Group;
-      if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
-      {
-         *Group = (PSID)((ULONG_PTR)*Group + (ULONG_PTR)SecurityDescriptor);
-      }
-   }
-   else
-   {
-      *Group = NULL;
-   }
-
-   if (*Group != NULL)
-   {
-      *GroupLength = ROUND_UP(RtlLengthSid(*Group), 4);
-   }
-   else
-   {
-      *GroupLength = 0;
-   }
-
-   if ((SecurityDescriptor->Control & SE_SACL_PRESENT) &&
-         SecurityDescriptor->Sacl != NULL)
-   {
-      *Sacl = SecurityDescriptor->Sacl;
-      if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
-      {
-         *Sacl = (PACL)((ULONG_PTR)*Sacl + (ULONG_PTR)SecurityDescriptor);
-      }
-   }
-   else
-   {
-      *Sacl = NULL;
-   }
-
-   if (*Sacl != NULL)
-   {
-      *SaclLength = ROUND_UP((*Sacl)->AclSize, 4);
-   }
-   else
-   {
-      *SaclLength = 0;
-   }
-}
-
-
 /*
  * @implemented
  */
 NTSTATUS STDCALL
 RtlMakeSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD,
-                      PSECURITY_DESCRIPTOR RelSD,
-                      PULONG BufferLength)
+		      PSECURITY_DESCRIPTOR_RELATIVE RelSD,
+		      PULONG BufferLength)
 {
    PSID Owner;
    PSID Group;
@@ -522,7 +432,7 @@
                                &Sacl,
                                &SaclLength);
 
-   TotalLength = OwnerLength + GroupLength + SaclLength + DaclLength + sizeof(SECURITY_DESCRIPTOR);
+   TotalLength = sizeof(SECURITY_DESCRIPTOR_RELATIVE) + OwnerLength + GroupLength + SaclLength + DaclLength;
    if (*BufferLength < TotalLength)
    {
       return STATUS_BUFFER_TOO_SMALL;
@@ -530,48 +440,48 @@
 
    RtlZeroMemory(RelSD,
                  TotalLength);
-   memmove(RelSD,
-           AbsSD,
-           sizeof(SECURITY_DESCRIPTOR));
-   Current = (ULONG_PTR)RelSD + sizeof(SECURITY_DESCRIPTOR);
 
+   RelSD->Revision = AbsSD->Revision;
+   RelSD->Sbz1 = AbsSD->Sbz1;
+   RelSD->Control = AbsSD->Control | SE_SELF_RELATIVE;
+   
+   Current = (ULONG_PTR)(RelSD + 1);
+
    if (SaclLength != 0)
    {
-      memmove((PVOID)Current,
-              Sacl,
-              SaclLength);
-      RelSD->Sacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)RelSD);
+      RtlCopyMemory((PVOID)Current,
+                    Sacl,
+                    SaclLength);
+      RelSD->Sacl = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)RelSD);
       Current += SaclLength;
    }
 
    if (DaclLength != 0)
    {
-      memmove((PVOID)Current,
-              Dacl,
-              DaclLength);
-      RelSD->Dacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)RelSD);
+      RtlCopyMemory((PVOID)Current,
+                    Dacl,
+                    DaclLength);
+      RelSD->Dacl = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)RelSD);
       Current += DaclLength;
    }
 
    if (OwnerLength != 0)
    {
-      memmove((PVOID)Current,
-              Owner,
-              OwnerLength);
-      RelSD->Owner = (PSID)((ULONG_PTR)Current - (ULONG_PTR)RelSD);
+      RtlCopyMemory((PVOID)Current,
+                    Owner,
+                    OwnerLength);
+      RelSD->Owner = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)RelSD);
       Current += OwnerLength;
    }
 
    if (GroupLength != 0)
    {
-      memmove((PVOID)Current,
-              Group,
-              GroupLength);
-      RelSD->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)RelSD);
+      RtlCopyMemory((PVOID)Current,
+                    Group,
+                    GroupLength);
+      RelSD->Group = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)RelSD);
    }
 
-   RelSD->Control |= SE_SELF_RELATIVE;
-
    return STATUS_SUCCESS;
 }
 
@@ -581,7 +491,7 @@
  */
 NTSTATUS STDCALL
 RtlAbsoluteToSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD,
-                            PSECURITY_DESCRIPTOR RelSD,
+                            PSECURITY_DESCRIPTOR_RELATIVE RelSD,
                             PULONG BufferLength)
 {
    if (AbsSD->Control & SE_SELF_RELATIVE)
@@ -658,27 +568,13 @@
    }
    *SaclPresent = TRUE;
 
-   if (SecurityDescriptor->Sacl == NULL)
-   {
-      *Sacl = NULL;
-   }
-   else
-   {
-      *Sacl = SecurityDescriptor->Sacl;
-      if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
-      {
-         *Sacl = (PACL)((ULONG_PTR)*Sacl + (ULONG_PTR)SecurityDescriptor);
-      }
-   }
+   RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
+                                       NULL,
+                                       NULL,
+                                       Sacl,
+                                       NULL);
 
-   if (SecurityDescriptor->Control & SE_SACL_DEFAULTED)
-   {
-      *SaclDefaulted = TRUE;
-   }
-   else
-   {
-      *SaclDefaulted = FALSE;
-   }
+   *SaclDefaulted = ((SecurityDescriptor->Control & SE_SACL_DEFAULTED) ? TRUE : FALSE);
 
    return STATUS_SUCCESS;
 }
@@ -726,7 +622,7 @@
  * @implemented
  */
 NTSTATUS STDCALL
-RtlSelfRelativeToAbsoluteSD(PSECURITY_DESCRIPTOR RelSD,
+RtlSelfRelativeToAbsoluteSD(PSECURITY_DESCRIPTOR_RELATIVE RelSD,
                             PSECURITY_DESCRIPTOR AbsSD,
                             PDWORD AbsSDSize,
                             PACL Dacl,
@@ -747,10 +643,17 @@
    PACL pDacl;
    PACL pSacl;
 
+   if (RelSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
+   {
+      return STATUS_UNKNOWN_REVISION;
+   }
+
    if (!(RelSD->Control & SE_SELF_RELATIVE))
+   {
       return STATUS_BAD_DESCRIPTOR_FORMAT;
+   }
 
-   RtlpQuerySecurityDescriptor (RelSD,
+   RtlpQuerySecurityDescriptor ((PSECURITY_DESCRIPTOR)RelSD,
                                 &pOwner,
                                 &OwnerLength,
                                 &pGroup,
@@ -764,16 +667,18 @@
        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);
+   RtlCopyMemory (Owner, pOwner, OwnerLength);
+   RtlCopyMemory (Group, pGroup, GroupLength);
+   RtlCopyMemory (Dacl, pDacl, DaclLength);
+   RtlCopyMemory (Sacl, pSacl, SaclLength);
 
-   memmove (AbsSD, RelSD, sizeof (SECURITY_DESCRIPTOR));
-
-   AbsSD->Control &= ~SE_SELF_RELATIVE;
+   AbsSD->Revision = RelSD->Revision;
+   AbsSD->Sbz1 = RelSD->Sbz1;
+   AbsSD->Control = RelSD->Control & ~SE_SELF_RELATIVE;
    AbsSD->Owner = Owner;
    AbsSD->Group = Group;
    AbsSD->Dacl = Dacl;
@@ -792,7 +697,7 @@
  * @unimplemented
  */
 NTSTATUS STDCALL
-RtlSelfRelativeToAbsoluteSD2(PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
+RtlSelfRelativeToAbsoluteSD2(PSECURITY_DESCRIPTOR_RELATIVE SelfRelativeSecurityDescriptor,
                              PULONG BufferSize)
 {
    UNIMPLEMENTED;
@@ -804,18 +709,18 @@
  * @implemented
  */
 BOOLEAN STDCALL
-RtlValidRelativeSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptorInput,
+RtlValidRelativeSecurityDescriptor(IN PSECURITY_DESCRIPTOR_RELATIVE SecurityDescriptorInput,
                                    IN ULONG SecurityDescriptorLength,
                                    IN SECURITY_INFORMATION RequiredInformation)
 {
-   if (SecurityDescriptorLength < sizeof(SECURITY_DESCRIPTOR) ||
+   if (SecurityDescriptorLength < sizeof(SECURITY_DESCRIPTOR_RELATIVE) ||
        SecurityDescriptorInput->Revision != SECURITY_DESCRIPTOR_REVISION1 ||
        !(SecurityDescriptorInput->Control & SE_SELF_RELATIVE))
    {
       return FALSE;
    }
 
-   if (SecurityDescriptorInput->Owner != NULL)
+   if (SecurityDescriptorInput->Owner != 0)
    {
       PSID Owner = (PSID)((ULONG_PTR)SecurityDescriptorInput->Owner + (ULONG_PTR)SecurityDescriptorInput);
       if (!RtlValidSid(Owner))
@@ -828,7 +733,7 @@
       return FALSE;
    }
 
-   if (SecurityDescriptorInput->Group != NULL)
+   if (SecurityDescriptorInput->Group != 0)
    {
       PSID Group = (PSID)((ULONG_PTR)SecurityDescriptorInput->Group + (ULONG_PTR)SecurityDescriptorInput);
       if (!RtlValidSid(Group))
@@ -843,7 +748,7 @@
 
    if (SecurityDescriptorInput->Control & SE_DACL_PRESENT)
    {
-      if (SecurityDescriptorInput->Dacl != NULL &&
+      if (SecurityDescriptorInput->Dacl != 0 &&
           !RtlValidAcl((PACL)((ULONG_PTR)SecurityDescriptorInput->Dacl + (ULONG_PTR)SecurityDescriptorInput)))
       {
          return FALSE;
@@ -856,7 +761,7 @@
 
    if (SecurityDescriptorInput->Control & SE_SACL_PRESENT)
    {
-      if (SecurityDescriptorInput->Sacl != NULL &&
+      if (SecurityDescriptorInput->Sacl != 0 &&
           !RtlValidAcl((PACL)((ULONG_PTR)SecurityDescriptorInput->Sacl + (ULONG_PTR)SecurityDescriptorInput)))
       {
          return FALSE;

Modified: trunk/reactos/ntoskrnl/se/sd.c
--- trunk/reactos/ntoskrnl/se/sd.c	2005-02-12 09:17:51 UTC (rev 13501)
+++ trunk/reactos/ntoskrnl/se/sd.c	2005-02-12 11:47:03 UTC (rev 13502)
@@ -126,7 +126,7 @@
   ULONG OwnerSAC = 0, GroupSAC = 0;
   ULONG OwnerSize = 0, GroupSize = 0;
   ULONG SaclSize = 0, DaclSize = 0;
-  ULONG DescriptorSize = sizeof(SECURITY_DESCRIPTOR);
+  ULONG DescriptorSize = 0;
   NTSTATUS Status = STATUS_SUCCESS;
   
   if(OriginalSecurityDescriptor != NULL)
@@ -135,12 +135,49 @@
     {
       _SEH_TRY
       {
+        /* first only probe and copy until the control field of the descriptor
+           to determine whether it's a self-relative descriptor */
+        DescriptorSize = (ULONG)((ULONG_PTR)&OriginalSecurityDescriptor->Control -
+                                 (ULONG_PTR)OriginalSecurityDescriptor) +
+                         sizeof(OriginalSecurityDescriptor->Control);
         ProbeForRead(OriginalSecurityDescriptor,
-                     sizeof(SECURITY_DESCRIPTOR),
+                     DescriptorSize,
                      sizeof(ULONG));
 
+        if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
+        {
+          Status = STATUS_UNKNOWN_REVISION;
+          _SEH_LEAVE;
+        }
+        
         /* make a copy on the stack */
-        DescriptorCopy = *OriginalSecurityDescriptor;
+        DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision;
+        DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1;
+        DescriptorCopy.Control = OriginalSecurityDescriptor->Control;
+        DescriptorSize = ((DescriptorCopy.Control & SE_SELF_RELATIVE) ?
+                          sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR));
+
+        /* probe and copy the entire security descriptor structure. The SIDs
+           and ACLs will be probed and copied later though */
+        ProbeForRead(OriginalSecurityDescriptor,
+                     DescriptorSize,
+                     sizeof(ULONG));
+        if(DescriptorCopy.Control & SE_SELF_RELATIVE)
+        {
+          PSECURITY_DESCRIPTOR_RELATIVE RelSD = (PSECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor;
+          
+          DescriptorCopy.Owner = (PSID)RelSD->Owner;
+          DescriptorCopy.Group = (PSID)RelSD->Group;
+          DescriptorCopy.Sacl = (PACL)RelSD->Sacl;
+          DescriptorCopy.Dacl = (PACL)RelSD->Dacl;
+        }
+        else
+        {
+          DescriptorCopy.Owner = OriginalSecurityDescriptor->Owner;
+          DescriptorCopy.Group = OriginalSecurityDescriptor->Group;
+          DescriptorCopy.Sacl = OriginalSecurityDescriptor->Sacl;
+          DescriptorCopy.Dacl = OriginalSecurityDescriptor->Dacl;
+        }
       }
       _SEH_HANDLE
       {
@@ -165,15 +202,35 @@
     }
     else
     {
+      if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
+      {
+        return STATUS_UNKNOWN_REVISION;
+      }
+      
       /* make a copy on the stack */
-      DescriptorCopy = *OriginalSecurityDescriptor;
+      DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision;
+      DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1;
+      DescriptorCopy.Control = OriginalSecurityDescriptor->Control;
+      DescriptorSize = ((DescriptorCopy.Control & SE_SELF_RELATIVE) ?
+                        sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR));
+      if(DescriptorCopy.Control & SE_SELF_RELATIVE)
+      {
+        PSECURITY_DESCRIPTOR_RELATIVE RelSD = (PSECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor;
+
+        DescriptorCopy.Owner = (PSID)RelSD->Owner;
+        DescriptorCopy.Group = (PSID)RelSD->Group;
+        DescriptorCopy.Sacl = (PACL)RelSD->Sacl;
+        DescriptorCopy.Dacl = (PACL)RelSD->Dacl;
+      }
+      else
+      {
+        DescriptorCopy.Owner = OriginalSecurityDescriptor->Owner;
+        DescriptorCopy.Group = OriginalSecurityDescriptor->Group;
+        DescriptorCopy.Sacl = OriginalSecurityDescriptor->Sacl;
+        DescriptorCopy.Dacl = OriginalSecurityDescriptor->Dacl;
+      }
     }
     
-    if(DescriptorCopy.Revision != SECURITY_DESCRIPTOR_REVISION1)
-    {
-      return STATUS_UNKNOWN_REVISION;
-    }
-    
     if(DescriptorCopy.Control & SE_SELF_RELATIVE)
     {
       /* in case we're dealing with a self-relative descriptor, do a basic convert
@@ -377,10 +434,11 @@
 			      IN PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor OPTIONAL)
 {
   PSECURITY_DESCRIPTOR ObjectSd;
-  PSID Owner = 0;
-  PSID Group = 0;
-  PACL Dacl = 0;
-  PACL Sacl = 0;
+  PSECURITY_DESCRIPTOR_RELATIVE RelSD;
+  PSID Owner = NULL;
+  PSID Group = NULL;
+  PACL Dacl = NULL;
+  PACL Sacl = NULL;
   ULONG OwnerLength = 0;
   ULONG GroupLength = 0;
   ULONG DaclLength = 0;
@@ -388,19 +446,20 @@
   ULONG Control = 0;
   ULONG_PTR Current;
   ULONG SdLength;
+  
+  RelSD = (PSECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
 
   if (*ObjectsSecurityDescriptor == NULL)
     {
-      if (*Length < sizeof(SECURITY_DESCRIPTOR))
+      if (*Length < sizeof(SECURITY_DESCRIPTOR_RELATIVE))
 	{
-	  *Length = sizeof(SECURITY_DESCRIPTOR);
+	  *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
 	  return STATUS_BUFFER_TOO_SMALL;
 	}
 
-      *Length = sizeof(SECURITY_DESCRIPTOR);
-      RtlCreateSecurityDescriptor(SecurityDescriptor,
-				  SECURITY_DESCRIPTOR_REVISION);
-      SecurityDescriptor->Control |= SE_SELF_RELATIVE;
+      *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
+      RtlCreateSecurityDescriptorRelative(RelSD,
+				          SECURITY_DESCRIPTOR_REVISION);
       return STATUS_SUCCESS;
     }
 
@@ -447,26 +506,26 @@
     }
 
   SdLength = OwnerLength + GroupLength + DaclLength +
-	     SaclLength + sizeof(SECURITY_DESCRIPTOR);
-  if (*Length < sizeof(SECURITY_DESCRIPTOR))
+	     SaclLength + sizeof(SECURITY_DESCRIPTOR_RELATIVE);
+  if (*Length < SdLength)
     {
       *Length = SdLength;
       return STATUS_BUFFER_TOO_SMALL;
     }
 
   /* Build the new security descrtiptor */
-  RtlCreateSecurityDescriptor(SecurityDescriptor,
-			      SECURITY_DESCRIPTOR_REVISION);
[truncated at 1000 lines; 124 more skipped]