Synchronize up to trunk's revision r57784.
[reactos.git] / ntoskrnl / se / sd.c
index fded835..c5b5777 100644 (file)
@@ -38,79 +38,79 @@ SepInitSDs(VOID)
                                               sizeof(SECURITY_DESCRIPTOR), TAG_SD);
     if (SePublicDefaultSd == NULL)
         return FALSE;
-    
+
     RtlCreateSecurityDescriptor(SePublicDefaultSd,
                                 SECURITY_DESCRIPTOR_REVISION);
     RtlSetDaclSecurityDescriptor(SePublicDefaultSd,
                                  TRUE,
                                  SePublicDefaultDacl,
                                  FALSE);
-    
+
     /* Create PublicDefaultUnrestrictedSd */
     SePublicDefaultUnrestrictedSd = ExAllocatePoolWithTag(PagedPool,
                                                           sizeof(SECURITY_DESCRIPTOR), TAG_SD);
     if (SePublicDefaultUnrestrictedSd == NULL)
         return FALSE;
-    
+
     RtlCreateSecurityDescriptor(SePublicDefaultUnrestrictedSd,
                                 SECURITY_DESCRIPTOR_REVISION);
     RtlSetDaclSecurityDescriptor(SePublicDefaultUnrestrictedSd,
                                  TRUE,
                                  SePublicDefaultUnrestrictedDacl,
                                  FALSE);
-    
+
     /* Create PublicOpenSd */
     SePublicOpenSd = ExAllocatePoolWithTag(PagedPool,
                                            sizeof(SECURITY_DESCRIPTOR), TAG_SD);
     if (SePublicOpenSd == NULL)
         return FALSE;
-    
+
     RtlCreateSecurityDescriptor(SePublicOpenSd,
                                 SECURITY_DESCRIPTOR_REVISION);
     RtlSetDaclSecurityDescriptor(SePublicOpenSd,
                                  TRUE,
                                  SePublicOpenDacl,
                                  FALSE);
-    
+
     /* Create PublicOpenUnrestrictedSd */
     SePublicOpenUnrestrictedSd = ExAllocatePoolWithTag(PagedPool,
                                                        sizeof(SECURITY_DESCRIPTOR), TAG_SD);
     if (SePublicOpenUnrestrictedSd == NULL)
         return FALSE;
-    
+
     RtlCreateSecurityDescriptor(SePublicOpenUnrestrictedSd,
                                 SECURITY_DESCRIPTOR_REVISION);
     RtlSetDaclSecurityDescriptor(SePublicOpenUnrestrictedSd,
                                  TRUE,
                                  SePublicOpenUnrestrictedDacl,
                                  FALSE);
-    
+
     /* Create SystemDefaultSd */
     SeSystemDefaultSd = ExAllocatePoolWithTag(PagedPool,
                                               sizeof(SECURITY_DESCRIPTOR), TAG_SD);
     if (SeSystemDefaultSd == NULL)
         return FALSE;
-    
+
     RtlCreateSecurityDescriptor(SeSystemDefaultSd,
                                 SECURITY_DESCRIPTOR_REVISION);
     RtlSetDaclSecurityDescriptor(SeSystemDefaultSd,
                                  TRUE,
                                  SeSystemDefaultDacl,
                                  FALSE);
-    
+
     /* Create UnrestrictedSd */
     SeUnrestrictedSd = ExAllocatePoolWithTag(PagedPool,
                                              sizeof(SECURITY_DESCRIPTOR), TAG_SD);
     if (SeUnrestrictedSd == NULL)
         return FALSE;
-    
+
     RtlCreateSecurityDescriptor(SeUnrestrictedSd,
                                 SECURITY_DESCRIPTOR_REVISION);
     RtlSetDaclSecurityDescriptor(SeUnrestrictedSd,
                                  TRUE,
                                  SeUnrestrictedDacl,
                                  FALSE);
-    
+
     return TRUE;
 }
 
@@ -120,19 +120,19 @@ SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation,
                              PISECURITY_DESCRIPTOR SecurityDescriptor,
                              PULONG BufferLength)
 {
-    ULONG_PTR Current;
+    ULONG Current;
     ULONG SidSize;
     ULONG SdSize;
     NTSTATUS Status;
     PISECURITY_DESCRIPTOR_RELATIVE SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
-    
+
     DPRINT("SeSetWorldSecurityDescriptor() called\n");
-    
+
     if (SecurityInformation == 0)
     {
         return STATUS_ACCESS_DENIED;
     }
-    
+
     /* calculate the minimum size of the buffer */
     SidSize = RtlLengthSid(SeWorldSid);
     SdSize = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
@@ -144,68 +144,64 @@ SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation,
     {
         SdSize += sizeof(ACL) + sizeof(ACE) + SidSize;
     }
-    
+
     if (*BufferLength < SdSize)
     {
         *BufferLength = SdSize;
         return STATUS_BUFFER_TOO_SMALL;
     }
-    
+
     *BufferLength = SdSize;
-    
+
     Status = RtlCreateSecurityDescriptorRelative(SdRel,
                                                  SECURITY_DESCRIPTOR_REVISION);
     if (!NT_SUCCESS(Status))
     {
         return Status;
     }
-    
-    Current = (ULONG_PTR)(SdRel + 1);
-    
+
+    Current = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
+
     if (SecurityInformation & OWNER_SECURITY_INFORMATION)
     {
-        RtlCopyMemory((PVOID)Current,
-                      SeWorldSid,
-                      SidSize);
-        SdRel->Owner = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel);
+        RtlCopyMemory((PUCHAR)SdRel + Current, SeWorldSid, SidSize);
+        SdRel->Owner = Current;
         Current += SidSize;
     }
-    
+
     if (SecurityInformation & GROUP_SECURITY_INFORMATION)
     {
-        RtlCopyMemory((PVOID)Current,
-                      SeWorldSid,
-                      SidSize);
-        SdRel->Group = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel);
+        RtlCopyMemory((PUCHAR)SdRel + Current, SeWorldSid, SidSize);
+        SdRel->Group = Current;
         Current += SidSize;
     }
-    
+
     if (SecurityInformation & DACL_SECURITY_INFORMATION)
     {
-        PACL Dacl = (PACL)Current;
+        PACL Dacl = (PACL)((PUCHAR)SdRel + Current);
         SdRel->Control |= SE_DACL_PRESENT;
-        
+
         Status = RtlCreateAcl(Dacl,
                               sizeof(ACL) + sizeof(ACE) + SidSize,
                               ACL_REVISION);
         if (!NT_SUCCESS(Status))
             return Status;
-        
+
         Status = RtlAddAccessAllowedAce(Dacl,
                                         ACL_REVISION,
                                         GENERIC_ALL,
                                         SeWorldSid);
         if (!NT_SUCCESS(Status))
             return Status;
-        
-        SdRel->Dacl = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel);
+
+        SdRel->Dacl = Current;
     }
-    
+
     if (SecurityInformation & SACL_SECURITY_INFORMATION)
     {
         /* FIXME - SdRel->Control |= SE_SACL_PRESENT; */
     }
-    
+
     return STATUS_SUCCESS;
 }
 
