[FORMATTING]
[reactos.git] / reactos / ntoskrnl / se / sd.c
index 93f4803..0e0eadc 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/se/sd.c
@@ -8,17 +7,17 @@
  * PROGRAMMERS:     David Welch <welch@cwcom.net>
  */
 
-/* INCLUDES *****************************************************************/
+/* INCLUDES *******************************************************************/
 
 #include <ntoskrnl.h>
-#include <internal/debug.h>
+#define NDEBUG
+#include <debug.h>
 
 #if defined (ALLOC_PRAGMA)
 #pragma alloc_text(INIT, SepInitSDs)
 #endif
 
-
-/* GLOBALS ******************************************************************/
+/* GLOBALS ********************************************************************/
 
 PSECURITY_DESCRIPTOR SePublicDefaultSd = NULL;
 PSECURITY_DESCRIPTOR SePublicDefaultUnrestrictedSd = NULL;
@@ -27,92 +26,92 @@ PSECURITY_DESCRIPTOR SePublicOpenUnrestrictedSd = NULL;
 PSECURITY_DESCRIPTOR SeSystemDefaultSd = NULL;
 PSECURITY_DESCRIPTOR SeUnrestrictedSd = NULL;
 
-/* FUNCTIONS ***************************************************************/
+/* PRIVATE FUNCTIONS **********************************************************/
 
 BOOLEAN
 INIT_FUNCTION
 NTAPI
 SepInitSDs(VOID)
 {
-  /* Create PublicDefaultSd */
-  SePublicDefaultSd = ExAllocatePoolWithTag(PagedPool,
-                                    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;
+    /* Create PublicDefaultSd */
+    SePublicDefaultSd = ExAllocatePoolWithTag(PagedPool,
+                                              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;
 }
 
 NTSTATUS
@@ -121,93 +120,93 @@ SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation,
                              PISECURITY_DESCRIPTOR SecurityDescriptor,
                              PULONG BufferLength)
 {
-  ULONG_PTR Current;
-  ULONG SidSize;
-  ULONG SdSize;
-  NTSTATUS Status;
-  PISECURITY_DESCRIPTOR_RELATIVE SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
+    ULONG_PTR Current;
+    ULONG SidSize;
+    ULONG SdSize;
+    NTSTATUS Status;
+    PISECURITY_DESCRIPTOR_RELATIVE SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
 
-  DPRINT("SeSetWorldSecurityDescriptor() called\n");
+    DPRINT("SeSetWorldSecurityDescriptor() called\n");
 
-  if (SecurityInformation == 0)
+    if (SecurityInformation == 0)
     {
-      return STATUS_ACCESS_DENIED;
+        return STATUS_ACCESS_DENIED;
     }
 
-  /* calculate the minimum size of the buffer */
-  SidSize = RtlLengthSid(SeWorldSid);
-  SdSize = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
-  if (SecurityInformation & OWNER_SECURITY_INFORMATION)
-      SdSize += SidSize;
-  if (SecurityInformation & GROUP_SECURITY_INFORMATION)
-      SdSize += SidSize;
-  if (SecurityInformation & DACL_SECURITY_INFORMATION)
+    /* calculate the minimum size of the buffer */
+    SidSize = RtlLengthSid(SeWorldSid);
+    SdSize = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
+    if (SecurityInformation & OWNER_SECURITY_INFORMATION)
+        SdSize += SidSize;
+    if (SecurityInformation & GROUP_SECURITY_INFORMATION)
+        SdSize += SidSize;
+    if (SecurityInformation & DACL_SECURITY_INFORMATION)
     {
-      SdSize += sizeof(ACL) + sizeof(ACE) + SidSize;
+        SdSize += sizeof(ACL) + sizeof(ACE) + SidSize;
     }
 
-  if (*BufferLength < SdSize)
+    if (*BufferLength < SdSize)
     {
-      *BufferLength = SdSize;
-      return STATUS_BUFFER_TOO_SMALL;
+        *BufferLength = SdSize;
+        return STATUS_BUFFER_TOO_SMALL;
     }
 
-  *BufferLength = SdSize;
+    *BufferLength = SdSize;
 
-  Status = RtlCreateSecurityDescriptorRelative(SdRel,
-                                               SECURITY_DESCRIPTOR_REVISION);
-  if (!NT_SUCCESS(Status))
+    Status = RtlCreateSecurityDescriptorRelative(SdRel,
+                                                 SECURITY_DESCRIPTOR_REVISION);
+    if (!NT_SUCCESS(Status))
     {
-      return Status;
+        return Status;
     }
 
-  Current = (ULONG_PTR)(SdRel + 1);
+    Current = (ULONG_PTR)(SdRel + 1);
 
-  if (SecurityInformation & OWNER_SECURITY_INFORMATION)
+    if (SecurityInformation & OWNER_SECURITY_INFORMATION)
     {
-      RtlCopyMemory((PVOID)Current,
-                    SeWorldSid,
-                    SidSize);
-      SdRel->Owner = (DWORD)((ULONG_PTR)Current - (ULONG_PTR)SdRel);
-      Current += SidSize;
+        RtlCopyMemory((PVOID)Current,
+                      SeWorldSid,
+                      SidSize);
+        SdRel->Owner = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel);
+        Current += SidSize;
     }
 
-  if (SecurityInformation & GROUP_SECURITY_INFORMATION)
+    if (SecurityInformation & GROUP_SECURITY_INFORMATION)
     {
-      RtlCopyMemory((PVOID)Current,
-                    SeWorldSid,
-                    SidSize);
-      SdRel->Group = (DWORD)((ULONG_PTR)Current - (ULONG_PTR)SdRel);
-      Current += SidSize;
+        RtlCopyMemory((PVOID)Current,
+                      SeWorldSid,
+                      SidSize);
+        SdRel->Group = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel);
+        Current += SidSize;
     }
 
-  if (SecurityInformation & DACL_SECURITY_INFORMATION)
+    if (SecurityInformation & DACL_SECURITY_INFORMATION)
     {
-      PACL Dacl = (PACL)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 = (DWORD)((ULONG_PTR)Current - (ULONG_PTR)SdRel);
+        PACL Dacl = (PACL)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);
     }
 
