- Initialize more fields when creating an Object Type
authorAlex Ionescu <aionescu@gmail.com>
Sun, 7 Aug 2005 18:38:37 +0000 (18:38 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Sun, 7 Aug 2005 18:38:37 +0000 (18:38 +0000)
- Correct the Pool Charge for Object Types, select a Default Object, always use a security procedure, read global flag for maintaing type lists, set the pool type
- Initialize a Default Wait Object.
- Fix security callback for objects.
- Implement SeDefaultObjectMethod for security callbacks of objects which don't have a custom one.

svn path=/trunk/; revision=17176

reactos/include/ndk/obtypes.h
reactos/ntoskrnl/cm/cm.h
reactos/ntoskrnl/cm/regobj.c
reactos/ntoskrnl/include/internal/io.h
reactos/ntoskrnl/include/internal/se.h
reactos/ntoskrnl/io/file.c
reactos/ntoskrnl/ob/handle.c
reactos/ntoskrnl/ob/namespc.c
reactos/ntoskrnl/ob/security.c
reactos/ntoskrnl/se/semgr.c

index 7b97d2d..c79a85e 100644 (file)
@@ -95,13 +95,17 @@ typedef PVOID
     ULONG  Attributes
 );
 
+
 typedef NTSTATUS
 (STDCALL *OB_SECURITY_METHOD)(
-    PVOID  ObjectBody,
-    SECURITY_OPERATION_CODE  OperationCode,
-    SECURITY_INFORMATION  SecurityInformation,
-    PSECURITY_DESCRIPTOR  SecurityDescriptor,
-    PULONG  BufferLength
+    PVOID Object,
+    SECURITY_OPERATION_CODE OperationType,                         
+    SECURITY_INFORMATION SecurityInformation,
+    PSECURITY_DESCRIPTOR NewSecurityDescriptor,
+    PULONG ReturnLength,
+    PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
+    POOL_TYPE PoolType,
+    PGENERIC_MAPPING GenericMapping
 );
 
 /* FIXME: TEMPORARY HACK */
