reactos/ntoskrnl/include/internal/io_x.h

163 lines
4.1 KiB
C
Raw Normal View History

/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/include/internal/io_x.h
* PURPOSE: Internal Inlined Functions for the I/O Manager
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
static
__inline
NTSTATUS
IopLockFileObject(
_In_ PFILE_OBJECT FileObject,
_In_ KPROCESSOR_MODE WaitMode)
{
BOOLEAN LockFailed;
/* Lock the FO and check for contention */
if (InterlockedExchange((PLONG)&FileObject->Busy, TRUE) == FALSE)
{
ObReferenceObject(FileObject);
return STATUS_SUCCESS;
}
else
{
return IopAcquireFileObjectLock(FileObject,
WaitMode,
BooleanFlagOn(FileObject->Flags, FO_ALERTABLE_IO),
&LockFailed);
}
}
static
__inline
VOID
IopUnlockFileObject(IN PFILE_OBJECT FileObject)
{
/* Unlock the FO and wake any waiters up */
NT_VERIFY(InterlockedExchange((PLONG)&FileObject->Busy, FALSE) == TRUE);
if (FileObject->Waiters)
{
KeSetEvent(&FileObject->Lock, IO_NO_INCREMENT, FALSE);
}
ObDereferenceObject(FileObject);
}
- 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
VOID
IopQueueIrpToThread(IN PIRP Irp)
{
KIRQL OldIrql;
/* Raise to APC Level */
KeRaiseIrql(APC_LEVEL, &OldIrql);
/* Insert it into the list */
InsertHeadList(&Irp->Tail.Overlay.Thread->IrpList, &Irp->ThreadListEntry);
/* Lower irql */
KeLowerIrql(OldIrql);
}
FORCEINLINE
VOID
IopUnQueueIrpFromThread(IN PIRP Irp)
{
/* Remove it from the list and reset it */
if (IsListEmpty(&Irp->ThreadListEntry))
return;
RemoveEntryList(&Irp->ThreadListEntry);
InitializeListHead(&Irp->ThreadListEntry);
}
static
__inline
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++;
CountToChange = &PsGetCurrentProcess()->WriteOperationCount;
}
else
{
/* Increase other count */
IoOtherOperationCount++;
CountToChange = &PsGetCurrentProcess()->OtherOperationCount;
}
/* Increase the process-wide count */
ExInterlockedAddLargeStatistic(CountToChange, 1);
}
}
static
__inline
VOID
IopUpdateTransferCount(IN IOP_TRANSFER_TYPE Type, IN ULONG TransferCount)
{
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);
}
}
static
__inline
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;
}