mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
- if a file object is a named pipe don't allow the FILE_APPEND_DATA access right as it equals FILE_CREATE_PIPE_INSTANCE (NtFlushBuffersFile and NtWriteFile)
- add more parameters probing and capturing code svn path=/trunk/; revision=18932
This commit is contained in:
parent
6e138c7f47
commit
0ecd041efc
1 changed files with 292 additions and 90 deletions
|
@ -755,7 +755,6 @@ IoCreateFile(OUT PHANDLE FileHandle,
|
||||||
IO_SECURITY_CONTEXT SecurityContext;
|
IO_SECURITY_CONTEXT SecurityContext;
|
||||||
KPROCESSOR_MODE AccessMode;
|
KPROCESSOR_MODE AccessMode;
|
||||||
HANDLE LocalHandle;
|
HANDLE LocalHandle;
|
||||||
IO_STATUS_BLOCK LocalIoStatusBlock;
|
|
||||||
LARGE_INTEGER SafeAllocationSize;
|
LARGE_INTEGER SafeAllocationSize;
|
||||||
PVOID SystemEaBuffer = NULL;
|
PVOID SystemEaBuffer = NULL;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
@ -988,7 +987,7 @@ IoCreateFile(OUT PHANDLE FileHandle,
|
||||||
//trigger FileObject/Event dereferencing
|
//trigger FileObject/Event dereferencing
|
||||||
Irp->Tail.Overlay.OriginalFileObject = FileObject;
|
Irp->Tail.Overlay.OriginalFileObject = FileObject;
|
||||||
Irp->RequestorMode = AccessMode;
|
Irp->RequestorMode = AccessMode;
|
||||||
Irp->UserIosb = &LocalIoStatusBlock;
|
Irp->UserIosb = IoStatusBlock;
|
||||||
Irp->AssociatedIrp.SystemBuffer = SystemEaBuffer;
|
Irp->AssociatedIrp.SystemBuffer = SystemEaBuffer;
|
||||||
Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
|
Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
|
||||||
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
||||||
|
@ -1054,7 +1053,7 @@ IoCreateFile(OUT PHANDLE FileHandle,
|
||||||
AccessMode,
|
AccessMode,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL);
|
NULL);
|
||||||
Status = LocalIoStatusBlock.Status;
|
Status = IoStatusBlock->Status;
|
||||||
}
|
}
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -1069,7 +1068,6 @@ IoCreateFile(OUT PHANDLE FileHandle,
|
||||||
_SEH_TRY
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
*FileHandle = LocalHandle;
|
*FileHandle = LocalHandle;
|
||||||
*IoStatusBlock = LocalIoStatusBlock;
|
|
||||||
}
|
}
|
||||||
_SEH_HANDLE
|
_SEH_HANDLE
|
||||||
{
|
{
|
||||||
|
@ -1380,20 +1378,41 @@ STDCALL
|
||||||
NtCancelIoFile(IN HANDLE FileHandle,
|
NtCancelIoFile(IN HANDLE FileHandle,
|
||||||
OUT PIO_STATUS_BLOCK IoStatusBlock)
|
OUT PIO_STATUS_BLOCK IoStatusBlock)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PETHREAD Thread;
|
PETHREAD Thread;
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
BOOLEAN OurIrpsInList = FALSE;
|
BOOLEAN OurIrpsInList = FALSE;
|
||||||
LARGE_INTEGER Interval;
|
LARGE_INTEGER Interval;
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
if ((ULONG_PTR)IoStatusBlock >= (ULONG_PTR)MmUserProbeAddress &&
|
PAGED_CODE();
|
||||||
KeGetPreviousMode() != KernelMode)
|
|
||||||
return STATUS_ACCESS_VIOLATION;
|
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(FileHandle, 0, IoFileObjectType,
|
PreviousMode = KeGetPreviousMode();
|
||||||
KeGetPreviousMode(), (PVOID*)&FileObject,
|
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(IoStatusBlock,
|
||||||
|
sizeof(IO_STATUS_BLOCK),
|
||||||
|
sizeof(ULONG));
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = ObReferenceObjectByHandle(FileHandle,
|
||||||
|
0,
|
||||||
|
IoFileObjectType,
|
||||||
|
PreviousMode,
|
||||||
|
(PVOID*)&FileObject,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -1531,23 +1550,39 @@ NtCreateMailslotFile(OUT PHANDLE FileHandle,
|
||||||
MAILSLOT_CREATE_PARAMETERS Buffer;
|
MAILSLOT_CREATE_PARAMETERS Buffer;
|
||||||
|
|
||||||
DPRINT("NtCreateMailslotFile(FileHandle 0x%p, DesiredAccess %x, "
|
DPRINT("NtCreateMailslotFile(FileHandle 0x%p, DesiredAccess %x, "
|
||||||
"ObjectAttributes 0x%p ObjectAttributes->ObjectName->Buffer %S)\n",
|
"ObjectAttributes 0x%p)\n",
|
||||||
FileHandle,DesiredAccess,ObjectAttributes,
|
FileHandle,DesiredAccess,ObjectAttributes);
|
||||||
ObjectAttributes->ObjectName->Buffer);
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Check for Timeout */
|
/* Check for Timeout */
|
||||||
if (TimeOut)
|
if (TimeOut != NULL)
|
||||||
{
|
{
|
||||||
/* Enable it */
|
if (KeGetPreviousMode() != KernelMode)
|
||||||
Buffer.TimeoutSpecified = TRUE;
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
/* FIXME: Add SEH */
|
_SEH_TRY
|
||||||
Buffer.ReadTimeout = *TimeOut;
|
{
|
||||||
|
Buffer.ReadTimeout = ProbeForReadLargeInteger(TimeOut);
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Buffer.ReadTimeout = *TimeOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer.TimeoutSpecified = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* No timeout */
|
|
||||||
Buffer.TimeoutSpecified = FALSE;
|
Buffer.TimeoutSpecified = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1592,25 +1627,39 @@ NtCreateNamedPipeFile(PHANDLE FileHandle,
|
||||||
NAMED_PIPE_CREATE_PARAMETERS Buffer;
|
NAMED_PIPE_CREATE_PARAMETERS Buffer;
|
||||||
|
|
||||||
DPRINT("NtCreateNamedPipeFile(FileHandle 0x%p, DesiredAccess %x, "
|
DPRINT("NtCreateNamedPipeFile(FileHandle 0x%p, DesiredAccess %x, "
|
||||||
"ObjectAttributes 0x%p ObjectAttributes->ObjectName->Buffer %S)\n",
|
"ObjectAttributes 0x%p)\n",
|
||||||
FileHandle,DesiredAccess,ObjectAttributes,
|
FileHandle,DesiredAccess,ObjectAttributes);
|
||||||
ObjectAttributes->ObjectName->Buffer);
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Check for Timeout */
|
/* Check for Timeout */
|
||||||
if (DefaultTimeout)
|
if (DefaultTimeout != NULL)
|
||||||
{
|
{
|
||||||
/* Enable it */
|
if (KeGetPreviousMode() != KernelMode)
|
||||||
Buffer.TimeoutSpecified = TRUE;
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
/* FIXME: Add SEH */
|
_SEH_TRY
|
||||||
Buffer.DefaultTimeout = *DefaultTimeout;
|
{
|
||||||
|
Buffer.DefaultTimeout = ProbeForReadLargeInteger(DefaultTimeout);
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Buffer.DefaultTimeout = *DefaultTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer.TimeoutSpecified = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
/* No timeout */
|
|
||||||
Buffer.TimeoutSpecified = FALSE;
|
Buffer.TimeoutSpecified = FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
/* Set Settings */
|
/* Set Settings */
|
||||||
Buffer.NamedPipeType = NamedPipeType;
|
Buffer.NamedPipeType = NamedPipeType;
|
||||||
|
@ -1724,6 +1773,8 @@ NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
NtFlushWriteBuffer(VOID)
|
NtFlushWriteBuffer(VOID)
|
||||||
{
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
KeFlushWriteBuffer();
|
KeFlushWriteBuffer();
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1746,20 +1797,56 @@ NtFlushBuffersFile(IN HANDLE FileHandle,
|
||||||
PFILE_OBJECT FileObject = NULL;
|
PFILE_OBJECT FileObject = NULL;
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
PIO_STACK_LOCATION StackPtr;
|
PIO_STACK_LOCATION StackPtr;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
BOOLEAN LocalEvent = FALSE;
|
BOOLEAN LocalEvent = FALSE;
|
||||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
ACCESS_MASK DesiredAccess = FILE_WRITE_DATA;
|
||||||
|
OBJECT_HANDLE_INFORMATION ObjectHandleInfo;
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
PreviousMode = KeGetPreviousMode();
|
||||||
|
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(IoStatusBlock,
|
||||||
|
sizeof(IO_STATUS_BLOCK),
|
||||||
|
sizeof(ULONG));
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the File Object */
|
/* Get the File Object */
|
||||||
Status = ObReferenceObjectByHandle(FileHandle,
|
Status = ObReferenceObjectByHandle(FileHandle,
|
||||||
FILE_WRITE_DATA,
|
0,
|
||||||
NULL,
|
IoFileObjectType,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
(PVOID*)&FileObject,
|
(PVOID*)&FileObject,
|
||||||
NULL);
|
&ObjectHandleInfo);
|
||||||
if (Status != STATUS_SUCCESS) return(Status);
|
if (!NT_SUCCESS(Status)) return(Status);
|
||||||
|
|
||||||
|
/* check if the handle has either FILE_WRITE_DATA or FILE_APPEND_DATA was
|
||||||
|
granted. However, if this is a named pipe, make sure we don't ask for
|
||||||
|
FILE_APPEND_DATA as it interferes with the FILE_CREATE_PIPE_INSTANCE
|
||||||
|
access right! */
|
||||||
|
if (!(FileObject->Flags & FO_NAMED_PIPE))
|
||||||
|
DesiredAccess |= FILE_APPEND_DATA;
|
||||||
|
if (!RtlAreAnyAccessesGranted(ObjectHandleInfo.GrantedAccess,
|
||||||
|
DesiredAccess))
|
||||||
|
{
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
return STATUS_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if this is a direct open or not */
|
/* Check if this is a direct open or not */
|
||||||
if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
|
if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
|
||||||
|
@ -1968,12 +2055,17 @@ NtLockFile(IN HANDLE FileHandle,
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
PKEVENT Event = NULL;
|
PKEVENT Event = NULL;
|
||||||
BOOLEAN LocalEvent = FALSE;
|
BOOLEAN LocalEvent = FALSE;
|
||||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
LARGE_INTEGER CapturedByteOffset, CapturedLength;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
OBJECT_HANDLE_INFORMATION HandleInformation;
|
OBJECT_HANDLE_INFORMATION HandleInformation;
|
||||||
|
|
||||||
/* FIXME: instead of this, use SEH */
|
PAGED_CODE();
|
||||||
if (!Length || !ByteOffset) return STATUS_INVALID_PARAMETER;
|
|
||||||
|
PreviousMode = KeGetPreviousMode();
|
||||||
|
|
||||||
|
CapturedByteOffset.QuadPart = 0;
|
||||||
|
CapturedLength.QuadPart = 0;
|
||||||
|
|
||||||
/* Get File Object */
|
/* Get File Object */
|
||||||
Status = ObReferenceObjectByHandle(FileHandle,
|
Status = ObReferenceObjectByHandle(FileHandle,
|
||||||
|
@ -1984,12 +2076,41 @@ NtLockFile(IN HANDLE FileHandle,
|
||||||
&HandleInformation);
|
&HandleInformation);
|
||||||
if (!NT_SUCCESS(Status)) return Status;
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
/* Must have FILE_READ_DATA | FILE_WRITE_DATA access */
|
if (PreviousMode != KernelMode)
|
||||||
if (!(HandleInformation.GrantedAccess & (FILE_WRITE_DATA | FILE_READ_DATA)))
|
|
||||||
{
|
{
|
||||||
DPRINT1("Invalid access rights\n");
|
/* Must have either FILE_READ_DATA or FILE_WRITE_DATA access unless
|
||||||
ObDereferenceObject(FileObject);
|
we're in KernelMode! */
|
||||||
return STATUS_ACCESS_DENIED;
|
if (!(HandleInformation.GrantedAccess & (FILE_WRITE_DATA | FILE_READ_DATA)))
|
||||||
|
{
|
||||||
|
DPRINT1("Invalid access rights\n");
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
return STATUS_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(IoStatusBlock,
|
||||||
|
sizeof(IO_STATUS_BLOCK),
|
||||||
|
sizeof(ULONG));
|
||||||
|
CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
|
||||||
|
CapturedLength = ProbeForReadLargeInteger(Length);
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CapturedByteOffset = *ByteOffset;
|
||||||
|
CapturedLength = *Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get Event Object */
|
/* Get Event Object */
|
||||||
|
@ -2043,7 +2164,7 @@ NtLockFile(IN HANDLE FileHandle,
|
||||||
ObDereferenceObject(FileObject);
|
ObDereferenceObject(FileObject);
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
*LocalLength = *Length;
|
*LocalLength = CapturedLength;
|
||||||
|
|
||||||
/* Set up the IRP */
|
/* Set up the IRP */
|
||||||
Irp->RequestorMode = PreviousMode;
|
Irp->RequestorMode = PreviousMode;
|
||||||
|
@ -2060,8 +2181,8 @@ NtLockFile(IN HANDLE FileHandle,
|
||||||
|
|
||||||
/* Set Parameters */
|
/* Set Parameters */
|
||||||
StackPtr->Parameters.LockControl.Length = LocalLength;
|
StackPtr->Parameters.LockControl.Length = LocalLength;
|
||||||
StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
|
StackPtr->Parameters.LockControl.ByteOffset = CapturedByteOffset;
|
||||||
StackPtr->Parameters.LockControl.Key = Key ? Key : 0;
|
StackPtr->Parameters.LockControl.Key = Key;
|
||||||
|
|
||||||
/* Set Flags */
|
/* Set Flags */
|
||||||
if (FailImmediately) StackPtr->Flags = SL_FAIL_IMMEDIATELY;
|
if (FailImmediately) StackPtr->Flags = SL_FAIL_IMMEDIATELY;
|
||||||
|
@ -2709,7 +2830,7 @@ NtReadFile(IN HANDLE FileHandle,
|
||||||
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||||
OUT PVOID Buffer,
|
OUT PVOID Buffer,
|
||||||
IN ULONG Length,
|
IN ULONG Length,
|
||||||
IN PLARGE_INTEGER ByteOffset OPTIONAL, /* NOT optional for asynch. operations! */
|
IN PLARGE_INTEGER ByteOffset OPTIONAL,
|
||||||
IN PULONG Key OPTIONAL)
|
IN PULONG Key OPTIONAL)
|
||||||
{
|
{
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
@ -2717,15 +2838,20 @@ NtReadFile(IN HANDLE FileHandle,
|
||||||
PIRP Irp = NULL;
|
PIRP Irp = NULL;
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
PIO_STACK_LOCATION StackPtr;
|
PIO_STACK_LOCATION StackPtr;
|
||||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
KPROCESSOR_MODE PreviousMode;
|
||||||
BOOLEAN LocalEvent = FALSE;
|
BOOLEAN LocalEvent = FALSE;
|
||||||
PKEVENT EventObject = NULL;
|
PKEVENT EventObject = NULL;
|
||||||
|
LARGE_INTEGER CapturedByteOffset;
|
||||||
|
|
||||||
DPRINT("NtReadFile(FileHandle 0x%p Buffer 0x%p Length %x ByteOffset 0x%p, "
|
DPRINT("NtReadFile(FileHandle 0x%p Buffer 0x%p Length %x ByteOffset 0x%p, "
|
||||||
"IoStatusBlock 0x%p)\n", FileHandle, Buffer, Length, ByteOffset,
|
"IoStatusBlock 0x%p)\n", FileHandle, Buffer, Length, ByteOffset,
|
||||||
IoStatusBlock);
|
IoStatusBlock);
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
PreviousMode = KeGetPreviousMode();
|
||||||
|
CapturedByteOffset.QuadPart = 0;
|
||||||
|
|
||||||
/* Validate User-Mode Buffers */
|
/* Validate User-Mode Buffers */
|
||||||
if(PreviousMode != KernelMode)
|
if(PreviousMode != KernelMode)
|
||||||
{
|
{
|
||||||
|
@ -2734,11 +2860,14 @@ NtReadFile(IN HANDLE FileHandle,
|
||||||
ProbeForWrite(IoStatusBlock,
|
ProbeForWrite(IoStatusBlock,
|
||||||
sizeof(IO_STATUS_BLOCK),
|
sizeof(IO_STATUS_BLOCK),
|
||||||
sizeof(ULONG));
|
sizeof(ULONG));
|
||||||
#if 0
|
|
||||||
ProbeForWrite(Buffer,
|
ProbeForWrite(Buffer,
|
||||||
Length,
|
Length,
|
||||||
sizeof(ULONG));
|
1);
|
||||||
#endif
|
if (ByteOffset != NULL)
|
||||||
|
{
|
||||||
|
CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
|
||||||
|
}
|
||||||
|
/* FIXME - probe other pointers and capture information */
|
||||||
}
|
}
|
||||||
_SEH_HANDLE
|
_SEH_HANDLE
|
||||||
{
|
{
|
||||||
|
@ -2748,6 +2877,13 @@ NtReadFile(IN HANDLE FileHandle,
|
||||||
|
|
||||||
if(!NT_SUCCESS(Status)) return Status;
|
if(!NT_SUCCESS(Status)) return Status;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ByteOffset != NULL)
|
||||||
|
{
|
||||||
|
CapturedByteOffset = *ByteOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Get File Object */
|
/* Get File Object */
|
||||||
Status = ObReferenceObjectByHandle(FileHandle,
|
Status = ObReferenceObjectByHandle(FileHandle,
|
||||||
|
@ -2759,9 +2895,9 @@ NtReadFile(IN HANDLE FileHandle,
|
||||||
if (!NT_SUCCESS(Status)) return Status;
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
/* Check the Byte Offset */
|
/* Check the Byte Offset */
|
||||||
if (!ByteOffset ||
|
if (ByteOffset == NULL ||
|
||||||
(ByteOffset->u.LowPart == FILE_USE_FILE_POINTER_POSITION &&
|
(CapturedByteOffset.u.LowPart == FILE_USE_FILE_POINTER_POSITION &&
|
||||||
ByteOffset->u.HighPart == -1))
|
CapturedByteOffset.u.HighPart == -1))
|
||||||
{
|
{
|
||||||
/* a valid ByteOffset is required if asynch. op. */
|
/* a valid ByteOffset is required if asynch. op. */
|
||||||
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
|
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
|
||||||
|
@ -2772,7 +2908,7 @@ NtReadFile(IN HANDLE FileHandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use the Current Byte OFfset */
|
/* Use the Current Byte OFfset */
|
||||||
ByteOffset = &FileObject->CurrentByteOffset;
|
CapturedByteOffset = FileObject->CurrentByteOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for event */
|
/* Check for event */
|
||||||
|
@ -2821,7 +2957,7 @@ NtReadFile(IN HANDLE FileHandle,
|
||||||
DeviceObject,
|
DeviceObject,
|
||||||
Buffer,
|
Buffer,
|
||||||
Length,
|
Length,
|
||||||
ByteOffset,
|
&CapturedByteOffset,
|
||||||
EventObject,
|
EventObject,
|
||||||
IoStatusBlock);
|
IoStatusBlock);
|
||||||
if (Irp == NULL)
|
if (Irp == NULL)
|
||||||
|
@ -3276,7 +3412,7 @@ NtUnlockFile(IN HANDLE FileHandle,
|
||||||
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||||
IN PLARGE_INTEGER ByteOffset,
|
IN PLARGE_INTEGER ByteOffset,
|
||||||
IN PLARGE_INTEGER Length,
|
IN PLARGE_INTEGER Length,
|
||||||
OUT ULONG Key OPTIONAL)
|
IN ULONG Key OPTIONAL)
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = NULL;
|
PFILE_OBJECT FileObject = NULL;
|
||||||
PLARGE_INTEGER LocalLength = NULL;
|
PLARGE_INTEGER LocalLength = NULL;
|
||||||
|
@ -3285,12 +3421,17 @@ NtUnlockFile(IN HANDLE FileHandle,
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
BOOLEAN LocalEvent = FALSE;
|
BOOLEAN LocalEvent = FALSE;
|
||||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
KPROCESSOR_MODE PreviousMode;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
LARGE_INTEGER CapturedByteOffset, CapturedLength;
|
||||||
OBJECT_HANDLE_INFORMATION HandleInformation;
|
OBJECT_HANDLE_INFORMATION HandleInformation;
|
||||||
|
|
||||||
/* FIXME: instead of this, use SEH */
|
PAGED_CODE();
|
||||||
if (!Length || !ByteOffset) return STATUS_INVALID_PARAMETER;
|
|
||||||
|
PreviousMode = KeGetPreviousMode();
|
||||||
|
|
||||||
|
CapturedByteOffset.QuadPart = 0;
|
||||||
|
CapturedLength.QuadPart = 0;
|
||||||
|
|
||||||
/* Get File Object */
|
/* Get File Object */
|
||||||
Status = ObReferenceObjectByHandle(FileHandle,
|
Status = ObReferenceObjectByHandle(FileHandle,
|
||||||
|
@ -3301,12 +3442,41 @@ NtUnlockFile(IN HANDLE FileHandle,
|
||||||
&HandleInformation);
|
&HandleInformation);
|
||||||
if (!NT_SUCCESS(Status)) return Status;
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
/* Must have FILE_READ_DATA | FILE_WRITE_DATA access */
|
if (PreviousMode != KernelMode)
|
||||||
if (!(HandleInformation.GrantedAccess & (FILE_WRITE_DATA | FILE_READ_DATA)))
|
|
||||||
{
|
{
|
||||||
DPRINT1("Invalid access rights\n");
|
/* Must have either FILE_READ_DATA or FILE_WRITE_DATA access unless we're
|
||||||
ObDereferenceObject(FileObject);
|
in KernelMode! */
|
||||||
return STATUS_ACCESS_DENIED;
|
if (!(HandleInformation.GrantedAccess & (FILE_WRITE_DATA | FILE_READ_DATA)))
|
||||||
|
{
|
||||||
|
DPRINT1("Invalid access rights\n");
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
return STATUS_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(IoStatusBlock,
|
||||||
|
sizeof(IO_STATUS_BLOCK),
|
||||||
|
sizeof(ULONG));
|
||||||
|
CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
|
||||||
|
CapturedLength = ProbeForReadLargeInteger(Length);
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CapturedByteOffset = *ByteOffset;
|
||||||
|
CapturedLength = *Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if this is a direct open or not */
|
/* Check if this is a direct open or not */
|
||||||
|
@ -3349,7 +3519,7 @@ NtUnlockFile(IN HANDLE FileHandle,
|
||||||
ObDereferenceObject(FileObject);
|
ObDereferenceObject(FileObject);
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
*LocalLength = *Length;
|
*LocalLength = CapturedLength;
|
||||||
|
|
||||||
/* Set up the IRP */
|
/* Set up the IRP */
|
||||||
Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
|
Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
|
||||||
|
@ -3367,8 +3537,8 @@ NtUnlockFile(IN HANDLE FileHandle,
|
||||||
|
|
||||||
/* Set Parameters */
|
/* Set Parameters */
|
||||||
StackPtr->Parameters.LockControl.Length = LocalLength;
|
StackPtr->Parameters.LockControl.Length = LocalLength;
|
||||||
StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
|
StackPtr->Parameters.LockControl.ByteOffset = CapturedByteOffset;
|
||||||
StackPtr->Parameters.LockControl.Key = Key ? Key : 0;
|
StackPtr->Parameters.LockControl.Key = Key;
|
||||||
|
|
||||||
/* Call the Driver */
|
/* Call the Driver */
|
||||||
Status = IoCallDriver(DeviceObject, Irp);
|
Status = IoCallDriver(DeviceObject, Irp);
|
||||||
|
@ -3424,34 +3594,49 @@ NtWriteFile (IN HANDLE FileHandle,
|
||||||
IN PLARGE_INTEGER ByteOffset OPTIONAL, /* NOT optional for asynch. operations! */
|
IN PLARGE_INTEGER ByteOffset OPTIONAL, /* NOT optional for asynch. operations! */
|
||||||
IN PULONG Key OPTIONAL)
|
IN PULONG Key OPTIONAL)
|
||||||
{
|
{
|
||||||
OBJECT_HANDLE_INFORMATION HandleInformation;
|
OBJECT_HANDLE_INFORMATION ObjectHandleInfo;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PIRP Irp = NULL;
|
PIRP Irp = NULL;
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
PIO_STACK_LOCATION StackPtr;
|
PIO_STACK_LOCATION StackPtr;
|
||||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
KPROCESSOR_MODE PreviousMode;
|
||||||
BOOLEAN LocalEvent = FALSE;
|
BOOLEAN LocalEvent = FALSE;
|
||||||
PKEVENT EventObject = NULL;
|
PKEVENT EventObject = NULL;
|
||||||
|
LARGE_INTEGER CapturedByteOffset;
|
||||||
|
ULONG CapturedKey = 0;
|
||||||
|
ACCESS_MASK DesiredAccess = FILE_WRITE_DATA;
|
||||||
|
|
||||||
DPRINT("NtWriteFile(FileHandle 0x%p Buffer 0x%p Length %x ByteOffset 0x%p, "
|
DPRINT("NtWriteFile(FileHandle 0x%p Buffer 0x%p Length %x ByteOffset 0x%p, "
|
||||||
"IoStatusBlock 0x%p)\n", FileHandle, Buffer, Length, ByteOffset,
|
"IoStatusBlock 0x%p)\n", FileHandle, Buffer, Length, ByteOffset,
|
||||||
IoStatusBlock);
|
IoStatusBlock);
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
PreviousMode = KeGetPreviousMode();
|
||||||
|
CapturedByteOffset.QuadPart = 0;
|
||||||
|
|
||||||
/* Validate User-Mode Buffers */
|
/* Validate User-Mode Buffers */
|
||||||
if(PreviousMode != KernelMode)
|
if(PreviousMode != KernelMode)
|
||||||
{
|
{
|
||||||
_SEH_TRY
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
ProbeForWrite(IoStatusBlock,
|
ProbeForWrite(IoStatusBlock,
|
||||||
sizeof(IO_STATUS_BLOCK),
|
sizeof(IO_STATUS_BLOCK),
|
||||||
sizeof(ULONG));
|
sizeof(ULONG));
|
||||||
|
|
||||||
ProbeForRead(Buffer,
|
ProbeForRead(Buffer,
|
||||||
Length,
|
Length,
|
||||||
sizeof(ULONG));
|
1);
|
||||||
#endif
|
if (ByteOffset != NULL)
|
||||||
|
{
|
||||||
|
CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Key != NULL)
|
||||||
|
{
|
||||||
|
CapturedKey = ProbeForReadUlong(Key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_SEH_HANDLE
|
_SEH_HANDLE
|
||||||
{
|
{
|
||||||
|
@ -3461,6 +3646,17 @@ NtWriteFile (IN HANDLE FileHandle,
|
||||||
|
|
||||||
if(!NT_SUCCESS(Status)) return Status;
|
if(!NT_SUCCESS(Status)) return Status;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ByteOffset != NULL)
|
||||||
|
{
|
||||||
|
CapturedByteOffset = *ByteOffset;
|
||||||
|
}
|
||||||
|
if (Key != NULL)
|
||||||
|
{
|
||||||
|
CapturedKey = *Key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Get File Object */
|
/* Get File Object */
|
||||||
Status = ObReferenceObjectByHandle(FileHandle,
|
Status = ObReferenceObjectByHandle(FileHandle,
|
||||||
|
@ -3468,24 +3664,29 @@ NtWriteFile (IN HANDLE FileHandle,
|
||||||
IoFileObjectType,
|
IoFileObjectType,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
(PVOID*)&FileObject,
|
(PVOID*)&FileObject,
|
||||||
&HandleInformation);
|
&ObjectHandleInfo);
|
||||||
if (!NT_SUCCESS(Status)) return Status;
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
/* Must have FILE_WRITE_DATA | FILE_APPEND_DATA access */
|
/* check if the handle has either FILE_WRITE_DATA or FILE_APPEND_DATA was
|
||||||
if (!(HandleInformation.GrantedAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)))
|
granted. However, if this is a named pipe, make sure we don't ask for
|
||||||
|
FILE_APPEND_DATA as it interferes with the FILE_CREATE_PIPE_INSTANCE
|
||||||
|
access right! */
|
||||||
|
if (!(FileObject->Flags & FO_NAMED_PIPE))
|
||||||
|
DesiredAccess |= FILE_APPEND_DATA;
|
||||||
|
if (!RtlAreAnyAccessesGranted(ObjectHandleInfo.GrantedAccess,
|
||||||
|
DesiredAccess))
|
||||||
{
|
{
|
||||||
DPRINT1("Invalid access rights\n");
|
|
||||||
ObDereferenceObject(FileObject);
|
ObDereferenceObject(FileObject);
|
||||||
return STATUS_ACCESS_DENIED;
|
return STATUS_ACCESS_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we got write Access */
|
/* Check if we got write Access */
|
||||||
if (HandleInformation.GrantedAccess & FILE_WRITE_DATA)
|
if (ObjectHandleInfo.GrantedAccess & FILE_WRITE_DATA)
|
||||||
{
|
{
|
||||||
/* Check the Byte Offset */
|
/* Check the Byte Offset */
|
||||||
if (!ByteOffset ||
|
if (ByteOffset == NULL ||
|
||||||
(ByteOffset->u.LowPart == FILE_USE_FILE_POINTER_POSITION &&
|
(CapturedByteOffset.u.LowPart == FILE_USE_FILE_POINTER_POSITION &&
|
||||||
ByteOffset->u.HighPart == -1))
|
CapturedByteOffset.u.HighPart == -1))
|
||||||
{
|
{
|
||||||
/* a valid ByteOffset is required if asynch. op. */
|
/* a valid ByteOffset is required if asynch. op. */
|
||||||
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
|
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
|
||||||
|
@ -3496,10 +3697,11 @@ NtWriteFile (IN HANDLE FileHandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use the Current Byte OFfset */
|
/* Use the Current Byte OFfset */
|
||||||
ByteOffset = &FileObject->CurrentByteOffset;
|
CapturedByteOffset = FileObject->CurrentByteOffset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (HandleInformation.GrantedAccess & FILE_APPEND_DATA)
|
else if ((ObjectHandleInfo.GrantedAccess & FILE_APPEND_DATA) &&
|
||||||
|
!(FileObject->Flags & FO_NAMED_PIPE))
|
||||||
{
|
{
|
||||||
/* a valid ByteOffset is required if asynch. op. */
|
/* a valid ByteOffset is required if asynch. op. */
|
||||||
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
|
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
|
||||||
|
@ -3510,8 +3712,8 @@ NtWriteFile (IN HANDLE FileHandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Give the drivers somethign to understand */
|
/* Give the drivers somethign to understand */
|
||||||
ByteOffset->u.LowPart = FILE_WRITE_TO_END_OF_FILE;
|
CapturedByteOffset.u.LowPart = FILE_WRITE_TO_END_OF_FILE;
|
||||||
ByteOffset->u.HighPart = 0xffffffff;
|
CapturedByteOffset.u.HighPart = 0xffffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we got an event */
|
/* Check if we got an event */
|
||||||
|
@ -3560,7 +3762,7 @@ NtWriteFile (IN HANDLE FileHandle,
|
||||||
DeviceObject,
|
DeviceObject,
|
||||||
Buffer,
|
Buffer,
|
||||||
Length,
|
Length,
|
||||||
ByteOffset,
|
&CapturedByteOffset,
|
||||||
EventObject,
|
EventObject,
|
||||||
IoStatusBlock);
|
IoStatusBlock);
|
||||||
if (Irp == NULL)
|
if (Irp == NULL)
|
||||||
|
@ -3601,7 +3803,7 @@ NtWriteFile (IN HANDLE FileHandle,
|
||||||
/* Setup Stack Data */
|
/* Setup Stack Data */
|
||||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||||
StackPtr->FileObject = FileObject;
|
StackPtr->FileObject = FileObject;
|
||||||
StackPtr->Parameters.Write.Key = Key ? *Key : 0;
|
StackPtr->Parameters.Write.Key = CapturedKey;
|
||||||
if (FileObject->Flags & FO_WRITE_THROUGH) StackPtr->Flags = SL_WRITE_THROUGH;
|
if (FileObject->Flags & FO_WRITE_THROUGH) StackPtr->Flags = SL_WRITE_THROUGH;
|
||||||
|
|
||||||
/* Call the Driver */
|
/* Call the Driver */
|
||||||
|
|
Loading…
Reference in a new issue