index 4a61034..338cbeb 100644 (file)
@@ -497,7 +497,10 @@ CmiObjectSecurity(PVOID ObjectBody,
                  SECURITY_OPERATION_CODE OperationCode,
                  SECURITY_INFORMATION SecurityInformation,
                  PSECURITY_DESCRIPTOR SecurityDescriptor,
-                 PULONG BufferLength);
+                 PULONG BufferLength,
+                 PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
+                 POOL_TYPE PoolType,
+                 PGENERIC_MAPPING GenericMapping);
 
 NTSTATUS STDCALL
 CmiObjectQueryName (PVOID ObjectBody,
index 0ac4f8f..5b0493f 100644 (file)
@@ -450,7 +450,10 @@ CmiObjectSecurity(PVOID ObjectBody,
                  SECURITY_OPERATION_CODE OperationCode,
                  SECURITY_INFORMATION SecurityInformation,
                  PSECURITY_DESCRIPTOR SecurityDescriptor,
-                 PULONG BufferLength)
+                 PULONG BufferLength,
+                 PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
+                 POOL_TYPE PoolType,
+                 PGENERIC_MAPPING GenericMapping)
 {
   DPRINT("CmiObjectSecurity() called\n");
 
index 74e1cba..ea37455 100644 (file)
@@ -400,7 +400,10 @@ IopSecurityFile(
     SECURITY_OPERATION_CODE OperationCode,
     SECURITY_INFORMATION SecurityInformation,
     PSECURITY_DESCRIPTOR SecurityDescriptor,
-    PULONG BufferLength
+    PULONG BufferLength,
+       PSECURITY_DESCRIPTOR *OldSecurityDescriptor,    
+    POOL_TYPE PoolType,
+    PGENERIC_MAPPING GenericMapping
 );
 
 NTSTATUS
index 5514eca..34d38ae 100644 (file)
@@ -181,6 +181,17 @@ SepReleaseAcl(IN PACL CapturedAcl,
               IN KPROCESSOR_MODE AccessMode,
               IN BOOLEAN CaptureIfKernel);
 
+NTSTATUS
+STDCALL
+SeDefaultObjectMethod(PVOID Object,
+                      SECURITY_OPERATION_CODE OperationType,                         
+                      SECURITY_INFORMATION SecurityInformation,
+                      PSECURITY_DESCRIPTOR NewSecurityDescriptor,
+                      PULONG ReturnLength,
+                      PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
+                      POOL_TYPE PoolType,
+                      PGENERIC_MAPPING GenericMapping);
+
 #define SepAcquireTokenLockExclusive(Token)                                    \
   do {                                                                         \
     KeEnterCriticalRegion();                                                   \
index 3453913..17bfea8 100644 (file)
@@ -239,7 +239,10 @@ IopSecurityFile(PVOID ObjectBody,
                 SECURITY_OPERATION_CODE OperationCode,
                 SECURITY_INFORMATION SecurityInformation,
                 PSECURITY_DESCRIPTOR SecurityDescriptor,
-                PULONG BufferLength)
+                PULONG BufferLength,
+                PSECURITY_DESCRIPTOR *OldSecurityDescriptor,    
+                POOL_TYPE PoolType,
+                PGENERIC_MAPPING GenericMapping)
 {
     IO_STATUS_BLOCK IoStatusBlock;
     PIO_STACK_LOCATION StackPtr;
index a9b46d3..0fffe18 100644 (file)
@@ -1109,6 +1109,9 @@ ObInsertObject(IN PVOID Object,
                                                                     AssignSecurityDescriptor,
                                                                     0,
                                                                     NewSecurityDescriptor,
+                                                                    NULL,
+                                                                    NULL,
+                                                                    NonPagedPool,
                                                                     NULL);
         }
         else
index 46f058d..df73bfe 100644 (file)
@@ -14,6 +14,7 @@
 #define NDEBUG
 #include <internal/debug.h>
 
+extern ULONG NtGlobalFlag;
 
 /* GLOBALS ****************************************************************/
 
@@ -24,7 +25,7 @@ PDIRECTORY_OBJECT NameSpaceRoot = NULL;
 PDIRECTORY_OBJECT ObpTypeDirectoryObject = NULL;
  /* FIXME: Move this somewhere else once devicemap support is in */
 PDEVICE_MAP ObSystemDeviceMap = NULL;
-
+KEVENT ObpDefaultObject;
 
 static GENERIC_MAPPING ObpDirectoryMapping = {
        STANDARD_RIGHTS_READ|DIRECTORY_QUERY|DIRECTORY_TRAVERSE,
@@ -430,6 +431,9 @@ ObInit(VOID)
     /* Initialize the security descriptor cache */
     ObpInitSdCache();
 
+    /* Initialize the Default Event */
+    KeInitializeEvent(&ObpDefaultObject, NotificationEvent, TRUE );
+
     /* Create the Type Type */
     DPRINT("Creating Type Type\n");
     RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
@@ -538,6 +542,7 @@ ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
 {
     POBJECT_HEADER Header;
     POBJECT_TYPE LocalObjectType;
+    ULONG HeaderSize;
     NTSTATUS Status;
 
     DPRINT("ObpCreateTypeObject(ObjectType: %wZ)\n", TypeName);
@@ -580,14 +585,71 @@ ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
     /* Set it up */
     LocalObjectType->TypeInfo = *ObjectTypeInitializer;
     LocalObjectType->Name = *TypeName;
+    LocalObjectType->TypeInfo.PoolType = ObjectTypeInitializer->PoolType;
+
+    /* These two flags need to be manually set up */
+    Header->Flags |= OB_FLAG_KERNEL_MODE | OB_FLAG_PERMANENT;
+
+    /* Check if we have to maintain a type list */
+    if (NtGlobalFlag & FLG_MAINTAIN_OBJECT_TYPELIST)
+    {
+        /* Enable support */
+        LocalObjectType->TypeInfo.MaintainTypeList = TRUE;
+    }
+
+    /* Calculate how much space our header'll take up */
+    HeaderSize = sizeof(OBJECT_HEADER) + sizeof(OBJECT_HEADER_NAME_INFO) +
+                 (ObjectTypeInitializer->MaintainHandleCount ? 
+                 sizeof(OBJECT_HEADER_HANDLE_INFO) : 0);
+
+    /* Update the Pool Charges */
+    if (ObjectTypeInitializer->PoolType == NonPagedPool)
+    {
+        LocalObjectType->TypeInfo.DefaultNonPagedPoolCharge += HeaderSize;
+    }
+    else
+    {
+        LocalObjectType->TypeInfo.DefaultPagedPoolCharge += HeaderSize;
+    }
     
+    /* All objects types need a security procedure */
+    if (!ObjectTypeInitializer->SecurityProcedure)
+    {
+        LocalObjectType->TypeInfo.SecurityProcedure = SeDefaultObjectMethod;
+    }
+
+    /* Select the Wait Object */
+    if (LocalObjectType->TypeInfo.UseDefaultObject)
+    {
+        /* Add the SYNCHRONIZE access mask since it's waitable */
+        LocalObjectType->TypeInfo.ValidAccessMask |= SYNCHRONIZE;
+
+        /* Use the "Default Object", a simple event */
+        LocalObjectType->DefaultObject = &ObpDefaultObject;
+    }
+    /* Special system objects get an optimized hack so they can be waited on */
+    else if (TypeName->Length == 8 && !wcscmp(TypeName->Buffer, L"File"))
+    {
+        LocalObjectType->DefaultObject = (PVOID)FIELD_OFFSET(FILE_OBJECT, Event);
+    }
+    /* FIXME: When LPC stops sucking, add a hack for Waitable Ports */
+    else
+    {
+        /* No default Object */
+        LocalObjectType->DefaultObject = NULL;
+    }
+
+    /* Initialize Object Type components */
+    ExInitializeResourceLite(&LocalObjectType->Mutex);
+    InitializeListHead(&LocalObjectType->TypeList);
+
     /* Insert it into the Object Directory */
     if (ObpTypeDirectoryObject)
     {
         ObpAddEntryDirectory(ObpTypeDirectoryObject, Header, TypeName->Buffer);
         ObReferenceObject(ObpTypeDirectoryObject);
     }
-        
+
     *ObjectType = LocalObjectType;
     return Status;
 } 
index 1fd2a2e..619dc99 100644 (file)
@@ -41,21 +41,15 @@ ObAssignSecurity(IN PACCESS_STATE AccessState,
   if (!NT_SUCCESS(Status))
     return Status;
 
-  if (Type->TypeInfo.SecurityProcedure != NULL)
-    {
       /* Call the security method */
       Status = Type->TypeInfo.SecurityProcedure(Object,
                              AssignSecurityDescriptor,
                              0,
                              NewDescriptor,
-                             NULL);
-    }
-  else
-    {
-      /* Assign the security descriptor to the object header */
-      Status = ObpAddSecurityDescriptor(NewDescriptor,
-                                       &(BODY_TO_HEADER(Object)->SecurityDescriptor));
-    }
+                             NULL,
+                  NULL,
+                  NonPagedPool,
+                  NULL);
 
   /* Release the new security descriptor */
   SeDeassignSecurity(&NewDescriptor);
@@ -97,7 +91,10 @@ ObGetObjectSecurity(IN PVOID Object,
                                        OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
                                        DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
                                        NULL,
-                                       &Length);
+                                       &Length,
+                    NULL,
+                    NonPagedPool,
+                    NULL);
   if (Status != STATUS_BUFFER_TOO_SMALL)
     return Status;
 
@@ -113,7 +110,10 @@ ObGetObjectSecurity(IN PVOID Object,
                                        OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
                                        DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
                                        *SecurityDescriptor,
-                                       &Length);
+                                       &Length,
+                    NULL,
+                    NonPagedPool,
+                    NULL);
   if (!NT_SUCCESS(Status))
     {
       ExFreePool(*SecurityDescriptor);
@@ -187,23 +187,15 @@ NtQuerySecurityObject(IN HANDLE Handle,
       return STATUS_UNSUCCESSFUL;
     }
 
-  if (Header->Type->TypeInfo.SecurityProcedure != NULL)
-    {
       *ResultLength = Length;
       Status = Header->Type->TypeInfo.SecurityProcedure(Object,
                                            QuerySecurityDescriptor,
                                            SecurityInformation,
                                            SecurityDescriptor,
-                                           ResultLength);
-    }
-  else
-    {
-      *ResultLength = Length;
-      Status = SeQuerySecurityDescriptorInfo(&SecurityInformation,
-                                            SecurityDescriptor,
-                                            ResultLength,
-                                            &Header->SecurityDescriptor);
-    }
+                                           ResultLength,
+                        NULL,
+                        NonPagedPool,
+                        NULL);
 
   ObDereferenceObject(Object);
 
