[NTOS:IO] Fail, if io completion port and an apc routine are used at the same time

Add checks to NtNotifyChangeDirectoryFile, NtLockFile, NtReadFile and NtWriteFile.
This fixes two ntdll tests.
This commit is contained in:
Eric Kohl 2021-11-24 13:34:26 +01:00
parent b3c6407d6e
commit 07e19a5e09

View file

@ -287,7 +287,7 @@ IopDeviceFsIoControl(IN HANDLE DeviceHandle,
&HandleInformation); &HandleInformation);
if (!NT_SUCCESS(Status)) return Status; if (!NT_SUCCESS(Status)) return Status;
/* Can't use an I/O completion port and an APC in the same time */ /* Can't use an I/O completion port and an APC at the same time */
if ((FileObject->CompletionContext) && (UserApcRoutine)) if ((FileObject->CompletionContext) && (UserApcRoutine))
{ {
/* Fail */ /* Fail */
@ -1675,6 +1675,14 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
NULL); NULL);
if (!NT_SUCCESS(Status)) return Status; if (!NT_SUCCESS(Status)) return Status;
/* Can't use an I/O completion port and an APC at the same time */
if ((FileObject->CompletionContext) && (ApcRoutine))
{
/* Fail */
ObDereferenceObject(FileObject);
return STATUS_INVALID_PARAMETER;
}
/* Check if we have an event handle */ /* Check if we have an event handle */
if (EventHandle) if (EventHandle)
{ {
@ -1793,6 +1801,14 @@ NtLockFile(IN HANDLE FileHandle,
/* Check if we're called from user mode */ /* Check if we're called from user mode */
if (PreviousMode != KernelMode) if (PreviousMode != KernelMode)
{ {
/* Can't use an I/O completion port and an APC at the same time */
if ((FileObject->CompletionContext) && (ApcRoutine))
{
/* Fail */
ObDereferenceObject(FileObject);
return STATUS_INVALID_PARAMETER;
}
/* Must have either FILE_READ_DATA or FILE_WRITE_DATA access */ /* Must have either FILE_READ_DATA or FILE_WRITE_DATA access */
if (!(HandleInformation.GrantedAccess & if (!(HandleInformation.GrantedAccess &
(FILE_WRITE_DATA | FILE_READ_DATA))) (FILE_WRITE_DATA | FILE_READ_DATA)))
@ -2743,6 +2759,14 @@ NtReadFile(IN HANDLE FileHandle,
CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset); CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
} }
/* Can't use an I/O completion port and an APC at the same time */
if ((FileObject->CompletionContext) && (ApcRoutine))
{
/* Fail */
ObDereferenceObject(FileObject);
return STATUS_INVALID_PARAMETER;
}
/* 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)
{ {
@ -3796,6 +3820,14 @@ NtWriteFile(IN HANDLE FileHandle,
CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset); CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
} }
/* Can't use an I/O completion port and an APC at the same time */
if ((FileObject->CompletionContext) && (ApcRoutine))
{
/* Fail */
ObDereferenceObject(FileObject);
return STATUS_INVALID_PARAMETER;
}
/* 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)
{ {