-  if (SecurityInformation & SACL_SECURITY_INFORMATION)
+    if (SecurityInformation & SACL_SECURITY_INFORMATION)
     {
-      /* FIXME - SdRel->Control |= SE_SACL_PRESENT; */
+        /* FIXME - SdRel->Control |= SE_SACL_PRESENT; */
     }
 
-  return STATUS_SUCCESS;
+    return STATUS_SUCCESS;
 }
 
 
@@ -220,146 +219,148 @@ SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIO
                                    OUT PSECURITY_QUALITY_OF_SERVICE *CapturedSecurityQualityOfService,
                                    OUT PBOOLEAN Present)
 {
-  PSECURITY_QUALITY_OF_SERVICE CapturedQos;
-  NTSTATUS Status = STATUS_SUCCESS;
+    PSECURITY_QUALITY_OF_SERVICE CapturedQos;
+    NTSTATUS Status = STATUS_SUCCESS;
 
-  PAGED_CODE();
+    PAGED_CODE();
 
-  ASSERT(CapturedSecurityQualityOfService);
-  ASSERT(Present);
+    ASSERT(CapturedSecurityQualityOfService);
+    ASSERT(Present);
 
-  if(ObjectAttributes != NULL)
-  {
-    if(AccessMode != KernelMode)
+    if (ObjectAttributes != NULL)
     {
-      SECURITY_QUALITY_OF_SERVICE SafeQos;
-
-      _SEH_TRY
-      {
-        ProbeForRead(ObjectAttributes,
-                     sizeof(ObjectAttributes),
-                     sizeof(ULONG));
-        if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
+        if (AccessMode != KernelMode)
         {
-          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))
+            SECURITY_QUALITY_OF_SERVICE SafeQos;
+
+            _SEH2_TRY
             {
-              /* 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));
-              *Present = TRUE;
+                ProbeForRead(ObjectAttributes,
+                             sizeof(OBJECT_ATTRIBUTES),
+                             sizeof(ULONG));
+                if (ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
+                {
+                    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))
+                        {
+                            /*
+                             * 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));
+                            *Present = TRUE;
+                        }
+                        else
+                        {
+                            Status = STATUS_INVALID_PARAMETER;
+                        }
+                    }
+                    else
+                    {
+                        *CapturedSecurityQualityOfService = NULL;
+                        *Present = FALSE;
+                    }
+                }
+                else
+                {
+                    Status = STATUS_INVALID_PARAMETER;
+                }
             }
-            else
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-              Status = STATUS_INVALID_PARAMETER;
+                Status = _SEH2_GetExceptionCode();
+            }
+            _SEH2_END;
+
+            if (NT_SUCCESS(Status))
+            {
+                if (*Present)
+                {
+                    CapturedQos = ExAllocatePool(PoolType,
+                                                 sizeof(SECURITY_QUALITY_OF_SERVICE));
+                    if (CapturedQos != NULL)
+                    {
+                        RtlCopyMemory(CapturedQos,
+                                      &SafeQos,
+                                      sizeof(SECURITY_QUALITY_OF_SERVICE));
+                        *CapturedSecurityQualityOfService = CapturedQos;
+                    }
+                    else
+                    {
+                        Status = STATUS_INSUFFICIENT_RESOURCES;
+                    }
+                }
+                else
+                {
+                    *CapturedSecurityQualityOfService = NULL;
+                }
             }
-          }
-          else
-          {
-            *CapturedSecurityQualityOfService = NULL;
-            *Present = FALSE;
-          }
-        }
-        else
-        {
-          Status = STATUS_INVALID_PARAMETER;
-        }
-      }
-      _SEH_HANDLE
-      {
-        Status = _SEH_GetExceptionCode();
-      }
-      _SEH_END;
-
-      if(NT_SUCCESS(Status))
-      {
-        if(*Present)
-        {
-          CapturedQos = ExAllocatePool(PoolType,
-                                       sizeof(SECURITY_QUALITY_OF_SERVICE));
-          if(CapturedQos != NULL)
-          {
-            RtlCopyMemory(CapturedQos,
-                          &SafeQos,
-                          sizeof(SECURITY_QUALITY_OF_SERVICE));
-            *CapturedSecurityQualityOfService = CapturedQos;
-          }
-          else
-          {
-            Status = STATUS_INSUFFICIENT_RESOURCES;
-          }
         }
         else
         {
-          *CapturedSecurityQualityOfService = NULL;
-        }
-      }
-    }
-    else
-    {
-      if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
-      {
-        if(CaptureIfKernel)
-        {
-          if(ObjectAttributes->SecurityQualityOfService != NULL)
-          {
-            if(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length ==
-               sizeof(SECURITY_QUALITY_OF_SERVICE))
+            if (ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
             {
-              CapturedQos = ExAllocatePool(PoolType,
-                                           sizeof(SECURITY_QUALITY_OF_SERVICE));
-              if(CapturedQos != NULL)
-              {
-                RtlCopyMemory(CapturedQos,
-                              ObjectAttributes->SecurityQualityOfService,
-                              sizeof(SECURITY_QUALITY_OF_SERVICE));
-                *CapturedSecurityQualityOfService = CapturedQos;
-                *Present = TRUE;
-              }
-              else
-              {
-                Status = STATUS_INSUFFICIENT_RESOURCES;
-              }
+                if (CaptureIfKernel)
+                {
+                    if (ObjectAttributes->SecurityQualityOfService != NULL)
+                    {
+                        if (((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length ==
+                            sizeof(SECURITY_QUALITY_OF_SERVICE))
+                        {
+                            CapturedQos = ExAllocatePool(PoolType,
+                                                         sizeof(SECURITY_QUALITY_OF_SERVICE));
+                            if (CapturedQos != NULL)
+                            {
+                                RtlCopyMemory(CapturedQos,
+                                              ObjectAttributes->SecurityQualityOfService,
+                                              sizeof(SECURITY_QUALITY_OF_SERVICE));
+                                *CapturedSecurityQualityOfService = CapturedQos;
+                                *Present = TRUE;
+                            }
+                            else
+                            {
+                                Status = STATUS_INSUFFICIENT_RESOURCES;
+                            }
+                        }
+                        else
+                        {
+                            Status = STATUS_INVALID_PARAMETER;
+                        }
+                    }
+                    else
+                    {
+                        *CapturedSecurityQualityOfService = NULL;
+                        *Present = FALSE;
+                    }
+                }
+                else
+                {
+                    *CapturedSecurityQualityOfService = (PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService;
+                    *Present = (ObjectAttributes->SecurityQualityOfService != NULL);
+                }
             }
             else
             {
-              Status = STATUS_INVALID_PARAMETER;
+                Status = STATUS_INVALID_PARAMETER;
             }
-          }
-          else
-          {
-            *CapturedSecurityQualityOfService = NULL;
-            *Present = FALSE;
-          }
-        }
-        else
-        {
-          *CapturedSecurityQualityOfService = (PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService;
-          *Present = (ObjectAttributes->SecurityQualityOfService != NULL);
         }
-      }
-      else
-      {
-        Status = STATUS_INVALID_PARAMETER;
-      }
-    }
-  }
-  else
-  {
-    *CapturedSecurityQualityOfService = NULL;
-    *Present = FALSE;
-  }
-
-  return Status;
+    }
+    else
+    {
+        *CapturedSecurityQualityOfService = NULL;
+        *Present = FALSE;
+    }
+
+    return Status;
 }
 
 
@@ -369,687 +370,1160 @@ SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecur
                                    IN KPROCESSOR_MODE AccessMode,
                                    IN BOOLEAN CaptureIfKernel)
 {
-  PAGED_CODE();
+    PAGED_CODE();
 
-  if(CapturedSecurityQualityOfService != NULL &&
-     (AccessMode != KernelMode || CaptureIfKernel))
-  {
-    ExFreePool(CapturedSecurityQualityOfService);
-  }
+    if (CapturedSecurityQualityOfService != NULL &&
+        (AccessMode != KernelMode || CaptureIfKernel))
+    {
+        ExFreePool(CapturedSecurityQualityOfService);
+    }
 }
 
+/* PUBLIC FUNCTIONS ***********************************************************/
 
 /*
  * @implemented
  */
 NTSTATUS
-STDCALL
-SeCaptureSecurityDescriptor(
-       IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor,
-       IN KPROCESSOR_MODE CurrentMode,
-       IN POOL_TYPE PoolType,
-       IN BOOLEAN CaptureIfKernel,
-       OUT PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor
-       )
+NTAPI
+SeCaptureSecurityDescriptor(IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor,
+                            IN KPROCESSOR_MODE CurrentMode,
+                            IN POOL_TYPE PoolType,
+                            IN BOOLEAN CaptureIfKernel,
+                            OUT PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor)
 {
-  PISECURITY_DESCRIPTOR OriginalSecurityDescriptor = _OriginalSecurityDescriptor;
-  SECURITY_DESCRIPTOR DescriptorCopy;
-  PISECURITY_DESCRIPTOR NewDescriptor;
-  ULONG OwnerSAC = 0, GroupSAC = 0;
-  ULONG OwnerSize = 0, GroupSize = 0;
-  ULONG SaclSize = 0, DaclSize = 0;
-  ULONG DescriptorSize = 0;
-  NTSTATUS Status = STATUS_SUCCESS;
-
-  if(OriginalSecurityDescriptor != NULL)
-  {
-    if(CurrentMode != KernelMode)
-    {
-      RtlZeroMemory(&DescriptorCopy, sizeof(DescriptorCopy));
-
-      _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,
-                     DescriptorSize,
-                     sizeof(ULONG));
-
-        if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
+    PISECURITY_DESCRIPTOR OriginalSecurityDescriptor = _OriginalSecurityDescriptor;
+    SECURITY_DESCRIPTOR DescriptorCopy;
+    PISECURITY_DESCRIPTOR NewDescriptor;
+    ULONG OwnerSAC = 0, GroupSAC = 0;
+    ULONG OwnerSize = 0, GroupSize = 0;
+    ULONG SaclSize = 0, DaclSize = 0;
+    ULONG DescriptorSize = 0;
+    NTSTATUS Status;
+
+    if (OriginalSecurityDescriptor != NULL)
+    {
+        if (CurrentMode != KernelMode)
         {
-          Status = STATUS_UNKNOWN_REVISION;
-          _SEH_LEAVE;
-        }
+            RtlZeroMemory(&DescriptorCopy, sizeof(DescriptorCopy));
 
-        /* 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)
+            _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;
+        }
+        else if (!CaptureIfKernel)
         {
-          PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor;
+            if (OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
+            {
+                return STATUS_UNKNOWN_REVISION;
+            }
 
-          DescriptorCopy.Owner = (PSID)RelSD->Owner;
-          DescriptorCopy.Group = (PSID)RelSD->Group;
-          DescriptorCopy.Sacl = (PACL)RelSD->Sacl;
-          DescriptorCopy.Dacl = (PACL)RelSD->Dacl;
+            *CapturedSecurityDescriptor = OriginalSecurityDescriptor;
+            return STATUS_SUCCESS;
         }
         else
         {
-          DescriptorCopy.Owner = OriginalSecurityDescriptor->Owner;
-          DescriptorCopy.Group = OriginalSecurityDescriptor->Group;
-          DescriptorCopy.Sacl = OriginalSecurityDescriptor->Sacl;
-          DescriptorCopy.Dacl = OriginalSecurityDescriptor->Dacl;
+            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;
+            }
         }
-      }
-      _SEH_HANDLE
-      {
-        Status = _SEH_GetExceptionCode();
-      }
-      _SEH_END;
-
-      if(!NT_SUCCESS(Status))
-      {
-        return Status;
-      }
-    }
-    else if(!CaptureIfKernel)
-    {
-      if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
-      {
-        return STATUS_UNKNOWN_REVISION;
-      }
 
-      *CapturedSecurityDescriptor = OriginalSecurityDescriptor;
-      return STATUS_SUCCESS;
-    }
-    else
-    {
-      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;
-      }
-    }
-
-    if(DescriptorCopy.Control & SE_SELF_RELATIVE)
-    {
-      /* 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);
-      }
-    }
-
-    /* determine the size of the SIDs */
+        if (DescriptorCopy.Control & SE_SELF_RELATIVE)
+        {
+            /*
+             * 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);
+            }
+        }
+
+        /* 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! */                                     \
-        _SEH_TRY                                                               \
-        {                                                                      \
-          ProbeForRead(&SidType->SubAuthorityCount,                            \
-                       sizeof(SidType->SubAuthorityCount),                     \
-                       1);                                                     \
-          SidType##SAC = SidType->SubAuthorityCount;                           \
-          SidType##Size = RtlLengthRequiredSid(SidType##SAC);                  \
-          DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG));            \
-          ProbeForRead(SidType,                                                \
-                       SidType##Size,                                          \
-                       sizeof(ULONG));                                         \
-        }                                                                      \
-        _SEH_HANDLE                                                            \
-        {                                                                      \
-          Status = _SEH_GetExceptionCode();                                    \
-        }                                                                      \
-        _SEH_END;                                                              \
-                                                                               \
-        if(!NT_SUCCESS(Status))                                                \
-        {                                                                      \
-          return Status;                                                       \
-        }                                                                      \
-      }                                                                        \
-      else                                                                     \
-      {                                                                        \
-        SidType##SAC = SidType->SubAuthorityCount;                             \
-        SidType##Size = RtlLengthRequiredSid(SidType##SAC);                    \
-        DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG));              \
-      }                                                                        \
-    }                                                                          \
-    } while(0)
-
-    DetermineSIDSize(Owner);
-    DetermineSIDSize(Group);
-
-    /* determine the size of the ACLs */
+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! */                                     \
-        _SEH_TRY                                                               \
-        {                                                                      \
-          ProbeForRead(&AclType->AclSize,                                      \
-                       sizeof(AclType->AclSize),                               \
-                       1);                                                     \
-          AclType##Size = AclType->AclSize;                                    \
-          DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG));            \
-          ProbeForRead(AclType,                                                \
-                       AclType##Size,                                          \
-                       sizeof(ULONG));                                         \
-        }                                                                      \
-        _SEH_HANDLE                                                            \
-        {                                                                      \
-          Status = _SEH_GetExceptionCode();                                    \
-        }                                                                      \
-        _SEH_END;                                                              \
-                                                                               \
-        if(!NT_SUCCESS(Status))                                                \
-        {                                                                      \
-          return Status;                                                       \
-        }                                                                      \
-      }                                                                        \
-      else                                                                     \
-      {                                                                        \
-        AclType##Size = AclType->AclSize;                                      \
-        DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG));              \
-      }                                                                        \
-    }                                                                          \
-    else                                                                       \
-    {                                                                          \
-      DescriptorCopy.AclType = NULL;                                           \
-    }                                                                          \
-    } while(0)
-
-    DetermineACLSize(Sacl, SACL);
-    DetermineACLSize(Dacl, DACL);
-
-    /* allocate enough memory to store a complete copy of a self-relative
-       security descriptor */
-    NewDescriptor = ExAllocatePool(PoolType,
-                                   DescriptorSize);
-    if(NewDescriptor != NULL)
-    {
-      ULONG_PTR Offset = sizeof(SECURITY_DESCRIPTOR);
-
-      RtlZeroMemory(NewDescriptor, DescriptorSize);
-      NewDescriptor->Revision = DescriptorCopy.Revision;
-      NewDescriptor->Sbz1 = DescriptorCopy.Sbz1;
-      NewDescriptor->Control = DescriptorCopy.Control | SE_SELF_RELATIVE;
-
-      _SEH_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! */
+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)
+        {
+            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);
+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);
-      }
-      _SEH_HANDLE
-      {
-        Status = _SEH_GetExceptionCode();
-      }
-      _SEH_END;
-
-      if(NT_SUCCESS(Status))
-      {
-        /* we're finally done! copy the pointer to the captured descriptor to
-           to the caller */
-        *CapturedSecurityDescriptor = NewDescriptor;
-        return STATUS_SUCCESS;
-      }
-      else
-      {
-        /* we failed to copy the data to the new descriptor */
-        ExFreePool(NewDescriptor);
-      }
+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;
+        }
+        else
+        {
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+        }
     }
     else
     {
-      Status = STATUS_INSUFFICIENT_RESOURCES;
+        /* Nothing to do... */
+        *CapturedSecurityDescriptor = NULL;
     }
