2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/io/cleanup.c
6 * PROGRAMMER: David Welch (welch@mcmail.com)
11 /* INCLUDES ****************************************************************/
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>
20 #include <internal/debug.h>
22 /* FUNCTIONS ***************************************************************/
25 IopCompleteRequest1(struct _KAPC* Apc,
26 PKNORMAL_ROUTINE* NormalRoutine,
28 PVOID* SystemArgument1,
29 PVOID* SystemArgument2)
33 PIO_STACK_LOCATION IoStack;
34 PFILE_OBJECT FileObject;
36 DPRINT("IopCompleteRequest1()\n");
38 Irp = (PIRP)(*SystemArgument1);
39 PriorityBoost = (CCHAR)(LONG)(*SystemArgument2);
41 IoStack = &Irp->Stack[(ULONG)Irp->CurrentLocation];
42 FileObject = IoStack->FileObject;
44 (*SystemArgument1) = (PVOID)Irp->UserIosb;
45 (*SystemArgument2) = (PVOID)Irp->IoStatus.Information;
47 if (Irp->UserIosb!=NULL)
49 *Irp->UserIosb=Irp->IoStatus;
54 KeSetEvent(Irp->UserEvent,PriorityBoost,FALSE);
57 if (!(Irp->Flags & IRP_PAGING_IO) && FileObject)
59 // if the event is not the one in the file object, it needs dereferenced
60 if (Irp->UserEvent && Irp->UserEvent != &FileObject->Event)
61 ObDereferenceObject(Irp->UserEvent);
63 if (IoStack->MajorFunction != IRP_MJ_CLOSE)
65 ObDereferenceObject(FileObject);
73 VOID IoDeviceControlCompletion(PDEVICE_OBJECT DeviceObject,
75 PIO_STACK_LOCATION IoStack)
79 IoControlCode = IoStack->Parameters.DeviceIoControl.IoControlCode;
81 switch (IO_METHOD_FROM_CTL_CODE(IoControlCode))
84 DPRINT ("Using METHOD_BUFFERED!\n");
86 /* copy output buffer back and free it */
87 if (Irp->AssociatedIrp.SystemBuffer)
89 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength)
91 RtlCopyMemory(Irp->UserBuffer,
92 Irp->AssociatedIrp.SystemBuffer,
93 IoStack->Parameters.DeviceIoControl.
96 ExFreePool (Irp->AssociatedIrp.SystemBuffer);
100 case METHOD_IN_DIRECT:
101 DPRINT ("Using METHOD_IN_DIRECT!\n");
103 /* copy output buffer back and free it */
104 if (Irp->AssociatedIrp.SystemBuffer)
106 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength)
108 RtlCopyMemory(Irp->UserBuffer,
109 Irp->AssociatedIrp.SystemBuffer,
110 IoStack->Parameters.DeviceIoControl.
113 ExFreePool (Irp->AssociatedIrp.SystemBuffer);
116 /* free input buffer (data transfer buffer) */
118 IoFreeMdl (Irp->MdlAddress);
121 case METHOD_OUT_DIRECT:
122 DPRINT ("Using METHOD_OUT_DIRECT!\n");
124 /* free input buffer (control buffer) */
125 if (Irp->AssociatedIrp.SystemBuffer)
126 ExFreePool (Irp->AssociatedIrp.SystemBuffer);
128 /* free output buffer (data transfer buffer) */
130 IoFreeMdl (Irp->MdlAddress);
134 DPRINT ("Using METHOD_NEITHER!\n");
140 VOID IoReadWriteCompletion(PDEVICE_OBJECT DeviceObject,
142 PIO_STACK_LOCATION IoStack)
144 PFILE_OBJECT FileObject;
146 FileObject = IoStack->FileObject;
148 if (DeviceObject->Flags & DO_BUFFERED_IO)
150 if (IoStack->MajorFunction == IRP_MJ_READ)
152 DPRINT("Copying buffered io back to user\n");
153 memcpy(Irp->UserBuffer,Irp->AssociatedIrp.SystemBuffer,
154 IoStack->Parameters.Read.Length);
156 ExFreePool(Irp->AssociatedIrp.SystemBuffer);
158 if (DeviceObject->Flags & DO_DIRECT_IO)
160 /* FIXME: Is the MDL destroyed on a paging i/o, check all cases. */
161 DPRINT("Tearing down MDL\n");
162 if (Irp->MdlAddress->MappedSystemVa != NULL)
164 MmUnmapLockedPages(Irp->MdlAddress->MappedSystemVa,
167 MmUnlockPages(Irp->MdlAddress);
168 ExFreePool(Irp->MdlAddress);
172 VOID IoVolumeInformationCompletion(PDEVICE_OBJECT DeviceObject,
174 PIO_STACK_LOCATION IoStack)
178 VOID IoSecondStageCompletion(PIRP Irp, CCHAR PriorityBoost)
180 * FUNCTION: Performs the second stage of irp completion for read/write irps
182 * Irp = Irp to completion
183 * FromDevice = True if the operation transfered data from the device
186 PIO_STACK_LOCATION IoStack;
187 PDEVICE_OBJECT DeviceObject;
188 PFILE_OBJECT FileObject;
190 DPRINT("IoSecondStageCompletion(Irp %x, PriorityBoost %d)\n",
193 IoStack = &Irp->Stack[(ULONG)Irp->CurrentLocation];
194 FileObject = IoStack->FileObject;
196 DeviceObject = IoStack->DeviceObject;
198 switch (IoStack->MajorFunction)
201 case IRP_MJ_FLUSH_BUFFERS:
207 IoReadWriteCompletion(DeviceObject,Irp,IoStack);
210 case IRP_MJ_DEVICE_CONTROL:
211 case IRP_MJ_INTERNAL_DEVICE_CONTROL:
212 IoDeviceControlCompletion(DeviceObject, Irp, IoStack);
215 case IRP_MJ_QUERY_VOLUME_INFORMATION:
216 case IRP_MJ_SET_VOLUME_INFORMATION:
217 IoVolumeInformationCompletion(DeviceObject, Irp, IoStack);
224 if (Irp->Overlay.AsynchronousParameters.UserApcRoutine != NULL)
227 PKNORMAL_ROUTINE UserApcRoutine;
228 PVOID UserApcContext;
230 DPRINT("Dispatching APC\n");
231 Thread = &Irp->Tail.Overlay.Thread->Tcb;
232 UserApcRoutine = (PKNORMAL_ROUTINE)
233 Irp->Overlay.AsynchronousParameters.UserApcRoutine;
234 UserApcContext = (PVOID)
235 Irp->Overlay.AsynchronousParameters.UserApcContext;
236 KeInitializeApc(&Irp->Tail.Apc,
244 KeInsertQueueApc(&Irp->Tail.Apc,
246 (PVOID)(LONG)PriorityBoost,
251 DPRINT("Irp->UserIosb %x &Irp->UserIosb %x\n",
254 if (Irp->UserIosb!=NULL)
256 *Irp->UserIosb=Irp->IoStatus;
261 KeSetEvent(Irp->UserEvent,PriorityBoost,FALSE);
264 if (!(Irp->Flags & IRP_PAGING_IO) && FileObject)
266 // if the event is not the one in the file object, it needs dereferenced
267 if (Irp->UserEvent && Irp->UserEvent != &FileObject->Event)
268 ObDereferenceObject(Irp->UserEvent);
270 if (IoStack->MajorFunction != IRP_MJ_CLOSE)
272 ObDereferenceObject(FileObject);