@@ -219,20 +211,8 @@ NtSetSecurityObject(IN HANDLE Handle,
                    IN SECURITY_INFORMATION SecurityInformation,
                    IN PSECURITY_DESCRIPTOR SecurityDescriptor)
 {
-  PSECURITY_DESCRIPTOR ObjectSd;
-  PSECURITY_DESCRIPTOR NewSd;
   POBJECT_HEADER Header;
   PVOID Object;
-  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;
   NTSTATUS Status;
 
   PAGED_CODE();
@@ -259,187 +239,14 @@ NtSetSecurityObject(IN HANDLE Handle,
       return STATUS_UNSUCCESSFUL;
     }
 
-  if (Header->Type->TypeInfo.SecurityProcedure != NULL)
-    {
       Status = Header->Type->TypeInfo.SecurityProcedure(Object,
                                            SetSecurityDescriptor,
                                            SecurityInformation,
                                            SecurityDescriptor,
-                                           NULL);
-    }
-  else
-    {
-      ObjectSd = Header->SecurityDescriptor;
-
-      /* 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 = 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;
-       }
-
-      /* Add the new SD */
-      Status = ObpAddSecurityDescriptor(NewSd,
-                                       &Header->SecurityDescriptor);
-      if (NT_SUCCESS(Status))
-       {
-         /* Remove the old security descriptor */
-         ObpRemoveSecurityDescriptor(ObjectSd);
-       }
-      else
-       {
-         /* Restore the old security descriptor */
-         Header->SecurityDescriptor = ObjectSd;
-       }
-
-      ExFreePool(NewSd);
-    }
+                                           NULL,
+                        NULL,
+                        NonPagedPool,
+                        NULL);
 
   ObDereferenceObject(Object);
 