-  }
-  else
-  {
-    /* nothing to do... */
-    *CapturedSecurityDescriptor = NULL;
-  }
 
-  return Status;
+    return Status;
 }
 
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
-                             IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
-                             IN OUT PULONG Length,
-                             IN PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor OPTIONAL)
+                              IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
+                              IN OUT PULONG Length,
+                              IN PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor OPTIONAL)
 {
-  PISECURITY_DESCRIPTOR ObjectSd;
-  PISECURITY_DESCRIPTOR_RELATIVE RelSD;
-  PSID Owner = NULL;
-  PSID Group = NULL;
-  PACL Dacl = NULL;
-  PACL Sacl = NULL;
-  ULONG OwnerLength = 0;
-  ULONG GroupLength = 0;
-  ULONG DaclLength = 0;
-  ULONG SaclLength = 0;
-  ULONG Control = 0;
-  ULONG_PTR Current;
-  ULONG SdLength;
-
-  RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
-
-  if (*ObjectsSecurityDescriptor == NULL)
+    PISECURITY_DESCRIPTOR ObjectSd;
+    PISECURITY_DESCRIPTOR_RELATIVE RelSD;
+    PSID Owner = NULL;
+    PSID Group = NULL;
+    PACL Dacl = NULL;
+    PACL Sacl = NULL;
+    ULONG OwnerLength = 0;
+    ULONG GroupLength = 0;
+    ULONG DaclLength = 0;
+    ULONG SaclLength = 0;
+    ULONG Control = 0;
+    ULONG_PTR Current;
+    ULONG SdLength;
+
+    RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
+
+    if (*ObjectsSecurityDescriptor == NULL)
     {
-      if (*Length < sizeof(SECURITY_DESCRIPTOR_RELATIVE))
-       {
-         *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
-         return STATUS_BUFFER_TOO_SMALL;
-       }
+        if (*Length < sizeof(SECURITY_DESCRIPTOR_RELATIVE))
+        {
+            *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
+            return STATUS_BUFFER_TOO_SMALL;
+        }
 
-      *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
-      RtlCreateSecurityDescriptorRelative(RelSD,
-                                         SECURITY_DESCRIPTOR_REVISION);
-      return STATUS_SUCCESS;
+        *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
+        RtlCreateSecurityDescriptorRelative(RelSD,
+                                            SECURITY_DESCRIPTOR_REVISION);
+        return STATUS_SUCCESS;
     }
 
-  ObjectSd = *ObjectsSecurityDescriptor;
+    ObjectSd = *ObjectsSecurityDescriptor;
 
-  /* Calculate the required security descriptor length */
-  Control = SE_SELF_RELATIVE;
-  if ((*SecurityInformation & OWNER_SECURITY_INFORMATION) &&
-      (ObjectSd->Owner != NULL))
+    /* Calculate the required security descriptor length */
+    Control = SE_SELF_RELATIVE;
+    if ((*SecurityInformation & OWNER_SECURITY_INFORMATION) &&
+        (ObjectSd->Owner != NULL))
     {
-      Owner = (PSID)((ULONG_PTR)ObjectSd->Owner + (ULONG_PTR)ObjectSd);
-      OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
-      Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED);
+        Owner = (PSID)((ULONG_PTR)ObjectSd->Owner + (ULONG_PTR)ObjectSd);
+        OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
+        Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED);
     }
 
