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 PETHREAD Thread = Irp->Tail.Overlay.Thread; 52 53 /* Disable special kernel APCs so we can't race with IopCompleteRequest. 54 * IRP's thread must be the current thread */ 55 KeEnterGuardedRegionThread(&Thread->Tcb); 56 57 /* Insert it into the list */ 58 InsertHeadList(&Thread->IrpList, &Irp->ThreadListEntry); 59 60 /* Leave the guarded region */ 61 KeLeaveGuardedRegionThread(&Thread->Tcb); 62 } 63 64 FORCEINLINE 65 VOID 66 IopUnQueueIrpFromThread(IN PIRP Irp) 67 { 68 /* Special kernel APCs must be disabled so we can't race with 69 * IopCompleteRequest (or because we are called from there) */ 70 ASSERT(KeAreAllApcsDisabled()); 71 72 /* Remove it from the list and reset it */ 73 if (IsListEmpty(&Irp->ThreadListEntry)) 74 return; 75 RemoveEntryList(&Irp->ThreadListEntry); 76 InitializeListHead(&Irp->ThreadListEntry); 77 } 78 79 static 80 __inline 81 VOID 82 IopUpdateOperationCount(IN IOP_TRANSFER_TYPE Type) 83 { 84 PLARGE_INTEGER CountToChange; 85 86 /* Make sure I/O operations are being counted */ 87 if (IoCountOperations) 88 { 89 if (Type == IopReadTransfer) 90 { 91 /* Increase read count */ 92 IoReadOperationCount++; 93 CountToChange = &PsGetCurrentProcess()->ReadOperationCount; 94 } 95 else if (Type == IopWriteTransfer) 96 { 97 /* Increase write count */ 98 IoWriteOperationCount++; 99 CountToChange = &PsGetCurrentProcess()->WriteOperationCount; 100 } 101 else 102 { 103 /* Increase other count */ 104 IoOtherOperationCount++; 105 CountToChange = &PsGetCurrentProcess()->OtherOperationCount; 106 } 107 108 /* Increase the process-wide count */ 109 ExInterlockedAddLargeStatistic(CountToChange, 1); 110 } 111 } 112 113 static 114 __inline 115 VOID 116 IopUpdateTransferCount(IN IOP_TRANSFER_TYPE Type, IN ULONG TransferCount) 117 { 118 PLARGE_INTEGER CountToChange; 119 PLARGE_INTEGER TransferToChange; 120 121 /* Make sure I/O operations are being counted */ 122 if (IoCountOperations) 123 { 124 if (Type == IopReadTransfer) 125 { 126 /* Increase read count */ 127 CountToChange = &PsGetCurrentProcess()->ReadTransferCount; 128 TransferToChange = &IoReadTransferCount; 129 } 130 else if (Type == IopWriteTransfer) 131 { 132 /* Increase write count */ 133 CountToChange = &PsGetCurrentProcess()->WriteTransferCount; 134 TransferToChange = &IoWriteTransferCount; 135 } 136 else 137 { 138 /* Increase other count */ 139 CountToChange = &PsGetCurrentProcess()->OtherTransferCount; 140 TransferToChange = &IoOtherTransferCount; 141 } 142 143 /* Increase the process-wide count */ 144 ExInterlockedAddLargeStatistic(CountToChange, TransferCount); 145 146 /* Increase global count */ 147 ExInterlockedAddLargeStatistic(TransferToChange, TransferCount); 148 } 149 } 150 151 static 152 __inline 153 BOOLEAN 154 IopValidateOpenPacket(IN POPEN_PACKET OpenPacket) 155 { 156 /* Validate the packet */ 157 if (!(OpenPacket) || 158 (OpenPacket->Type != IO_TYPE_OPEN_PACKET) || 159 (OpenPacket->Size != sizeof(OPEN_PACKET))) 160 { 161 /* Fail */ 162 return FALSE; 163 } 164 165 /* Good packet */ 166 return TRUE; 167 } 168