index b72d6c5..b2af8a7 100644 (file)
@@ -188,6 +188,222 @@ VOID SepDeReferenceLogonSession(PLUID AuthenticationId)
    UNIMPLEMENTED;
 }
 
+NTSTATUS
+STDCALL
+SeDefaultObjectMethod(PVOID Object,
+                      SECURITY_OPERATION_CODE OperationType,                         
+                      SECURITY_INFORMATION SecurityInformation,
+                      PSECURITY_DESCRIPTOR SecurityDescriptor,
+                      PULONG ReturnLength,
+                      PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
+                      POOL_TYPE PoolType,
+                      PGENERIC_MAPPING GenericMapping)
+{
+  PSECURITY_DESCRIPTOR ObjectSd;
+  PSECURITY_DESCRIPTOR NewSd;
+  POBJECT_HEADER Header = BODY_TO_HEADER(Object);
+  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;
+  NTSTATUS Status;
+
+    if (OperationType == SetSecurityDescriptor)
+    {
+        ObjectSd = Header->SecurityDescriptor;
+
+      /* 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 = 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;
+       }
+
+      /* Add the new SD */
+      Status = ObpAddSecurityDescriptor(NewSd,
+                                       &Header->SecurityDescriptor);
+      if (NT_SUCCESS(Status))
+       {
+         /* Remove the old security descriptor */
+         ObpRemoveSecurityDescriptor(ObjectSd);
+       }
+      else
+       {
+         /* Restore the old security descriptor */
+         Header->SecurityDescriptor = ObjectSd;
+       }
+
+      ExFreePool(NewSd);
+    }
+    else if (OperationType == QuerySecurityDescriptor)
+    {
+        Status = SeQuerySecurityDescriptorInfo(&SecurityInformation,
+                                               SecurityDescriptor,
+                                               ReturnLength,
+                                               &Header->SecurityDescriptor);
+    }
+    else if (OperationType == AssignSecurityDescriptor)
+    {
+      /* Assign the security descriptor to the object header */
+      Status = ObpAddSecurityDescriptor(SecurityDescriptor,
+                                                       &Header->SecurityDescriptor);
+    }
+
+
+    return STATUS_SUCCESS;
+}
 
 /*
  * @implemented