@@ -221,37 +217,39 @@ SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIO
 {
     PSECURITY_QUALITY_OF_SERVICE CapturedQos;
     NTSTATUS Status = STATUS_SUCCESS;
-    
+
     PAGED_CODE();
-    
+
     ASSERT(CapturedSecurityQualityOfService);
     ASSERT(Present);
-    
-    if(ObjectAttributes != NULL)
+
+    if (ObjectAttributes != NULL)
     {
-        if(AccessMode != KernelMode)
+        if (AccessMode != KernelMode)
         {
             SECURITY_QUALITY_OF_SERVICE SafeQos;
-            
+
             _SEH2_TRY
             {
                 ProbeForRead(ObjectAttributes,
                              sizeof(OBJECT_ATTRIBUTES),
                              sizeof(ULONG));
-                if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
+                if (ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
                 {
-                    if(ObjectAttributes->SecurityQualityOfService != NULL)
+                    if (ObjectAttributes->SecurityQualityOfService != NULL)
                     {
                         ProbeForRead(ObjectAttributes->SecurityQualityOfService,
                                      sizeof(SECURITY_QUALITY_OF_SERVICE),
                                      sizeof(ULONG));
-                        
-                        if(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length ==
-                           sizeof(SECURITY_QUALITY_OF_SERVICE))
+
+                        if (((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length ==
+                            sizeof(SECURITY_QUALITY_OF_SERVICE))
                         {
-                            /* don't allocate memory here because ExAllocate should bugcheck
-                             the system if it's buggy, SEH would catch that! So make a local
-                             copy of the qos structure.*/
+                            /*
+                             * Don't allocate memory here because ExAllocate should bugcheck
+                             * the system if it's buggy, SEH would catch that! So make a local
+                             * copy of the qos structure.
+                             */
                             RtlCopyMemory(&SafeQos,
                                           ObjectAttributes->SecurityQualityOfService,
                                           sizeof(SECURITY_QUALITY_OF_SERVICE));
@@ -278,14 +276,14 @@ SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIO
                 Status = _SEH2_GetExceptionCode();
             }
             _SEH2_END;
-            
-            if(NT_SUCCESS(Status))
+
+            if (NT_SUCCESS(Status))
             {
-                if(*Present)
+                if (*Present)
                 {
                     CapturedQos = ExAllocatePool(PoolType,
                                                  sizeof(SECURITY_QUALITY_OF_SERVICE));
-                    if(CapturedQos != NULL)
+                    if (CapturedQos != NULL)
                     {
                         RtlCopyMemory(CapturedQos,
                                       &SafeQos,
@@ -305,18 +303,18 @@ SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIO
         }
         else
         {
-            if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
+            if (ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
             {
-                if(CaptureIfKernel)
+                if (CaptureIfKernel)
                 {
-                    if(ObjectAttributes->SecurityQualityOfService != NULL)
+                    if (ObjectAttributes->SecurityQualityOfService != NULL)
                     {
-                        if(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length ==
-                           sizeof(SECURITY_QUALITY_OF_SERVICE))
+                        if (((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length ==
+                            sizeof(SECURITY_QUALITY_OF_SERVICE))
                         {
                             CapturedQos = ExAllocatePool(PoolType,
                                                          sizeof(SECURITY_QUALITY_OF_SERVICE));
-                            if(CapturedQos != NULL)
+                            if (CapturedQos != NULL)
                             {
                                 RtlCopyMemory(CapturedQos,
                                               ObjectAttributes->SecurityQualityOfService,
@@ -357,7 +355,7 @@ SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIO
         *CapturedSecurityQualityOfService = NULL;
         *Present = FALSE;
     }
-    
+
     return Status;
 }
 
@@ -369,9 +367,9 @@ SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecur
                                    IN BOOLEAN CaptureIfKernel)
 {
     PAGED_CODE();
-    
-    if(CapturedSecurityQualityOfService != NULL &&
-       (AccessMode != KernelMode || CaptureIfKernel))
+
+    if (CapturedSecurityQualityOfService != NULL &&
+        (AccessMode != KernelMode || CaptureIfKernel))
     {
         ExFreePool(CapturedSecurityQualityOfService);
     }
@@ -379,324 +377,239 @@ SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecur
 
 /* PUBLIC FUNCTIONS ***********************************************************/
 
-/*
- * @implemented
- */
+static
+ULONG
+DetermineSIDSize(
+    PISID Sid,
+    PULONG OutSAC,
+    KPROCESSOR_MODE ProcessorMode)
+{
+    ULONG Size;
+
+    if (!Sid)
+    {
+        *OutSAC = 0;
+        return 0;
+    }
+
+    if (ProcessorMode != KernelMode)
+    {
+        /* Securely access the buffers! */
+        *OutSAC = ProbeForReadUchar(&Sid->SubAuthorityCount);
+        Size = RtlLengthRequiredSid(*OutSAC);
+        ProbeForRead(Sid, Size, sizeof(ULONG));
+    }
+    else
+    {
+        *OutSAC = Sid->SubAuthorityCount;
+        Size = RtlLengthRequiredSid(*OutSAC);
+    }
+
+    return Size;
+}
+
+static
+ULONG
+DetermineACLSize(
+    PACL Acl,
+    KPROCESSOR_MODE ProcessorMode)
+{
+    ULONG Size;
+
+    if (!Acl) return 0;
+
+    if (ProcessorMode == KernelMode) return Acl->AclSize;
+
+    /* Probe the buffers! */
+    Size = ProbeForReadUshort(&Acl->AclSize);
+    ProbeForRead(Acl, Size, sizeof(ULONG));
+
+    return Size;
+}
+
 NTSTATUS
 NTAPI
-SeCaptureSecurityDescriptor(IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor,
-                            IN KPROCESSOR_MODE CurrentMode,
-                            IN POOL_TYPE PoolType,
-                            IN BOOLEAN CaptureIfKernel,
-                            OUT PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor)
+SeCaptureSecurityDescriptor(
+    IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor,
+    IN KPROCESSOR_MODE CurrentMode,
+    IN POOL_TYPE PoolType,
+    IN BOOLEAN CaptureIfKernel,
+    OUT PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor)
 {
-    PISECURITY_DESCRIPTOR OriginalSecurityDescriptor = _OriginalSecurityDescriptor;
+    PISECURITY_DESCRIPTOR OriginalDescriptor = _OriginalSecurityDescriptor;
     SECURITY_DESCRIPTOR DescriptorCopy;
-    PISECURITY_DESCRIPTOR NewDescriptor;
+    PISECURITY_DESCRIPTOR_RELATIVE NewDescriptor;
     ULONG OwnerSAC = 0, GroupSAC = 0;
     ULONG OwnerSize = 0, GroupSize = 0;
     ULONG SaclSize = 0, DaclSize = 0;
     ULONG DescriptorSize = 0;
-    NTSTATUS Status;
-    
-    if(OriginalSecurityDescriptor != NULL)
+    ULONG Offset;
+
+    if (!OriginalDescriptor)
     {
-        if(CurrentMode != KernelMode)
+        /* Nothing to do... */
+        *CapturedSecurityDescriptor = NULL;
+        return STATUS_SUCCESS;
+    }
+
+    /* Quick path */
+    if (CurrentMode == KernelMode && !CaptureIfKernel)
+    {
+        /* Check descriptor version */
+        if (OriginalDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
         {
-            RtlZeroMemory(&DescriptorCopy, sizeof(DescriptorCopy));
-            
-            _SEH2_TRY
-            {
-                /* first only probe and copy until the control field of the descriptor
-                 to determine whether it's a self-relative descriptor */
-                DescriptorSize = FIELD_OFFSET(SECURITY_DESCRIPTOR,
-                                              Owner);
-                ProbeForRead(OriginalSecurityDescriptor,
-                             DescriptorSize,
-                             sizeof(ULONG));
-                
-                if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
-                {
-                    _SEH2_YIELD(return STATUS_UNKNOWN_REVISION);
-                }
-                
-                /* make a copy on the stack */
-                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)
-                {
-                    PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_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;
-                }
-            }
-            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-            {
-                /* Return the exception code */
-                _SEH2_YIELD(return _SEH2_GetExceptionCode());
-            }
-            _SEH2_END;
+            return STATUS_UNKNOWN_REVISION;
         }
-        else if(!CaptureIfKernel)
+
+        *CapturedSecurityDescriptor = _OriginalSecurityDescriptor;
+        return STATUS_SUCCESS;
+    }
+
+    _SEH2_TRY
+    {
+        if (CurrentMode != KernelMode)
         {
-            if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
-            {
-                return STATUS_UNKNOWN_REVISION;
-            }
-            
-            *CapturedSecurityDescriptor = OriginalSecurityDescriptor;
-            return STATUS_SUCCESS;
+            ProbeForRead(OriginalDescriptor,
+                         sizeof(SECURITY_DESCRIPTOR_RELATIVE),
+                         sizeof(ULONG));
         }
-        else
+
+        /* Check the descriptor version */
+        if (OriginalDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
         {
-            if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
-            {
-                return STATUS_UNKNOWN_REVISION;
-            }
-            
-            /* make a copy on the stack */
-            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)
-            {
-                PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_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;
-            }
+            _SEH2_YIELD(return STATUS_UNKNOWN_REVISION);
         }
-        
-        if(DescriptorCopy.Control & SE_SELF_RELATIVE)
+
+        if (CurrentMode != KernelMode)
         {
-            /* in case we're dealing with a self-relative descriptor, do a basic convert
-             to an absolute descriptor. We do this so we can simply access the data
-             using the pointers without calculating them again. */
-            DescriptorCopy.Control &= ~SE_SELF_RELATIVE;
-            if(DescriptorCopy.Owner != NULL)
-            {
-                DescriptorCopy.Owner = (PSID)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Owner);
-            }
-            if(DescriptorCopy.Group != NULL)
-            {
-                DescriptorCopy.Group = (PSID)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Group);
-            }
-            if(DescriptorCopy.Dacl != NULL)
-            {
-                DescriptorCopy.Dacl = (PACL)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Dacl);
-            }
-            if(DescriptorCopy.Sacl != NULL)
-            {
-                DescriptorCopy.Sacl = (PACL)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Sacl);
-            }
+            /* Get the size of the descriptor */
+            DescriptorSize = (OriginalDescriptor->Control & SE_SELF_RELATIVE) ?
+                sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR);
+
+            /* Probe the entire security descriptor structure. The SIDs
+             * and ACLs will be probed and copied later though */
+            ProbeForRead(OriginalDescriptor, DescriptorSize, sizeof(ULONG));
         }
-        
-        /* determine the size of the SIDs */
-#define DetermineSIDSize(SidType)                                              \
-do {                                                                       \
-if(DescriptorCopy.SidType != NULL)                                         \
-{                                                                          \
-SID *SidType = (SID*)DescriptorCopy.SidType;                             \
-\
-if(CurrentMode != KernelMode)                                            \
-{                                                                        \
-/* securely access the buffers! */                                     \
-_SEH2_TRY                                                               \
-{                                                                      \
-SidType##SAC = ProbeForReadUchar(&SidType->SubAuthorityCount);       \
-SidType##Size = RtlLengthRequiredSid(SidType##SAC);                  \
-DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG));            \
-ProbeForRead(SidType,                                                \
-SidType##Size,                                          \
-sizeof(ULONG));                                         \
-}                                                                      \
-_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)                                                            \
-{                                                                      \
-_SEH2_YIELD(return _SEH2_GetExceptionCode());                          \
-}                                                                      \
-_SEH2_END;                                                              \
-\
-}                                                                        \
-else                                                                     \
-{                                                                        \
-SidType##SAC = SidType->SubAuthorityCount;                             \
-SidType##Size = RtlLengthRequiredSid(SidType##SAC);                    \
-DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG));              \
-}                                                                        \
-}                                                                          \
-} while(0)
-        
-        DetermineSIDSize(Owner);
-        DetermineSIDSize(Group);
-        
-#undef DetermineSIDSize
-        
-        /* determine the size of the ACLs */
-#define DetermineACLSize(AclType, AclFlag)                                     \
-do {                                                                       \
-if((DescriptorCopy.Control & SE_##AclFlag##_PRESENT) &&                    \
-DescriptorCopy.AclType != NULL)                                         \
-{                                                                          \
-PACL AclType = (PACL)DescriptorCopy.AclType;                             \
-\
-if(CurrentMode != KernelMode)                                            \
-{                                                                        \
-/* securely access the buffers! */                                     \
-_SEH2_TRY                                                               \
-{                                                                      \
-AclType##Size = ProbeForReadUshort(&AclType->AclSize);               \
-DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG));            \
-ProbeForRead(AclType,                                                \
-AclType##Size,                                          \
-sizeof(ULONG));                                         \
-}                                                                      \
-_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)                                                            \
-{                                                                      \
-_SEH2_YIELD(return _SEH2_GetExceptionCode());                          \
-}                                                                      \
-_SEH2_END;                                                              \
-\
-}                                                                        \
-else                                                                     \
-{                                                                        \
-AclType##Size = AclType->AclSize;                                      \
-DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG));              \
-}                                                                        \
-}                                                                          \
-else                                                                       \
-{                                                                          \
-DescriptorCopy.AclType = NULL;                                           \
-}                                                                          \
-} while(0)
-        
-        DetermineACLSize(Sacl, SACL);
-        DetermineACLSize(Dacl, DACL);
-        
-#undef DetermineACLSize
-        
-        /* allocate enough memory to store a complete copy of a self-relative
-         security descriptor */
-        NewDescriptor = ExAllocatePoolWithTag(PoolType,
-                                              DescriptorSize,
-                                              TAG_SD);
-        if(NewDescriptor != NULL)
+
+        /* Now capture all fields and convert to an absolute descriptor */
+        DescriptorCopy.Revision = OriginalDescriptor->Revision;
+        DescriptorCopy.Sbz1 = OriginalDescriptor->Sbz1;
+        DescriptorCopy.Control = OriginalDescriptor->Control & ~SE_SELF_RELATIVE;
+        DescriptorCopy.Owner = SepGetOwnerFromDescriptor(OriginalDescriptor);
+        DescriptorCopy.Group = SepGetGroupFromDescriptor(OriginalDescriptor);
+        DescriptorCopy.Sacl = SepGetSaclFromDescriptor(OriginalDescriptor);
+        DescriptorCopy.Dacl = SepGetDaclFromDescriptor(OriginalDescriptor);
+        DescriptorSize = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
+
+        /* Determine owner and group sizes */
+        OwnerSize = DetermineSIDSize(DescriptorCopy.Owner, &OwnerSAC, CurrentMode);
+        DescriptorSize += ROUND_UP(OwnerSize, sizeof(ULONG));
+        GroupSize = DetermineSIDSize(DescriptorCopy.Group, &GroupSAC, CurrentMode);
+        DescriptorSize += ROUND_UP(GroupSize, sizeof(ULONG));
+
+        /* Determine the size of the ACLs */
+        if (DescriptorCopy.Control & SE_SACL_PRESENT)
         {
-            ULONG_PTR Offset = sizeof(SECURITY_DESCRIPTOR);
-            
-            RtlZeroMemory(NewDescriptor, DescriptorSize);
-            NewDescriptor->Revision = DescriptorCopy.Revision;
-            NewDescriptor->Sbz1 = DescriptorCopy.Sbz1;
-            NewDescriptor->Control = DescriptorCopy.Control | SE_SELF_RELATIVE;
-            
-            _SEH2_TRY
-            {
-                /* setup the offsets and copy the SIDs and ACLs to the new
-                 self-relative security descriptor. Probing the pointers is not
-                 neccessary anymore as we did that when collecting the sizes!
-                 Make sure to validate the SIDs and ACLs *again* as they could have
-                 been modified in the meanwhile! */
-#define CopySID(Type)                                                          \
-do {                                                                   \
-if(DescriptorCopy.Type != NULL)                                        \
-{                                                                      \
-NewDescriptor->Type = (PVOID)Offset;                                 \
-RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor +                     \
-(ULONG_PTR)NewDescriptor->Type),               \
-DescriptorCopy.Type,                                   \
-Type##Size);                                           \
-if (!RtlValidSid((PSID)((ULONG_PTR)NewDescriptor +                   \
-(ULONG_PTR)NewDescriptor->Type)))            \
-{                                                                    \
-RtlRaiseStatus(STATUS_INVALID_SID);                                \
-}                                                                    \
-Offset += ROUND_UP(Type##Size, sizeof(ULONG));                       \
-}                                                                      \
-} while(0)
-                
-                CopySID(Owner);
-                CopySID(Group);
-                
-#undef CopySID
-                
-#define CopyACL(Type)                                                          \
-do {                                                                   \
-if(DescriptorCopy.Type != NULL)                                        \
-{                                                                      \
-NewDescriptor->Type = (PVOID)Offset;                                 \
-RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor +                     \
-(ULONG_PTR)NewDescriptor->Type),               \
-DescriptorCopy.Type,                                   \
-Type##Size);                                           \
-if (!RtlValidAcl((PACL)((ULONG_PTR)NewDescriptor +                   \
-(ULONG_PTR)NewDescriptor->Type)))            \
-{                                                                    \
-RtlRaiseStatus(STATUS_INVALID_ACL);                                \
-}                                                                    \
-Offset += ROUND_UP(Type##Size, sizeof(ULONG));                       \
-}                                                                      \
-} while(0)
-                
-                CopyACL(Sacl);
-                CopyACL(Dacl);
-                
-#undef CopyACL
-            }
-            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-            {
-                /* we failed to copy the data to the new descriptor */
-                ExFreePool(NewDescriptor);
-                _SEH2_YIELD(return _SEH2_GetExceptionCode());
-            }
-            _SEH2_END;
-            
-            /* we're finally done! copy the pointer to the captured descriptor to
-             to the caller */
-            *CapturedSecurityDescriptor = NewDescriptor;
-            return STATUS_SUCCESS;
+            /* Get the size and probe if user mode */
+            SaclSize = DetermineACLSize(DescriptorCopy.Sacl, CurrentMode);
+            DescriptorSize += ROUND_UP(SaclSize, sizeof(ULONG));
+        }
 
+        if (DescriptorCopy.Control & SE_DACL_PRESENT)
+        {
+            /* Get the size and probe if user mode */
+            DaclSize = DetermineACLSize(DescriptorCopy.Dacl, CurrentMode);
+            DescriptorSize += ROUND_UP(DaclSize, sizeof(ULONG));
         }
-        else
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
+    }
+    _SEH2_END
+
+    /*
+     * Allocate enough memory to store a complete copy of a self-relative
+     * security descriptor
+     */
+    NewDescriptor = ExAllocatePoolWithTag(PoolType,
+                                          DescriptorSize,
+                                          TAG_SD);
+    if (!NewDescriptor) return STATUS_INSUFFICIENT_RESOURCES;
+
+    RtlZeroMemory(NewDescriptor, DescriptorSize);
+    NewDescriptor->Revision = DescriptorCopy.Revision;
+    NewDescriptor->Sbz1 = DescriptorCopy.Sbz1;
+    NewDescriptor->Control = DescriptorCopy.Control | SE_SELF_RELATIVE;
+
+    _SEH2_TRY
+    {
+        /*
+         * Setup the offsets and copy the SIDs and ACLs to the new
+         * self-relative security descriptor. Probing the pointers is not
+         * neccessary anymore as we did that when collecting the sizes!
+         * Make sure to validate the SIDs and ACLs *again* as they could have
+         * been modified in the meanwhile!
+         */
+        Offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
+
+        if (DescriptorCopy.Owner)
+        {
+            if (!RtlValidSid(DescriptorCopy.Owner)) RtlRaiseStatus(STATUS_INVALID_SID);
+            NewDescriptor->Owner = Offset;
+            RtlCopyMemory((PUCHAR)NewDescriptor + Offset,
+                          DescriptorCopy.Owner,
+                          OwnerSize);
+            Offset += ROUND_UP(OwnerSize, sizeof(ULONG));
+        }
+
+        if (DescriptorCopy.Group)
+        {
+            if (!RtlValidSid(DescriptorCopy.Group)) RtlRaiseStatus(STATUS_INVALID_SID);
+            NewDescriptor->Group = Offset;
+            RtlCopyMemory((PUCHAR)NewDescriptor + Offset,
+                          DescriptorCopy.Group,
+                          GroupSize);
+            Offset += ROUND_UP(GroupSize, sizeof(ULONG));
+        }
+
+        if (DescriptorCopy.Sacl)
         {
-            Status = STATUS_INSUFFICIENT_RESOURCES;
+            if (!RtlValidAcl(DescriptorCopy.Sacl)) RtlRaiseStatus(STATUS_INVALID_ACL);
+            NewDescriptor->Sacl = Offset;
+            RtlCopyMemory((PUCHAR)NewDescriptor + Offset,
+                          DescriptorCopy.Sacl,
+                          SaclSize);
+            Offset += ROUND_UP(SaclSize, sizeof(ULONG));
         }
+
+        if (DescriptorCopy.Dacl)
+        {
+            if (!RtlValidAcl(DescriptorCopy.Dacl)) RtlRaiseStatus(STATUS_INVALID_ACL);
+            NewDescriptor->Dacl = Offset;
+            RtlCopyMemory((PUCHAR)NewDescriptor + Offset,
+                          DescriptorCopy.Dacl,
+                          DaclSize);
+            Offset += ROUND_UP(DaclSize, sizeof(ULONG));
+        }
+
+        /* Make sure the size was correct */
+        ASSERT(Offset == DescriptorSize);
     }
-    else
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        /* nothing to do... */
-        *CapturedSecurityDescriptor = NULL;
+        /* We failed to copy the data to the new descriptor */
+        ExFreePoolWithTag(NewDescriptor, TAG_SD);
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
     }
-    
-    return Status;
+    _SEH2_END;
+
+    /*
+     * We're finally done!
+     * Copy the pointer to the captured descriptor to to the caller.
+     */
+    *CapturedSecurityDescriptor = NewDescriptor;
+    return STATUS_SUCCESS;
 }
 
 /*
@@ -721,9 +634,9 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
     ULONG Control = 0;
     ULONG_PTR Current;
     ULONG SdLength;
-    
+
     RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
-    
+
     if (*ObjectsSecurityDescriptor == NULL)
     {
         if (*Length < sizeof(SECURITY_DESCRIPTOR_RELATIVE))
@@ -731,15 +644,15 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
             *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
             return STATUS_BUFFER_TOO_SMALL;
         }
-        
+
         *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
         RtlCreateSecurityDescriptorRelative(RelSD,
                                             SECURITY_DESCRIPTOR_REVISION);
         return STATUS_SUCCESS;
     }
-    
+
     ObjectSd = *ObjectsSecurityDescriptor;
-    
+
     /* Calculate the required security descriptor length */
     Control = SE_SELF_RELATIVE;
     if ((*SecurityInformation & OWNER_SECURITY_INFORMATION) &&
@@ -749,7 +662,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
         OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
         Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED);
     }
-    
+
     if ((*SecurityInformation & GROUP_SECURITY_INFORMATION) &&
         (ObjectSd->Group != NULL))
     {
@@ -757,7 +670,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
         GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
         Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED);
     }
-    
+
     if ((*SecurityInformation & DACL_SECURITY_INFORMATION) &&
         (ObjectSd->Control & SE_DACL_PRESENT))
     {
@@ -766,9 +679,10 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
             Dacl = (PACL)((ULONG_PTR)ObjectSd->Dacl + (ULONG_PTR)ObjectSd);
             DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4);
         }
+
         Control |= (ObjectSd->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT));
     }