-  if ((*SecurityInformation & GROUP_SECURITY_INFORMATION) &&
-      (ObjectSd->Group != NULL))
+    if ((*SecurityInformation & GROUP_SECURITY_INFORMATION) &&
+        (ObjectSd->Group != NULL))
     {
-      Group = (PSID)((ULONG_PTR)ObjectSd->Group + (ULONG_PTR)ObjectSd);
-      GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
-      Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED);
+        Group = (PSID)((ULONG_PTR)ObjectSd->Group + (ULONG_PTR)ObjectSd);
+        GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
+        Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED);
     }
 
-  if ((*SecurityInformation & DACL_SECURITY_INFORMATION) &&
-      (ObjectSd->Control & SE_DACL_PRESENT))
+    if ((*SecurityInformation & DACL_SECURITY_INFORMATION) &&
+        (ObjectSd->Control & SE_DACL_PRESENT))
     {
-      if (ObjectSd->Dacl != NULL)
-       {
-         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 (ObjectSd->Dacl != NULL)
+        {
+            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))
+    if ((*SecurityInformation & SACL_SECURITY_INFORMATION) &&
+        (ObjectSd->Control & SE_SACL_PRESENT))
     {
-      if (ObjectSd->Sacl != NULL)
-       {
-         Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd);
-         SaclLength = ROUND_UP(Sacl->AclSize, 4);
-       }
-      Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
+        if (ObjectSd->Sacl != NULL)
+        {
+            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)
+    SdLength = OwnerLength + GroupLength + DaclLength +
+    SaclLength + sizeof(SECURITY_DESCRIPTOR_RELATIVE);
+    if (*Length < SdLength)
     {
-      *Length = SdLength;
-      return STATUS_BUFFER_TOO_SMALL;
+        *Length = SdLength;
+        return STATUS_BUFFER_TOO_SMALL;
     }
 
-  /* Build the new security descrtiptor */
-  RtlCreateSecurityDescriptorRelative(RelSD,
-                                     SECURITY_DESCRIPTOR_REVISION);
-  RelSD->Control = Control;
+    /* Build the new security descrtiptor */
+    RtlCreateSecurityDescriptorRelative(RelSD,
+                                        SECURITY_DESCRIPTOR_REVISION);
+    RelSD->Control = (USHORT)Control;
 
-  Current = (ULONG_PTR)(RelSD + 1);
+    Current = (ULONG_PTR)(RelSD + 1);
 
-  if (OwnerLength != 0)
+    if (OwnerLength != 0)
     {
-      RtlCopyMemory((PVOID)Current,
-                   Owner,
-                   OwnerLength);
-      RelSD->Owner = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
-      Current += OwnerLength;
+        RtlCopyMemory((PVOID)Current,
+                      Owner,
+                      OwnerLength);
+        RelSD->Owner = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
+        Current += OwnerLength;
     }
 
-  if (GroupLength != 0)
+    if (GroupLength != 0)
     {
-      RtlCopyMemory((PVOID)Current,
-                   Group,
-                   GroupLength);
-      RelSD->Group = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
-      Current += GroupLength;
+        RtlCopyMemory((PVOID)Current,
+                      Group,
+                      GroupLength);
+        RelSD->Group = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
+        Current += GroupLength;
     }
 
-  if (DaclLength != 0)
+    if (DaclLength != 0)
     {
-      RtlCopyMemory((PVOID)Current,
-                   Dacl,
-                   DaclLength);
-      RelSD->Dacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
-      Current += DaclLength;
+        RtlCopyMemory((PVOID)Current,
+                      Dacl,
+                      DaclLength);
+        RelSD->Dacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
+        Current += DaclLength;
     }
 
-  if (SaclLength != 0)
+    if (SaclLength != 0)
     {
-      RtlCopyMemory((PVOID)Current,
-                   Sacl,
-                   SaclLength);
-      RelSD->Sacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
-      Current += SaclLength;
+        RtlCopyMemory((PVOID)Current,
+                      Sacl,
+                      SaclLength);
+        RelSD->Sacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
+        Current += SaclLength;
     }
 
-  *Length = SdLength;
+    *Length = SdLength;
 
-  return STATUS_SUCCESS;
+    return STATUS_SUCCESS;
 }
 
 /*
  * @implemented
  */
 NTSTATUS
