some more parameter checks in IoCreateFile()
Modified: trunk/reactos/include/ddk/iodef.h
Modified: trunk/reactos/ntoskrnl/io/create.c

Modified: trunk/reactos/include/ddk/iodef.h
--- trunk/reactos/include/ddk/iodef.h	2005-01-24 23:23:38 UTC (rev 13258)
+++ trunk/reactos/include/ddk/iodef.h	2005-01-24 23:59:30 UTC (rev 13259)
@@ -163,7 +163,8 @@
 /*
  * IoCreateFile options
  */
-#define IO_NO_PARAMETER_CHECKING 0x100
+#define IO_NO_PARAMETER_CHECKING   0x0100
+#define IO_CHECK_CREATE_PARAMETERS 0x0200
 
 /*
  * Possible flags for the device object flags

Modified: trunk/reactos/ntoskrnl/io/create.c
--- trunk/reactos/ntoskrnl/io/create.c	2005-01-24 23:23:38 UTC (rev 13258)
+++ trunk/reactos/ntoskrnl/io/create.c	2005-01-24 23:59:30 UTC (rev 13259)
@@ -337,13 +337,15 @@
 	     IN	ULONG			Options)
 {
    PFILE_OBJECT		FileObject;
-   NTSTATUS		Status;
    PIRP			Irp;
    PIO_STACK_LOCATION	StackLoc;
    IO_SECURITY_CONTEXT  SecurityContext;
-   KPROCESSOR_MODE      PreviousMode;
+   KPROCESSOR_MODE      AccessMode;
    HANDLE               LocalFileHandle;
    IO_STATUS_BLOCK      LocalIoStatusBlock;
+   LARGE_INTEGER        SafeAllocationSize;
+   PVOID                SystemEaBuffer = NULL;
+   NTSTATUS		Status = STATUS_SUCCESS;
    
    DPRINT("IoCreateFile(FileHandle %x, DesiredAccess %x, "
 	  "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
@@ -357,12 +359,79 @@
 
    LocalFileHandle = 0;
 
-   PreviousMode = ExGetPreviousMode();
+   if(Options & IO_NO_PARAMETER_CHECKING)
+     AccessMode = KernelMode;
+   else
+     AccessMode = ExGetPreviousMode();
+   
+   if(AccessMode != KernelMode)
+   {
+     _SEH_TRY
+     {
+       ProbeForWrite(FileHandle,
+                     sizeof(HANDLE),
+                     sizeof(ULONG));
+       ProbeForWrite(IoStatusBlock,
+                     sizeof(IO_STATUS_BLOCK),
+                     sizeof(ULONG));
+       if(AllocationSize != NULL)
+       {
+         ProbeForRead(AllocationSize,
+                      sizeof(LARGE_INTEGER),
+                      sizeof(ULONG));
+         SafeAllocationSize = *AllocationSize;
+       }
+       else
+         SafeAllocationSize.QuadPart = 0;
 
-   Status = ObCreateObject(0 == (Options & IO_NO_PARAMETER_CHECKING) ? PreviousMode : KernelMode,
+       if(EaBuffer != NULL && EaLength > 0)
+       {
+         ProbeForRead(EaBuffer,
+                      EaLength,
+                      sizeof(ULONG));
+
+         /* marshal EaBuffer */
+         SystemEaBuffer = ExAllocatePool(NonPagedPool,
+                                         EaLength);
+         if(SystemEaBuffer == NULL)
+         {
+           Status = STATUS_INSUFFICIENT_RESOURCES;
+           _SEH_LEAVE;
+         }
+
+         RtlCopyMemory(SystemEaBuffer,
+                       EaBuffer,
+                       EaLength);
+       }
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
+   }
+   else
+   {
+     if(AllocationSize != NULL)
+       SafeAllocationSize = *AllocationSize;
+     else
+       SafeAllocationSize.QuadPart = 0;
+
+     if(EaBuffer != NULL && EaLength > 0)
+     {
+       SystemEaBuffer = EaBuffer;
+     }
+   }
+
+   if(Options & IO_CHECK_CREATE_PARAMETERS)
+   {
+     DPRINT1("FIXME: IO_CHECK_CREATE_PARAMETERS not yet supported!\n");
+   }
+
+   Status = ObCreateObject(AccessMode,
 			   IoFileObjectType,
 			   ObjectAttributes,
-			   PreviousMode,
+			   AccessMode,
 			   NULL,
 			   sizeof(FILE_OBJECT),
 			   0,
@@ -426,16 +495,13 @@
 
    //trigger FileObject/Event dereferencing
    Irp->Tail.Overlay.OriginalFileObject = FileObject;
-   Irp->RequestorMode = PreviousMode;
+   Irp->RequestorMode = AccessMode;
    Irp->UserIosb = &LocalIoStatusBlock;
-   Irp->AssociatedIrp.SystemBuffer = EaBuffer;
+   Irp->AssociatedIrp.SystemBuffer = SystemEaBuffer;
    Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
    Irp->Tail.Overlay.Thread = PsGetCurrentThread();
    Irp->UserEvent = &FileObject->Event;
-   if (AllocationSize)
-   {
-      Irp->Overlay.AllocationSize = *AllocationSize;
-   }
+   Irp->Overlay.AllocationSize = SafeAllocationSize;
    
    /*
     * Get the stack location for the new
@@ -458,7 +524,7 @@
 	  StackLoc->Parameters.Create.Options |= (CreateDisposition << 24);
 	  StackLoc->Parameters.Create.FileAttributes = (USHORT)FileAttributes;
 	  StackLoc->Parameters.Create.ShareAccess = (USHORT)ShareAccess;
-	  StackLoc->Parameters.Create.EaLength = EaLength;
+	  StackLoc->Parameters.Create.EaLength = SystemEaBuffer != NULL ? EaLength : 0;
 	  break;
 	
 	case CreateFileTypeNamedPipe:
@@ -492,7 +558,7 @@
      {
 	KeWaitForSingleObject(&FileObject->Event,
 			      Executive,
-			      PreviousMode,
+			      AccessMode,
 			      FALSE,
 			      NULL);
 	Status = LocalIoStatusBlock.Status;
@@ -507,32 +573,24 @@
      }
    else
      {
-	if (KernelMode == PreviousMode || 0 != (Options & IO_NO_PARAMETER_CHECKING))
-	  {
-	     *FileHandle = LocalFileHandle;
-	     *IoStatusBlock = LocalIoStatusBlock;
-	  }
-	else
-	  {
-	     _SEH_TRY
-	       {
-	          ProbeForWrite(FileHandle,
-	                        sizeof(HANDLE),
-	                        sizeof(ULONG));
-	          *FileHandle = LocalFileHandle;
-	          ProbeForWrite(IoStatusBlock,
-	                        sizeof(IO_STATUS_BLOCK),
-	                        sizeof(ULONG));
-	          *IoStatusBlock = LocalIoStatusBlock;
-	       }
-	     _SEH_HANDLE
-	       {
-	          Status = _SEH_GetExceptionCode();
-	       }
-	     _SEH_END;
-	  }
+	 _SEH_TRY
+	   {
+	      *FileHandle = LocalFileHandle;
+	      *IoStatusBlock = LocalIoStatusBlock;
+	   }
+	 _SEH_HANDLE
+	   {
+	      Status = _SEH_GetExceptionCode();
+	   }
+	 _SEH_END;
      }
 
+   /* cleanup EABuffer if captured */
+   if(AccessMode != KernelMode && SystemEaBuffer != NULL)
+   {
+     ExFreePool(SystemEaBuffer);
+   }
+
    ASSERT_IRQL(PASSIVE_LEVEL);
 
    DPRINT("Finished IoCreateFile() (*FileHandle) %x\n", (*FileHandle));