[NTOSKRNL] NtReadFile/NtWriteFile: If a file has been opened for non-cached access...
authorEric Kohl <eric.kohl@reactos.org>
Wed, 3 Oct 2018 23:16:17 +0000 (01:16 +0200)
committerEric Kohl <eric.kohl@reactos.org>
Wed, 3 Oct 2018 23:17:58 +0000 (01:17 +0200)
This fixed two ntdll apitests.

ntoskrnl/io/iomgr/iofunc.c

index 58a6316..c344b42 100644 (file)
@@ -2579,6 +2579,18 @@ NtReadFile(IN HANDLE FileHandle,
     CapturedByteOffset.QuadPart = 0;
     IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
 
+    /* Get File Object */
+    Status = ObReferenceObjectByHandle(FileHandle,
+                                       FILE_READ_DATA,
+                                       IoFileObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&FileObject,
+                                       NULL);
+    if (!NT_SUCCESS(Status)) return Status;
+
+    /* Get the device object */
+    DeviceObject = IoGetRelatedDeviceObject(FileObject);
+
     /* Validate User-Mode Buffers */
     if (PreviousMode != KernelMode)
     {
@@ -2597,12 +2609,38 @@ NtReadFile(IN HANDLE FileHandle,
                 CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
             }
 
+            /* Perform additional checks for non-cached file access */
+            if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING)
+            {
+                /* Fail if Length is not sector size aligned */
+                if ((DeviceObject->SectorSize != 0) &&
+                    (Length % DeviceObject->SectorSize != 0))
+                {
+                    /* Release the file object and and fail */
+                    ObDereferenceObject(FileObject);
+                    return STATUS_INVALID_PARAMETER;
+                }
+
+                if (ByteOffset)
+                {
+                    /* Fail if ByteOffset is not sector size aligned */
+                    if ((DeviceObject->SectorSize != 0) &&
+                        (ByteOffset->QuadPart % DeviceObject->SectorSize != 0))
+                    {
+                        /* Release the file object and and fail */
+                        ObDereferenceObject(FileObject);
+                        return STATUS_INVALID_PARAMETER;
+                    }
+                }
+            }
+
             /* Capture and probe the key */
             if (Key) CapturedKey = ProbeForReadUlong(Key);
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            /* Return the exception code */
+            /* Release the file object and return the exception code */
+            ObDereferenceObject(FileObject);
             _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
@@ -2614,15 +2652,6 @@ NtReadFile(IN HANDLE FileHandle,
         if (Key) CapturedKey = *Key;
     }
 
-    /* Get File Object */
-    Status = ObReferenceObjectByHandle(FileHandle,
-                                       FILE_READ_DATA,
-                                       IoFileObjectType,
-                                       PreviousMode,
-                                       (PVOID*)&FileObject,
-                                       NULL);
-    if (!NT_SUCCESS(Status)) return Status;
-
     /* Check for event */
     if (Event)
     {
@@ -2644,9 +2673,6 @@ NtReadFile(IN HANDLE FileHandle,
         KeClearEvent(EventObject);
     }
 
-    /* Get the device object */
-    DeviceObject = IoGetRelatedDeviceObject(FileObject);
-
     /* Check if we should use Sync IO or not */
     if (FileObject->Flags & FO_SYNCHRONOUS_IO)
     {
@@ -3591,6 +3617,9 @@ NtWriteFile(IN HANDLE FileHandle,
                                            &ObjectHandleInfo);
     if (!NT_SUCCESS(Status)) return Status;
 
+    /* Get the device object */
+    DeviceObject = IoGetRelatedDeviceObject(FileObject);
+
     /* Validate User-Mode Buffers */
     if (PreviousMode != KernelMode)
     {
@@ -3609,6 +3638,31 @@ NtWriteFile(IN HANDLE FileHandle,
                 CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
             }
 
+            /* Perform additional checks for non-cached file access */
+            if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING)
+            {
+                /* Fail if Length is not sector size aligned */
+                if ((DeviceObject->SectorSize != 0) &&
+                    (Length % DeviceObject->SectorSize != 0))
+                {
+                    /* Release the file object and and fail */
+                    ObDereferenceObject(FileObject);
+                    return STATUS_INVALID_PARAMETER;
+                }
+
+                if (ByteOffset)
+                {
+                    /* Fail if ByteOffset is not sector size aligned */
+                    if ((DeviceObject->SectorSize != 0) &&
+                        (ByteOffset->QuadPart % DeviceObject->SectorSize != 0))
+                    {
+                        /* Release the file object and and fail */
+                        ObDereferenceObject(FileObject);
+                        return STATUS_INVALID_PARAMETER;
+                    }
+                }
+            }
+
             /* Capture and probe the key */
             if (Key) CapturedKey = ProbeForReadUlong(Key);
         }
@@ -3657,9 +3711,6 @@ NtWriteFile(IN HANDLE FileHandle,
         KeClearEvent(EventObject);
     }
 
-    /* Get the device object */
-    DeviceObject = IoGetRelatedDeviceObject(FileObject);
-
     /* Check if we should use Sync IO or not */
     if (FileObject->Flags & FO_SYNCHRONOUS_IO)
     {