https://git.reactos.org/?p=reactos.git;a=commitdiff;h=fd334021040e0377816e0…
commit fd334021040e0377816e0ca198c9940ed8135e3a
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Thu Oct 4 01:16:17 2018 +0200
Commit: Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Thu Oct 4 01:17:58 2018 +0200
[NTOSKRNL] NtReadFile/NtWriteFile: If a file has been opened for non-cached access,
Length and ByteOffset must be sector size aligned.
This fixed two ntdll apitests.
---
ntoskrnl/io/iomgr/iofunc.c | 83 +++++++++++++++++++++++++++++++++++++---------
1 file changed, 67 insertions(+), 16 deletions(-)
diff --git a/ntoskrnl/io/iomgr/iofunc.c b/ntoskrnl/io/iomgr/iofunc.c
index 58a6316751..c344b422d8 100644
--- a/ntoskrnl/io/iomgr/iofunc.c
+++ b/ntoskrnl/io/iomgr/iofunc.c
@@ -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)
{