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>
16 #include <internal/string.h>
17 #include <internal/ob.h>
20 #include <internal/debug.h>
22 /* FUNCTIONS ***************************************************************/
24 VOID
IopCompleteRequest1(struct _KAPC
* Apc
,
25 PKNORMAL_ROUTINE
* NormalRoutine
,
27 PVOID
* SystemArgument1
,
28 PVOID
* SystemArgument2
)
32 DPRINT("IopCompleteRequest1()\n");
34 Irp
= (PIRP
)(*SystemArgument1
);
35 (*SystemArgument1
) = (PVOID
)Irp
->UserIosb
;
36 (*SystemArgument2
) = (PVOID
)Irp
->IoStatus
.Information
;
37 IoFreeIrp((PIRP
)(*SystemArgument1
));
40 VOID
IoDeviceControlCompletion(PDEVICE_OBJECT DeviceObject
,
42 PIO_STACK_LOCATION IoStack
)
46 IoControlCode
= IoStack
->Parameters
.DeviceIoControl
.IoControlCode
;
48 switch (IO_METHOD_FROM_CTL_CODE(IoControlCode
))
51 DPRINT ("Using METHOD_BUFFERED!\n");
53 /* copy output buffer back and free it */
54 if (Irp
->AssociatedIrp
.SystemBuffer
)
56 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
)
58 RtlCopyMemory(Irp
->UserBuffer
,
59 Irp
->AssociatedIrp
.SystemBuffer
,
60 IoStack
->Parameters
.DeviceIoControl
.
63 ExFreePool (Irp
->AssociatedIrp
.SystemBuffer
);
67 case METHOD_IN_DIRECT
:
68 DPRINT ("Using METHOD_IN_DIRECT!\n");
70 /* free input buffer (control buffer) */
71 if (Irp
->AssociatedIrp
.SystemBuffer
)
72 ExFreePool (Irp
->AssociatedIrp
.SystemBuffer
);
74 /* free output buffer (data transfer buffer) */
76 IoFreeMdl (Irp
->MdlAddress
);
79 case METHOD_OUT_DIRECT
:
80 DPRINT ("Using METHOD_OUT_DIRECT!\n");
82 /* free input buffer (control buffer) */
83 if (Irp
->AssociatedIrp
.SystemBuffer
)
84 ExFreePool (Irp
->AssociatedIrp
.SystemBuffer
);
86 /* free output buffer (data transfer buffer) */
88 IoFreeMdl (Irp
->MdlAddress
);
92 DPRINT ("Using METHOD_NEITHER!\n");
98 VOID
IoReadWriteCompletion(PDEVICE_OBJECT DeviceObject
,
100 PIO_STACK_LOCATION IoStack
)
102 PFILE_OBJECT FileObject
;
104 FileObject
= IoStack
->FileObject
;
106 if (DeviceObject
->Flags
& DO_BUFFERED_IO
)
108 if (IoStack
->MajorFunction
== IRP_MJ_READ
)
110 DPRINT("Copying buffered io back to user\n");
111 memcpy(Irp
->UserBuffer
,Irp
->AssociatedIrp
.SystemBuffer
,
112 IoStack
->Parameters
.Read
.Length
);
114 ExFreePool(Irp
->AssociatedIrp
.SystemBuffer
);
116 if (DeviceObject
->Flags
& DO_DIRECT_IO
)
118 DPRINT("Tearing down MDL\n");
119 if (Irp
->MdlAddress
->MappedSystemVa
!=NULL
)
121 MmUnmapLockedPages(Irp
->MdlAddress
->MappedSystemVa
,
124 MmUnlockPages(Irp
->MdlAddress
);
125 ExFreePool(Irp
->MdlAddress
);
127 if (FileObject
!= NULL
)
129 FileObject
->CurrentByteOffset
.u
.LowPart
=
130 FileObject
->CurrentByteOffset
.u
.LowPart
+
131 Irp
->IoStatus
.Information
;
135 VOID
IoVolumeInformationCompletion(PDEVICE_OBJECT DeviceObject
,
137 PIO_STACK_LOCATION IoStack
)
141 VOID
IoSecondStageCompletion(PIRP Irp
, CCHAR PriorityBoost
)
143 * FUNCTION: Performs the second stage of irp completion for read/write irps
145 * Irp = Irp to completion
146 * FromDevice = True if the operation transfered data from the device
149 PIO_STACK_LOCATION IoStack
;
150 PDEVICE_OBJECT DeviceObject
;
151 PFILE_OBJECT FileObject
;
153 DPRINT("IoSecondStageCompletion(Irp %x, PriorityBoost %d)\n",
156 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
158 DeviceObject
= IoStack
->DeviceObject
;
160 switch (IoStack
->MajorFunction
)
163 case IRP_MJ_FLUSH_BUFFERS
:
169 IoReadWriteCompletion(DeviceObject
,Irp
,IoStack
);
172 case IRP_MJ_DEVICE_CONTROL
:
173 case IRP_MJ_INTERNAL_DEVICE_CONTROL
:
174 IoDeviceControlCompletion(DeviceObject
, Irp
, IoStack
);
177 case IRP_MJ_QUERY_VOLUME_INFORMATION
:
178 case IRP_MJ_SET_VOLUME_INFORMATION
:
179 IoVolumeInformationCompletion(DeviceObject
, Irp
, IoStack
);
185 if (Irp
->Overlay
.AsynchronousParameters
.UserApcRoutine
!= NULL
)
188 PKNORMAL_ROUTINE UserApcRoutine
;
189 PVOID UserApcContext
;
191 DPRINT("Dispatching APC\n");
192 Thread
= &Irp
->Tail
.Overlay
.Thread
->Tcb
;
193 UserApcRoutine
= (PKNORMAL_ROUTINE
)
194 Irp
->Overlay
.AsynchronousParameters
.UserApcRoutine
;
195 UserApcContext
= (PVOID
)
196 Irp
->Overlay
.AsynchronousParameters
.UserApcRoutine
;
197 KeInitializeApc(&Irp
->Tail
.Apc
,
205 KeInsertQueueApc(&Irp
->Tail
.Apc
,
212 DPRINT("Irp->UserIosb %x &Irp->UserIosb %x\n",
215 if (Irp
->UserIosb
!=NULL
)
217 *Irp
->UserIosb
=Irp
->IoStatus
;
219 if (Irp
->UserEvent
!=NULL
)
221 KeSetEvent(Irp
->UserEvent
,PriorityBoost
,FALSE
);
224 FileObject
= IoStack
->FileObject
;
226 if (FileObject
!= NULL
&& IoStack
->MajorFunction
!= IRP_MJ_CLOSE
)
228 ObDereferenceObject(FileObject
);