1 /* $Id: buildirp.c,v 1.35 2003/10/12 17:05:44 hbirr Exp $
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 *****************************************************************/
15 #include <ddk/ntddk.h>
16 #include <internal/pool.h>
17 #include <internal/io.h>
20 #include <internal/debug.h>
22 /* GLOBALS ******************************************************************/
24 #define TAG_SYS_BUF TAG('S', 'B', 'U', 'F')
26 /* FUNCTIONS *****************************************************************/
28 NTSTATUS
IoPrepareIrpBuffer(PIRP Irp
,
29 PDEVICE_OBJECT DeviceObject
,
34 * FUNCTION: Prepares the buffer to be used for an IRP
37 Irp
->UserBuffer
= Buffer
;
38 if (DeviceObject
->Flags
& DO_BUFFERED_IO
)
40 DPRINT("Doing buffer i/o\n");
41 Irp
->AssociatedIrp
.SystemBuffer
=
42 (PVOID
)ExAllocatePoolWithTag(NonPagedPool
,Length
, TAG_SYS_BUF
);
43 if (Irp
->AssociatedIrp
.SystemBuffer
==NULL
)
46 return(STATUS_NOT_IMPLEMENTED
);
48 /* FIXME: should copy buffer in on other ops */
49 if (MajorFunction
== IRP_MJ_WRITE
)
51 RtlCopyMemory(Irp
->AssociatedIrp
.SystemBuffer
, Buffer
, Length
);
54 if (DeviceObject
->Flags
& DO_DIRECT_IO
)
56 DPRINT("Doing direct i/o\n");
58 Irp
->MdlAddress
= MmCreateMdl(NULL
,Buffer
,Length
);
59 if (MajorFunction
== IRP_MJ_READ
)
61 MmProbeAndLockPages(Irp
->MdlAddress
,UserMode
,IoWriteAccess
);
65 MmProbeAndLockPages(Irp
->MdlAddress
,UserMode
,IoReadAccess
);
67 Irp
->UserBuffer
= NULL
;
68 Irp
->AssociatedIrp
.SystemBuffer
= NULL
;
70 return(STATUS_SUCCESS
);
78 IoBuildAsynchronousFsdRequest(ULONG MajorFunction
,
79 PDEVICE_OBJECT DeviceObject
,
82 PLARGE_INTEGER StartingOffset
,
83 PIO_STATUS_BLOCK IoStatusBlock
)
85 * FUNCTION: Allocates and sets up an IRP to be sent to lower level drivers
87 * MajorFunction = One of IRP_MJ_READ, IRP_MJ_WRITE,
88 * IRP_MJ_FLUSH_BUFFERS or IRP_MJ_SHUTDOWN
89 * DeviceObject = Device object to send the irp to
90 * Buffer = Buffer into which data will be read or written
91 * Length = Length in bytes of the irp to be allocated
92 * StartingOffset = Starting offset on the device
93 * IoStatusBlock (OUT) = Storage for the result of the operation
94 * RETURNS: The IRP allocated on success, or
99 PIO_STACK_LOCATION StackPtr
;
101 DPRINT("IoBuildAsynchronousFsdRequest(MajorFunction %x, DeviceObject %x, "
102 "Buffer %x, Length %x, StartingOffset %x, "
103 "IoStatusBlock %x\n",MajorFunction
,DeviceObject
,Buffer
,Length
,
104 StartingOffset
,IoStatusBlock
);
106 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,TRUE
);
112 Irp
->UserIosb
= IoStatusBlock
;
113 DPRINT("Irp->UserIosb %x\n", Irp
->UserIosb
);
114 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
116 StackPtr
= IoGetNextIrpStackLocation(Irp
);
117 StackPtr
->MajorFunction
= MajorFunction
;
118 StackPtr
->MinorFunction
= 0;
120 StackPtr
->Control
= 0;
121 StackPtr
->DeviceObject
= DeviceObject
;
122 StackPtr
->FileObject
= NULL
;
123 StackPtr
->CompletionRoutine
= NULL
;
127 IoPrepareIrpBuffer(Irp
,
134 if (MajorFunction
== IRP_MJ_READ
)
136 StackPtr
->Parameters
.Read
.Length
= Length
;
137 if (StartingOffset
!=NULL
)
139 StackPtr
->Parameters
.Read
.ByteOffset
= *StartingOffset
;
143 StackPtr
->Parameters
.Read
.ByteOffset
.QuadPart
= 0;
146 else if (MajorFunction
== IRP_MJ_WRITE
)
148 StackPtr
->Parameters
.Write
.Length
= Length
;
149 if (StartingOffset
!=NULL
)
151 StackPtr
->Parameters
.Write
.ByteOffset
= *StartingOffset
;
155 StackPtr
->Parameters
.Write
.ByteOffset
.QuadPart
= 0;
159 Irp
->UserIosb
= IoStatusBlock
;
169 IoBuildDeviceIoControlRequest(ULONG IoControlCode
,
170 PDEVICE_OBJECT DeviceObject
,
172 ULONG InputBufferLength
,
174 ULONG OutputBufferLength
,
175 BOOLEAN InternalDeviceIoControl
,
177 PIO_STATUS_BLOCK IoStatusBlock
)
179 * FUNCTION: Allocates and sets up an IRP to be sent to drivers
181 * IoControlCode = Device io control code
182 * DeviceObject = Device object to send the irp to
183 * InputBuffer = Buffer from which data will be read by the driver
184 * InputBufferLength = Length in bytes of the input buffer
185 * OutputBuffer = Buffer into which data will be written by the driver
186 * OutputBufferLength = Length in bytes of the output buffer
187 * InternalDeviceIoControl = Determines weather
188 * IRP_MJ_INTERNAL_DEVICE_CONTROL or
189 * IRP_MJ_DEVICE_CONTROL will be used
190 * Event = Event used to notify the caller of completion
191 * IoStatusBlock (OUT) = Storage for the result of the operation
192 * RETURNS: The IRP allocated on success, or
197 PIO_STACK_LOCATION StackPtr
;
200 DPRINT("IoBuildDeviceIoRequest(IoControlCode %x, DeviceObject %x, "
201 "InputBuffer %x, InputBufferLength %x, OutputBuffer %x, "
202 "OutputBufferLength %x, InternalDeviceIoControl %x "
203 "Event %x, IoStatusBlock %x\n",IoControlCode
,DeviceObject
,
204 InputBuffer
,InputBufferLength
,OutputBuffer
,OutputBufferLength
,
205 InternalDeviceIoControl
,Event
,IoStatusBlock
);
207 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,TRUE
);
213 Irp
->UserEvent
= Event
;
214 Irp
->UserIosb
= IoStatusBlock
;
215 DPRINT("Irp->UserIosb %x\n", Irp
->UserIosb
);
216 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
218 StackPtr
= IoGetNextIrpStackLocation(Irp
);
219 StackPtr
->MajorFunction
= InternalDeviceIoControl
?
220 IRP_MJ_INTERNAL_DEVICE_CONTROL
: IRP_MJ_DEVICE_CONTROL
;
221 StackPtr
->MinorFunction
= 0;
223 StackPtr
->Control
= 0;
224 StackPtr
->DeviceObject
= DeviceObject
;
225 StackPtr
->FileObject
= NULL
;
226 StackPtr
->CompletionRoutine
= NULL
;
227 StackPtr
->Parameters
.DeviceIoControl
.IoControlCode
= IoControlCode
;
228 StackPtr
->Parameters
.DeviceIoControl
.InputBufferLength
= InputBufferLength
;
229 StackPtr
->Parameters
.DeviceIoControl
.OutputBufferLength
=
232 switch (IO_METHOD_FROM_CTL_CODE(IoControlCode
))
234 case METHOD_BUFFERED
:
235 DPRINT("Using METHOD_BUFFERED!\n");
237 if (InputBufferLength
> OutputBufferLength
)
239 BufferLength
= InputBufferLength
;
243 BufferLength
= OutputBufferLength
;
247 Irp
->AssociatedIrp
.SystemBuffer
= (PVOID
)
248 ExAllocatePoolWithTag(NonPagedPool
,BufferLength
, TAG_SYS_BUF
);
250 if (Irp
->AssociatedIrp
.SystemBuffer
== NULL
)
257 if (InputBuffer
&& InputBufferLength
)
259 RtlCopyMemory(Irp
->AssociatedIrp
.SystemBuffer
,
263 Irp
->UserBuffer
= OutputBuffer
;
266 case METHOD_IN_DIRECT
:
267 DPRINT("Using METHOD_IN_DIRECT!\n");
269 /* build output buffer (control buffer) */
270 if (OutputBuffer
&& OutputBufferLength
)
272 Irp
->AssociatedIrp
.SystemBuffer
= (PVOID
)
273 ExAllocatePoolWithTag(NonPagedPool
,OutputBufferLength
,
277 if (Irp
->AssociatedIrp
.SystemBuffer
== NULL
)
282 Irp
->UserBuffer
= OutputBuffer
;
285 /* build input buffer (data transfer buffer) */
286 if (InputBuffer
&& InputBufferLength
)
288 Irp
->MdlAddress
= IoAllocateMdl(InputBuffer
,
293 MmProbeAndLockPages (Irp
->MdlAddress
,UserMode
,IoReadAccess
);
297 case METHOD_OUT_DIRECT
:
298 DPRINT("Using METHOD_OUT_DIRECT!\n");
300 /* build input buffer (control buffer) */
301 if (InputBuffer
&& InputBufferLength
)
303 Irp
->AssociatedIrp
.SystemBuffer
= (PVOID
)
304 ExAllocatePoolWithTag(NonPagedPool
,InputBufferLength
,
307 if (Irp
->AssociatedIrp
.SystemBuffer
==NULL
)
313 RtlCopyMemory(Irp
->AssociatedIrp
.SystemBuffer
,
318 /* build output buffer (data transfer buffer) */
319 if (OutputBuffer
&& OutputBufferLength
)
321 Irp
->MdlAddress
= IoAllocateMdl(OutputBuffer
,
326 MmProbeAndLockPages(Irp
->MdlAddress
,UserMode
,IoWriteAccess
);
331 DPRINT("Using METHOD_NEITHER!\n");
333 Irp
->UserBuffer
= OutputBuffer
;
334 StackPtr
->Parameters
.DeviceIoControl
.Type3InputBuffer
= InputBuffer
;
346 IoBuildSynchronousFsdRequest(ULONG MajorFunction
,
347 PDEVICE_OBJECT DeviceObject
,
350 PLARGE_INTEGER StartingOffset
,
352 PIO_STATUS_BLOCK IoStatusBlock
)
354 * FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
357 * MajorFunction = Major function code, one of IRP_MJ_READ,
358 * IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, IRP_MJ_SHUTDOWN
359 * DeviceObject = Target device object
360 * Buffer = Buffer containing data for a read or write
361 * Length = Length in bytes of the information to be transferred
362 * StartingOffset = Offset to begin the read/write from
363 * Event (OUT) = Will be set when the operation is complete
364 * IoStatusBlock (OUT) = Set to the status of the operation
365 * RETURNS: The IRP allocated on success, or
371 DPRINT("IoBuildSynchronousFsdRequest(MajorFunction %x, DeviceObject %x, "
372 "Buffer %x, Length %x, StartingOffset %x, Event %x, "
373 "IoStatusBlock %x\n",MajorFunction
,DeviceObject
,Buffer
,Length
,
374 StartingOffset
,Event
,IoStatusBlock
);
376 Irp
= IoBuildAsynchronousFsdRequest(MajorFunction
,
387 Irp
->UserEvent
= Event
;
394 IoBuildSynchronousFsdRequestWithMdl(ULONG MajorFunction
,
395 PDEVICE_OBJECT DeviceObject
,
397 PLARGE_INTEGER StartingOffset
,
399 PIO_STATUS_BLOCK IoStatusBlock
,
402 * FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
405 * MajorFunction = Major function code, one of IRP_MJ_READ,
406 * IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, IRP_MJ_SHUTDOWN
407 * DeviceObject = Target device object
408 * Buffer = Buffer containing data for a read or write
409 * Length = Length in bytes of the information to be transferred
410 * StartingOffset = Offset to begin the read/write from
411 * Event (OUT) = Will be set when the operation is complete
412 * IoStatusBlock (OUT) = Set to the status of the operation
413 * RETURNS: The IRP allocated on success, or
418 PIO_STACK_LOCATION StackPtr
;
420 DPRINT("IoBuildSynchronousFsdRequestWithMdl(MajorFunction %x, "
422 "Mdl %x, StartingOffset %x, Event %x, "
423 "IoStatusBlock %x\n",MajorFunction
,DeviceObject
,Mdl
,
424 StartingOffset
,Event
,IoStatusBlock
);
426 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,TRUE
);
432 Irp
->UserEvent
= Event
;
433 Irp
->UserIosb
= IoStatusBlock
;
434 DPRINT("Irp->UserIosb %x\n", Irp
->UserIosb
);
435 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
438 Irp
->Flags
= IRP_PAGING_IO
;
445 StackPtr
= IoGetNextIrpStackLocation(Irp
);
446 StackPtr
->MajorFunction
= MajorFunction
;
447 StackPtr
->MinorFunction
= 0;
449 StackPtr
->Control
= 0;
450 StackPtr
->DeviceObject
= DeviceObject
;
451 StackPtr
->FileObject
= NULL
;
452 StackPtr
->CompletionRoutine
= NULL
;
454 Irp
->MdlAddress
= Mdl
;
455 Irp
->UserBuffer
= NULL
;
456 Irp
->AssociatedIrp
.SystemBuffer
= NULL
;
458 if (MajorFunction
== IRP_MJ_READ
)
460 if (StartingOffset
!= NULL
)
462 StackPtr
->Parameters
.Read
.ByteOffset
= *StartingOffset
;
466 StackPtr
->Parameters
.Read
.ByteOffset
.QuadPart
= 0;
468 StackPtr
->Parameters
.Read
.Length
= MmGetMdlByteCount(Mdl
);
472 if (StartingOffset
!=NULL
)
474 StackPtr
->Parameters
.Write
.ByteOffset
= *StartingOffset
;
478 StackPtr
->Parameters
.Write
.ByteOffset
.QuadPart
= 0;
480 StackPtr
->Parameters
.Write
.Length
= MmGetMdlByteCount(Mdl
);