xref: /reactos/ntoskrnl/include/internal/io_x.h (revision 8a978a17)
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