[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / io / iomgr / iofunc.c
index 61ff138..03069ec 100644 (file)
 VOID
 NTAPI
 IopCleanupAfterException(IN PFILE_OBJECT FileObject,
-                         IN PIRP Irp,
+                         IN PIRP Irp OPTIONAL,
                          IN PKEVENT Event OPTIONAL,
                          IN PKEVENT LocalEvent OPTIONAL)
 {
     PAGED_CODE();
     IOTRACE(IO_API_DEBUG, "IRP: %p. FO: %p \n", Irp, FileObject);
 
-    /* Check if we had a buffer */
-    if (Irp->AssociatedIrp.SystemBuffer)
+    if (Irp)
     {
-        /* Free it */
-        ExFreePool(Irp->AssociatedIrp.SystemBuffer);
-    }
+        /* Check if we had a buffer */
+        if (Irp->AssociatedIrp.SystemBuffer)
+        {
+            /* Free it */
+            ExFreePool(Irp->AssociatedIrp.SystemBuffer);
+        }
 
-    /* Free the mdl */
-    if (Irp->MdlAddress) IoFreeMdl(Irp->MdlAddress);
+        /* Free the mdl */
+        if (Irp->MdlAddress) IoFreeMdl(Irp->MdlAddress);
 
-    /* Free the IRP */
-    IoFreeIrp(Irp);
+        /* Free the IRP */
+        IoFreeIrp(Irp);
+    }
 
     /* Check if we had a file lock */
     if (FileObject->Flags & FO_SYNCHRONOUS_IO)
@@ -210,6 +213,9 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
     ACCESS_MASK DesiredAccess;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     ULONG BufferLength;
+
+    PAGED_CODE();
+
     IOTRACE(IO_CTL_DEBUG, "Handle: %p. CTL: %lx. Type: %lx \n",
             DeviceHandle, IoControlCode, IsDevIoCtl);
 
@@ -342,8 +348,8 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
         DeviceObject = IoGetRelatedDeviceObject(FileObject);
     }
 
-    /* If that's FS I/O, try to do it with FastIO path */
-    if (!IsDevIoCtl)
+    /* If this is a device I/O, try to do it with FastIO path */
+    if (IsDevIoCtl)
     {
         PFAST_IO_DISPATCH FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch;
 
@@ -378,10 +384,10 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
                 _SEH2_END;
             }
 
-            /* If we're to dismount a volume, increaase the dismount count */
+            /* If we are dismounting a volume, increase the dismount count */
             if (IoControlCode == FSCTL_DISMOUNT_VOLUME)
             {
-                InterlockedExchangeAdd((PLONG)&SharedUserData->DismountCount, 1);
+                InterlockedIncrement((PLONG)&SharedUserData->DismountCount);
             }
 
             /* Call the FSD */
@@ -412,7 +418,7 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
                 /* Backup our complete context in case it exists */
                 if (FileObject->CompletionContext)
                 {
-                     CompletionInfo = *(FileObject->CompletionContext);
+                    CompletionInfo = *(FileObject->CompletionContext);
                 }
 
                 /* If we had an event, signal it */
@@ -606,7 +612,16 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
     }
 
     /* Use deferred completion for FS I/O */
