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 /* free input buffer (control buffer) */
104 if (Irp->AssociatedIrp.SystemBuffer)
105 ExFreePool (Irp->AssociatedIrp.SystemBuffer);
107 /* free output buffer (data transfer buffer) */
109 IoFreeMdl (Irp->MdlAddress);
112 case METHOD_OUT_DIRECT:
113 DPRINT ("Using METHOD_OUT_DIRECT!\n");
115 /* free input buffer (control buffer) */
116 if (Irp->AssociatedIrp.SystemBuffer)
117 ExFreePool (Irp->AssociatedIrp.SystemBuffer);
119 /* free output buffer (data transfer buffer) */
121 IoFreeMdl (Irp->MdlAddress);
125 DPRINT ("Using METHOD_NEITHER!\n");
131 VOID IoReadWriteCompletion(PDEVICE_OBJECT DeviceObject,
133 PIO_STACK_LOCATION IoStack)
135 PFILE_OBJECT FileObject;
137 FileObject = IoStack->FileObject;
139 if (DeviceObject->Flags & DO_BUFFERED_IO)
141 if (IoStack->MajorFunction == IRP_MJ_READ)
143 DPRINT("Copying buffered io back to user\n");
144 memcpy(Irp->UserBuffer,Irp->AssociatedIrp.SystemBuffer,
145 IoStack->Parameters.Read.Length);
147 ExFreePool(Irp->AssociatedIrp.SystemBuffer);
149 if (DeviceObject->Flags & DO_DIRECT_IO)
151 /* FIXME: Is the MDL destroyed on a paging i/o, check all cases. */
152 DPRINT("Tearing down MDL\n");
153 if (Irp->MdlAddress->MappedSystemVa != NULL)
155 MmUnmapLockedPages(Irp->MdlAddress->MappedSystemVa,
158 MmUnlockPages(Irp->MdlAddress);
159 ExFreePool(Irp->MdlAddress);
163 VOID IoVolumeInformationCompletion(PDEVICE_OBJECT DeviceObject,
165 PIO_STACK_LOCATION IoStack)
169 VOID IoSecondStageCompletion(PIRP Irp, CCHAR PriorityBoost)
171 * FUNCTION: Performs the second stage of irp completion for read/write irps
173 * Irp = Irp to completion
174 * FromDevice = True if the operation transfered data from the device
177 PIO_STACK_LOCATION IoStack;
178 PDEVICE_OBJECT DeviceObject;
179 PFILE_OBJECT FileObject;
181 DPRINT("IoSecondStageCompletion(Irp %x, PriorityBoost %d)\n",
184 IoStack = &Irp->Stack[(ULONG)Irp->CurrentLocation];
185 FileObject = IoStack->FileObject;
187 DeviceObject = IoStack->DeviceObject;
189 switch (IoStack->MajorFunction)
192 case IRP_MJ_FLUSH_BUFFERS:
198 IoReadWriteCompletion(DeviceObject,Irp,IoStack);
201 case IRP_MJ_DEVICE_CONTROL:
202 case IRP_MJ_INTERNAL_DEVICE_CONTROL:
203 IoDeviceControlCompletion(DeviceObject, Irp, IoStack);
206 case IRP_MJ_QUERY_VOLUME_INFORMATION:
207 case IRP_MJ_SET_VOLUME_INFORMATION:
208 IoVolumeInformationCompletion(DeviceObject, Irp, IoStack);
215 if (Irp->Overlay.AsynchronousParameters.UserApcRoutine != NULL)
219 PKNORMAL_ROUTINE UserApcRoutine;
220 PVOID UserApcContext;
221 #endif /* LIBCAPTIVE */
223 DPRINT("Dispatching APC\n");
225 Thread = &Irp->Tail.Overlay.Thread->Tcb;
226 UserApcRoutine = (PKNORMAL_ROUTINE)
227 Irp->Overlay.AsynchronousParameters.UserApcRoutine;
228 UserApcContext = (PVOID)
229 Irp->Overlay.AsynchronousParameters.UserApcContext;
230 KeInitializeApc(&Irp->Tail.Apc,
238 KeInsertQueueApc(&Irp->Tail.Apc,
240 (PVOID)(LONG)PriorityBoost,
242 #else /* !LIBCAPTIVE */
244 #endif /* !LIBCAPTIVE */
248 DPRINT("Irp->UserIosb %x &Irp->UserIosb %x\n",
251 if (Irp->UserIosb!=NULL)
253 *Irp->UserIosb=Irp->IoStatus;
258 KeSetEvent(Irp->UserEvent,PriorityBoost,FALSE);
261 if (!(Irp->Flags & IRP_PAGING_IO) && FileObject)
263 // if the event is not the one in the file object, it needs dereferenced
264 if (Irp->UserEvent && Irp->UserEvent != &FileObject->Event)
265 ObDereferenceObject(Irp->UserEvent);
267 if (IoStack->MajorFunction != IRP_MJ_CLOSE)
269 ObDereferenceObject(FileObject);