3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/buildirp.c
6 * PURPOSE: Building various types of irp
7 * PROGRAMMER: David Welch (welch@mcmail.com)
10 * Fixed IO method handling 04/03/99
13 /* INCLUDES *****************************************************************/
17 #include <internal/debug.h>
19 /* GLOBALS ******************************************************************/
21 #define TAG_SYS_BUF TAG('S', 'B', 'U', 'F')
23 /* FUNCTIONS *****************************************************************/
25 NTSTATUS
IoPrepareIrpBuffer(PIRP Irp
,
26 PDEVICE_OBJECT DeviceObject
,
31 * FUNCTION: Prepares the buffer to be used for an IRP
34 Irp
->UserBuffer
= Buffer
;
35 if (DeviceObject
->Flags
& DO_BUFFERED_IO
)
37 DPRINT("Doing buffer i/o\n");
38 Irp
->AssociatedIrp
.SystemBuffer
=
39 (PVOID
)ExAllocatePoolWithTag(NonPagedPool
,Length
, TAG_SYS_BUF
);
40 if (Irp
->AssociatedIrp
.SystemBuffer
==NULL
)
43 return(STATUS_NOT_IMPLEMENTED
);
45 /* FIXME: should copy buffer in on other ops */
46 if (MajorFunction
== IRP_MJ_WRITE
)
48 RtlCopyMemory(Irp
->AssociatedIrp
.SystemBuffer
, Buffer
, Length
);
51 if (DeviceObject
->Flags
& DO_DIRECT_IO
)
53 DPRINT("Doing direct i/o\n");
55 Irp
->MdlAddress
= MmCreateMdl(NULL
,Buffer
,Length
);
56 if(Irp
->MdlAddress
== NULL
) {
57 DPRINT("MmCreateMdl: Out of memory!");
58 return(STATUS_NO_MEMORY
);
60 if (MajorFunction
== IRP_MJ_READ
)
62 MmProbeAndLockPages(Irp
->MdlAddress
,UserMode
,IoWriteAccess
);
66 MmProbeAndLockPages(Irp
->MdlAddress
,UserMode
,IoReadAccess
);
68 Irp
->UserBuffer
= NULL
;
69 Irp
->AssociatedIrp
.SystemBuffer
= NULL
;
71 return(STATUS_SUCCESS
);
79 IoBuildAsynchronousFsdRequest(ULONG MajorFunction
,
80 PDEVICE_OBJECT DeviceObject
,
83 PLARGE_INTEGER StartingOffset
,
84 PIO_STATUS_BLOCK IoStatusBlock
)
86 * FUNCTION: Allocates and sets up an IRP to be sent to lower level drivers
88 * MajorFunction = One of IRP_MJ_READ, IRP_MJ_WRITE,
89 * IRP_MJ_FLUSH_BUFFERS or IRP_MJ_SHUTDOWN
90 * DeviceObject = Device object to send the irp to
91 * Buffer = Buffer into which data will be read or written
92 * Length = Length in bytes of the irp to be allocated
93 * StartingOffset = Starting offset on the device
94 * IoStatusBlock (OUT) = Storage for the result of the operation
95 * RETURNS: The IRP allocated on success, or
100 PIO_STACK_LOCATION StackPtr
;
102 DPRINT("IoBuildAsynchronousFsdRequest(MajorFunction %x, DeviceObject %x, "
103 "Buffer %x, Length %x, StartingOffset %x, "
104 "IoStatusBlock %x\n",MajorFunction
,DeviceObject
,Buffer
,Length
,
105 StartingOffset
,IoStatusBlock
);
107 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,TRUE
);
113 Irp
->UserIosb
= IoStatusBlock
;
114 DPRINT("Irp->UserIosb %x\n", Irp
->UserIosb
);
115 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
117 StackPtr
= IoGetNextIrpStackLocation(Irp
);
118 StackPtr
->MajorFunction
= (UCHAR
)MajorFunction
;
119 StackPtr
->MinorFunction
= 0;
121 StackPtr
->Control
= 0;
122 StackPtr
->DeviceObject
= DeviceObject
;
123 StackPtr
->FileObject
= NULL
;
124 StackPtr
->CompletionRoutine
= NULL
;
128 IoPrepareIrpBuffer(Irp
,
135 if (MajorFunction
== IRP_MJ_READ
)
137 StackPtr
->Parameters
.Read
.Length
= Length
;
138 if (StartingOffset
!=NULL
)
140 StackPtr
->Parameters
.Read
.ByteOffset
= *StartingOffset
;
144 StackPtr
->Parameters
.Read
.ByteOffset
.QuadPart
= 0;
147 else if (MajorFunction
== IRP_MJ_WRITE
)
149 StackPtr
->Parameters
.Write
.Length
= Length
;
150 if (StartingOffset
!=NULL
)
152 StackPtr
->Parameters
.Write
.ByteOffset
= *StartingOffset
;
156 StackPtr
->Parameters
.Write
.ByteOffset
.QuadPart
= 0;
168 IoBuildDeviceIoControlRequest(ULONG IoControlCode
,
169 PDEVICE_OBJECT DeviceObject
,
171 ULONG InputBufferLength
,
173 ULONG OutputBufferLength
,
174 BOOLEAN InternalDeviceIoControl
,
176 PIO_STATUS_BLOCK IoStatusBlock
)
178 * FUNCTION: Allocates and sets up an IRP to be sent to drivers
180 * IoControlCode = Device io control code
181 * DeviceObject = Device object to send the irp to
182 * InputBuffer = Buffer from which data will be read by the driver
183 * InputBufferLength = Length in bytes of the input buffer
184 * OutputBuffer = Buffer into which data will be written by the driver
185 * OutputBufferLength = Length in bytes of the output buffer
186 * InternalDeviceIoControl = Determines weather
187 * IRP_MJ_INTERNAL_DEVICE_CONTROL or
188 * IRP_MJ_DEVICE_CONTROL will be used
189 * Event = Event used to notify the caller of completion
190 * IoStatusBlock (OUT) = Storage for the result of the operation
191 * RETURNS: The IRP allocated on success, or
196 PIO_STACK_LOCATION StackPtr
;
199 DPRINT("IoBuildDeviceIoRequest(IoControlCode %x, DeviceObject %x, "
200 "InputBuffer %x, InputBufferLength %x, OutputBuffer %x, "
201 "OutputBufferLength %x, InternalDeviceIoControl %x "
202 "Event %x, IoStatusBlock %x\n",IoControlCode
,DeviceObject
,
203 InputBuffer
,InputBufferLength
,OutputBuffer
,OutputBufferLength
,
204 InternalDeviceIoControl
,Event
,IoStatusBlock
);
206 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,TRUE
);
212 Irp
->UserEvent
= Event
;
213 Irp
->UserIosb
= IoStatusBlock
;
214 DPRINT("Irp->UserIosb %x\n", Irp
->UserIosb
);
215 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
217 StackPtr
= IoGetNextIrpStackLocation(Irp
);
218 StackPtr
->MajorFunction
= InternalDeviceIoControl
?
219 IRP_MJ_INTERNAL_DEVICE_CONTROL
: IRP_MJ_DEVICE_CONTROL
;
220 StackPtr
->MinorFunction
= 0;
222 StackPtr
->Control
= 0;
223 StackPtr
->DeviceObject
= DeviceObject
;
224 StackPtr
->FileObject
= NULL
;
225 StackPtr
->CompletionRoutine
= NULL
;
226 StackPtr
->Parameters
.DeviceIoControl
.IoControlCode
= IoControlCode
;
227 StackPtr
->Parameters
.DeviceIoControl
.InputBufferLength
= InputBufferLength
;
228 StackPtr
->Parameters
.DeviceIoControl
.OutputBufferLength
=
231 switch (IO_METHOD_FROM_CTL_CODE(IoControlCode
))
233 case METHOD_BUFFERED
:
234 DPRINT("Using METHOD_BUFFERED!\n");
236 if (InputBufferLength
> OutputBufferLength
)
238 BufferLength
= InputBufferLength
;
242 BufferLength
= OutputBufferLength
;
246 Irp
->AssociatedIrp
.SystemBuffer
= (PVOID
)
247 ExAllocatePoolWithTag(NonPagedPool
,BufferLength
, TAG_SYS_BUF
);
249 if (Irp
->AssociatedIrp
.SystemBuffer
== NULL
)
256 if (InputBuffer
&& InputBufferLength
)
258 RtlCopyMemory(Irp
->AssociatedIrp
.SystemBuffer
,
261 RtlZeroMemory((char*)Irp
->AssociatedIrp
.SystemBuffer
+ InputBufferLength
,
262 BufferLength
- InputBufferLength
);
266 RtlZeroMemory(Irp
->AssociatedIrp
.SystemBuffer
,
269 Irp
->UserBuffer
= OutputBuffer
;
272 case METHOD_IN_DIRECT
:
273 DPRINT("Using METHOD_IN_DIRECT!\n");
275 /* build input buffer (control buffer) */
276 if (InputBuffer
&& InputBufferLength
)
278 Irp
->AssociatedIrp
.SystemBuffer
= (PVOID
)
279 ExAllocatePoolWithTag(NonPagedPool
,InputBufferLength
,
282 if (Irp
->AssociatedIrp
.SystemBuffer
==NULL
)
288 RtlCopyMemory(Irp
->AssociatedIrp
.SystemBuffer
,
293 /* build output buffer (data transfer buffer) */
294 if (OutputBuffer
&& OutputBufferLength
)
296 Irp
->MdlAddress
= IoAllocateMdl(OutputBuffer
,
301 MmProbeAndLockPages(Irp
->MdlAddress
,UserMode
,IoReadAccess
);
305 case METHOD_OUT_DIRECT
:
306 DPRINT("Using METHOD_OUT_DIRECT!\n");
308 /* build input buffer (control buffer) */
309 if (InputBuffer
&& InputBufferLength
)
311 Irp
->AssociatedIrp
.SystemBuffer
= (PVOID
)
312 ExAllocatePoolWithTag(NonPagedPool
,InputBufferLength
,
315 if (Irp
->AssociatedIrp
.SystemBuffer
==NULL
)
321 RtlCopyMemory(Irp
->AssociatedIrp
.SystemBuffer
,
326 /* build output buffer (data transfer buffer) */
327 if (OutputBuffer
&& OutputBufferLength
)
329 Irp
->MdlAddress
= IoAllocateMdl(OutputBuffer
,
334 MmProbeAndLockPages(Irp
->MdlAddress
,UserMode
,IoWriteAccess
);
339 DPRINT("Using METHOD_NEITHER!\n");
341 Irp
->UserBuffer
= OutputBuffer
;
342 StackPtr
->Parameters
.DeviceIoControl
.Type3InputBuffer
= InputBuffer
;
346 /* synchronous irp's are queued to requestor thread's irp cancel/cleanup list */
347 IoQueueThreadIrp(Irp
);
356 IoBuildSynchronousFsdRequest(ULONG MajorFunction
,
357 PDEVICE_OBJECT DeviceObject
,
360 PLARGE_INTEGER StartingOffset
,
362 PIO_STATUS_BLOCK IoStatusBlock
)
364 * FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
367 * MajorFunction = Major function code, one of IRP_MJ_READ,
368 * IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, IRP_MJ_SHUTDOWN
369 * DeviceObject = Target device object
370 * Buffer = Buffer containing data for a read or write
371 * Length = Length in bytes of the information to be transferred
372 * StartingOffset = Offset to begin the read/write from
373 * Event (OUT) = Will be set when the operation is complete
374 * IoStatusBlock (OUT) = Set to the status of the operation
375 * RETURNS: The IRP allocated on success, or
381 DPRINT("IoBuildSynchronousFsdRequest(MajorFunction %x, DeviceObject %x, "
382 "Buffer %x, Length %x, StartingOffset %x, Event %x, "
383 "IoStatusBlock %x\n",MajorFunction
,DeviceObject
,Buffer
,Length
,
384 StartingOffset
,Event
,IoStatusBlock
);
386 Irp
= IoBuildAsynchronousFsdRequest(MajorFunction
,
397 Irp
->UserEvent
= Event
;
399 /* synchronous irp's are queued to requestor thread's irp cancel/cleanup list */
400 IoQueueThreadIrp(Irp
);
406 IoBuildSynchronousFsdRequestWithMdl(ULONG MajorFunction
,
407 PDEVICE_OBJECT DeviceObject
,
409 PLARGE_INTEGER StartingOffset
,
411 PIO_STATUS_BLOCK IoStatusBlock
,
414 * FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
417 * MajorFunction = Major function code, one of IRP_MJ_READ,
418 * IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, IRP_MJ_SHUTDOWN
419 * DeviceObject = Target device object
420 * Buffer = Buffer containing data for a read or write
421 * Length = Length in bytes of the information to be transferred
422 * StartingOffset = Offset to begin the read/write from
423 * Event (OUT) = Will be set when the operation is complete
424 * IoStatusBlock (OUT) = Set to the status of the operation
425 * RETURNS: The IRP allocated on success, or
430 PIO_STACK_LOCATION StackPtr
;
432 DPRINT("IoBuildSynchronousFsdRequestWithMdl(MajorFunction %x, "
434 "Mdl %x, StartingOffset %x, Event %x, "
435 "IoStatusBlock %x\n",MajorFunction
,DeviceObject
,Mdl
,
436 StartingOffset
,Event
,IoStatusBlock
);
438 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,TRUE
);
444 Irp
->UserEvent
= Event
;
445 Irp
->UserIosb
= IoStatusBlock
;
446 DPRINT("Irp->UserIosb %x\n", Irp
->UserIosb
);
447 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
450 Irp
->Flags
= IRP_PAGING_IO
;
457 StackPtr
= IoGetNextIrpStackLocation(Irp
);
458 StackPtr
->MajorFunction
= (UCHAR
)MajorFunction
;
459 StackPtr
->MinorFunction
= 0;
461 StackPtr
->Control
= 0;
462 StackPtr
->DeviceObject
= DeviceObject
;
463 StackPtr
->FileObject
= NULL
;
464 StackPtr
->CompletionRoutine
= NULL
;
466 Irp
->MdlAddress
= Mdl
;
467 Irp
->UserBuffer
= MmGetMdlVirtualAddress(Mdl
);
468 Irp
->AssociatedIrp
.SystemBuffer
= NULL
;
470 if (MajorFunction
== IRP_MJ_READ
)
472 if (StartingOffset
!= NULL
)
474 StackPtr
->Parameters
.Read
.ByteOffset
= *StartingOffset
;
478 StackPtr
->Parameters
.Read
.ByteOffset
.QuadPart
= 0;
480 StackPtr
->Parameters
.Read
.Length
= MmGetMdlByteCount(Mdl
);
484 if (StartingOffset
!=NULL
)
486 StackPtr
->Parameters
.Write
.ByteOffset
= *StartingOffset
;
490 StackPtr
->Parameters
.Write
.ByteOffset
.QuadPart
= 0;
492 StackPtr
->Parameters
.Write
.Length
= MmGetMdlByteCount(Mdl
);