-STDCALL
-SeReleaseSecurityDescriptor(
-       IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor,
-       IN KPROCESSOR_MODE CurrentMode,
-       IN BOOLEAN CaptureIfKernelMode
-       )
+NTAPI
+SeReleaseSecurityDescriptor(IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor,
+                            IN KPROCESSOR_MODE CurrentMode,
+                            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! */
-    ExFreePool(CapturedSecurityDescriptor);
-  }
-
-  return STATUS_SUCCESS;
+    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! */
+        ExFreePoolWithTag(CapturedSecurityDescriptor, TAG_SD);
+    }
+
+    return STATUS_SUCCESS;
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL,
-                           IN PSECURITY_INFORMATION SecurityInformation,
-                           IN PSECURITY_DESCRIPTOR SecurityDescriptor,
-                           IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
-                           IN POOL_TYPE PoolType,
-                           IN PGENERIC_MAPPING GenericMapping)
+                            IN PSECURITY_INFORMATION _SecurityInformation,
+                            IN PSECURITY_DESCRIPTOR _SecurityDescriptor,
+                            IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
+                            IN POOL_TYPE PoolType,
+                            IN PGENERIC_MAPPING GenericMapping)
 {
-  UNIMPLEMENTED;
-  return STATUS_NOT_IMPLEMENTED;
+    PISECURITY_DESCRIPTOR ObjectSd;
+    PISECURITY_DESCRIPTOR NewSd;
+    PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor;
+    PSID Owner = 0;
+    PSID Group = 0;
+    PACL Dacl = 0;
+    PACL Sacl = 0;
+    ULONG OwnerLength = 0;
+    ULONG GroupLength = 0;
+    ULONG DaclLength = 0;
+    ULONG SaclLength = 0;
+    ULONG Control = 0;
+    ULONG_PTR Current;
+    SECURITY_INFORMATION SecurityInformation;
+
+    ObjectSd = *ObjectsSecurityDescriptor;
+
+    /* The object does not have a security descriptor. */
+    if (!ObjectSd)
+        return STATUS_NO_SECURITY_ON_OBJECT;
+
+    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 +
+                               (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)
+        {
+            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)
+    {
+        if (SecurityDescriptor->Group != NULL)
+        {
+            if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
+                Group = (PSID)((ULONG_PTR)SecurityDescriptor->Group +
+                               (ULONG_PTR)SecurityDescriptor);
+            else
+                Group = (PSID)SecurityDescriptor->Group;
+            GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
+        }
+
+        Control |= (SecurityDescriptor->Control & SE_GROUP_DEFAULTED);
+    }
+    else
+    {
+        if (ObjectSd->Group != NULL)
+        {
+            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)
+    {
+        if ((SecurityDescriptor->Control & SE_DACL_PRESENT) &&
+            (SecurityDescriptor->Dacl != NULL))
+        {
+            if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
+                Dacl = (PACL)((ULONG_PTR)SecurityDescriptor->Dacl +
+                              (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))
+        {
+            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)
+    {
+        if ((SecurityDescriptor->Control & SE_SACL_PRESENT) &&
+            (SecurityDescriptor->Sacl != NULL))
+        {
+            if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
+                Sacl = (PACL)((ULONG_PTR)SecurityDescriptor->Sacl +
+                              (ULONG_PTR)SecurityDescriptor);
+            else
+                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))
+        {
+            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 +
+                           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);
+
+    if (OwnerLength != 0)
+    {
+        RtlCopyMemory((PVOID)Current,
+                      Owner,
+                      OwnerLength);
+        NewSd->Owner = (PSID)(Current - (ULONG_PTR)NewSd);
+        Current += OwnerLength;
+    }
+
+    if (GroupLength != 0)
+    {
+        RtlCopyMemory((PVOID)Current,
+                      Group,
+                      GroupLength);
+        NewSd->Group = (PSID)(Current - (ULONG_PTR)NewSd);
+        Current += GroupLength;
+    }
+
+    if (DaclLength != 0)
+    {
+        RtlCopyMemory((PVOID)Current,
+                      Dacl,
+                      DaclLength);
+        NewSd->Dacl = (PACL)(Current - (ULONG_PTR)NewSd);
+        Current += DaclLength;
+    }
+
+    if (SaclLength != 0)
+    {
+        RtlCopyMemory((PVOID)Current,
+                      Sacl,
+                      SaclLength);
+        NewSd->Sacl = (PACL)(Current - (ULONG_PTR)NewSd);
+        Current += SaclLength;
+    }
+
+    *ObjectsSecurityDescriptor = NewSd;
+    return STATUS_SUCCESS;
 }
 
 /*
  * @unimplemented
  */
 NTSTATUS
-STDCALL
-SeSetSecurityDescriptorInfoEx(
-       IN PVOID Object OPTIONAL,
-       IN PSECURITY_INFORMATION SecurityInformation,
-       IN PSECURITY_DESCRIPTOR ModificationDescriptor,
-       IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
-       IN ULONG AutoInheritFlags,
-       IN POOL_TYPE PoolType,
-       IN PGENERIC_MAPPING GenericMapping
-       )
+NTAPI
+SeSetSecurityDescriptorInfoEx(IN PVOID Object OPTIONAL,
+                              IN PSECURITY_INFORMATION SecurityInformation,
+                              IN PSECURITY_DESCRIPTOR ModificationDescriptor,
+                              IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
+                              IN ULONG AutoInheritFlags,
+                              IN POOL_TYPE PoolType,
+                              IN PGENERIC_MAPPING GenericMapping)
 {
-       UNIMPLEMENTED;
-       return STATUS_NOT_IMPLEMENTED;
+    PISECURITY_DESCRIPTOR ObjectSd = *ObjectsSecurityDescriptor;
+
+    /* The object does not have a security descriptor. */
+    if (!ObjectSd)
+        return STATUS_NO_SECURITY_ON_OBJECT;
+
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
 }
 
 
 /*
  * @implemented
  */
-BOOLEAN STDCALL
+BOOLEAN NTAPI
 SeValidSecurityDescriptor(IN ULONG Length,
-                         IN PSECURITY_DESCRIPTOR _SecurityDescriptor)
+                          IN PSECURITY_DESCRIPTOR _SecurityDescriptor)
 {
-  ULONG SdLength;
-  PISID Sid;
-  PACL Acl;
-  PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor;
+    ULONG SdLength;
+    PISID Sid;
+    PACL Acl;
+    PISECURITY_DESCRIPTOR 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)
+    {
+        DPRINT1("No Owner SID\n");
+        return FALSE;
+    }
+
+    if ((ULONG_PTR)SecurityDescriptor->Owner % sizeof(ULONG))
+    {
+        DPRINT1("Invalid Owner SID alignment\n");
+        return FALSE;
+    }
+
+    Sid = (PISID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Owner);
+    if (Sid->Revision != SID_REVISION)
+    {
+        DPRINT1("Invalid Owner SID revision\n");
+        return FALSE;
+    }
 
-  if (Length < SECURITY_DESCRIPTOR_MIN_LENGTH)
+    SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG));
+    if (Length < SdLength)
     {
-      DPRINT1("Invalid Security Descriptor revision\n");
-      return FALSE;
+        DPRINT1("Invalid Owner SID size\n");
+        return FALSE;
     }
 
