[NTOSKRNL]
authorPierre Schweitzer <pierre@reactos.org>
Mon, 29 Feb 2016 13:59:32 +0000 (13:59 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Mon, 29 Feb 2016 13:59:32 +0000 (13:59 +0000)
Don't attempt to null-dereference fastio routine without checking whether it was set first.

This fixes RW with FSDs using cache but no FastIO possibilities.

CORE-10892

svn path=/trunk/; revision=70819

reactos/ntoskrnl/io/iomgr/iofunc.c

index ec64bab..61ff138 100644 (file)
@@ -2561,55 +2561,58 @@ NtReadFile(IN HANDLE FileHandle,
         /* If the file is cached, try fast I/O */
         if (FileObject->PrivateCacheMap)
         {
-            /* Perform fast write */
+            /* Perform fast read */
             FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch;
-            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))
+            if (FastIoDispatch != NULL && FastIoDispatch->FastIoRead != NULL)
             {
-                /* Fast path -- update transfer & operation counts */
-                IopUpdateOperationCount(IopReadTransfer);
-                IopUpdateTransferCount(IopReadTransfer,
-                                       (ULONG)KernelIosb.Information);
-
-                /* Enter SEH to write the IOSB back */
-                _SEH2_TRY
+                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))
                 {
-                    /* 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);
+                    /* 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 */
                     IopUnlockFileObject(FileObject);
                     ObDereferenceObject(FileObject);
-                    _SEH2_YIELD(return _SEH2_GetExceptionCode());
+                    return KernelIosb.Status;
                 }
-                _SEH2_END;
-
-                /* Signal the completion event */
-                if (EventObject)
-                {
-                    KeSetEvent(EventObject, 0, FALSE);
-                    ObDereferenceObject(EventObject);
-                }
-
-                /* Clean up */
-                IopUnlockFileObject(FileObject);
-                ObDereferenceObject(FileObject);
-                return KernelIosb.Status;
             }
         }
 
@@ -3573,53 +3576,56 @@ NtWriteFile(IN HANDLE FileHandle,
         /* If the file is cached, try fast I/O */
         if (FileObject->PrivateCacheMap)
         {
-            /* Perform fast read */
+            /* Perform fast write */
             FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch;
-            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)
+            if (FastIoDispatch != NULL && FastIoDispatch->FastIoWrite != NULL)
             {
-                /* Fast path -- update transfer & operation counts */
-                IopUpdateOperationCount(IopWriteTransfer);
-                IopUpdateTransferCount(IopWriteTransfer,
-                                       (ULONG)KernelIosb.Information);
-
-                /* Enter SEH to write the IOSB back */
-                _SEH2_TRY
+                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)
                 {
-                    /* 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);
+                    /* 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 */
                     IopUnlockFileObject(FileObject);
                     ObDereferenceObject(FileObject);
-                    _SEH2_YIELD(return _SEH2_GetExceptionCode());
+                    return KernelIosb.Status;
                 }
-                _SEH2_END;
-
-                /* Signal the completion event */
-                if (EventObject)
-                {
-                    KeSetEvent(EventObject, 0, FALSE);
-                    ObDereferenceObject(EventObject);
-                }
-
-                /* Clean up */
-                IopUnlockFileObject(FileObject);
-                ObDereferenceObject(FileObject);
-                return KernelIosb.Status;
             }
         }