-    
+
     if ((*SecurityInformation & SACL_SECURITY_INFORMATION) &&
         (ObjectSd->Control & SE_SACL_PRESENT))
     {
@@ -777,9 +691,10 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
             Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd);
             SaclLength = ROUND_UP(Sacl->AclSize, 4);
         }
+
         Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
     }
-    
+
     SdLength = OwnerLength + GroupLength + DaclLength +
     SaclLength + sizeof(SECURITY_DESCRIPTOR_RELATIVE);
     if (*Length < SdLength)
@@ -787,14 +702,14 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
         *Length = SdLength;
         return STATUS_BUFFER_TOO_SMALL;
     }
-    
+
     /* Build the new security descrtiptor */
     RtlCreateSecurityDescriptorRelative(RelSD,
                                         SECURITY_DESCRIPTOR_REVISION);
     RelSD->Control = (USHORT)Control;
-    
+
     Current = (ULONG_PTR)(RelSD + 1);
-    
+
     if (OwnerLength != 0)
     {
         RtlCopyMemory((PVOID)Current,
@@ -803,7 +718,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
         RelSD->Owner = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
         Current += OwnerLength;
     }
-    
+
     if (GroupLength != 0)
     {
         RtlCopyMemory((PVOID)Current,
@@ -812,7 +727,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
         RelSD->Group = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
         Current += GroupLength;
     }
-    
+
     if (DaclLength != 0)
     {
         RtlCopyMemory((PVOID)Current,
@@ -821,7 +736,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
         RelSD->Dacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
         Current += DaclLength;
     }
-    
+
     if (SaclLength != 0)
     {
         RtlCopyMemory((PVOID)Current,
@@ -830,9 +745,9 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
         RelSD->Sacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
         Current += SaclLength;
     }
-    
+
     *Length = SdLength;
-    
+
     return STATUS_SUCCESS;
 }
 
@@ -846,18 +761,20 @@ SeReleaseSecurityDescriptor(IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor,
                             IN BOOLEAN CaptureIfKernelMode)
 {
     PAGED_CODE();
-    
-    /* WARNING! You need to call this function with the same value for CurrentMode
-     and CaptureIfKernelMode that you previously passed to
-     SeCaptureSecurityDescriptor() in order to avoid memory leaks! */
-    if(CapturedSecurityDescriptor != NULL &&
-       (CurrentMode != KernelMode ||
-        (CurrentMode == KernelMode && CaptureIfKernelMode)))
-    {
-        /* only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */
+
+    /*
+     * WARNING! You need to call this function with the same value for CurrentMode
+     * and CaptureIfKernelMode that you previously passed to
+     * SeCaptureSecurityDescriptor() in order to avoid memory leaks!
+     */
+    if (CapturedSecurityDescriptor != NULL &&
+        (CurrentMode != KernelMode ||
+         (CurrentMode == KernelMode && CaptureIfKernelMode)))
+    {
+        /* Only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */
         ExFreePoolWithTag(CapturedSecurityDescriptor, TAG_SD);
     }
-    
+
     return STATUS_SUCCESS;
 }
 
@@ -872,9 +789,10 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL,
                             IN POOL_TYPE PoolType,
                             IN PGENERIC_MAPPING GenericMapping)
 {
-    PISECURITY_DESCRIPTOR ObjectSd;
-    PISECURITY_DESCRIPTOR NewSd;
+    PISECURITY_DESCRIPTOR_RELATIVE ObjectSd;
+    PISECURITY_DESCRIPTOR_RELATIVE NewSd;
     PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor;
+    PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
     PSID Owner = 0;
     PSID Group = 0;
     PACL Dacl = 0;
@@ -884,40 +802,45 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL,
     ULONG DaclLength = 0;
     ULONG SaclLength = 0;
     ULONG Control = 0;
-    ULONG_PTR Current;
+    ULONG Current;
     SECURITY_INFORMATION SecurityInformation;
-    
+
     ObjectSd = *ObjectsSecurityDescriptor;
-    
+
+    /* The object does not have a security descriptor. */
     if (!ObjectSd)
-        return STATUS_NO_SECURITY_ON_OBJECT; // The object does not have a security descriptor.
-    
+        return STATUS_NO_SECURITY_ON_OBJECT;
+
+    ASSERT(ObjectSd->Control & SE_SELF_RELATIVE);
+
     SecurityInformation = *_SecurityInformation;
-    
+
     /* Get owner and owner size */
     if (SecurityInformation & OWNER_SECURITY_INFORMATION)
     {
         if (SecurityDescriptor->Owner != NULL)
         {
-            if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
-                Owner = (PSID)((ULONG_PTR)SecurityDescriptor->Owner +
+            if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
+                Owner = (PSID)((ULONG_PTR)RelSD->Owner +
                                (ULONG_PTR)SecurityDescriptor);
             else
                 Owner = (PSID)SecurityDescriptor->Owner;
             OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
         }
+
         Control |= (SecurityDescriptor->Control & SE_OWNER_DEFAULTED);
     }
     else
     {
-        if (ObjectSd->Owner != NULL)
+        if (ObjectSd->Owner)
         {
             Owner = (PSID)((ULONG_PTR)ObjectSd->Owner + (ULONG_PTR)ObjectSd);
             OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
         }
+
         Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED);
     }
-    
+
     /* Get group and group size */
     if (SecurityInformation & GROUP_SECURITY_INFORMATION)
     {
@@ -930,18 +853,20 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL,
                 Group = (PSID)SecurityDescriptor->Group;
             GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
         }
+
         Control |= (SecurityDescriptor->Control & SE_GROUP_DEFAULTED);
     }
     else
     {
-        if (ObjectSd->Group != NULL)
+        if (ObjectSd->Group)
         {
             Group = (PSID)((ULONG_PTR)ObjectSd->Group + (ULONG_PTR)ObjectSd);
             GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
         }
+
         Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED);
     }
-    
+
     /* Get DACL and DACL size */
     if (SecurityInformation & DACL_SECURITY_INFORMATION)
     {
@@ -953,22 +878,23 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL,
                               (ULONG_PTR)SecurityDescriptor);
             else
                 Dacl = (PACL)SecurityDescriptor->Dacl;
-            
+
             DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4);
         }
