Author: dcote
Date: Sat Jan 27 08:26:30 2007
New Revision: 25646
URL: 
http://svn.reactos.org/svn/reactos?rev=25646&view=rev
Log:
Added function FsRtlGetFileSize()
Added function FsRtlMdlRead() (mostly Alex's reviewed)
Modified:
    trunk/reactos/ntoskrnl/fsrtl/fastio.c
Modified: trunk/reactos/ntoskrnl/fsrtl/fastio.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/fsrtl/fastio.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/fsrtl/fastio.c (original)
+++ trunk/reactos/ntoskrnl/fsrtl/fastio.c Sat Jan 27 08:26:30 2007
@@ -701,9 +701,95 @@
 FsRtlGetFileSize(IN PFILE_OBJECT  FileObject,
                  IN OUT PLARGE_INTEGER FileSize)
 {
-    KEBUGCHECK(0);
-    return STATUS_UNSUCCESSFUL;
-}
+    FILE_STANDARD_INFORMATION Info;
+    NTSTATUS Status;
+    IO_STATUS_BLOCK IoStatus;
+    PDEVICE_OBJECT DeviceObject;
+    PFAST_IO_DISPATCH FastDispatch;
+    KEVENT Event;
+    PIO_STACK_LOCATION IoStackLocation;
+    PIRP Irp;
+    BOOLEAN OldHardError;
+
+
+    PAGED_CODE();
+
+    /* Get Device Object and Fast Calls */
+    DeviceObject = IoGetRelatedDeviceObject(FileObject);
+    FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
+
+    /* Check if we support Fast Calls, and check FastIoQueryStandardInfo */
+    /* Call the function and see if it succeeds */
+    if (    !FastDispatch ||
+            !FastDispatch->FastIoQueryStandardInfo ||
+            !FastDispatch->FastIoQueryStandardInfo(FileObject,TRUE,
+                &Info,&IoStatus,DeviceObject))
+    {
+        /* If any of the above failed, then we are going to send an IRP to the device
object */
+        /* Initialize the even for the IO */
+        KeInitializeEvent(&Event,NotificationEvent,FALSE);
+        /* Allocate the IRP */
+        Irp = IoAllocateIrp(DeviceObject->StackSize,FALSE);
+        if (Irp == NULL)
+        {
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+
+        /* Don't process hard error */
+        OldHardError = IoSetThreadHardErrorMode(FALSE);
+
+        /* Setup the IRP */
+        Irp->UserIosb = &IoStatus;
+        Irp->UserEvent = &Event;
+        Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+        Irp->Flags = IRP_INPUT_OPERATION | IRP_PAGING_IO;
+        Irp->RequestorMode = KernelMode;
+        Irp->Tail.Overlay.OriginalFileObject = FileObject;
+        Irp->AssociatedIrp.SystemBuffer = &Info;
+
+        /* Setup out stack location */
+        IoStackLocation = Irp->Tail.Overlay.CurrentStackLocation;
+        IoStackLocation--;
+        IoStackLocation->MajorFunction = IRP_MJ_QUERY_INFORMATION;
+        IoStackLocation->FileObject = FileObject;
+        IoStackLocation->DeviceObject = DeviceObject;
+        IoStackLocation->Parameters.QueryFile.Length =
ALIGN_UP(sizeof(FILE_INFORMATION_CLASS),ULONG);
+        IoStackLocation->Parameters.QueryFile.FileInformationClass =
FileStandardInformation;
+
+        /* Send the IRP to the related device object */
+        Status = IofCallDriver(DeviceObject,Irp);
+
+        /* Standard DDK IRP result processing */
+        if (Status == STATUS_PENDING) {
+            KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
+        }
+
+        /* If there was a synchronous error, signal it */
+        if (!NT_SUCCESS(Status)) {
+            IoStatus.Status = Status;
+        }
+
+        IoSetThreadHardErrorMode(OldHardError);
+    }
+
+    /* Check the sync/async IO result */
+    if (NT_SUCCESS(IoStatus.Status))
+    {
+        /* Was the request for a directory ? */
+        if (Info.Directory)
+        {
+            IoStatus.Status = STATUS_FILE_IS_A_DIRECTORY;
+        }
+        else
+        {
+            FileSize->QuadPart = Info.EndOfFile.QuadPart;
+         }
+    }
+
+    return IoStatus.Status;
+}
+
 /*
  * @implemented
@@ -717,8 +803,45 @@
              OUT PMDL *MdlChain,
              OUT PIO_STATUS_BLOCK IoStatus)
 {
-    KEBUGCHECK(0);
-    return FALSE;
+    PDEVICE_OBJECT DeviceObject, BaseDeviceObject;
+    PFAST_IO_DISPATCH FastDispatch;
+
+    /* Get Device Object and Fast Calls */
+    DeviceObject = IoGetRelatedDeviceObject(FileObject);
+    FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
+
+    /* Check if we support Fast Calls, and check this one */
+    if (FastDispatch && FastDispatch->MdlRead)
+    {
+        /* Use the fast path */
+        return FastDispatch->MdlRead(FileObject,
+                                     FileOffset,
+                                     Length,
+                                     LockKey,
+                                     MdlChain,
+                                     IoStatus,
+                                     DeviceObject);
+    }
+
+    /* Get the Base File System (Volume) and Fast Calls */
+    BaseDeviceObject = IoGetBaseFileSystemDeviceObject(FileObject);
+    FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch;
+
+    /* If the Base Device Object has its own FastDispatch Routine, fail */
+    if (FastDispatch && FastDispatch->MdlRead &&
+        BaseDeviceObject != DeviceObject)
+    {
+        return FALSE;
+    }
+
+    /* No fast path, use slow path */
+    return FsRtlMdlReadDev(FileObject,
+                           FileOffset,
+                           Length,
+                           LockKey,
+                           MdlChain,
+                           IoStatus,
+                           DeviceObject);
 }
 /*