-  if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
+    /* Check Group SID */
+    if (SecurityDescriptor->Group != NULL)
+    {
+        if ((ULONG_PTR)SecurityDescriptor->Group % sizeof(ULONG))
+        {
+            DPRINT1("Invalid Group SID alignment\n");
+            return FALSE;
+        }
+
+        Sid = (PSID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)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)
+        {
+            DPRINT1("Invalid Group SID size\n");
+            return FALSE;
+        }
+    }
+
+    /* Check DACL */
+    if (SecurityDescriptor->Dacl != NULL)
+    {
+        if ((ULONG_PTR)SecurityDescriptor->Dacl % sizeof(ULONG))
+        {
+            DPRINT1("Invalid DACL alignment\n");
+            return FALSE;
+        }
+
+        Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)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)
+        {
+            DPRINT1("Invalid DACL size\n");
+            return FALSE;
+        }
+    }
+
+    /* Check SACL */
+    if (SecurityDescriptor->Sacl != NULL)
+    {
+        if ((ULONG_PTR)SecurityDescriptor->Sacl % sizeof(ULONG))
+        {
+            DPRINT1("Invalid SACL alignment\n");
+            return FALSE;
+        }
+
+        Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)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)
+        {
+            DPRINT1("Invalid SACL size\n");
+            return FALSE;
+        }
+    }
+
+    return TRUE;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS NTAPI
+SeDeassignSecurity(PSECURITY_DESCRIPTOR *SecurityDescriptor)
+{
+    PAGED_CODE();
+
+    if (*SecurityDescriptor != NULL)
     {
-      DPRINT1("Invalid Security Descriptor revision\n");
-      return FALSE;
+        ExFreePool(*SecurityDescriptor);
+        *SecurityDescriptor = NULL;
     }
 
-  if (!(SecurityDescriptor->Control & SE_SELF_RELATIVE))
+    return STATUS_SUCCESS;
+}
+
+
+/*
+ * @unimplemented
+ */
+NTSTATUS NTAPI
+SeAssignSecurityEx(IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
+                   IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL,
+                   OUT PSECURITY_DESCRIPTOR *NewDescriptor,
+                   IN GUID *ObjectType OPTIONAL,
+                   IN BOOLEAN IsDirectoryObject,
+                   IN ULONG AutoInheritFlags,
+                   IN PSECURITY_SUBJECT_CONTEXT SubjectContext,
+                   IN PGENERIC_MAPPING GenericMapping,
+                   IN POOL_TYPE PoolType)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS NTAPI
+SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL,
+                 PSECURITY_DESCRIPTOR _ExplicitDescriptor OPTIONAL,
+                 PSECURITY_DESCRIPTOR *NewDescriptor,
+                 BOOLEAN IsDirectoryObject,
+                 PSECURITY_SUBJECT_CONTEXT SubjectContext,
+                 PGENERIC_MAPPING GenericMapping,
+                 POOL_TYPE PoolType)
+{
+    PISECURITY_DESCRIPTOR ParentDescriptor = _ParentDescriptor;
+    PISECURITY_DESCRIPTOR ExplicitDescriptor = _ExplicitDescriptor;
+    PISECURITY_DESCRIPTOR Descriptor;
+    PTOKEN Token;
+    ULONG OwnerLength = 0;
+    ULONG GroupLength = 0;
+    ULONG DaclLength = 0;
+    ULONG SaclLength = 0;
+    ULONG Length = 0;
+    ULONG Control = 0;
+    ULONG_PTR Current;
+    PSID Owner = NULL;
+    PSID Group = NULL;
+    PACL Dacl = NULL;
+    PACL Sacl = NULL;
+
+    PAGED_CODE();
+
+    /* Lock subject context */
+    SeLockSubjectContext(SubjectContext);
+
+    if (SubjectContext->ClientToken != NULL)
     {
-      DPRINT1("No self-relative Security Descriptor\n");
-      return FALSE;
+        Token = SubjectContext->ClientToken;
+    }
+    else
+    {
+        Token = SubjectContext->PrimaryToken;
     }
 
-  SdLength = sizeof(SECURITY_DESCRIPTOR);
+    /* Inherit the Owner SID */
+    if (ExplicitDescriptor != NULL && ExplicitDescriptor->Owner != NULL)
+    {
+        DPRINT("Use explicit owner sid!\n");
+        Owner = ExplicitDescriptor->Owner;
 
-  /* Check Owner SID */
-  if (SecurityDescriptor->Owner == NULL)
+        if (ExplicitDescriptor->Control & SE_SELF_RELATIVE)
+        {
+            Owner = (PSID)(((ULONG_PTR)Owner) + (ULONG_PTR)ExplicitDescriptor);
+        }
+    }
+    else
     {
-      DPRINT1("No Owner SID\n");
-      return FALSE;
+        if (Token != NULL)
+        {
+            DPRINT("Use token owner sid!\n");
+            Owner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid;
+        }
+        else
+        {
+            DPRINT("Use default owner sid!\n");
+            Owner = SeLocalSystemSid;
+        }
+
+        Control |= SE_OWNER_DEFAULTED;
     }
 
-  if ((ULONG_PTR)SecurityDescriptor->Owner % sizeof(ULONG))
+    OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
+
+    /* Inherit the Group SID */
+    if (ExplicitDescriptor != NULL && ExplicitDescriptor->Group != NULL)
     {
-      DPRINT1("Invalid Owner SID alignment\n");
-      return FALSE;
+        DPRINT("Use explicit group sid!\n");
+        Group = ExplicitDescriptor->Group;
+        if (ExplicitDescriptor->Control & SE_SELF_RELATIVE)
+        {
+            Group = (PSID)(((ULONG_PTR)Group) + (ULONG_PTR)ExplicitDescriptor);
+        }
+    }
+    else
+    {
+        if (Token != NULL)
+        {
+            DPRINT("Use token group sid!\n");
+            Group = Token->PrimaryGroup;
+        }
+        else
+        {
+            DPRINT("Use default group sid!\n");
+            Group = SeLocalSystemSid;
+        }
+
+        Control |= SE_OWNER_DEFAULTED;
     }
 
-  Sid = (PISID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Owner);
-  if (Sid->Revision != SID_REVISION)
+    GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
+
+    /* Inherit the DACL */
+    if (ExplicitDescriptor != NULL &&
+        (ExplicitDescriptor->Control & SE_DACL_PRESENT) &&
+        !(ExplicitDescriptor->Control & SE_DACL_DEFAULTED))
     {
-      DPRINT1("Invalid Owner SID revision\n");
-      return FALSE;
+        DPRINT("Use explicit DACL!\n");
+        Dacl = ExplicitDescriptor->Dacl;
+        if (Dacl != NULL && (ExplicitDescriptor->Control & SE_SELF_RELATIVE))
+        {
+            Dacl = (PACL)(((ULONG_PTR)Dacl) + (ULONG_PTR)ExplicitDescriptor);
+        }
+
+        Control |= SE_DACL_PRESENT;
     }
+    else if (ParentDescriptor != NULL &&
+             (ParentDescriptor->Control & SE_DACL_PRESENT))
+    {
+        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);
+        }
 