+
         Control |= (SecurityDescriptor->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT));
     }
     else
     {
-        if ((ObjectSd->Control & SE_DACL_PRESENT) &&
-            (ObjectSd->Dacl != NULL))
+        if ((ObjectSd->Control & SE_DACL_PRESENT) && (ObjectSd->Dacl))
         {
             Dacl = (PACL)((ULONG_PTR)ObjectSd->Dacl + (ULONG_PTR)ObjectSd);
             DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4);
         }
+
         Control |= (ObjectSd->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT));
     }
-    
+
     /* Get SACL and SACL size */
     if (SecurityInformation & SACL_SECURITY_INFORMATION)
     {
@@ -982,71 +908,65 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL,
                 Sacl = (PACL)SecurityDescriptor->Sacl;
             SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4);
         }
+
         Control |= (SecurityDescriptor->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
     }
     else
     {
-        if ((ObjectSd->Control & SE_SACL_PRESENT) &&
-            (ObjectSd->Sacl != NULL))
+        if ((ObjectSd->Control & SE_SACL_PRESENT) && (ObjectSd->Sacl))
         {
             Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd);
             SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4);
         }
+
         Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
     }
-    
+
     NewSd = ExAllocatePool(NonPagedPool,
-                           sizeof(SECURITY_DESCRIPTOR) + OwnerLength + GroupLength +
+                           sizeof(SECURITY_DESCRIPTOR_RELATIVE) + OwnerLength + GroupLength +
                            DaclLength + SaclLength);
     if (NewSd == NULL)
     {
         ObDereferenceObject(Object);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
-    
+
     RtlCreateSecurityDescriptor(NewSd,
                                 SECURITY_DESCRIPTOR_REVISION1);
+
     /* We always build a self-relative descriptor */
     NewSd->Control = (USHORT)Control | SE_SELF_RELATIVE;
-    
-    Current = (ULONG_PTR)NewSd + sizeof(SECURITY_DESCRIPTOR);
-    
+
+    Current = sizeof(SECURITY_DESCRIPTOR);
+
     if (OwnerLength != 0)
     {
-        RtlCopyMemory((PVOID)Current,
-                      Owner,
-                      OwnerLength);
-        NewSd->Owner = (PSID)(Current - (ULONG_PTR)NewSd);
+        RtlCopyMemory((PUCHAR)NewSd + Current, Owner, OwnerLength);
+        NewSd->Owner = Current;
         Current += OwnerLength;
     }
-    
+
     if (GroupLength != 0)
     {
-        RtlCopyMemory((PVOID)Current,
-                      Group,
-                      GroupLength);
-        NewSd->Group = (PSID)(Current - (ULONG_PTR)NewSd);
+        RtlCopyMemory((PUCHAR)NewSd + Current, Group, GroupLength);
+        NewSd->Group = Current;
         Current += GroupLength;
     }
-    
+
     if (DaclLength != 0)
     {
-        RtlCopyMemory((PVOID)Current,
-                      Dacl,
-                      DaclLength);
-        NewSd->Dacl = (PACL)(Current - (ULONG_PTR)NewSd);
+        RtlCopyMemory((PUCHAR)NewSd + Current, Dacl, DaclLength);
+        NewSd->Dacl = Current;
         Current += DaclLength;
     }
-    
+
     if (SaclLength != 0)
     {
-        RtlCopyMemory((PVOID)Current,
-                      Sacl,
-                      SaclLength);
-        NewSd->Sacl = (PACL)(Current - (ULONG_PTR)NewSd);
+        RtlCopyMemory((PUCHAR)NewSd + Current, Sacl, SaclLength);
+        NewSd->Sacl = Current;
         Current += SaclLength;
-    }    
-    
+    }
+
     *ObjectsSecurityDescriptor = NewSd;
     return STATUS_SUCCESS;
 }