-    Irp->Flags |= (!IsDevIoCtl) ? IRP_DEFER_IO_COMPLETION : 0;
+    if (!IsDevIoCtl)
+    {
+        Irp->Flags |= IRP_DEFER_IO_COMPLETION;
+    }
+
+    /* If we are dismounting a volume, increaase the dismount count */
+    if (IoControlCode == FSCTL_DISMOUNT_VOLUME)
+    {
+        InterlockedIncrement((PLONG)&SharedUserData->DismountCount);
+    }
 
     /* Perform the call */
     return IopPerformSynchronousRequest(DeviceObject,
@@ -704,7 +719,7 @@ IopQueryDeviceInformation(IN PFILE_OBJECT FileObject,
     /* Check if this was synch I/O */
     if (!LocalEvent)
     {
-        /* Check if the requet is pending */
+        /* Check if the request is pending */
         if (Status == STATUS_PENDING)
         {
             /* Wait on the file object */
@@ -1217,7 +1232,7 @@ IoSetInformation(IN PFILE_OBJECT FileObject,
     /* Check if this was synch I/O */
     if (!LocalEvent)
     {
-        /* Check if the requet is pending */
+        /* Check if the request is pending */
         if (Status == STATUS_PENDING)
         {
             /* Wait on the file object */
@@ -2563,56 +2578,55 @@ NtReadFile(IN HANDLE FileHandle,
         {
             /* Perform fast read */
             FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch;
-            if (FastIoDispatch != NULL && FastIoDispatch->FastIoRead != NULL)
+            ASSERT(FastIoDispatch != NULL && FastIoDispatch->FastIoRead != NULL);
+
+            Success = FastIoDispatch->FastIoRead(FileObject,
+                                                 &CapturedByteOffset,
+                                                 Length,
+                                                 TRUE,
+                                                 CapturedKey,
+                                                 Buffer,
+                                                 &KernelIosb,
+                                                 DeviceObject);
+
+            /* Only accept the result if we got a straightforward status */
+            if (Success &&
+                (KernelIosb.Status == STATUS_SUCCESS ||
+                 KernelIosb.Status == STATUS_BUFFER_OVERFLOW ||
+                 KernelIosb.Status == STATUS_END_OF_FILE))
             {
-                Success = FastIoDispatch->FastIoRead(FileObject,
-                                                     &CapturedByteOffset,
-                                                     Length,
-                                                     TRUE,
-                                                     CapturedKey,
-                                                     Buffer,
-                                                     &KernelIosb,
-                                                     DeviceObject);
-
-                /* Only accept the result if we got a straightforward status */
-                if (Success &&
-                    (KernelIosb.Status == STATUS_SUCCESS ||
-                     KernelIosb.Status == STATUS_BUFFER_OVERFLOW ||
-                     KernelIosb.Status == STATUS_END_OF_FILE))
-                {
-                    /* Fast path -- update transfer & operation counts */
-                    IopUpdateOperationCount(IopReadTransfer);
-                    IopUpdateTransferCount(IopReadTransfer,
-                                           (ULONG)KernelIosb.Information);
+                /* Fast path -- update transfer & operation counts */
+                IopUpdateOperationCount(IopReadTransfer);
+                IopUpdateTransferCount(IopReadTransfer,
+                                       (ULONG)KernelIosb.Information);
 
-                    /* Enter SEH to write the IOSB back */
-                    _SEH2_TRY
-                    {
-                        /* Write it back to the caller */
-                        *IoStatusBlock = KernelIosb;
-                    }
-                    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-                    {
-                        /* The caller's IOSB was invalid, so fail */
-                        if (EventObject) ObDereferenceObject(EventObject);
-                        IopUnlockFileObject(FileObject);
-                        ObDereferenceObject(FileObject);
-                        _SEH2_YIELD(return _SEH2_GetExceptionCode());
-                    }
-                    _SEH2_END;
-
-                    /* Signal the completion event */
-                    if (EventObject)
-                    {
-                        KeSetEvent(EventObject, 0, FALSE);
-                        ObDereferenceObject(EventObject);
-                    }
-
-                    /* Clean up */
+                /* Enter SEH to write the IOSB back */
+                _SEH2_TRY
+                {
+                    /* Write it back to the caller */
+                    *IoStatusBlock = KernelIosb;
+                }
+                _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+                {
+                    /* The caller's IOSB was invalid, so fail */
+                    if (EventObject) ObDereferenceObject(EventObject);
                     IopUnlockFileObject(FileObject);
                     ObDereferenceObject(FileObject);
-                    return KernelIosb.Status;
+                    _SEH2_YIELD(return _SEH2_GetExceptionCode());
+                }
+                _SEH2_END;
+
+                /* Signal the completion event */
+                if (EventObject)
+                {
+                    KeSetEvent(EventObject, 0, FALSE);
+                    ObDereferenceObject(EventObject);
                 }
+
+                /* Clean up */
+                IopUnlockFileObject(FileObject);
+                ObDereferenceObject(FileObject);
+                return KernelIosb.Status;
             }
         }
 
@@ -2727,10 +2741,7 @@ NtReadFile(IN HANDLE FileHandle,
 
     /* Now set the deferred read flags */
     Irp->Flags |= (IRP_READ_OPERATION | IRP_DEFER_IO_COMPLETION);
-#if 0
-    /* FIXME: VFAT SUCKS */
     if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING) Irp->Flags |= IRP_NOCACHE;
-#endif
 
     /* Perform the call */
     return IopPerformSynchronousRequest(DeviceObject,
@@ -3578,54 +3589,53 @@ NtWriteFile(IN HANDLE FileHandle,
         {
             /* Perform fast write */
             FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch;
-            if (FastIoDispatch != NULL && FastIoDispatch->FastIoWrite != NULL)
+            ASSERT(FastIoDispatch != NULL && FastIoDispatch->FastIoWrite != NULL);
+
+            Success = FastIoDispatch->FastIoWrite(FileObject,
+                                                  &CapturedByteOffset,
+                                                  Length,
+                                                  TRUE,
+                                                  CapturedKey,
+                                                  Buffer,
+                                                  &KernelIosb,
+                                                  DeviceObject);
+
+            /* Only accept the result if it was successful */
+            if (Success &&
+                KernelIosb.Status == STATUS_SUCCESS)
             {
-                Success = FastIoDispatch->FastIoWrite(FileObject,
-                                                      &CapturedByteOffset,
-                                                      Length,
-                                                      TRUE,
-                                                      CapturedKey,
-                                                      Buffer,
-                                                      &KernelIosb,
-                                                      DeviceObject);
-
-                /* Only accept the result if it was successful */
-                if (Success &&
-                    KernelIosb.Status == STATUS_SUCCESS)
-                {
-                    /* Fast path -- update transfer & operation counts */
-                    IopUpdateOperationCount(IopWriteTransfer);
-                    IopUpdateTransferCount(IopWriteTransfer,
-                                           (ULONG)KernelIosb.Information);
+                /* Fast path -- update transfer & operation counts */
+                IopUpdateOperationCount(IopWriteTransfer);
+                IopUpdateTransferCount(IopWriteTransfer,
+                                       (ULONG)KernelIosb.Information);
 
-                    /* Enter SEH to write the IOSB back */
-                    _SEH2_TRY
-                    {
-                        /* Write it back to the caller */
-                        *IoStatusBlock = KernelIosb;
-                    }
-                    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-                    {
-                        /* The caller's IOSB was invalid, so fail */
-                        if (EventObject) ObDereferenceObject(EventObject);
-                        IopUnlockFileObject(FileObject);
-                        ObDereferenceObject(FileObject);
-                        _SEH2_YIELD(return _SEH2_GetExceptionCode());
-                    }
-                    _SEH2_END;
-
-                    /* Signal the completion event */
-                    if (EventObject)
-                    {
-                        KeSetEvent(EventObject, 0, FALSE);
-                        ObDereferenceObject(EventObject);
-                    }
-
-                    /* Clean up */
+                /* Enter SEH to write the IOSB back */
+                _SEH2_TRY
+                {
+                    /* Write it back to the caller */
+                    *IoStatusBlock = KernelIosb;
+                }
+                _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+                {
+                    /* The caller's IOSB was invalid, so fail */
+                    if (EventObject) ObDereferenceObject(EventObject);
                     IopUnlockFileObject(FileObject);
                     ObDereferenceObject(FileObject);
-                    return KernelIosb.Status;
+                    _SEH2_YIELD(return _SEH2_GetExceptionCode());
+                }
+                _SEH2_END;
+
+                /* Signal the completion event */
+                if (EventObject)
+                {
+                    KeSetEvent(EventObject, 0, FALSE);
+                    ObDereferenceObject(EventObject);
                 }
+
+                /* Clean up */
+                IopUnlockFileObject(FileObject);
+                ObDereferenceObject(FileObject);
+                return KernelIosb.Status;
             }
         }
 
@@ -3741,10 +3751,7 @@ NtWriteFile(IN HANDLE FileHandle,
 
     /* Now set the deferred read flags */
     Irp->Flags |= (IRP_WRITE_OPERATION | IRP_DEFER_IO_COMPLETION);
-#if 0
-    /* FIXME: VFAT SUCKS */
     if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING) Irp->Flags |= IRP_NOCACHE;
-#endif
 
     /* Perform the call */
     return IopPerformSynchronousRequest(DeviceObject,