[NTOSKRNL] Quickly check for alignment in NtRead/WriteFile

This quick check based on bits and operation is for 2^ based
sector sizes (most of the cases) and will perform faster than
the modulo operation which is still used in fallback in case
the sector size wouldn't be a power of 2.
This commit is contained in:
Pierre Schweitzer 2018-10-04 10:42:13 +02:00
parent 44155053cd
commit e19e907a2c
No known key found for this signature in database
GPG Key ID: 7545556C3D585B0B

View File

@ -2612,14 +2612,20 @@ NtReadFile(IN HANDLE FileHandle,
/* Perform additional checks for non-cached file access */ /* Perform additional checks for non-cached file access */
if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING) if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING)
{ {
/* Fail if Length is not sector size aligned */ /* Fail if Length is not sector size aligned
* Perform a quick check for 2^ sector sizes
* If it fails, try a more standard way
*/
if ((DeviceObject->SectorSize != 0) && if ((DeviceObject->SectorSize != 0) &&
(Length % DeviceObject->SectorSize != 0)) ((DeviceObject->SectorSize - 1) & Length) != 0)
{
if (Length % DeviceObject->SectorSize != 0)
{ {
/* Release the file object and and fail */ /* Release the file object and and fail */
ObDereferenceObject(FileObject); ObDereferenceObject(FileObject);
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
}
/* Fail if buffer doesn't match alignment requirements */ /* Fail if buffer doesn't match alignment requirements */
if (((ULONG_PTR)Buffer & DeviceObject->AlignmentRequirement) != 0) if (((ULONG_PTR)Buffer & DeviceObject->AlignmentRequirement) != 0)
@ -3649,14 +3655,20 @@ NtWriteFile(IN HANDLE FileHandle,
/* Perform additional checks for non-cached file access */ /* Perform additional checks for non-cached file access */
if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING) if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING)
{ {
/* Fail if Length is not sector size aligned */ /* Fail if Length is not sector size aligned
* Perform a quick check for 2^ sector sizes
* If it fails, try a more standard way
*/
if ((DeviceObject->SectorSize != 0) && if ((DeviceObject->SectorSize != 0) &&
(Length % DeviceObject->SectorSize != 0)) ((DeviceObject->SectorSize - 1) & Length) != 0)
{
if (Length % DeviceObject->SectorSize != 0)
{ {
/* Release the file object and and fail */ /* Release the file object and and fail */
ObDereferenceObject(FileObject); ObDereferenceObject(FileObject);
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
}
/* Fail if buffer doesn't match alignment requirements */ /* Fail if buffer doesn't match alignment requirements */
if (((ULONG_PTR)Buffer & DeviceObject->AlignmentRequirement) != 0) if (((ULONG_PTR)Buffer & DeviceObject->AlignmentRequirement) != 0)