@@ -1065,12 +985,13 @@ SeSetSecurityDescriptorInfoEx(IN PVOID Object OPTIONAL,
                               IN PGENERIC_MAPPING GenericMapping)
 {
     PISECURITY_DESCRIPTOR ObjectSd = *ObjectsSecurityDescriptor;
-    
+
+    /* The object does not have a security descriptor. */
     if (!ObjectSd)
-        return STATUS_NO_SECURITY_ON_OBJECT; // The object does not have a security descriptor.
-    
-       UNIMPLEMENTED;
-       return STATUS_NOT_IMPLEMENTED;
+        return STATUS_NO_SECURITY_ON_OBJECT;
+
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
 }
 
 
@@ -1084,71 +1005,71 @@ SeValidSecurityDescriptor(IN ULONG Length,
     ULONG SdLength;
     PISID Sid;
     PACL Acl;
-    PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor;
-    
+    PISECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor = _SecurityDescriptor;
+
     if (Length < SECURITY_DESCRIPTOR_MIN_LENGTH)
     {
         DPRINT1("Invalid Security Descriptor revision\n");
         return FALSE;
     }
-    
+
     if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
     {
         DPRINT1("Invalid Security Descriptor revision\n");
         return FALSE;
     }
-    
+
     if (!(SecurityDescriptor->Control & SE_SELF_RELATIVE))
     {
         DPRINT1("No self-relative Security Descriptor\n");
         return FALSE;
     }
-    
+
     SdLength = sizeof(SECURITY_DESCRIPTOR);
-    
+
     /* Check Owner SID */
-    if (SecurityDescriptor->Owner == NULL)
+    if (SecurityDescriptor->Owner)
     {
         DPRINT1("No Owner SID\n");
         return FALSE;
     }
-    
-    if ((ULONG_PTR)SecurityDescriptor->Owner % sizeof(ULONG))
+
+    if (SecurityDescriptor->Owner % sizeof(ULONG))
     {
         DPRINT1("Invalid Owner SID alignment\n");
         return FALSE;
     }
-    
-    Sid = (PISID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Owner);
+
+    Sid = (PISID)((ULONG_PTR)SecurityDescriptor + SecurityDescriptor->Owner);
     if (Sid->Revision != SID_REVISION)
     {
         DPRINT1("Invalid Owner SID revision\n");
         return FALSE;
     }
-    
+
     SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG));
     if (Length < SdLength)
     {
         DPRINT1("Invalid Owner SID size\n");
         return FALSE;
     }
