Fixed header inclusion order.
[reactos.git] / reactos / ntoskrnl / io / cleanup.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/io/cleanup.c
5 * PURPOSE: IRP cleanup
6 * PROGRAMMER: David Welch (welch@mcmail.com)
7 * UPDATE HISTORY:
8 * 30/05/98: Created
9 */
10
11 /* INCLUDES ****************************************************************/
12
13 #include <ddk/ntddk.h>
14 #include <internal/io.h>
15 #include <string.h>
16 #include <internal/string.h>
17 #include <internal/ob.h>
18
19 #define NDEBUG
20 #include <internal/debug.h>
21
22 /* FUNCTIONS ***************************************************************/
23
24
25 VOID IoDeviceControlCompletion(PDEVICE_OBJECT DeviceObject,
26 PIRP Irp,
27 PIO_STACK_LOCATION IoStack)
28 {
29 ULONG IoControlCode;
30
31 IoControlCode = IoStack->Parameters.DeviceIoControl.IoControlCode;
32
33 switch (IO_METHOD_FROM_CTL_CODE(IoControlCode))
34 {
35 case METHOD_BUFFERED:
36 DPRINT ("Using METHOD_BUFFERED!\n");
37
38 /* copy output buffer back and free it */
39 if (Irp->AssociatedIrp.SystemBuffer)
40 {
41 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength)
42 {
43 RtlCopyMemory(Irp->UserBuffer,
44 Irp->AssociatedIrp.SystemBuffer,
45 IoStack->Parameters.DeviceIoControl.
46 OutputBufferLength);
47 }
48 ExFreePool (Irp->AssociatedIrp.SystemBuffer);
49 }
50 break;
51
52 case METHOD_IN_DIRECT:
53 DPRINT ("Using METHOD_IN_DIRECT!\n");
54
55 /* free input buffer (control buffer) */
56 if (Irp->AssociatedIrp.SystemBuffer)
57 ExFreePool (Irp->AssociatedIrp.SystemBuffer);
58
59 /* free output buffer (data transfer buffer) */
60 if (Irp->MdlAddress)
61 IoFreeMdl (Irp->MdlAddress);
62 break;
63
64 case METHOD_OUT_DIRECT:
65 DPRINT ("Using METHOD_OUT_DIRECT!\n");
66
67 /* free input buffer (control buffer) */
68 if (Irp->AssociatedIrp.SystemBuffer)
69 ExFreePool (Irp->AssociatedIrp.SystemBuffer);
70
71 /* free output buffer (data transfer buffer) */
72 if (Irp->MdlAddress)
73 IoFreeMdl (Irp->MdlAddress);
74 break;
75
76 case METHOD_NEITHER:
77 DPRINT ("Using METHOD_NEITHER!\n");
78 /* nothing to do */
79 break;
80 }
81 }
82
83 VOID IoReadWriteCompletion(PDEVICE_OBJECT DeviceObject,
84 PIRP Irp,
85 PIO_STACK_LOCATION IoStack)
86 {
87 PFILE_OBJECT FileObject;
88
89 FileObject = IoStack->FileObject;
90
91 if (DeviceObject->Flags & DO_BUFFERED_IO)
92 {
93 if (IoStack->MajorFunction == IRP_MJ_READ)
94 {
95 DPRINT("Copying buffered io back to user\n");
96 memcpy(Irp->UserBuffer,Irp->AssociatedIrp.SystemBuffer,
97 IoStack->Parameters.Read.Length);
98 }
99 ExFreePool(Irp->AssociatedIrp.SystemBuffer);
100 }
101 if (DeviceObject->Flags & DO_DIRECT_IO)
102 {
103 DPRINT("Tearing down MDL\n");
104 if (Irp->MdlAddress->MappedSystemVa!=NULL)
105 {
106 MmUnmapLockedPages(Irp->MdlAddress->MappedSystemVa,
107 Irp->MdlAddress);
108 }
109 MmUnlockPages(Irp->MdlAddress);
110 ExFreePool(Irp->MdlAddress);
111 }
112 if (FileObject != NULL)
113 {
114 FileObject->CurrentByteOffset.u.LowPart =
115 FileObject->CurrentByteOffset.u.LowPart +
116 Irp->IoStatus.Information;
117 }
118 }
119
120 VOID IoVolumeInformationCompletion(PDEVICE_OBJECT DeviceObject,
121 PIRP Irp,
122 PIO_STACK_LOCATION IoStack)
123 {
124 }
125
126 VOID IoSecondStageCompletion(PIRP Irp, CCHAR PriorityBoost)
127 /*
128 * FUNCTION: Performs the second stage of irp completion for read/write irps
129 * ARGUMENTS:
130 * Irp = Irp to completion
131 * FromDevice = True if the operation transfered data from the device
132 */
133 {
134 PIO_STACK_LOCATION IoStack;
135 PDEVICE_OBJECT DeviceObject;
136 PFILE_OBJECT FileObject;
137
138 IoStack = IoGetCurrentIrpStackLocation(Irp);
139
140 DeviceObject = IoStack->DeviceObject;
141
142 switch (IoStack->MajorFunction)
143 {
144 case IRP_MJ_CREATE:
145 case IRP_MJ_FLUSH_BUFFERS:
146 /* NOP */
147 break;
148
149 case IRP_MJ_READ:
150 case IRP_MJ_WRITE:
151 IoReadWriteCompletion(DeviceObject,Irp,IoStack);
152 break;
153
154 case IRP_MJ_DEVICE_CONTROL:
155 case IRP_MJ_INTERNAL_DEVICE_CONTROL:
156 IoDeviceControlCompletion(DeviceObject, Irp, IoStack);
157 break;
158
159 case IRP_MJ_QUERY_VOLUME_INFORMATION:
160 case IRP_MJ_SET_VOLUME_INFORMATION:
161 IoVolumeInformationCompletion(DeviceObject, Irp, IoStack);
162 break;
163
164 default:
165 }
166
167 if (Irp->UserIosb!=NULL)
168 {
169 *Irp->UserIosb=Irp->IoStatus;
170 }
171 if (Irp->UserEvent!=NULL)
172 {
173 KeSetEvent(Irp->UserEvent,PriorityBoost,FALSE);
174 }
175
176 FileObject = IoStack->FileObject;
177
178 if (FileObject != NULL && IoStack->MajorFunction != IRP_MJ_CLOSE)
179 {
180 ObDereferenceObject(FileObject);
181 }
182
183 IoFreeIrp(Irp);
184 }