Fixed an uninitialized variable error.
[reactos.git] / reactos / ntoskrnl / io / vpb.c
index afe8832..f7d0722 100644 (file)
@@ -4,7 +4,7 @@
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/io/vpb.c
  * PURPOSE:         Volume Parameter Block managment
- * 
+ *
  * PROGRAMMERS:     David Welch (welch@mcmail.com)
  */
 
@@ -18,9 +18,6 @@
 
 static KSPIN_LOCK IoVpbLock;
 
-#define TAG_VPB    TAG('V', 'P', 'B', ' ')
-#define TAG_SYSB   TAG('S', 'Y', 'S', 'B')
-
 /* FUNCTIONS *****************************************************************/
 
 VOID INIT_FUNCTION
@@ -34,16 +31,16 @@ STDCALL
 IopAttachVpb(PDEVICE_OBJECT DeviceObject)
 {
     PVPB Vpb;
-   
+
     /* Allocate the Vpb */
     Vpb = ExAllocatePoolWithTag(NonPagedPool,
                                 sizeof(VPB),
                                 TAG_VPB);
     if (Vpb == NULL) return(STATUS_UNSUCCESSFUL);
-    
+
     /* Clear it so we don't waste time manually */
     RtlZeroMemory(Vpb, sizeof(VPB));
-   
+
     /* Set the Header and Device Field */
     Vpb->Type = IO_TYPE_VPB;
     Vpb->Size = sizeof(VPB);
@@ -56,10 +53,10 @@ IopAttachVpb(PDEVICE_OBJECT DeviceObject)
 
 /*
  * FUNCTION: Queries the volume information
- * ARGUMENTS: 
+ * ARGUMENTS:
  *       FileHandle  = Handle to a file object on the target volume
  *       ReturnLength = DataWritten
- *       FsInformation = Caller should supply storage for the information 
+ *       FsInformation = Caller should supply storage for the information
  *                       structure.
  *       Length = Size of the information structure
  *       FsInformationClass = Index to a information structure
@@ -69,10 +66,10 @@ IopAttachVpb(PDEVICE_OBJECT DeviceObject)
  *             FileFsSizeInformation           FILE_FS_SIZE_INFORMATION
  *             FileFsDeviceInformation         FILE_FS_DEVICE_INFORMATION
  *             FileFsAttributeInformation      FILE_FS_ATTRIBUTE_INFORMATION
- *             FileFsControlInformation        
+ *             FileFsControlInformation
  *             FileFsQuotaQueryInformation     --
  *             FileFsQuotaSetInformation       --
- *             FileFsMaximumInformation        
+ *             FileFsMaximumInformation
  *
  * RETURNS: Status
  *
@@ -89,17 +86,49 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
    PFILE_OBJECT FileObject;
    PDEVICE_OBJECT DeviceObject;
    PIRP Irp;
-   NTSTATUS Status;
+   NTSTATUS Status = STATUS_SUCCESS;
    PIO_STACK_LOCATION StackPtr;
    PVOID SystemBuffer;
    KPROCESSOR_MODE PreviousMode;
-   
-   ASSERT(IoStatusBlock != NULL);
-   ASSERT(FsInformation != NULL);
-   
+
    DPRINT("FsInformation %p\n", FsInformation);
 
    PreviousMode = ExGetPreviousMode();
+   
+   if (PreviousMode != KernelMode)
+   {
+        _SEH_TRY
+        {
+            if (IoStatusBlock != NULL)
+            {
+                ProbeForWrite(IoStatusBlock,
+                              sizeof(IO_STATUS_BLOCK),
+                              sizeof(ULONG));
+            }
+
+            if (Length != 0)
+            {
+                ProbeForWrite(FsInformation,
+                              Length,
+                              1);
+            }
+        }
+        _SEH_HANDLE
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        if (!NT_SUCCESS(Status))
+        {
+            return Status;
+        }
+   }
+   else
+   {
+       ASSERT(IoStatusBlock != NULL);
+       ASSERT(FsInformation != NULL);
+   }
 
    Status = ObReferenceObjectByHandle(FileHandle,
                                      0, /* FIXME - depends on the information class! */
@@ -111,9 +140,9 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
      {
        return(Status);
      }
-   
+
    DeviceObject = FileObject->DeviceObject;
-   
+
    Irp = IoAllocateIrp(DeviceObject->StackSize,
                       TRUE);
    if (Irp == NULL)
@@ -121,7 +150,7 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
        ObDereferenceObject(FileObject);
        return(STATUS_INSUFFICIENT_RESOURCES);
      }