-    
+
     /* Check Group SID */
-    if (SecurityDescriptor->Group != NULL)
+    if (SecurityDescriptor->Group)
     {
-        if ((ULONG_PTR)SecurityDescriptor->Group % sizeof(ULONG))
+        if (SecurityDescriptor->Group % sizeof(ULONG))
         {
             DPRINT1("Invalid Group SID alignment\n");
             return FALSE;
         }
-        
-        Sid = (PSID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Group);
+
+        Sid = (PSID)((ULONG_PTR)SecurityDescriptor + SecurityDescriptor->Group);
         if (Sid->Revision != SID_REVISION)
         {
             DPRINT1("Invalid Group SID revision\n");
             return FALSE;
         }
-        
+
         SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG));
         if (Length < SdLength)
         {
@@ -1156,24 +1077,24 @@ SeValidSecurityDescriptor(IN ULONG Length,
             return FALSE;
         }
     }
-    
+
     /* Check DACL */
-    if (SecurityDescriptor->Dacl != NULL)
+    if (SecurityDescriptor->Dacl)
     {
-        if ((ULONG_PTR)SecurityDescriptor->Dacl % sizeof(ULONG))
+        if (SecurityDescriptor->Dacl % sizeof(ULONG))
         {
             DPRINT1("Invalid DACL alignment\n");
             return FALSE;
         }
-        
-        Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Dacl);
+
+        Acl = (PACL)((ULONG_PTR)SecurityDescriptor + SecurityDescriptor->Dacl);
         if ((Acl->AclRevision < MIN_ACL_REVISION) &&
             (Acl->AclRevision > MAX_ACL_REVISION))
         {
             DPRINT1("Invalid DACL revision\n");
             return FALSE;
         }
