1 /* 2 * PROJECT: ReactOS Kernel 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: ntoskrnl/include/internal/io_x.h 5 * PURPOSE: Internal Inlined Functions for the I/O Manager 6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 7 */ 8 9 static 10 __inline 11 NTSTATUS 12 IopLockFileObject( 13 _In_ PFILE_OBJECT FileObject, 14 _In_ KPROCESSOR_MODE WaitMode) 15 { 16 BOOLEAN LockFailed; 17 18 /* Lock the FO and check for contention */ 19 if (InterlockedExchange((PLONG)&FileObject->Busy, TRUE) == FALSE) 20 { 21 ObReferenceObject(FileObject); 22 return STATUS_SUCCESS; 23 } 24 else 25 { 26 return IopAcquireFileObjectLock(FileObject, 27 WaitMode, 28 BooleanFlagOn(FileObject->Flags, FO_ALERTABLE_IO), 29 &LockFailed); 30 } 31 } 32 33 static 34 __inline 35 VOID 36 IopUnlockFileObject(IN PFILE_OBJECT FileObject) 37 { 38 /* Unlock the FO and wake any waiters up */ 39 NT_VERIFY(InterlockedExchange((PLONG)&FileObject->Busy, FALSE) == TRUE); 40 if (FileObject->Waiters) 41 { 42 KeSetEvent(&FileObject->Lock, IO_NO_INCREMENT, FALSE); 43 } 44 ObDereferenceObject(FileObject); 45 } 46 47 FORCEINLINE 48 VOID 49 IopQueueIrpToThread(IN PIRP Irp) 50 { 51 KIRQL OldIrql; 52 53 /* Raise to APC Level */ 54 KeRaiseIrql(APC_LEVEL, &OldIrql); 55 56 /* Insert it into the list */ 57 InsertHeadList(&Irp->Tail.Overlay.Thread->IrpList, &Irp->ThreadListEntry); 58 59 /* Lower irql */ 60 KeLowerIrql(OldIrql); 61 } 62 63 FORCEINLINE 64 VOID 65 IopUnQueueIrpFromThread(IN PIRP Irp) 66 { 67 /* Remove it from the list and reset it */ 68 if (IsListEmpty(&Irp->ThreadListEntry)) 69 return; 70 RemoveEntryList(&Irp->ThreadListEntry); 71 InitializeListHead(&Irp->ThreadListEntry); 72 } 73 74 static 75 __inline 76 VOID 77 IopUpdateOperationCount(IN IOP_TRANSFER_TYPE Type) 78 { 79 PLARGE_INTEGER CountToChange; 80 81 /* Make sure I/O operations are being counted */ 82 if (IoCountOperations) 83 { 84 if (Type == IopReadTransfer) 85 { 86 /* Increase read count */ 87 IoReadOperationCount++; 88 CountToChange = &PsGetCurrentProcess()->ReadOperationCount; 89 } 90 else if (Type == IopWriteTransfer) 91 { 92 /* Increase write count */ 93 IoWriteOperationCount++; 94 CountToChange = &PsGetCurrentProcess()->WriteOperationCount; 95 } 96 else 97 { 98 /* Increase other count */ 99 IoOtherOperationCount++; 100 CountToChange = &PsGetCurrentProcess()->OtherOperationCount; 101 } 102 103 /* Increase the process-wide count */ 104 ExInterlockedAddLargeStatistic(CountToChange, 1); 105 } 106 } 107 108 static 109 __inline 110 VOID 111 IopUpdateTransferCount(IN IOP_TRANSFER_TYPE Type, IN ULONG TransferCount) 112 { 113 PLARGE_INTEGER CountToChange; 114 PLARGE_INTEGER TransferToChange; 115 116 /* Make sure I/O operations are being counted */ 117 if (IoCountOperations) 118 { 119 if (Type == IopReadTransfer) 120 { 121 /* Increase read count */ 122 CountToChange = &PsGetCurrentProcess()->ReadTransferCount; 123 TransferToChange = &IoReadTransferCount; 124 } 125 else if (Type == IopWriteTransfer) 126 { 127 /* Increase write count */ 128 CountToChange = &PsGetCurrentProcess()->WriteTransferCount; 129 TransferToChange = &IoWriteTransferCount; 130 } 131 else 132 { 133 /* Increase other count */ 134 CountToChange = &PsGetCurrentProcess()->OtherTransferCount; 135 TransferToChange = &IoOtherTransferCount; 136 } 137 138 /* Increase the process-wide count */ 139 ExInterlockedAddLargeStatistic(CountToChange, TransferCount); 140 141 /* Increase global count */ 142 ExInterlockedAddLargeStatistic(TransferToChange, TransferCount); 143 } 144 } 145 146 static 147 __inline 148 BOOLEAN 149 IopValidateOpenPacket(IN POPEN_PACKET OpenPacket) 150 { 151 /* Validate the packet */ 152 if (!(OpenPacket) || 153 (OpenPacket->Type != IO_TYPE_OPEN_PACKET) || 154 (OpenPacket->Size != sizeof(OPEN_PACKET))) 155 { 156 /* Fail */ 157 return FALSE; 158 } 159 160 /* Good packet */ 161 return TRUE; 162 } 163