-   
+
    SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
                                        Length,
                                        TAG_SYSB);
@@ -131,7 +160,7 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
        ObDereferenceObject(FileObject);
        return(STATUS_INSUFFICIENT_RESOURCES);
      }
-   
+
    /* Trigger FileObject/Event dereferencing */
    Irp->Tail.Overlay.OriginalFileObject = FileObject;
 
@@ -141,7 +170,7 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
    Irp->UserEvent = &FileObject->Event;
    Irp->UserIosb = IoStatusBlock;
    Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-   
+
    StackPtr = IoGetNextIrpStackLocation(Irp);
    StackPtr->MajorFunction = IRP_MJ_QUERY_VOLUME_INFORMATION;
    StackPtr->MinorFunction = 0;
@@ -152,7 +181,7 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
    StackPtr->Parameters.QueryVolume.Length = Length;
    StackPtr->Parameters.QueryVolume.FsInformationClass =
        FsInformationClass;
-   
+
    Status = IoCallDriver(DeviceObject,
                         Irp);
    if (Status == STATUS_PENDING)
@@ -165,17 +194,25 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
        Status = IoStatusBlock->Status;
      }
    DPRINT("Status %x\n", Status);
-   
+
    if (NT_SUCCESS(Status))
      {
-       DPRINT("Information %lu\n", IoStatusBlock->Information);
-       MmSafeCopyToUser(FsInformation,
-                        SystemBuffer,
-                        IoStatusBlock->Information);
+        _SEH_TRY
+        {
+            DPRINT("Information %lu\n", IoStatusBlock->Information);
+            RtlCopyMemory(FsInformation,
+                          SystemBuffer,
+                          IoStatusBlock->Information);
+       }
+       _SEH_HANDLE
+       {
+            Status = _SEH_GetExceptionCode();
+       }
+        _SEH_END;
      }
 
    ExFreePool(SystemBuffer);
-   
+
    return(Status);
 }
 