-        
+
         SdLength += Acl->AclSize;
         if (Length < SdLength)
         {
@@ -1181,24 +1102,24 @@ SeValidSecurityDescriptor(IN ULONG Length,
             return FALSE;
         }
     }
-    
+
     /* Check SACL */
-    if (SecurityDescriptor->Sacl != NULL)
+    if (SecurityDescriptor->Sacl)
     {
-        if ((ULONG_PTR)SecurityDescriptor->Sacl % sizeof(ULONG))
+        if (SecurityDescriptor->Sacl % sizeof(ULONG))
         {
             DPRINT1("Invalid SACL alignment\n");
             return FALSE;
         }
-        
-        Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Sacl);
+
+        Acl = (PACL)((ULONG_PTR)SecurityDescriptor + SecurityDescriptor->Sacl);
         if ((Acl->AclRevision < MIN_ACL_REVISION) ||
             (Acl->AclRevision > MAX_ACL_REVISION))
         {
             DPRINT1("Invalid SACL revision\n");
             return FALSE;
         }
-        
+
         SdLength += Acl->AclSize;
         if (Length < SdLength)
         {
@@ -1206,7 +1127,7 @@ SeValidSecurityDescriptor(IN ULONG Length,
             return FALSE;
         }
     }
-    
+
     return TRUE;
 }
 
@@ -1217,17 +1138,18 @@ NTSTATUS NTAPI
 SeDeassignSecurity(PSECURITY_DESCRIPTOR *SecurityDescriptor)
 {
     PAGED_CODE();
-    
+
     if (*SecurityDescriptor != NULL)
     {
-        ExFreePool(*SecurityDescriptor);
+        ExFreePoolWithTag(*SecurityDescriptor, TAG_SD);
         *SecurityDescriptor = NULL;
     }
-    
+
     return STATUS_SUCCESS;
 }
 
 
+
 /*
  * @unimplemented
  */
@@ -1260,7 +1182,7 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL,
 {
     PISECURITY_DESCRIPTOR ParentDescriptor = _ParentDescriptor;
     PISECURITY_DESCRIPTOR ExplicitDescriptor = _ExplicitDescriptor;
-    PISECURITY_DESCRIPTOR Descriptor;
+    PISECURITY_DESCRIPTOR_RELATIVE Descriptor;
     PTOKEN Token;
     ULONG OwnerLength = 0;
     ULONG GroupLength = 0;
@@ -1268,17 +1190,17 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL,
     ULONG SaclLength = 0;
     ULONG Length = 0;
     ULONG Control = 0;
-    ULONG_PTR Current;
+    ULONG Current;
     PSID Owner = NULL;
     PSID Group = NULL;
     PACL Dacl = NULL;
     PACL Sacl = NULL;
-    
+
     PAGED_CODE();
-    
+
     /* Lock subject context */
     SeLockSubjectContext(SubjectContext);
-    
+
     if (SubjectContext->ClientToken != NULL)
     {
         Token = SubjectContext->ClientToken;
@@ -1287,21 +1209,15 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL,
     {
         Token = SubjectContext->PrimaryToken;
     }
-    
-    
+
     /* Inherit the Owner SID */
-    if (ExplicitDescriptor != NULL && ExplicitDescriptor->Owner != NULL)
+    if (ExplicitDescriptor != NULL)
     {
         DPRINT("Use explicit owner sid!\n");
-        Owner = ExplicitDescriptor->Owner;
-        
-        if (ExplicitDescriptor->Control & SE_SELF_RELATIVE)
-        {
-            Owner = (PSID)(((ULONG_PTR)Owner) + (ULONG_PTR)ExplicitDescriptor);
-            
-        }
+        Owner = SepGetOwnerFromDescriptor(ExplicitDescriptor);
     }
-    else
+
+    if (!Owner)
     {
         if (Token != NULL)
         {
@@ -1313,24 +1229,19 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL,
             DPRINT("Use default owner sid!\n");
             Owner = SeLocalSystemSid;
         }
-        
+
         Control |= SE_OWNER_DEFAULTED;
     }
-    
+
     OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
-    
-    
+
     /* Inherit the Group SID */
-    if (ExplicitDescriptor != NULL && ExplicitDescriptor->Group != NULL)
+    if (ExplicitDescriptor != NULL)
     {
-        DPRINT("Use explicit group sid!\n");
-        Group = ExplicitDescriptor->Group;
-        if (ExplicitDescriptor->Control & SE_SELF_RELATIVE)
-        {
-            Group = (PSID)(((ULONG_PTR)Group) + (ULONG_PTR)ExplicitDescriptor);
-        }
+        Group = SepGetGroupFromDescriptor(ExplicitDescriptor);
     }
-    else
+
+    if (!Group)
     {
         if (Token != NULL)
         {
@@ -1342,25 +1253,19 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL,
             DPRINT("Use default group sid!\n");
             Group = SeLocalSystemSid;
         }
-        
-        Control |= SE_OWNER_DEFAULTED;
+
+        Control |= SE_GROUP_DEFAULTED;
     }
-    
+
     GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
-    
-    
+
     /* Inherit the DACL */
     if (ExplicitDescriptor != NULL &&
         (ExplicitDescriptor->Control & SE_DACL_PRESENT) &&
         !(ExplicitDescriptor->Control & SE_DACL_DEFAULTED))
     {
         DPRINT("Use explicit DACL!\n");
-        Dacl = ExplicitDescriptor->Dacl;
-        if (Dacl != NULL && (ExplicitDescriptor->Control & SE_SELF_RELATIVE))
-        {
-            Dacl = (PACL)(((ULONG_PTR)Dacl) + (ULONG_PTR)ExplicitDescriptor);
-        }
-        
+        Dacl = SepGetDaclFromDescriptor(ExplicitDescriptor);
         Control |= SE_DACL_PRESENT;
     }
     else if (ParentDescriptor != NULL &&
@@ -1368,11 +1273,7 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL,
     {
         DPRINT("Use parent DACL!\n");
         /* FIXME: Inherit */
-        Dacl = ParentDescriptor->Dacl;
-        if (Dacl != NULL && (ParentDescriptor->Control & SE_SELF_RELATIVE))
-        {
-            Dacl = (PACL)(((ULONG_PTR)Dacl) + (ULONG_PTR)ParentDescriptor);
-        }
+        Dacl = SepGetDaclFromDescriptor(ParentDescriptor);
         Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED);
     }
     else if (Token != NULL && Token->DefaultDacl != NULL)
@@ -1388,22 +1289,16 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL,
         Dacl = NULL;
         Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED);
     }
