Added ObGetObjectHandleCount().
[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 <internal/ob.h>
16 #include <internal/mm.h>
17 #include <internal/ps.h>
18
19 #define NDEBUG
20 #include <internal/debug.h>
21
22 /* FUNCTIONS ***************************************************************/
23
24 VOID STDCALL
25 IopCompleteRequest1(struct _KAPC* Apc,
26 PKNORMAL_ROUTINE* NormalRoutine,
27 PVOID* NormalContext,
28 PVOID* SystemArgument1,
29 PVOID* SystemArgument2)
30 {
31 PIRP Irp;
32 CCHAR PriorityBoost;
33 PIO_STACK_LOCATION IoStack;
34 PFILE_OBJECT FileObject;
35
36 DPRINT("IopCompleteRequest1()\n");
37
38 Irp = (PIRP)(*SystemArgument1);
39 PriorityBoost = (CCHAR)(LONG)(*SystemArgument2);
40
41 IoStack = &Irp->Stack[(ULONG)Irp->CurrentLocation];
42
43 (*SystemArgument1) = (PVOID)Irp->UserIosb;
44 (*SystemArgument2) = (PVOID)Irp->IoStatus.Information;
45
46 if (Irp->UserIosb!=NULL)
47 {
48 *Irp->UserIosb=Irp->IoStatus;
49 }
50 if (Irp->UserEvent!=NULL)
51 {
52 KeSetEvent(Irp->UserEvent,PriorityBoost,FALSE);
53 }
54
55 FileObject = IoStack->FileObject;
56
57 if (FileObject != NULL && IoStack->MajorFunction != IRP_MJ_CLOSE)
58 {
59 ObDereferenceObject(FileObject);
60 }
61
62 IoFreeIrp(Irp);
63
64 }
65
66 VOID IoDeviceControlCompletion(PDEVICE_OBJECT DeviceObject,
67 PIRP Irp,
68 PIO_STACK_LOCATION IoStack)
69 {
70 ULONG IoControlCode;
71
72 IoControlCode = IoStack->Parameters.DeviceIoControl.IoControlCode;
73
74 switch (IO_METHOD_FROM_CTL_CODE(IoControlCode))
75 {
76 case METHOD_BUFFERED:
77 DPRINT ("Using METHOD_BUFFERED!\n");
78
79 /* copy output buffer back and free it */
80 if (Irp->AssociatedIrp.SystemBuffer)
81 {
82 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength)
83 {
84 RtlCopyMemory(Irp->UserBuffer,
85 Irp->AssociatedIrp.SystemBuffer,
86 IoStack->Parameters.DeviceIoControl.
87 OutputBufferLength);
88 }
89 ExFreePool (Irp->AssociatedIrp.SystemBuffer);
90 }
91 break;
92
93 case METHOD_IN_DIRECT:
94 DPRINT ("Using METHOD_IN_DIRECT!\n");
95
96 /* free input buffer (control buffer) */
97 if (Irp->AssociatedIrp.SystemBuffer)
98 ExFreePool (Irp->AssociatedIrp.SystemBuffer);
99
100 /* free output buffer (data transfer buffer) */
101 if (Irp->MdlAddress)
102 IoFreeMdl (Irp->MdlAddress);
103 break;
104
105 case METHOD_OUT_DIRECT:
106 DPRINT ("Using METHOD_OUT_DIRECT!\n");
107
108 /* free input buffer (control buffer) */
109 if (Irp->AssociatedIrp.SystemBuffer)
110 ExFreePool (Irp->AssociatedIrp.SystemBuffer);
111
112 /* free output buffer (data transfer buffer) */
113 if (Irp->MdlAddress)
114 IoFreeMdl (Irp->MdlAddress);
115 break;
116
117 case METHOD_NEITHER:
118 DPRINT ("Using METHOD_NEITHER!\n");
119 /* nothing to do */
120 break;
121 }
122 }
123
124 VOID IoReadWriteCompletion(PDEVICE_OBJECT DeviceObject,
125 PIRP Irp,
126 PIO_STACK_LOCATION IoStack)
127 {
128 PFILE_OBJECT FileObject;
129
130 FileObject = IoStack->FileObject;
131
132 if (DeviceObject->Flags & DO_BUFFERED_IO)
133 {
134 if (IoStack->MajorFunction == IRP_MJ_READ)
135 {
136 DPRINT("Copying buffered io back to user\n");
137 memcpy(Irp->UserBuffer,Irp->AssociatedIrp.SystemBuffer,
138 IoStack->Parameters.Read.Length);
139 }
140 ExFreePool(Irp->AssociatedIrp.SystemBuffer);
141 }
142 if (DeviceObject->Flags & DO_DIRECT_IO)
143 {
144 /* FIXME: Is the MDL destroyed on a paging i/o, check all cases. */
145 DPRINT("Tearing down MDL\n");
146 if (Irp->MdlAddress->MappedSystemVa != NULL)
147 {
148 MmUnmapLockedPages(Irp->MdlAddress->MappedSystemVa,
149 Irp->MdlAddress);
150 }
151 MmUnlockPages(Irp->MdlAddress);
152 ExFreePool(Irp->MdlAddress);
153 }
154 }
155
156 VOID IoVolumeInformationCompletion(PDEVICE_OBJECT DeviceObject,
157 PIRP Irp,
158 PIO_STACK_LOCATION IoStack)
159 {
160 }
161
162 VOID IoSecondStageCompletion(PIRP Irp, CCHAR PriorityBoost)
163 /*
164 * FUNCTION: Performs the second stage of irp completion for read/write irps
165 * ARGUMENTS:
166 * Irp = Irp to completion
167 * FromDevice = True if the operation transfered data from the device
168 */
169 {
170 PIO_STACK_LOCATION IoStack;
171 PDEVICE_OBJECT DeviceObject;
172 PFILE_OBJECT FileObject;
173
174 DPRINT("IoSecondStageCompletion(Irp %x, PriorityBoost %d)\n",
175 Irp, PriorityBoost);
176
177 IoStack = &Irp->Stack[(ULONG)Irp->CurrentLocation];
178
179 DeviceObject = IoStack->DeviceObject;
180
181 switch (IoStack->MajorFunction)
182 {
183 case IRP_MJ_CREATE:
184 case IRP_MJ_FLUSH_BUFFERS:
185 /* NOP */
186 break;
187
188 case IRP_MJ_READ:
189 case IRP_MJ_WRITE:
190 IoReadWriteCompletion(DeviceObject,Irp,IoStack);
191 break;
192
193 case IRP_MJ_DEVICE_CONTROL:
194 case IRP_MJ_INTERNAL_DEVICE_CONTROL:
195 IoDeviceControlCompletion(DeviceObject, Irp, IoStack);
196 break;
197
198 case IRP_MJ_QUERY_VOLUME_INFORMATION:
199 case IRP_MJ_SET_VOLUME_INFORMATION:
200 IoVolumeInformationCompletion(DeviceObject, Irp, IoStack);
201 break;
202
203 default:
204 break;
205 }
206
207 if (Irp->Overlay.AsynchronousParameters.UserApcRoutine != NULL)
208 {
209 PKTHREAD Thread;
210 PKNORMAL_ROUTINE UserApcRoutine;
211 PVOID UserApcContext;
212
213 DPRINT("Dispatching APC\n");
214 Thread = &Irp->Tail.Overlay.Thread->Tcb;
215 UserApcRoutine = (PKNORMAL_ROUTINE)
216 Irp->Overlay.AsynchronousParameters.UserApcRoutine;
217 UserApcContext = (PVOID)
218 Irp->Overlay.AsynchronousParameters.UserApcContext;
219 KeInitializeApc(&Irp->Tail.Apc,
220 Thread,
221 0,
222 IopCompleteRequest1,
223 NULL,
224 UserApcRoutine,
225 UserMode,
226 UserApcContext);
227 KeInsertQueueApc(&Irp->Tail.Apc,
228 Irp,
229 (PVOID)(LONG)PriorityBoost,
230 KernelMode);
231 return;
232 }
233
234 DPRINT("Irp->UserIosb %x &Irp->UserIosb %x\n",
235 Irp->UserIosb,
236 &Irp->UserIosb);
237 if (Irp->UserIosb!=NULL)
238 {
239 *Irp->UserIosb=Irp->IoStatus;
240 }
241 if (Irp->UserEvent!=NULL)
242 {
243 KeSetEvent(Irp->UserEvent,PriorityBoost,FALSE);
244 }
245
246 FileObject = IoStack->FileObject;
247
248 if (FileObject != NULL && IoStack->MajorFunction != IRP_MJ_CLOSE)
249 {
250 //ObDereferenceObject(FileObject);
251 }
252 if (FileObject != NULL && (IoStack->MajorFunction == IRP_MJ_READ || IoStack->MajorFunction == IRP_MJ_WRITE || IoStack->MajorFunction ==IRP_MJ_CLEANUP || IoStack->MajorFunction ==IRP_MJ_CREATE || IoStack->MajorFunction==IRP_MJ_DIRECTORY_CONTROL))
253 {
254 ObDereferenceObject(FileObject);
255 }
256
257 IoFreeIrp(Irp);
258 }