2006-11-08 11:47:44 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS Kernel
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
2015-10-04 11:54:25 +00:00
|
|
|
* FILE: ntoskrnl/include/internal/io_x.h
|
2006-11-08 11:47:44 +00:00
|
|
|
* PURPOSE: Internal Inlined Functions for the I/O Manager
|
|
|
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
|
|
|
*/
|
|
|
|
|
2008-12-03 17:28:33 +00:00
|
|
|
static
|
|
|
|
__inline
|
2018-10-02 07:55:07 +00:00
|
|
|
NTSTATUS
|
|
|
|
IopLockFileObject(
|
|
|
|
_In_ PFILE_OBJECT FileObject,
|
|
|
|
_In_ KPROCESSOR_MODE WaitMode)
|
2006-11-08 11:47:44 +00:00
|
|
|
{
|
2018-10-02 07:55:07 +00:00
|
|
|
BOOLEAN LockFailed;
|
|
|
|
|
2016-11-07 01:06:24 +00:00
|
|
|
/* Lock the FO and check for contention */
|
2018-10-02 07:55:07 +00:00
|
|
|
if (InterlockedExchange((PLONG)&FileObject->Busy, TRUE) == FALSE)
|
|
|
|
{
|
|
|
|
ObReferenceObject(FileObject);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
else
|
2006-11-08 11:47:44 +00:00
|
|
|
{
|
2018-10-02 07:55:07 +00:00
|
|
|
return IopAcquireFileObjectLock(FileObject,
|
|
|
|
WaitMode,
|
|
|
|
BooleanFlagOn(FileObject->Flags, FO_ALERTABLE_IO),
|
|
|
|
&LockFailed);
|
2006-11-08 11:47:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-03 17:28:33 +00:00
|
|
|
static
|
|
|
|
__inline
|
2006-11-08 11:47:44 +00:00
|
|
|
VOID
|
|
|
|
IopUnlockFileObject(IN PFILE_OBJECT FileObject)
|
|
|
|
{
|
|
|
|
/* Unlock the FO and wake any waiters up */
|
2018-10-02 07:55:07 +00:00
|
|
|
NT_VERIFY(InterlockedExchange((PLONG)&FileObject->Busy, FALSE) == TRUE);
|
|
|
|
if (FileObject->Waiters)
|
|
|
|
{
|
|
|
|
KeSetEvent(&FileObject->Lock, IO_NO_INCREMENT, FALSE);
|
|
|
|
}
|
|
|
|
ObDereferenceObject(FileObject);
|
2006-11-08 11:47:44 +00:00
|
|
|
}
|
|
|
|
|
- Fix SleepEx.
- Put volatile statements in EX_RUNDOWN_REF, IRP, DEVICE_OBJECT, ERESOURCE, FILE_OBJECT, IO_REMOVE_LOCK, WORK_QUEUE_ITEM where required (thanks to Microsoft's changes in the WDK to mark the fields properly).
- Update FILE_OBJECT definition.
- Add some asserts to some I/O functions.
- Add stub support for File Objects created by XP+ Drivers which have File Object Extensions.
- Add some fixes to IopDeleteFile, including proper reference counting for the DO and VPB, as well as cleanup when the file is closed without a handle.
- Fix a bug in IopSecurityFile.
- Queue and unqueue IRPs in all I/O functions.
- Fully support IRP cancellation now.
- Fix critical bugs in NtDeviceIoControlFile and NtDeviceFsControlFile which were causing double queueing of IRPs and freeing of invalid memory, as well as invalid paramter checking for user-mode buffers.
- Add exhaustive validation checks to IoCreateFile, add more failure cases, and validate the EA buffer. Also support IO_ATTACH_DEVICE_API flag.
- Implement IoCreateStreamFileObjectEx and IoCreateStreamFileObjectLite and fix several bugs in the original implementation of IoCreateStreamFileObject.
- Fix a bug in RtlRaiseException.
- Update Io*ShareAccess routines to support XP+ style semantics related to special File Object flags which disable their use.
- Add validation to all Query/Set routines so that information clasess, lengths, buffers and alignment are properly checked.
- Also add an array for the proper acess rights that each query/set operation requires.
- Check backup/restore privileges during I/O File operations.
- Check traverse access during I/O File Operations.
- Check access privileges to the device during I/O file operations.
- Rename IopReferenceDeviceObject and also verify if an exclusive DO is trying to be invalidly opened.
- Support various extra security checks during I/O File/Device Parse Routine.
- Fix a bug during IopCleanupIrp so that we don't dereference the File OBject if this was a create operation.
- Fix some bogus asserts in IofCompleteRequest, and save the IRP Flags before signalling it's event, since the driver might've freed it behind our back.
- Fix a large bug in ObInsertObject which affected the insert of unnamed objects with forced security options (Such as process/threads).
- Fix the creation of the Process/Thread/Job Obejct Types to that security information is forced.
- Remove "Fix PS!!!" messages since the bug is now fixed and these objects now get proper security descriptors.
- Fix another bug in ObInsertObjet which wasn't properly validating user-mode objects and always assumed kernel mode.
- Silence multiple trace/checkpoint messages that have accumulated throughout time for various debugging purposes.
svn path=/trunk/; revision=25118
2006-12-10 18:40:30 +00:00
|
|
|
FORCEINLINE
|
2008-12-03 17:28:33 +00:00
|
|
|
VOID
|
2006-11-08 11:47:44 +00:00
|
|
|
IopQueueIrpToThread(IN PIRP Irp)
|
|
|
|
{
|
2021-10-28 14:59:20 +00:00
|
|
|
PETHREAD Thread = Irp->Tail.Overlay.Thread;
|
2006-11-08 11:47:44 +00:00
|
|
|
|
2021-10-28 14:59:20 +00:00
|
|
|
/* Disable special kernel APCs so we can't race with IopCompleteRequest.
|
|
|
|
* IRP's thread must be the current thread */
|
|
|
|
KeEnterGuardedRegionThread(&Thread->Tcb);
|
2006-11-08 11:47:44 +00:00
|
|
|
|
|
|
|
/* Insert it into the list */
|
2021-10-28 14:59:20 +00:00
|
|
|
InsertHeadList(&Thread->IrpList, &Irp->ThreadListEntry);
|
2006-11-08 11:47:44 +00:00
|
|
|
|
2021-10-28 14:59:20 +00:00
|
|
|
/* Leave the guarded region */
|
|
|
|
KeLeaveGuardedRegionThread(&Thread->Tcb);
|
2006-11-08 11:47:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
FORCEINLINE
|
2008-12-03 17:28:33 +00:00
|
|
|
VOID
|
2006-11-08 11:47:44 +00:00
|
|
|
IopUnQueueIrpFromThread(IN PIRP Irp)
|
|
|
|
{
|
2021-10-28 14:59:20 +00:00
|
|
|
/* Special kernel APCs must be disabled so we can't race with
|
|
|
|
* IopCompleteRequest (or because we are called from there) */
|
|
|
|
ASSERT(KeAreAllApcsDisabled());
|
|
|
|
|
2006-11-08 11:47:44 +00:00
|
|
|
/* Remove it from the list and reset it */
|
2015-02-08 14:15:45 +00:00
|
|
|
if (IsListEmpty(&Irp->ThreadListEntry))
|
|
|
|
return;
|
2006-11-08 11:47:44 +00:00
|
|
|
RemoveEntryList(&Irp->ThreadListEntry);
|
|
|
|
InitializeListHead(&Irp->ThreadListEntry);
|
|
|
|
}
|
|
|
|
|
2008-12-03 17:28:33 +00:00
|
|
|
static
|
|
|
|
__inline
|
2006-11-08 11:47:44 +00:00
|
|
|
VOID
|
|
|
|
IopUpdateOperationCount(IN IOP_TRANSFER_TYPE Type)
|
|
|
|
{
|
|
|
|
PLARGE_INTEGER CountToChange;
|
|
|
|
|
|
|
|
/* Make sure I/O operations are being counted */
|
|
|
|
if (IoCountOperations)
|
|
|
|
{
|
|
|
|
if (Type == IopReadTransfer)
|
|
|
|
{
|
|
|
|
/* Increase read count */
|
|
|
|
IoReadOperationCount++;
|
|
|
|
CountToChange = &PsGetCurrentProcess()->ReadOperationCount;
|
|
|
|
}
|
|
|
|
else if (Type == IopWriteTransfer)
|
|
|
|
{
|
|
|
|
/* Increase write count */
|
|
|
|
IoWriteOperationCount++;
|
2009-02-16 11:02:23 +00:00
|
|
|
CountToChange = &PsGetCurrentProcess()->WriteOperationCount;
|
2006-11-08 11:47:44 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Increase other count */
|
|
|
|
IoOtherOperationCount++;
|
2009-02-16 11:02:23 +00:00
|
|
|
CountToChange = &PsGetCurrentProcess()->OtherOperationCount;
|
2006-11-08 11:47:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Increase the process-wide count */
|
|
|
|
ExInterlockedAddLargeStatistic(CountToChange, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-06-09 16:17:34 +00:00
|
|
|
static
|
|
|
|
__inline
|
|
|
|
VOID
|
2009-06-09 16:43:22 +00:00
|
|
|
IopUpdateTransferCount(IN IOP_TRANSFER_TYPE Type, IN ULONG TransferCount)
|
2009-06-09 16:17:34 +00:00
|
|
|
{
|
|
|
|
PLARGE_INTEGER CountToChange;
|
|
|
|
PLARGE_INTEGER TransferToChange;
|
|
|
|
|
|
|
|
/* Make sure I/O operations are being counted */
|
|
|
|
if (IoCountOperations)
|
|
|
|
{
|
|
|
|
if (Type == IopReadTransfer)
|
|
|
|
{
|
|
|
|
/* Increase read count */
|
|
|
|
CountToChange = &PsGetCurrentProcess()->ReadTransferCount;
|
|
|
|
TransferToChange = &IoReadTransferCount;
|
|
|
|
}
|
|
|
|
else if (Type == IopWriteTransfer)
|
|
|
|
{
|
|
|
|
/* Increase write count */
|
|
|
|
CountToChange = &PsGetCurrentProcess()->WriteTransferCount;
|
|
|
|
TransferToChange = &IoWriteTransferCount;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Increase other count */
|
|
|
|
CountToChange = &PsGetCurrentProcess()->OtherTransferCount;
|
|
|
|
TransferToChange = &IoOtherTransferCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Increase the process-wide count */
|
|
|
|
ExInterlockedAddLargeStatistic(CountToChange, TransferCount);
|
|
|
|
|
|
|
|
/* Increase global count */
|
|
|
|
ExInterlockedAddLargeStatistic(TransferToChange, TransferCount);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-03 17:28:33 +00:00
|
|
|
static
|
|
|
|
__inline
|
2006-11-08 11:47:44 +00:00
|
|
|
BOOLEAN
|
|
|
|
IopValidateOpenPacket(IN POPEN_PACKET OpenPacket)
|
|
|
|
{
|
|
|
|
/* Validate the packet */
|
|
|
|
if (!(OpenPacket) ||
|
|
|
|
(OpenPacket->Type != IO_TYPE_OPEN_PACKET) ||
|
|
|
|
(OpenPacket->Size != sizeof(OPEN_PACKET)))
|
|
|
|
{
|
|
|
|
/* Fail */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Good packet */
|
|
|
|
return TRUE;
|
|
|
|
}
|