-  SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG));
-  if (Length < SdLength)
+        Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED);
+    }
+    else if (Token != NULL && Token->DefaultDacl != NULL)
     {
-      DPRINT1("Invalid Owner SID size\n");
-      return FALSE;
+        DPRINT("Use token default DACL!\n");
+        /* FIXME: Inherit */
+        Dacl = Token->DefaultDacl;
+        Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED);
     }
+    else
+    {
+        DPRINT("Use NULL DACL!\n");
+        Dacl = NULL;
+        Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED);
+    }
+
+    DaclLength = (Dacl != NULL) ? ROUND_UP(Dacl->AclSize, 4) : 0;
 
-  /* Check Group SID */
-  if (SecurityDescriptor->Group != NULL)
+    /* Inherit the SACL */
+    if (ExplicitDescriptor != NULL &&
+        (ExplicitDescriptor->Control & SE_SACL_PRESENT) &&
+        !(ExplicitDescriptor->Control & SE_SACL_DEFAULTED))
     {
-      if ((ULONG_PTR)SecurityDescriptor->Group % sizeof(ULONG))
-       {
-         DPRINT1("Invalid Group SID alignment\n");
-         return FALSE;
-       }
+        DPRINT("Use explicit SACL!\n");
+        Sacl = ExplicitDescriptor->Sacl;
+        if (Sacl != NULL && (ExplicitDescriptor->Control & SE_SELF_RELATIVE))
+        {
+            Sacl = (PACL)(((ULONG_PTR)Sacl) + (ULONG_PTR)ExplicitDescriptor);
+        }
 
-      Sid = (PSID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Group);
-      if (Sid->Revision != SID_REVISION)
-       {
-         DPRINT1("Invalid Group SID revision\n");
-         return FALSE;
-       }
+        Control |= SE_SACL_PRESENT;
+    }
+    else if (ParentDescriptor != NULL &&
+             (ParentDescriptor->Control & SE_SACL_PRESENT))
+    {
+        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);
+        }
 
