2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/io/buildirp.c
5 * PURPOSE: Building various types of irp
6 * PROGRAMMER: David Welch (welch@mcmail.com)
9 * Fixed IO method handling 04/03/99
12 /* INCLUDES *****************************************************************/
14 #include <ddk/ntddk.h>
17 #include <internal/debug.h>
19 /* FUNCTIONS *****************************************************************/
21 NTSTATUS
IoPrepareIrpBuffer(PIRP Irp
,
22 PDEVICE_OBJECT DeviceObject
,
27 * FUNCTION: Prepares the buffer to be used for an IRP
30 Irp
->UserBuffer
= Buffer
;
31 if (DeviceObject
->Flags
& DO_BUFFERED_IO
)
33 DPRINT("Doing buffer i/o\n");
34 Irp
->AssociatedIrp
.SystemBuffer
= (PVOID
)
35 ExAllocatePool(NonPagedPool
,Length
);
36 if (Irp
->AssociatedIrp
.SystemBuffer
==NULL
)
39 return(STATUS_NOT_IMPLEMENTED
);
41 /* FIXME: should copy buffer in on other ops */
42 if (MajorFunction
== IRP_MJ_WRITE
)
44 RtlCopyMemory(Irp
->AssociatedIrp
.SystemBuffer
, Buffer
, Length
);
47 if (DeviceObject
->Flags
& DO_DIRECT_IO
)
49 DPRINT("Doing direct i/o\n");
51 Irp
->MdlAddress
= MmCreateMdl(NULL
,Buffer
,Length
);
52 if (MajorFunction
== IRP_MJ_READ
)
54 MmProbeAndLockPages(Irp
->MdlAddress
,UserMode
,IoWriteAccess
);
58 MmProbeAndLockPages(Irp
->MdlAddress
,UserMode
,IoReadAccess
);
60 Irp
->UserBuffer
= NULL
;
61 Irp
->AssociatedIrp
.SystemBuffer
= NULL
;
63 return(STATUS_SUCCESS
);
66 PIRP
IoBuildFilesystemControlRequest(ULONG MinorFunction
,
67 PDEVICE_OBJECT DeviceObject
,
69 PIO_STATUS_BLOCK IoStatusBlock
,
70 PDEVICE_OBJECT DeviceToMount
)
72 * FUNCTION: Allocates and sets up a filesystem control IRP
74 * MinorFunction = Type of filesystem control
75 * DeviceObject = Device object to send the request to
76 * UserEvent = Event used to notify the caller of completion
77 * IoStatusBlock (OUT) = Used to return the status of the operation
78 * DeviceToMount = Device to mount (for the IRP_MN_MOUNT_DEVICE
83 PIO_STACK_LOCATION StackPtr
;
85 Irp
= IoAllocateIrp(DeviceObject
->StackSize
, TRUE
);
91 Irp
->UserIosb
= IoStatusBlock
;
92 Irp
->UserEvent
= UserEvent
;
94 StackPtr
= IoGetNextIrpStackLocation(Irp
);
95 StackPtr
->MajorFunction
= IRP_MJ_FILE_SYSTEM_CONTROL
;
96 StackPtr
->MinorFunction
= MinorFunction
;
98 StackPtr
->Control
= 0;
99 StackPtr
->DeviceObject
= DeviceObject
;
100 StackPtr
->FileObject
= NULL
;
101 StackPtr
->CompletionRoutine
= NULL
;
103 switch(MinorFunction
)
105 case IRP_MN_USER_FS_REQUEST
:
108 case IRP_MN_MOUNT_VOLUME
:
109 StackPtr
->Parameters
.Mount
.Vpb
= DeviceObject
->Vpb
;
110 StackPtr
->Parameters
.Mount
.DeviceObject
= DeviceToMount
;
113 case IRP_MN_VERIFY_VOLUME
:
116 case IRP_MN_LOAD_FILE_SYSTEM
:
122 PIRP
IoBuildAsynchronousFsdRequest(ULONG MajorFunction
,
123 PDEVICE_OBJECT DeviceObject
,
126 PLARGE_INTEGER StartingOffset
,
127 PIO_STATUS_BLOCK IoStatusBlock
)
129 * FUNCTION: Allocates and sets up an IRP to be sent to lower level drivers
131 * MajorFunction = One of IRP_MJ_READ, IRP_MJ_WRITE,
132 * IRP_MJ_FLUSH_BUFFERS or IRP_MJ_SHUTDOWN
133 * DeviceObject = Device object to send the irp to
134 * Buffer = Buffer into which data will be read or written
135 * Length = Length in bytes of the irp to be allocated
136 * StartingOffset = Starting offset on the device
137 * IoStatusBlock (OUT) = Storage for the result of the operation
138 * RETURNS: The IRP allocated on success, or
143 PIO_STACK_LOCATION StackPtr
;
145 DPRINT("IoBuildAsynchronousFsdRequest(MajorFunction %x, DeviceObject %x, "
146 "Buffer %x, Length %x, StartingOffset %x, "
147 "IoStatusBlock %x\n",MajorFunction
,DeviceObject
,Buffer
,Length
,
148 StartingOffset
,IoStatusBlock
);
150 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,TRUE
);
156 StackPtr
= IoGetNextIrpStackLocation(Irp
);
157 StackPtr
->MajorFunction
= MajorFunction
;
158 StackPtr
->MinorFunction
= 0;
160 StackPtr
->Control
= 0;
161 StackPtr
->DeviceObject
= DeviceObject
;
162 StackPtr
->FileObject
= NULL
;
163 StackPtr
->CompletionRoutine
= NULL
;
164 StackPtr
->Parameters
.Write
.Length
= Length
;
166 if (MajorFunction
== IRP_MJ_READ
|| MajorFunction
== IRP_MJ_WRITE
)
168 Irp
->UserBuffer
= (LPVOID
)Buffer
;
169 if (DeviceObject
->Flags
&DO_BUFFERED_IO
)
171 DPRINT("Doing buffer i/o\n",0);
172 Irp
->AssociatedIrp
.SystemBuffer
= (PVOID
)
173 ExAllocatePool(NonPagedPool
,Length
);
174 if (Irp
->AssociatedIrp
.SystemBuffer
==NULL
)
179 if (DeviceObject
->Flags
&DO_DIRECT_IO
)
181 DPRINT("Doing direct i/o\n",0);
183 Irp
->MdlAddress
= MmCreateMdl(NULL
,Buffer
,Length
);
184 MmProbeAndLockPages(Irp
->MdlAddress
,UserMode
,IoWriteAccess
);
185 Irp
->UserBuffer
= NULL
;
186 Irp
->AssociatedIrp
.SystemBuffer
= NULL
;
188 if (StartingOffset
!=NULL
)
190 StackPtr
->Parameters
.Write
.ByteOffset
= *StartingOffset
;
194 StackPtr
->Parameters
.Write
.ByteOffset
.QuadPart
= 0;
198 Irp
->UserIosb
= IoStatusBlock
;
203 PIRP
IoBuildDeviceIoControlRequest(ULONG IoControlCode
,
204 PDEVICE_OBJECT DeviceObject
,
206 ULONG InputBufferLength
,
208 ULONG OutputBufferLength
,
209 BOOLEAN InternalDeviceIoControl
,
211 PIO_STATUS_BLOCK IoStatusBlock
)
213 * FUNCTION: Allocates and sets up an IRP to be sent to drivers
215 * IoControlCode = Device io control code
216 * DeviceObject = Device object to send the irp to
217 * InputBuffer = Buffer from which data will be read by the driver
218 * InputBufferLength = Length in bytes of the input buffer
219 * OutputBuffer = Buffer into which data will be written by the driver
220 * OutputBufferLength = Length in bytes of the output buffer
221 * InternalDeviceIoControl = Determines weather
222 * IRP_MJ_INTERNAL_DEVICE_CONTROL or
223 * IRP_MJ_DEVICE_CONTROL will be used
224 * Event = Event used to notify the caller of completion
225 * IoStatusBlock (OUT) = Storage for the result of the operation
226 * RETURNS: The IRP allocated on success, or
231 PIO_STACK_LOCATION StackPtr
;
234 DPRINT("IoBuildDeviceIoRequest(IoControlCode %x, DeviceObject %x, "
235 "InputBuffer %x, InputBufferLength %x, OutputBuffer %x, "
236 "OutputBufferLength %x, InternalDeviceIoControl %x "
237 "Event %x, IoStatusBlock %x\n",IoControlCode
,DeviceObject
,
238 InputBuffer
,InputBufferLength
,OutputBuffer
,OutputBufferLength
,
239 InternalDeviceIoControl
,Event
,IoStatusBlock
);
241 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,TRUE
);
247 Irp
->UserEvent
= Event
;
248 Irp
->UserIosb
= IoStatusBlock
;
250 StackPtr
= IoGetNextIrpStackLocation(Irp
);
251 StackPtr
->MajorFunction
= InternalDeviceIoControl
? IRP_MJ_INTERNAL_DEVICE_CONTROL
: IRP_MJ_DEVICE_CONTROL
;
252 StackPtr
->MinorFunction
= 0;
254 StackPtr
->Control
= 0;
255 StackPtr
->DeviceObject
= DeviceObject
;
256 StackPtr
->FileObject
= NULL
;
257 StackPtr
->CompletionRoutine
= NULL
;
258 StackPtr
->Parameters
.DeviceIoControl
.IoControlCode
= IoControlCode
;
259 StackPtr
->Parameters
.DeviceIoControl
.InputBufferLength
= InputBufferLength
;
260 StackPtr
->Parameters
.DeviceIoControl
.OutputBufferLength
= OutputBufferLength
;
262 switch (IO_METHOD_FROM_CTL_CODE(IoControlCode
))
264 case METHOD_BUFFERED
:
265 DPRINT("Using METHOD_BUFFERED!\n");
267 BufferLength
= (InputBufferLength
>OutputBufferLength
)?InputBufferLength
:OutputBufferLength
;
270 Irp
->AssociatedIrp
.SystemBuffer
= (PVOID
)
271 ExAllocatePool(NonPagedPool
,BufferLength
);
273 if (Irp
->AssociatedIrp
.SystemBuffer
==NULL
)
280 if (InputBuffer
&& InputBufferLength
)
282 RtlCopyMemory(Irp
->AssociatedIrp
.SystemBuffer
,
286 Irp
->UserBuffer
= OutputBuffer
;
289 case METHOD_IN_DIRECT
:
290 DPRINT("Using METHOD_IN_DIRECT!\n");
292 /* build input buffer (control buffer) */
293 if (InputBuffer
&& InputBufferLength
)
295 Irp
->AssociatedIrp
.SystemBuffer
= (PVOID
)
296 ExAllocatePool(NonPagedPool
,InputBufferLength
);
298 if (Irp
->AssociatedIrp
.SystemBuffer
==NULL
)
304 RtlCopyMemory(Irp
->AssociatedIrp
.SystemBuffer
,
309 /* build output buffer (data transfer buffer) */
310 if (OutputBuffer
&& OutputBufferLength
)
312 Irp
->MdlAddress
= IoAllocateMdl (OutputBuffer
,OutputBufferLength
,FALSE
,FALSE
,Irp
);
313 MmProbeAndLockPages (Irp
->MdlAddress
,UserMode
,IoReadAccess
);
317 case METHOD_OUT_DIRECT
:
318 DPRINT("Using METHOD_OUT_DIRECT!\n");
320 /* build input buffer (control buffer) */
321 if (InputBuffer
&& InputBufferLength
)
323 Irp
->AssociatedIrp
.SystemBuffer
= (PVOID
)
324 ExAllocatePool(NonPagedPool
,InputBufferLength
);
326 if (Irp
->AssociatedIrp
.SystemBuffer
==NULL
)
332 RtlCopyMemory(Irp
->AssociatedIrp
.SystemBuffer
,
337 /* build output buffer (data transfer buffer) */
338 if (OutputBuffer
&& OutputBufferLength
)
340 Irp
->MdlAddress
= IoAllocateMdl(OutputBuffer
,
345 MmProbeAndLockPages(Irp
->MdlAddress
,UserMode
,IoWriteAccess
);
350 DPRINT("Using METHOD_NEITHER!\n");
352 Irp
->UserBuffer
= OutputBuffer
;
353 StackPtr
->Parameters
.DeviceIoControl
.Type3InputBuffer
= InputBuffer
;
360 PIRP
IoBuildSynchronousFsdRequest(ULONG MajorFunction
,
361 PDEVICE_OBJECT DeviceObject
,
364 PLARGE_INTEGER StartingOffset
,
366 PIO_STATUS_BLOCK IoStatusBlock
)
368 * FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
371 * MajorFunction = Major function code, one of IRP_MJ_READ,
372 * IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, IRP_MJ_SHUTDOWN
373 * DeviceObject = Target device object
374 * Buffer = Buffer containing data for a read or write
375 * Length = Length in bytes of the information to be transferred
376 * StartingOffset = Offset to begin the read/write from
377 * Event (OUT) = Will be set when the operation is complete
378 * IoStatusBlock (OUT) = Set to the status of the operation
379 * RETURNS: The IRP allocated on success, or
384 PIO_STACK_LOCATION StackPtr
;
386 DPRINT("IoBuildSynchronousFsdRequest(MajorFunction %x, DeviceObject %x, "
387 "Buffer %x, Length %x, StartingOffset %x, Event %x, "
388 "IoStatusBlock %x\n",MajorFunction
,DeviceObject
,Buffer
,Length
,
389 StartingOffset
,Event
,IoStatusBlock
);
391 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,TRUE
);
397 Irp
->UserEvent
= Event
;
398 Irp
->UserIosb
= IoStatusBlock
;
400 StackPtr
= IoGetNextIrpStackLocation(Irp
);
401 StackPtr
->MajorFunction
= MajorFunction
;
402 StackPtr
->MinorFunction
= 0;
404 StackPtr
->Control
= 0;
405 StackPtr
->DeviceObject
= DeviceObject
;
406 StackPtr
->FileObject
= NULL
;
407 StackPtr
->CompletionRoutine
= NULL
;
411 IoPrepareIrpBuffer(Irp
,
418 if (MajorFunction
== IRP_MJ_READ
)
420 if (StartingOffset
!= NULL
)
422 StackPtr
->Parameters
.Read
.ByteOffset
= *StartingOffset
;
426 StackPtr
->Parameters
.Read
.ByteOffset
.QuadPart
= 0;
428 StackPtr
->Parameters
.Read
.Length
= Length
;
432 if (StartingOffset
!=NULL
)
434 StackPtr
->Parameters
.Write
.ByteOffset
= *StartingOffset
;
438 StackPtr
->Parameters
.Write
.ByteOffset
.QuadPart
= 0;
440 StackPtr
->Parameters
.Write
.Length
= Length
;