@@ -195,11 +232,11 @@ IoQueryVolumeInformation(IN PFILE_OBJECT FileObject,
    PDEVICE_OBJECT DeviceObject;
    PIRP Irp;
    NTSTATUS Status;
-   
+
    ASSERT(FsInformation != NULL);
-   
+
    DPRINT("FsInformation %p\n", FsInformation);
-   
+
    Status = ObReferenceObjectByPointer(FileObject,
                                       FILE_READ_ATTRIBUTES,
                                       IoFileObjectType,
@@ -208,9 +245,9 @@ IoQueryVolumeInformation(IN PFILE_OBJECT FileObject,
      {
        return(Status);
      }
-   
+
    DeviceObject = FileObject->DeviceObject;
-   
+
    Irp = IoAllocateIrp(DeviceObject->StackSize,
                       TRUE);
    if (Irp == NULL)
@@ -227,7 +264,7 @@ IoQueryVolumeInformation(IN PFILE_OBJECT FileObject,
    Irp->UserEvent = &FileObject->Event;
    Irp->UserIosb = &IoStatusBlock;
    Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-   
+
    StackPtr = IoGetNextIrpStackLocation(Irp);
    StackPtr->MajorFunction = IRP_MJ_QUERY_VOLUME_INFORMATION;
    StackPtr->MinorFunction = 0;
@@ -238,7 +275,7 @@ IoQueryVolumeInformation(IN PFILE_OBJECT FileObject,
    StackPtr->Parameters.QueryVolume.Length = Length;
    StackPtr->Parameters.QueryVolume.FsInformationClass =
        FsInformationClass;
-   
+
    Status = IoCallDriver(DeviceObject,
                         Irp);
    if (Status == STATUS_PENDING)
@@ -251,12 +288,12 @@ IoQueryVolumeInformation(IN PFILE_OBJECT FileObject,
        Status = IoStatusBlock.Status;
      }
    DPRINT("Status %x\n", Status);
-   
+
    if (ReturnedLength != NULL)
      {
        *ReturnedLength = IoStatusBlock.Information;
      }
-   
+
    return(Status);
 }
 
@@ -279,10 +316,43 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
    PVOID SystemBuffer;
    KPROCESSOR_MODE PreviousMode;
 
-   ASSERT(IoStatusBlock != NULL);
-   ASSERT(FsInformation != NULL);
-
    PreviousMode = ExGetPreviousMode();
+   
+   if (PreviousMode != KernelMode)
+   {
+      Status = STATUS_SUCCESS;
+      _SEH_TRY
+      {
+         if (IoStatusBlock != NULL)
+         {
+            ProbeForWrite(IoStatusBlock,
+                          sizeof(IO_STATUS_BLOCK),
+                          sizeof(ULONG));
+         }
+
+         if (Length != 0)
+         {
+            ProbeForRead(FsInformation,
+                         Length,
+                         1);
+         }
+      }
+      _SEH_HANDLE
+      {
+         Status = _SEH_GetExceptionCode();
+      }
+      _SEH_END;
+
+      if (!NT_SUCCESS(Status))
+      {
+         return Status;
+      }
+   }
+   else
+   {
+      ASSERT(IoStatusBlock != NULL);
+      ASSERT(FsInformation != NULL);
+   }
 
    Status = ObReferenceObjectByHandle(FileHandle,
                                      FILE_WRITE_ATTRIBUTES,
@@ -294,30 +364,57 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
      {
        return(Status);
      }
-   
+
    DeviceObject = FileObject->DeviceObject;
-   
+
    Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
    if (Irp == NULL)
      {
        ObDereferenceObject(FileObject);
        return(STATUS_INSUFFICIENT_RESOURCES);
      }
-   
+
    SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
                                        Length,
                                        TAG_SYSB);
    if (SystemBuffer == NULL)
      {
-       IoFreeIrp(Irp);
-       ObDereferenceObject(FileObject);
-       return(STATUS_INSUFFICIENT_RESOURCES);
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto failfreeirp;
      }
-   
-   MmSafeCopyFromUser(SystemBuffer,
-                     FsInformation,
-                     Length);
-   
+
+   if (PreviousMode != KernelMode)
+   {
+      _SEH_TRY
+      {
+         /* no need to probe again */
+         RtlCopyMemory(SystemBuffer,
+                       FsInformation,
+                       Length);
+      }
+      _SEH_HANDLE
+      {
+         Status = _SEH_GetExceptionCode();
+      }
+      _SEH_END;
+
+      if (!NT_SUCCESS(Status))
+      {
+         ExFreePoolWithTag(SystemBuffer,
+                           TAG_SYSB);
+failfreeirp:
+         IoFreeIrp(Irp);
+         ObDereferenceObject(FileObject);
+         return Status;
+      }
+   }
+   else
+   {
+      RtlCopyMemory(SystemBuffer,
+                    FsInformation,
+                    Length);
+   }
+
    /* Trigger FileObject/Event dereferencing */
    Irp->Tail.Overlay.OriginalFileObject = FileObject;
    Irp->RequestorMode = PreviousMode;
@@ -326,7 +423,7 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
    Irp->UserEvent = &FileObject->Event;
    Irp->UserIosb = IoStatusBlock;
    Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-   
+
    StackPtr = IoGetNextIrpStackLocation(Irp);
    StackPtr->MajorFunction = IRP_MJ_SET_VOLUME_INFORMATION;
    StackPtr->MinorFunction = 0;
@@ -337,7 +434,7 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
    StackPtr->Parameters.SetVolume.Length = Length;
    StackPtr->Parameters.SetVolume.FsInformationClass =
        FsInformationClass;
-   
+
    Status = IoCallDriver(DeviceObject,Irp);
    if (Status == STATUS_PENDING)
      {
@@ -346,11 +443,19 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
                              PreviousMode,
                              FALSE,
                              NULL);
-       Status = IoStatusBlock->Status;
+        _SEH_TRY
+        {
+           Status = IoStatusBlock->Status;
+        }
+        _SEH_HANDLE
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
      }
 
    ExFreePool(SystemBuffer);
-   
+
    return(Status);
 }