-    
+
     DaclLength = (Dacl != NULL) ? ROUND_UP(Dacl->AclSize, 4) : 0;
-    
-    
+
     /* Inherit the SACL */
     if (ExplicitDescriptor != NULL &&
         (ExplicitDescriptor->Control & SE_SACL_PRESENT) &&
         !(ExplicitDescriptor->Control & SE_SACL_DEFAULTED))
     {
         DPRINT("Use explicit SACL!\n");
-        Sacl = ExplicitDescriptor->Sacl;
-        if (Sacl != NULL && (ExplicitDescriptor->Control & SE_SELF_RELATIVE))
-        {
-            Sacl = (PACL)(((ULONG_PTR)Sacl) + (ULONG_PTR)ExplicitDescriptor);
-        }
-        
+        Sacl = SepGetSaclFromDescriptor(ExplicitDescriptor);
         Control |= SE_SACL_PRESENT;
     }
     else if (ParentDescriptor != NULL &&
@@ -1411,92 +1306,78 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL,
     {
         DPRINT("Use parent SACL!\n");
         /* FIXME: Inherit */
-        Sacl = ParentDescriptor->Sacl;
-        if (Sacl != NULL && (ParentDescriptor->Control & SE_SELF_RELATIVE))
-        {
-            Sacl = (PACL)(((ULONG_PTR)Sacl) + (ULONG_PTR)ParentDescriptor);
-        }
+        Sacl = SepGetSaclFromDescriptor(ParentDescriptor);
         Control |= (SE_SACL_PRESENT | SE_SACL_DEFAULTED);
     }
-    
+
     SaclLength = (Sacl != NULL) ? ROUND_UP(Sacl->AclSize, 4) : 0;
-    
-    
+
     /* Allocate and initialize the new security descriptor */
-    Length = sizeof(SECURITY_DESCRIPTOR) +
-    OwnerLength + GroupLength + DaclLength + SaclLength;
-    
+    Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE) +
+        OwnerLength + GroupLength + DaclLength + SaclLength;
+
     DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n",
            sizeof(SECURITY_DESCRIPTOR),
            OwnerLength,
            GroupLength,
            DaclLength,
            SaclLength);
-    
-    Descriptor = ExAllocatePoolWithTag(PagedPool,
-                                       Length,
-                                       TAG_SD);
+
+    Descriptor = ExAllocatePoolWithTag(PagedPool, Length, TAG_SD);
     if (Descriptor == NULL)
     {
         DPRINT1("ExAlloctePool() failed\n");
         /* FIXME: Unlock subject context */
         return STATUS_INSUFFICIENT_RESOURCES;
     }
-    
-    RtlZeroMemory( Descriptor, Length );
-    RtlCreateSecurityDescriptor(Descriptor,
-                                SECURITY_DESCRIPTOR_REVISION);
-    
+
+    RtlZeroMemory(Descriptor, Length);
+    RtlCreateSecurityDescriptor(Descriptor, SECURITY_DESCRIPTOR_REVISION);
+
     Descriptor->Control = (USHORT)Control | SE_SELF_RELATIVE;
-    
-    Current = (ULONG_PTR)Descriptor + sizeof(SECURITY_DESCRIPTOR);
-    
+
+    Current = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
+
     if (SaclLength != 0)
     {
-        RtlCopyMemory((PVOID)Current,
-                      Sacl,
-                      SaclLength);
-        Descriptor->Sacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
+        RtlCopyMemory((PUCHAR)Descriptor + Current, Sacl, SaclLength);
+        Descriptor->Sacl = Current;
         Current += SaclLength;
     }
-    
+
     if (DaclLength != 0)
     {
-        RtlCopyMemory((PVOID)Current,
-                      Dacl,
-                      DaclLength);
-        Descriptor->Dacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
+        RtlCopyMemory((PUCHAR)Descriptor + Current, Dacl, DaclLength);
+        Descriptor->Dacl = Current;
         Current += DaclLength;
     }
-    
+
     if (OwnerLength != 0)
     {
-        RtlCopyMemory((PVOID)Current,
-                      Owner,
-                      OwnerLength);
-        Descriptor->Owner = (PSID)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
+        RtlCopyMemory((PUCHAR)Descriptor + Current, Owner, OwnerLength);
+        Descriptor->Owner = Current;
         Current += OwnerLength;
         DPRINT("Owner of %x at %x\n", Descriptor, Descriptor->Owner);
     }
     else
+    {
         DPRINT("Owner of %x is zero length\n", Descriptor);
-    
+    }
+
     if (GroupLength != 0)
     {
-        memmove((PVOID)Current,
-                Group,
-                GroupLength);
-        Descriptor->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
+        RtlCopyMemory((PUCHAR)Descriptor + Current, Group, GroupLength);
+        Descriptor->Group = Current;
     }
-    
+
     /* Unlock subject context */
     SeUnlockSubjectContext(SubjectContext);
-    
+
     *NewDescriptor = Descriptor;
-    
+
     DPRINT("Descrptor %x\n", Descriptor);
     ASSERT(RtlLengthSecurityDescriptor(Descriptor));
-    
+
     return STATUS_SUCCESS;
 }