IoCreateFile should be passed kernelmode parameters.
Modified: trunk/reactos/ntoskrnl/include/internal/safe.h
Modified: trunk/reactos/ntoskrnl/io/create.c
Modified: trunk/reactos/ntoskrnl/io/mailslot.c
Modified: trunk/reactos/ntoskrnl/io/npipe.c
Modified: trunk/reactos/ntoskrnl/rtl/capture.c

Modified: trunk/reactos/ntoskrnl/include/internal/safe.h
--- trunk/reactos/ntoskrnl/include/internal/safe.h	2005-01-24 19:32:40 UTC (rev 13251)
+++ trunk/reactos/ntoskrnl/include/internal/safe.h	2005-01-24 19:42:54 UTC (rev 13252)
@@ -21,4 +21,28 @@
 	                        IN KPROCESSOR_MODE CurrentMode,
 	                        IN BOOLEAN CaptureIfKernel);
 
-#endif /* __NTOSKRNL_INCLUDE_INTERNAL_SAFE_Hb */
+NTSTATUS
+RtlCaptureSecurityDescriptor(OUT PSECURITY_DESCRIPTOR Dest,
+                             IN KPROCESSOR_MODE PreviousMode,
+                             IN POOL_TYPE PoolType,
+                             IN BOOLEAN CaptureIfKernel,
+                             IN PSECURITY_DESCRIPTOR UnsafeSrc);
+
+VOID
+RtlReleaseCapturedSecurityDescriptor(IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor,
+                                     IN KPROCESSOR_MODE CurrentMode,
+                                     IN BOOLEAN CaptureIfKernel);
+
+NTSTATUS
+RtlCaptureObjectAttributes(OUT POBJECT_ATTRIBUTES Dest,
+                           IN KPROCESSOR_MODE CurrentMode,
+                           IN POOL_TYPE PoolType,
+                           IN BOOLEAN CaptureIfKernel,
+                           IN POBJECT_ATTRIBUTES UnsafeSrc);
+
+VOID
+RtlReleaseCapturedObjectAttributes(IN POBJECT_ATTRIBUTES CapturedObjectAttributes,
+                                   IN KPROCESSOR_MODE CurrentMode,
+                                   IN BOOLEAN CaptureIfKernel);
+
+#endif /* __NTOSKRNL_INCLUDE_INTERNAL_SAFE_H */

Modified: trunk/reactos/ntoskrnl/io/create.c
--- trunk/reactos/ntoskrnl/io/create.c	2005-01-24 19:32:40 UTC (rev 13251)
+++ trunk/reactos/ntoskrnl/io/create.c	2005-01-24 19:42:54 UTC (rev 13252)
@@ -17,7 +17,7 @@
 
 /* GLOBALS *******************************************************************/
 
-#define TAG_FILE_NAME     TAG('F', 'N', 'A', 'M')
+#define TAG_IO_CREATE     TAG('I', 'O', 'C', 'R')
 
 /* FUNCTIONS *************************************************************/
 
@@ -357,7 +357,7 @@
 
    PreviousMode = ExGetPreviousMode();
 
