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
];
43 (*SystemArgument1
) = (PVOID
)Irp
->UserIosb
;
44 (*SystemArgument2
) = (PVOID
)Irp
->IoStatus
.Information
;
46 if (Irp
->UserIosb
!=NULL
)
48 *Irp
->UserIosb
=Irp
->IoStatus
;
50 if (Irp
->UserEvent
!=NULL
)
52 KeSetEvent(Irp
->UserEvent
,PriorityBoost
,FALSE
);
55 FileObject
= IoStack
->FileObject
;
57 if (FileObject
!= NULL
&& IoStack
->MajorFunction
!= IRP_MJ_CLOSE
)
59 ObDereferenceObject(FileObject
);
66 VOID
IoDeviceControlCompletion(PDEVICE_OBJECT DeviceObject
,
68 PIO_STACK_LOCATION IoStack
)
72 IoControlCode
= IoStack
->Parameters
.DeviceIoControl
.IoControlCode
;
74 switch (IO_METHOD_FROM_CTL_CODE(IoControlCode
))
77 DPRINT ("Using METHOD_BUFFERED!\n");
79 /* copy output buffer back and free it */
80 if (Irp
->AssociatedIrp
.SystemBuffer
)
82 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
)
84 RtlCopyMemory(Irp
->UserBuffer
,
85 Irp
->AssociatedIrp
.SystemBuffer
,
86 IoStack
->Parameters
.DeviceIoControl
.
89 ExFreePool (Irp
->AssociatedIrp
.SystemBuffer
);
93 case METHOD_IN_DIRECT
:
94 DPRINT ("Using METHOD_IN_DIRECT!\n");
96 /* free input buffer (control buffer) */
97 if (Irp
->AssociatedIrp
.SystemBuffer
)
98 ExFreePool (Irp
->AssociatedIrp
.SystemBuffer
);
100 /* free output buffer (data transfer buffer) */
102 IoFreeMdl (Irp
->MdlAddress
);
105 case METHOD_OUT_DIRECT
:
106 DPRINT ("Using METHOD_OUT_DIRECT!\n");
108 /* free input buffer (control buffer) */
109 if (Irp
->AssociatedIrp
.SystemBuffer
)
110 ExFreePool (Irp
->AssociatedIrp
.SystemBuffer
);
112 /* free output buffer (data transfer buffer) */
114 IoFreeMdl (Irp
->MdlAddress
);
118 DPRINT ("Using METHOD_NEITHER!\n");
124 VOID
IoReadWriteCompletion(PDEVICE_OBJECT DeviceObject
,
126 PIO_STACK_LOCATION IoStack
)
128 PFILE_OBJECT FileObject
;
130 FileObject
= IoStack
->FileObject
;
132 if (DeviceObject
->Flags
& DO_BUFFERED_IO
)
134 if (IoStack
->MajorFunction
== IRP_MJ_READ
)
136 DPRINT("Copying buffered io back to user\n");
137 memcpy(Irp
->UserBuffer
,Irp
->AssociatedIrp
.SystemBuffer
,
138 IoStack
->Parameters
.Read
.Length
);
140 ExFreePool(Irp
->AssociatedIrp
.SystemBuffer
);
142 if (DeviceObject
->Flags
& DO_DIRECT_IO
)
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
)
148 MmUnmapLockedPages(Irp
->MdlAddress
->MappedSystemVa
,
151 MmUnlockPages(Irp
->MdlAddress
);
152 ExFreePool(Irp
->MdlAddress
);
156 VOID
IoVolumeInformationCompletion(PDEVICE_OBJECT DeviceObject
,
158 PIO_STACK_LOCATION IoStack
)
162 VOID
IoSecondStageCompletion(PIRP Irp
, CCHAR PriorityBoost
)
164 * FUNCTION: Performs the second stage of irp completion for read/write irps
166 * Irp = Irp to completion
167 * FromDevice = True if the operation transfered data from the device
170 PIO_STACK_LOCATION IoStack
;
171 PDEVICE_OBJECT DeviceObject
;
172 PFILE_OBJECT FileObject
;
174 DPRINT("IoSecondStageCompletion(Irp %x, PriorityBoost %d)\n",
177 IoStack
= &Irp
->Stack
[(ULONG
)Irp
->CurrentLocation
];
179 DeviceObject
= IoStack
->DeviceObject
;
181 switch (IoStack
->MajorFunction
)
184 case IRP_MJ_FLUSH_BUFFERS
:
190 IoReadWriteCompletion(DeviceObject
,Irp
,IoStack
);
193 case IRP_MJ_DEVICE_CONTROL
:
194 case IRP_MJ_INTERNAL_DEVICE_CONTROL
:
195 IoDeviceControlCompletion(DeviceObject
, Irp
, IoStack
);
198 case IRP_MJ_QUERY_VOLUME_INFORMATION
:
199 case IRP_MJ_SET_VOLUME_INFORMATION
:
200 IoVolumeInformationCompletion(DeviceObject
, Irp
, IoStack
);
207 if (Irp
->Overlay
.AsynchronousParameters
.UserApcRoutine
!= NULL
)
210 PKNORMAL_ROUTINE UserApcRoutine
;
211 PVOID UserApcContext
;
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
,
227 KeInsertQueueApc(&Irp
->Tail
.Apc
,
229 (PVOID
)(LONG
)PriorityBoost
,
234 DPRINT("Irp->UserIosb %x &Irp->UserIosb %x\n",
237 if (Irp
->UserIosb
!=NULL
)
239 *Irp
->UserIosb
=Irp
->IoStatus
;
241 if (Irp
->UserEvent
!=NULL
)
243 KeSetEvent(Irp
->UserEvent
,PriorityBoost
,FALSE
);
246 FileObject
= IoStack
->FileObject
;
248 if (FileObject
!= NULL
&& IoStack
->MajorFunction
!= IRP_MJ_CLOSE
)
250 //ObDereferenceObject(FileObject);
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
))
254 ObDereferenceObject(FileObject
);