- Initialize more fields when creating an Object Type
- 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.
Modified: trunk/reactos/include/ndk/obtypes.h
Modified: trunk/reactos/ntoskrnl/cm/cm.h
Modified: trunk/reactos/ntoskrnl/cm/regobj.c
Modified: trunk/reactos/ntoskrnl/include/internal/io.h
Modified: trunk/reactos/ntoskrnl/include/internal/se.h
Modified: trunk/reactos/ntoskrnl/io/file.c
Modified: trunk/reactos/ntoskrnl/ob/handle.c
Modified: trunk/reactos/ntoskrnl/ob/namespc.c
Modified: trunk/reactos/ntoskrnl/ob/security.c
Modified: trunk/reactos/ntoskrnl/se/semgr.c

Modified: trunk/reactos/include/ndk/obtypes.h
--- trunk/reactos/include/ndk/obtypes.h	2005-08-07 17:46:50 UTC (rev 17175)
+++ trunk/reactos/include/ndk/obtypes.h	2005-08-07 18:38:37 UTC (rev 17176)
@@ -95,13 +95,17 @@
     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 */

Modified: trunk/reactos/ntoskrnl/cm/cm.h
--- trunk/reactos/ntoskrnl/cm/cm.h	2005-08-07 17:46:50 UTC (rev 17175)
+++ trunk/reactos/ntoskrnl/cm/cm.h	2005-08-07 18:38:37 UTC (rev 17176)
@@ -497,7 +497,10 @@
 		  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,

Modified: trunk/reactos/ntoskrnl/cm/regobj.c
--- trunk/reactos/ntoskrnl/cm/regobj.c	2005-08-07 17:46:50 UTC (rev 17175)
+++ trunk/reactos/ntoskrnl/cm/regobj.c	2005-08-07 18:38:37 UTC (rev 17176)
@@ -450,7 +450,10 @@
 		  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");
 

Modified: trunk/reactos/ntoskrnl/include/internal/io.h
--- trunk/reactos/ntoskrnl/include/internal/io.h	2005-08-07 17:46:50 UTC (rev 17175)
+++ trunk/reactos/ntoskrnl/include/internal/io.h	2005-08-07 18:38:37 UTC (rev 17176)
@@ -400,7 +400,10 @@
     SECURITY_OPERATION_CODE OperationCode,
     SECURITY_INFORMATION SecurityInformation,
     PSECURITY_DESCRIPTOR SecurityDescriptor,
-    PULONG BufferLength
+    PULONG BufferLength,
+	PSECURITY_DESCRIPTOR *OldSecurityDescriptor,    
+    POOL_TYPE PoolType,
+    PGENERIC_MAPPING GenericMapping
 );
 
 NTSTATUS

Modified: trunk/reactos/ntoskrnl/include/internal/se.h
--- trunk/reactos/ntoskrnl/include/internal/se.h	2005-08-07 17:46:50 UTC (rev 17175)
+++ trunk/reactos/ntoskrnl/include/internal/se.h	2005-08-07 18:38:37 UTC (rev 17176)
@@ -181,6 +181,17 @@
               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();                                                   \

Modified: trunk/reactos/ntoskrnl/io/file.c
--- trunk/reactos/ntoskrnl/io/file.c	2005-08-07 17:46:50 UTC (rev 17175)
+++ trunk/reactos/ntoskrnl/io/file.c	2005-08-07 18:38:37 UTC (rev 17176)
@@ -239,7 +239,10 @@
                 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;

Modified: trunk/reactos/ntoskrnl/ob/handle.c
--- trunk/reactos/ntoskrnl/ob/handle.c	2005-08-07 17:46:50 UTC (rev 17175)
+++ trunk/reactos/ntoskrnl/ob/handle.c	2005-08-07 18:38:37 UTC (rev 17176)
@@ -1109,6 +1109,9 @@
                                                                     AssignSecurityDescriptor,
                                                                     0,
                                                                     NewSecurityDescriptor,
+                                                                    NULL,
+                                                                    NULL,
+                                                                    NonPagedPool,
                                                                     NULL);
         }
         else

Modified: trunk/reactos/ntoskrnl/ob/namespc.c
--- trunk/reactos/ntoskrnl/ob/namespc.c	2005-08-07 17:46:50 UTC (rev 17175)
+++ trunk/reactos/ntoskrnl/ob/namespc.c	2005-08-07 18:38:37 UTC (rev 17176)
@@ -14,6 +14,7 @@
 #define NDEBUG
 #include <internal/debug.h>
 
+extern ULONG NtGlobalFlag;
 
 /* GLOBALS ****************************************************************/
 
@@ -24,8 +25,8 @@
 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,
 	STANDARD_RIGHTS_WRITE|DIRECTORY_CREATE_OBJECT|DIRECTORY_CREATE_SUBDIRECTORY,
@@ -430,6 +431,9 @@
     /* 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 @@
 {
     POBJECT_HEADER Header;
     POBJECT_TYPE LocalObjectType;
+    ULONG HeaderSize;
     NTSTATUS Status;
 
     DPRINT("ObpCreateTypeObject(ObjectType: %wZ)\n", TypeName);
@@ -580,14 +585,71 @@
     /* 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;
 } 

Modified: trunk/reactos/ntoskrnl/ob/security.c
--- trunk/reactos/ntoskrnl/ob/security.c	2005-08-07 17:46:50 UTC (rev 17175)
+++ trunk/reactos/ntoskrnl/ob/security.c	2005-08-07 18:38:37 UTC (rev 17176)
@@ -41,21 +41,15 @@
   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 @@
 					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 @@
 					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 @@
       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 @@
 		    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,188 +239,15 @@
       return STATUS_UNSUCCESSFUL;
     }
 
-  if (Header->Type->TypeInfo.SecurityProcedure != NULL)
-    {
       Status = Header->Type->TypeInfo.SecurityProcedure(Object,
 					    SetSecurityDescriptor,
 					    SecurityInformation,
 					    SecurityDescriptor,
-					    NULL);
-    }
-  else
-    {
-      ObjectSd = Header->SecurityDescriptor;
+					    NULL,
+                        NULL,
+                        NonPagedPool,
+                        NULL);
 
-      /* 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);
-    }
-
   ObDereferenceObject(Object);
 
   return Status;

Modified: trunk/reactos/ntoskrnl/se/semgr.c
--- trunk/reactos/ntoskrnl/se/semgr.c	2005-08-07 17:46:50 UTC (rev 17175)
+++ trunk/reactos/ntoskrnl/se/semgr.c	2005-08-07 18:38:37 UTC (rev 17176)
@@ -188,7 +188,223 @@
    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
  */