-   Status = ObCreateObject(PreviousMode,
+   Status = ObCreateObject(KernelMode,
 			   IoFileObjectType,
 			   ObjectAttributes,
 			   PreviousMode,
@@ -533,32 +533,132 @@
  * @implemented
  */
 NTSTATUS STDCALL
-NtCreateFile(PHANDLE FileHandle,
+NtCreateFile(PHANDLE FileHandleUnsafe,
 	     ACCESS_MASK DesiredAccess,
-	     POBJECT_ATTRIBUTES ObjectAttributes,
-	     PIO_STATUS_BLOCK IoStatusBlock,
-	     PLARGE_INTEGER AllocateSize,
+	     POBJECT_ATTRIBUTES ObjectAttributesUnsafe,
+	     PIO_STATUS_BLOCK IoStatusBlockUnsafe,
+	     PLARGE_INTEGER AllocateSizeUnsafe,
 	     ULONG FileAttributes,
 	     ULONG ShareAccess,
 	     ULONG CreateDisposition,
 	     ULONG CreateOptions,
-	     PVOID EaBuffer,
+	     PVOID EaBufferUnsafe,
 	     ULONG EaLength)
 {
-   return IoCreateFile(FileHandle,
-		       DesiredAccess,
-		       ObjectAttributes,
-		       IoStatusBlock,
-		       AllocateSize,
-		       FileAttributes,
-		       ShareAccess,
-		       CreateDisposition,
-		       CreateOptions,
-		       EaBuffer,
-		       EaLength,
-		       CreateFileTypeNone,
-		       NULL,
-		       0);
+   KPROCESSOR_MODE PreviousMode;
+   NTSTATUS Status;
+   HANDLE FileHandle;
+   OBJECT_ATTRIBUTES ObjectAttributes;
+   IO_STATUS_BLOCK IoStatusBlock;
+   LARGE_INTEGER AllocateSize;
+   PVOID EaBuffer;
+
+   PreviousMode = ExGetPreviousMode();
+   if (KernelMode == PreviousMode)
+     {
+        return IoCreateFile(FileHandleUnsafe,
+                            DesiredAccess,
+                            ObjectAttributesUnsafe,
+                            IoStatusBlockUnsafe,
+                            AllocateSizeUnsafe,
+                            FileAttributes,
+                            ShareAccess,
+                            CreateDisposition,
+                            CreateOptions,
+                            EaBufferUnsafe,
+                            EaLength,
+                            CreateFileTypeNone,
+                            NULL,
+                            0);
+     }
+
+   Status = RtlCaptureObjectAttributes(&ObjectAttributes,
+                                       PreviousMode,
+                                       PagedPool,
+                                       FALSE,
+                                       ObjectAttributesUnsafe);
+   if (! NT_SUCCESS(Status))
+     {
+        return Status;
+     }
+
+   if (0 != EaLength)
+     {
+        EaBuffer = ExAllocatePoolWithTag(PagedPool, EaLength, TAG_IO_CREATE);
+        if (NULL == EaBuffer)
+          {
+             RtlReleaseCapturedObjectAttributes(&ObjectAttributes,
+                                                PreviousMode,
+                                                FALSE);
+             return STATUS_NO_MEMORY;
+          }
+     }
+
+   _SEH_TRY
+     {
+        if (NULL != AllocateSizeUnsafe)
+          {
+             ProbeForRead(AllocateSizeUnsafe,
+                          sizeof(LARGE_INTEGER),
+                          sizeof(ULONG));
+             AllocateSize = *AllocateSizeUnsafe;
+          }
+        if (0 != EaLength)
+          {
+             ProbeForRead(EaBufferUnsafe,
+                          EaLength,
+                          sizeof(UCHAR));
+             RtlCopyMemory(EaBuffer, EaBufferUnsafe, EaLength);
+          }
+     }
+   _SEH_HANDLE
+     {
+        Status = _SEH_GetExceptionCode();
+     }
+   _SEH_END;
+    
+   if (! NT_SUCCESS(Status))
+     {
+        return Status;
+     }
+
+   Status = IoCreateFile(&FileHandle,
+                         DesiredAccess,
+                         &ObjectAttributes,
+                         &IoStatusBlock,
+                         (NULL == AllocateSizeUnsafe ? NULL : &AllocateSize),
+                         FileAttributes,
+                         ShareAccess,
+                         CreateDisposition,
+                         CreateOptions,
+                         (0 == EaLength ? NULL : EaBuffer),
+                         EaLength,
+                         CreateFileTypeNone,
+                         NULL,
+                         0);
+   if (! NT_SUCCESS(Status))
+     {
+        return Status;
+     }
+
+   _SEH_TRY
+     {
+        ProbeForWrite(FileHandleUnsafe,
+                      sizeof(HANDLE),
+                      sizeof(ULONG));
+        *FileHandleUnsafe = FileHandle;
+        ProbeForWrite(IoStatusBlockUnsafe,
+                      sizeof(IO_STATUS_BLOCK),
+                      sizeof(ULONG));
+        *IoStatusBlockUnsafe = IoStatusBlock;
+     }
+   _SEH_HANDLE
+     {
+        Status = _SEH_GetExceptionCode();
+     }
+   _SEH_END;
+
+   return Status;
 }
 
 
@@ -598,27 +698,90 @@
  * @implemented
  */
 NTSTATUS STDCALL
-NtOpenFile(PHANDLE FileHandle,
+NtOpenFile(PHANDLE FileHandleUnsafe,
 	   ACCESS_MASK DesiredAccess,
-	   POBJECT_ATTRIBUTES ObjectAttributes,
-	   PIO_STATUS_BLOCK IoStatusBlock,
+	   POBJECT_ATTRIBUTES ObjectAttributesUnsafe,
+	   PIO_STATUS_BLOCK IoStatusBlockUnsafe,
 	   ULONG ShareAccess,
 	   ULONG OpenOptions)
 {
-   return IoCreateFile(FileHandle,
-		       DesiredAccess,
-		       ObjectAttributes,
-		       IoStatusBlock,
-		       NULL,
-		       0,
-		       ShareAccess,
-		       FILE_OPEN,
-		       OpenOptions,
-		       NULL,
-		       0,
-		       CreateFileTypeNone,
-		       NULL,
-		       0);
+   KPROCESSOR_MODE PreviousMode;
+   NTSTATUS Status;
+   HANDLE FileHandle;
+   OBJECT_ATTRIBUTES ObjectAttributes;
+   IO_STATUS_BLOCK IoStatusBlock;
+
+   PreviousMode = ExGetPreviousMode();
+   if (KernelMode == PreviousMode)
+     {
+        return IoCreateFile(FileHandleUnsafe,
+                            DesiredAccess,
+                            ObjectAttributesUnsafe,
+                            IoStatusBlockUnsafe,
+                            NULL,
+                            0,
+                            ShareAccess,
+                            FILE_OPEN,
+                            OpenOptions,
+                            NULL,
+                            0,
+                            CreateFileTypeNone,
+                            NULL,
+                            0);
+     }
+
+   Status = RtlCaptureObjectAttributes(&ObjectAttributes,
+                                       PreviousMode,
+                                       PagedPool,
+                                       FALSE,
+                                       ObjectAttributesUnsafe);
+   if (! NT_SUCCESS(Status))
+     {
+        return Status;
+     }
+    
+   if (! NT_SUCCESS(Status))
+     {
+        return Status;
+     }
+
+   Status = IoCreateFile(&FileHandle,
+                         DesiredAccess,
+                         &ObjectAttributes,
+                         &IoStatusBlock,
+                         NULL,
+                         0,
+                         ShareAccess,
+                         FILE_OPEN,
+                         OpenOptions,
+                         NULL,
+                         0,
+                         CreateFileTypeNone,
+                         NULL,
+                         0);
+   if (! NT_SUCCESS(Status))
+     {
+        return Status;
+     }
+
+   _SEH_TRY
+     {
+        ProbeForWrite(FileHandleUnsafe,
+                      sizeof(HANDLE),
+                      sizeof(ULONG));
+        *FileHandleUnsafe = FileHandle;
+        ProbeForWrite(IoStatusBlockUnsafe,
+                      sizeof(IO_STATUS_BLOCK),
+                      sizeof(ULONG));
+        *IoStatusBlockUnsafe = IoStatusBlock;
+     }
+   _SEH_HANDLE
+     {
+        Status = _SEH_GetExceptionCode();
+     }
+   _SEH_END;
+
+   return Status;
 }
 
 /* EOF */

Modified: trunk/reactos/ntoskrnl/io/mailslot.c
--- trunk/reactos/ntoskrnl/io/mailslot.c	2005-01-24 19:32:40 UTC (rev 13251)
+++ trunk/reactos/ntoskrnl/io/mailslot.c	2005-01-24 19:42:54 UTC (rev 13252)
@@ -18,16 +18,21 @@
 /* FUNCTIONS *****************************************************************/
 
 NTSTATUS STDCALL
-NtCreateMailslotFile(OUT PHANDLE FileHandle,
+NtCreateMailslotFile(OUT PHANDLE FileHandleUnsafe,
 		     IN ACCESS_MASK DesiredAccess,
-		     IN POBJECT_ATTRIBUTES ObjectAttributes,
-		     OUT PIO_STATUS_BLOCK IoStatusBlock,
+		     IN POBJECT_ATTRIBUTES ObjectAttributesUnsafe,
+		     OUT PIO_STATUS_BLOCK IoStatusBlockUnsafe,
 		     IN ULONG CreateOptions,
 		     IN ULONG MailslotQuota,
 		     IN ULONG MaxMessageSize,
-		     IN PLARGE_INTEGER TimeOut)
+		     IN PLARGE_INTEGER TimeOutUnsafe)
 {
    MAILSLOT_CREATE_PARAMETERS Buffer;
+   KPROCESSOR_MODE PreviousMode;
+   NTSTATUS Status;
+   HANDLE FileHandle;
+   OBJECT_ATTRIBUTES ObjectAttributes;
+   IO_STATUS_BLOCK IoStatusBlock;
    
    DPRINT("NtCreateMailslotFile(FileHandle %x, DesiredAccess %x, "
 	  "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
@@ -36,32 +41,103 @@
    
    ASSERT_IRQL(PASSIVE_LEVEL);
    
-   if (TimeOut != NULL)
+   if (TimeOutUnsafe != NULL)
      {
-	Buffer.ReadTimeout.QuadPart = TimeOut->QuadPart;
-	Buffer.TimeoutSpecified = TRUE;
+        if (UserMode == PreviousMode)
+          {
+             Status = STATUS_SUCCESS;
+             _SEH_TRY
+               {
+                  ProbeForRead(TimeOutUnsafe,
+                               sizeof(LARGE_INTEGER),
+                               sizeof(LARGE_INTEGER));
+                  Buffer.ReadTimeout.QuadPart = TimeOutUnsafe->QuadPart;
+               }
+             _SEH_HANDLE
+               {
+                  Status = _SEH_GetExceptionCode();
+               }
+             _SEH_END;
+          }
+        else
+          {
+             Buffer.ReadTimeout.QuadPart = TimeOutUnsafe->QuadPart;
+          }
+        Buffer.TimeoutSpecified = TRUE;
      }
    else
      {
-	Buffer.TimeoutSpecified = FALSE;
+        Buffer.TimeoutSpecified = FALSE;
      }
    Buffer.MailslotQuota = MailslotQuota;
    Buffer.MaximumMessageSize = MaxMessageSize;
 
-   return IoCreateFile(FileHandle,
-		       DesiredAccess,
-		       ObjectAttributes,
-		       IoStatusBlock,
-		       NULL,
-		       FILE_ATTRIBUTE_NORMAL,
-		       FILE_SHARE_READ | FILE_SHARE_WRITE,
-		       FILE_CREATE,
-		       CreateOptions,
-		       NULL,
-		       0,
-		       CreateFileTypeMailslot,
-		       (PVOID)&Buffer,
-		       0);
+   PreviousMode = ExGetPreviousMode();
+   if (KernelMode == PreviousMode)
+     {
+        return IoCreateFile(FileHandleUnsafe,
+                            DesiredAccess,
+                            ObjectAttributesUnsafe,
+                            IoStatusBlockUnsafe,
+                            NULL,
+                            FILE_ATTRIBUTE_NORMAL,
+                            FILE_SHARE_READ | FILE_SHARE_WRITE,
+                            FILE_CREATE,
+                            CreateOptions,
+                            NULL,
+                            0,
+                            CreateFileTypeMailslot,
+                            (PVOID)&Buffer,
+                            0);
+     }
+
+   Status = RtlCaptureObjectAttributes(&ObjectAttributes,
+                                       PreviousMode,
+                                       PagedPool,
+                                       FALSE,
+                                       ObjectAttributesUnsafe);
+   if (! NT_SUCCESS(Status))
+     {
+        return Status;
+     }
+
+   Status = IoCreateFile(&FileHandle,
+                         DesiredAccess,
+                         &ObjectAttributes,
+                         &IoStatusBlock,
+                         NULL,
+                         FILE_ATTRIBUTE_NORMAL,
+                         FILE_SHARE_READ | FILE_SHARE_WRITE,
+                         FILE_CREATE,
+                         CreateOptions,
+                         NULL,
+                         0,
+                         CreateFileTypeMailslot,
+                         (PVOID)&Buffer,
+                         0);
+   if (! NT_SUCCESS(Status))
+     {
+        return Status;
+     }
+
+   _SEH_TRY
+     {
+        ProbeForWrite(FileHandleUnsafe,
+                      sizeof(HANDLE),
+                      sizeof(ULONG));
+        *FileHandleUnsafe = FileHandle;
+        ProbeForWrite(IoStatusBlockUnsafe,
+                      sizeof(IO_STATUS_BLOCK),
+                      sizeof(ULONG));
+        *IoStatusBlockUnsafe = IoStatusBlock;
+     }
+   _SEH_HANDLE
+     {
+        Status = _SEH_GetExceptionCode();
+     }
+   _SEH_END;
+
+   return Status;
 }
 
 /* EOF */

Modified: trunk/reactos/ntoskrnl/io/npipe.c
--- trunk/reactos/ntoskrnl/io/npipe.c	2005-01-24 19:32:40 UTC (rev 13251)
+++ trunk/reactos/ntoskrnl/io/npipe.c	2005-01-24 19:42:54 UTC (rev 13252)
@@ -17,10 +17,10 @@
 /* FUNCTIONS *****************************************************************/
 
 NTSTATUS STDCALL
-NtCreateNamedPipeFile(PHANDLE FileHandle,
+NtCreateNamedPipeFile(PHANDLE FileHandleUnsafe,
 		      ACCESS_MASK DesiredAccess,
-		      POBJECT_ATTRIBUTES ObjectAttributes,
-		      PIO_STATUS_BLOCK IoStatusBlock,
+		      POBJECT_ATTRIBUTES ObjectAttributesUnsafe,
+		      PIO_STATUS_BLOCK IoStatusBlockUnsafe,
 		      ULONG ShareAccess,
 		      ULONG CreateDisposition,
 		      ULONG CreateOptions,
@@ -30,9 +30,14 @@
 		      ULONG MaximumInstances,
 		      ULONG InboundQuota,
 		      ULONG OutboundQuota,
-		      PLARGE_INTEGER DefaultTimeout)
+		      PLARGE_INTEGER DefaultTimeoutUnsafe)
 {
   NAMED_PIPE_CREATE_PARAMETERS Buffer;
+  KPROCESSOR_MODE PreviousMode;
+  NTSTATUS Status;
+  HANDLE FileHandle;
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  IO_STATUS_BLOCK IoStatusBlock;
 
   DPRINT("NtCreateNamedPipeFile(FileHandle %x, DesiredAccess %x, "
 	 "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
@@ -41,9 +46,28 @@
 
   ASSERT_IRQL(PASSIVE_LEVEL);
 
-  if (DefaultTimeout != NULL)
+  if (DefaultTimeoutUnsafe != NULL)
     {
-      Buffer.DefaultTimeout.QuadPart = DefaultTimeout->QuadPart;
+      if (UserMode == PreviousMode)
+        {
+          Status = STATUS_SUCCESS;
+          _SEH_TRY
+            {
+              ProbeForRead(DefaultTimeoutUnsafe,
+                           sizeof(LARGE_INTEGER),
+                           sizeof(LARGE_INTEGER));
+              Buffer.DefaultTimeout.QuadPart = DefaultTimeoutUnsafe->QuadPart;
+            }
+          _SEH_HANDLE
+            {
+              Status = _SEH_GetExceptionCode();
+            }
+          _SEH_END;
+        }
+      else
+        {
+          Buffer.DefaultTimeout.QuadPart = DefaultTimeoutUnsafe->QuadPart;
+        }
       Buffer.TimeoutSpecified = TRUE;
     }
   else
@@ -57,20 +81,72 @@
   Buffer.InboundQuota = InboundQuota;
   Buffer.OutboundQuota = OutboundQuota;
 
-  return IoCreateFile(FileHandle,
-		      DesiredAccess,
-		      ObjectAttributes,
-		      IoStatusBlock,
-		      NULL,
-		      FILE_ATTRIBUTE_NORMAL,
-		      ShareAccess,
-		      CreateDisposition,
-		      CreateOptions,
-		      NULL,
-		      0,
-		      CreateFileTypeNamedPipe,
-		      (PVOID)&Buffer,
-		      0);
+  PreviousMode = ExGetPreviousMode();
+  if (KernelMode == PreviousMode)
+    {
+      return IoCreateFile(FileHandleUnsafe,
+                          DesiredAccess,
+                          ObjectAttributesUnsafe,
+                          IoStatusBlockUnsafe,
+                          NULL,
+                          FILE_ATTRIBUTE_NORMAL,
+                          ShareAccess,
+                          CreateDisposition,
+                          CreateOptions,
+                          NULL,
+                          0,
+                          CreateFileTypeNamedPipe,
+                          (PVOID)&Buffer,
+                          0);
+    }
+
+  Status = RtlCaptureObjectAttributes(&ObjectAttributes,
+                                      PreviousMode,
+                                      PagedPool,
+                                      FALSE,
+                                      ObjectAttributesUnsafe);
+  if (! NT_SUCCESS(Status))
+    {
+      return Status;
+    }
+
+  Status = IoCreateFile(&FileHandle,
+                        DesiredAccess,
+                        &ObjectAttributes,
+                        &IoStatusBlock,
+                        NULL,
+                        FILE_ATTRIBUTE_NORMAL,
+                        ShareAccess,
+                        CreateDisposition,
+                        CreateOptions,
+                        NULL,
+                        0,
+                        CreateFileTypeNamedPipe,
+                        (PVOID)&Buffer,
+                        0);
+  if (! NT_SUCCESS(Status))
+    {
+      return Status;
+    }
+
+  _SEH_TRY
+    {
+      ProbeForWrite(FileHandleUnsafe,
+                    sizeof(HANDLE),
+                    sizeof(ULONG));
+      *FileHandleUnsafe = FileHandle;
+      ProbeForWrite(IoStatusBlockUnsafe,
+                    sizeof(IO_STATUS_BLOCK),
+                    sizeof(ULONG));
+      *IoStatusBlockUnsafe = IoStatusBlock;
+    }
+  _SEH_HANDLE
+    {
+      Status = _SEH_GetExceptionCode();
+    }
+  _SEH_END;
+
+  return Status;
 }
 
 /* EOF */

Modified: trunk/reactos/ntoskrnl/rtl/capture.c
--- trunk/reactos/ntoskrnl/rtl/capture.c	2005-01-24 19:32:40 UTC (rev 13251)
+++ trunk/reactos/ntoskrnl/rtl/capture.c	2005-01-24 19:42:54 UTC (rev 13252)
@@ -32,6 +32,8 @@
 #define NDEBUG
 #include <internal/debug.h>
 
+#define TAG_CAPT  TAG('C', 'A', 'P', 'T')
+
 /* FUNCTIONS *****************************************************************/
 
 NTSTATUS
@@ -95,7 +97,7 @@
   if(Src.Length > 0)
   {
     Dest->MaximumLength = Src.Length + sizeof(WCHAR);
-    Dest->Buffer = ExAllocatePool(PoolType, Dest->MaximumLength);
+    Dest->Buffer = ExAllocatePoolWithTag(PoolType, Dest->MaximumLength, TAG_CAPT);
     if (Dest->Buffer == NULL)
     {
       Dest->Length = Dest->MaximumLength = 0;
@@ -164,7 +166,7 @@
    */
   Dest->Length = Src->Length;
   Dest->MaximumLength = Src->MaximumLength;
-  Dest->Buffer = ExAllocatePool(NonPagedPool, Dest->MaximumLength);
+  Dest->Buffer = ExAllocatePoolWithTag(NonPagedPool, Dest->MaximumLength, TAG_CAPT);
   if (Dest->Buffer == NULL)
     {
       return(Status);
@@ -183,6 +185,478 @@
   return(STATUS_SUCCESS);
 }
 
+static NTSTATUS
+CaptureSID(OUT PSID *Dest,
+           IN KPROCESSOR_MODE PreviousMode,
+           IN POOL_TYPE PoolType,
+           IN PSID UnsafeSrc)
+{
+  SID Src;
+  ULONG Length;
+  NTSTATUS Status = STATUS_SUCCESS;
+  
+  ASSERT(Dest != NULL);
+
+  if(UserMode == PreviousMode)
+  {  
+    _SEH_TRY
+    {
+      ProbeForRead(UnsafeSrc,
+                   sizeof(SID),
+                   sizeof(ULONG));
+      RtlCopyMemory(&Src, UnsafeSrc, sizeof(SID));
+    }
+    _SEH_HANDLE
+    {
+      Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+    
+    if(!NT_SUCCESS(Status))
+    {
+      return Status;
+    }
+  }
+  else
+  {
+    /* capture even though it is considered to be valid */
+    RtlCopyMemory(&Src, UnsafeSrc, sizeof(SID));
+  }
+
+  if(SID_REVISION != Src.Revision)
+  {
+    return STATUS_INVALID_PARAMETER;
+  }
+
+  Length = RtlLengthSid(&Src);
+  *Dest = ExAllocatePoolWithTag(PoolType, Length, TAG_CAPT);
+  if(NULL == *Dest)
+  {
+    return STATUS_NO_MEMORY;
+  }
+
+  if(UserMode == PreviousMode)
+  {  
+    _SEH_TRY
+    {
+      ProbeForRead(UnsafeSrc,
+                   Length,
+                   sizeof(ULONG));
+      RtlCopyMemory(*Dest, UnsafeSrc, Length);
+    }
+    _SEH_HANDLE
+    {
+      Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+    
+    if(!NT_SUCCESS(Status))
+    {
+      return Status;
+    }
+  }
+  else
+  {
+    RtlCopyMemory(*Dest, UnsafeSrc, Length);
+  }
+
+  return Status;
+}
+
+static NTSTATUS
+CaptureACL(OUT PACL *Dest,
+           IN KPROCESSOR_MODE PreviousMode,
+           IN POOL_TYPE PoolType,
+           IN PACL UnsafeSrc)
+{
+  ACL Src;
+  ULONG Length;
+  NTSTATUS Status = STATUS_SUCCESS;
+  
+  ASSERT(Dest != NULL);
+
+  if(UserMode == PreviousMode)
+  {  
+    _SEH_TRY
+    {
+      ProbeForRead(UnsafeSrc,
+                   sizeof(ACL),
+                   sizeof(ULONG));
+      RtlCopyMemory(&Src, UnsafeSrc, sizeof(ACL));
+    }
+    _SEH_HANDLE
+    {
+      Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+    
+    if(!NT_SUCCESS(Status))
+    {
+      return Status;
+    }
+  }
+  else
+  {
+    /* capture even though it is considered to be valid */
+    RtlCopyMemory(&Src, UnsafeSrc, sizeof(ACL));
+  }
+
+  if(Src.AclRevision < MIN_ACL_REVISION || MAX_ACL_REVISION < Src.AclRevision)
+  {
+    return STATUS_INVALID_PARAMETER;
+  }
+
+  Length = Src.AclSize;
+  *Dest = ExAllocatePoolWithTag(PoolType, Length, TAG_CAPT);
+  if(NULL == *Dest)
+  {
+    return STATUS_NO_MEMORY;
+  }
+
+  if(UserMode == PreviousMode)
+  {  
+    _SEH_TRY
+    {
+      ProbeForRead(UnsafeSrc,
+                   Length,
+                   sizeof(ULONG));
+      RtlCopyMemory(*Dest, UnsafeSrc, Length);
+    }
+    _SEH_HANDLE
+    {
+      Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+    
+    if(!NT_SUCCESS(Status))
+    {
+      return Status;
+    }
+  }
+  else
+  {
+    RtlCopyMemory(*Dest, UnsafeSrc, Length);
+  }
+
+  return Status;
+}
+
+NTSTATUS
+RtlCaptureSecurityDescriptor(OUT PSECURITY_DESCRIPTOR Dest,
+                             IN KPROCESSOR_MODE PreviousMode,
+                             IN POOL_TYPE PoolType,
+                             IN BOOLEAN CaptureIfKernel,
+                             IN PSECURITY_DESCRIPTOR UnsafeSrc)
+{
+  SECURITY_DESCRIPTOR Src;
+  NTSTATUS Status = STATUS_SUCCESS;
+  
+  ASSERT(Dest != NULL);
+  
+  /*
+   * Copy the object attributes to kernel space.
+   */
+  
+  if(PreviousMode == UserMode)
+  {
+    _SEH_TRY
+    {
+      ProbeForRead(UnsafeSrc,
+                   sizeof(SECURITY_DESCRIPTOR),
+                   sizeof(ULONG));
+      Src = *UnsafeSrc;
+    }
+    _SEH_HANDLE
+    {
+      Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+    
+    if(!NT_SUCCESS(Status))
+    {
+      return Status;
+    }
+  }
+  else if(!CaptureIfKernel)
+  {
+    /* just copy the structure, the pointers are considered valid */
+    *Dest = *UnsafeSrc;
+    return STATUS_SUCCESS;
+  }
+  else
+  {
+    /* capture the object attributes even though it is considered to be valid */
+    Src = *UnsafeSrc;
+  }
+
+  if(SECURITY_DESCRIPTOR_REVISION1 != Src.Revision)
+  {
+    return STATUS_INVALID_PARAMETER;
+  }
+
+  Dest->Revision = Src.Revision;  
+  Dest->Sbz1 = Src.Sbz1;
+  Dest->Control = Src.Control;
+  Status = CaptureSID(&Dest->Owner, PreviousMode, PoolType, Src.Owner);
+  if(!NT_SUCCESS(Status))
+  {
+    return Status;
+  }
+  Status = CaptureSID(&Dest->Group, PreviousMode, PoolType, Src.Group);
+  if(!NT_SUCCESS(Status))
+  {
+    if(NULL != Dest->Owner)
+    {
+      ExFreePool(Dest->Owner);
+    }
+    return Status;
+  }
+  Status = CaptureACL(&Dest->Sacl, PreviousMode, PoolType, Src.Sacl);
+  if(!NT_SUCCESS(Status))
+  {
+    if(NULL != Dest->Group)
+    {
+      ExFreePool(Dest->Group);
+    }
+    if(NULL != Dest->Owner)
+    {
+      ExFreePool(Dest->Owner);
+    }
+    return Status;
+  }
+  Status = CaptureACL(&Dest->Dacl, PreviousMode, PoolType, Src.Dacl);
+  if(!NT_SUCCESS(Status))
+  {
+    if(NULL != Dest->Sacl)
+    {
+      ExFreePool(Dest->Sacl);
+    }
+    if(NULL != Dest->Group)
+    {
+      ExFreePool(Dest->Group);
+    }
+    if(NULL != Dest->Owner)
+    {
+      ExFreePool(Dest->Owner);
+    }
+    return Status;
+  }
+
+  return Status;
+}
+
+VOID
+RtlReleaseCapturedSecurityDescriptor(IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor,
+                                     IN KPROCESSOR_MODE PreviousMode,
+                                     IN BOOLEAN CaptureIfKernel) 
+{
+  ASSERT(SECURITY_DESCRIPTOR_REVISION1 == CapturedSecurityDescriptor->Revision);
+
+  if(PreviousMode == KernelMode && !CaptureIfKernel)
+  {
+    return;
+  }
+
+  if(NULL != CapturedSecurityDescriptor->Dacl)
+  {
+    ExFreePool(CapturedSecurityDescriptor->Dacl);
+  }
+  if(NULL != CapturedSecurityDescriptor->Sacl)
+  {
+    ExFreePool(CapturedSecurityDescriptor->Sacl);
+  }
+  if(NULL != CapturedSecurityDescriptor->Group)
+  {
+    ExFreePool(CapturedSecurityDescriptor->Group);
+  }
+  if(NULL != CapturedSecurityDescriptor->Owner)
+  {
+    ExFreePool(CapturedSecurityDescriptor->Owner);
+  }
+}
+
+NTSTATUS
+RtlCaptureObjectAttributes(OUT POBJECT_ATTRIBUTES Dest,
+                           IN KPROCESSOR_MODE PreviousMode,
+                           IN POOL_TYPE PoolType,
+                           IN BOOLEAN CaptureIfKernel,
+                           IN POBJECT_ATTRIBUTES UnsafeSrc)
+{
+  OBJECT_ATTRIBUTES Src;
+  NTSTATUS Status = STATUS_SUCCESS;
+  
+  ASSERT(Dest != NULL);
+  
+  /*
+   * Copy the object attributes to kernel space.
+   */
+  
+  if(PreviousMode == UserMode)
+  {
+    _SEH_TRY
+    {
+      ProbeForRead(UnsafeSrc,
+                   sizeof(OBJECT_ATTRIBUTES),
+                   sizeof(ULONG));
+      Src = *UnsafeSrc;
+    }
+    _SEH_HANDLE
+    {
+      Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+    
+    if(!NT_SUCCESS(Status))
+    {
+      return Status;
+    }
+  }
+  else if(!CaptureIfKernel)
+  {
+    /* just copy the structure, the pointers are considered valid */
+    *Dest = *UnsafeSrc;
+    return STATUS_SUCCESS;
+  }
+  else
+  {
+    /* capture the object attributes even though it is considered to be valid */
+    Src = *UnsafeSrc;
+  }
+
+  if(Src.Length < sizeof(OBJECT_ATTRIBUTES) || NULL == Src.ObjectName)
+  {
+    return STATUS_INVALID_PARAMETER;
+  }
+
+  Dest->Length = sizeof(OBJECT_ATTRIBUTES);
+  Dest->RootDirectory = Src.RootDirectory;
[truncated at 1000 lines; 130 more skipped]