[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.
This commit is contained in:
Eric Kohl 2018-10-04 01:16:17 +02:00
parent d8f22735ed
commit fd33402104

View 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)
{