-      SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG));
-      if (Length < SdLength)
-       {
-         DPRINT1("Invalid Group SID size\n");
-         return FALSE;
-       }
+        Control |= (SE_SACL_PRESENT | SE_SACL_DEFAULTED);
     }
 
-  /* Check DACL */
-  if (SecurityDescriptor->Dacl != NULL)
+    SaclLength = (Sacl != NULL) ? ROUND_UP(Sacl->AclSize, 4) : 0;
+
+    /* Allocate and initialize the new security descriptor */
+    Length = sizeof(SECURITY_DESCRIPTOR) +
+    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);
+    if (Descriptor == NULL)
     {
-      if ((ULONG_PTR)SecurityDescriptor->Dacl % sizeof(ULONG))
-       {
-         DPRINT1("Invalid DACL alignment\n");
-         return FALSE;
-       }
+        DPRINT1("ExAlloctePool() failed\n");
+        /* FIXME: Unlock subject context */
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    RtlZeroMemory( Descriptor, Length );
+    RtlCreateSecurityDescriptor(Descriptor,
+                                SECURITY_DESCRIPTOR_REVISION);
+
+    Descriptor->Control = (USHORT)Control | SE_SELF_RELATIVE;
 
-      Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Dacl);
-      if ((Acl->AclRevision < MIN_ACL_REVISION) &&
-         (Acl->AclRevision > MAX_ACL_REVISION))
-       {
-         DPRINT1("Invalid DACL revision\n");
-         return FALSE;
-       }
+    Current = (ULONG_PTR)Descriptor + sizeof(SECURITY_DESCRIPTOR);
 
-      SdLength += Acl->AclSize;
-      if (Length < SdLength)
-       {
-         DPRINT1("Invalid DACL size\n");
-         return FALSE;
-       }
+    if (SaclLength != 0)
+    {
+        RtlCopyMemory((PVOID)Current,
+                      Sacl,
+                      SaclLength);
+        Descriptor->Sacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
+        Current += SaclLength;
     }
 
-  /* Check SACL */
-  if (SecurityDescriptor->Sacl != NULL)
+    if (DaclLength != 0)
     {
-      if ((ULONG_PTR)SecurityDescriptor->Sacl % sizeof(ULONG))
-       {
-         DPRINT1("Invalid SACL alignment\n");
-         return FALSE;
-       }
+        RtlCopyMemory((PVOID)Current,
+                      Dacl,
+                      DaclLength);
+        Descriptor->Dacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
+        Current += DaclLength;
+    }
 
-      Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Sacl);
-      if ((Acl->AclRevision < MIN_ACL_REVISION) ||
-         (Acl->AclRevision > MAX_ACL_REVISION))
-       {
-         DPRINT1("Invalid SACL revision\n");
-         return FALSE;
-       }
+    if (OwnerLength != 0)
+    {
+        RtlCopyMemory((PVOID)Current,
+                      Owner,
+                      OwnerLength);
+        Descriptor->Owner = (PSID)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
+        Current += OwnerLength;
+        DPRINT("Owner of %x at %x\n", Descriptor, Descriptor->Owner);
+    }
+    else
+    {
+        DPRINT("Owner of %x is zero length\n", Descriptor);
+    }
 
-      SdLength += Acl->AclSize;
-      if (Length < SdLength)
-       {
-         DPRINT1("Invalid SACL size\n");
-         return FALSE;
-       }
+    if (GroupLength != 0)
+    {
+        memmove((PVOID)Current,
+                Group,
+                GroupLength);
+        Descriptor->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)Descriptor);
     }
 
-  return TRUE;
+    /* Unlock subject context */
+    SeUnlockSubjectContext(SubjectContext);
+
+    *NewDescriptor = Descriptor;
+
+    DPRINT("Descrptor %x\n", Descriptor);
+    ASSERT(RtlLengthSecurityDescriptor(Descriptor));
+
+    return STATUS_SUCCESS;
 }
 
 /* EOF */