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>
19 #include <internal/debug.h>
21 /* GLOBALS ******************************************************************/
23 #define TAG_SYS_BUF TAG('S', 'B', 'U', 'F')
25 /* FUNCTIONS *****************************************************************/
27 NTSTATUS IoPrepareIrpBuffer(PIRP Irp,
28 PDEVICE_OBJECT DeviceObject,
33 * FUNCTION: Prepares the buffer to be used for an IRP
36 Irp->UserBuffer = Buffer;
37 if (DeviceObject->Flags & DO_BUFFERED_IO)
39 DPRINT("Doing buffer i/o\n");
40 Irp->AssociatedIrp.SystemBuffer =
41 (PVOID)ExAllocatePoolWithTag(NonPagedPool,Length, TAG_SYS_BUF);
42 if (Irp->AssociatedIrp.SystemBuffer==NULL)
45 return(STATUS_NOT_IMPLEMENTED);
47 /* FIXME: should copy buffer in on other ops */
48 if (MajorFunction == IRP_MJ_WRITE)
50 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, Buffer, Length);
53 if (DeviceObject->Flags & DO_DIRECT_IO)
55 DPRINT("Doing direct i/o\n");
57 Irp->MdlAddress = MmCreateMdl(NULL,Buffer,Length);
58 if (MajorFunction == IRP_MJ_READ)
60 MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoWriteAccess);
64 MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoReadAccess);
66 Irp->UserBuffer = NULL;
67 Irp->AssociatedIrp.SystemBuffer = NULL;
69 return(STATUS_SUCCESS);
74 IoBuildAsynchronousFsdRequest(ULONG MajorFunction,
75 PDEVICE_OBJECT DeviceObject,
78 PLARGE_INTEGER StartingOffset,
79 PIO_STATUS_BLOCK IoStatusBlock)
81 * FUNCTION: Allocates and sets up an IRP to be sent to lower level drivers
83 * MajorFunction = One of IRP_MJ_READ, IRP_MJ_WRITE,
84 * IRP_MJ_FLUSH_BUFFERS or IRP_MJ_SHUTDOWN
85 * DeviceObject = Device object to send the irp to
86 * Buffer = Buffer into which data will be read or written
87 * Length = Length in bytes of the irp to be allocated
88 * StartingOffset = Starting offset on the device
89 * IoStatusBlock (OUT) = Storage for the result of the operation
90 * RETURNS: The IRP allocated on success, or
95 PIO_STACK_LOCATION StackPtr;
97 DPRINT("IoBuildAsynchronousFsdRequest(MajorFunction %x, DeviceObject %x, "
98 "Buffer %x, Length %x, StartingOffset %x, "
99 "IoStatusBlock %x\n",MajorFunction,DeviceObject,Buffer,Length,
100 StartingOffset,IoStatusBlock);
102 Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
108 Irp->UserIosb = IoStatusBlock;
109 DPRINT("Irp->UserIosb %x\n", Irp->UserIosb);
110 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
112 StackPtr = IoGetNextIrpStackLocation(Irp);
113 StackPtr->MajorFunction = MajorFunction;
114 StackPtr->MinorFunction = 0;
116 StackPtr->Control = 0;
117 StackPtr->DeviceObject = DeviceObject;
118 StackPtr->FileObject = NULL;
119 StackPtr->CompletionRoutine = NULL;
123 IoPrepareIrpBuffer(Irp,
130 if (MajorFunction == IRP_MJ_READ)
132 StackPtr->Parameters.Read.Length = Length;
133 if (StartingOffset!=NULL)
135 StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
139 StackPtr->Parameters.Read.ByteOffset.u.LowPart = 0;
140 StackPtr->Parameters.Read.ByteOffset.u.LowPart = 0;
143 else if (MajorFunction == IRP_MJ_WRITE)
145 StackPtr->Parameters.Write.Length = Length;
146 if (StartingOffset!=NULL)
148 StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
152 StackPtr->Parameters.Write.ByteOffset.QuadPart = 0;
156 Irp->UserIosb = IoStatusBlock;
163 IoBuildDeviceIoControlRequest(ULONG IoControlCode,
164 PDEVICE_OBJECT DeviceObject,
166 ULONG InputBufferLength,
168 ULONG OutputBufferLength,
169 BOOLEAN InternalDeviceIoControl,
171 PIO_STATUS_BLOCK IoStatusBlock)
173 * FUNCTION: Allocates and sets up an IRP to be sent to drivers
175 * IoControlCode = Device io control code
176 * DeviceObject = Device object to send the irp to
177 * InputBuffer = Buffer from which data will be read by the driver
178 * InputBufferLength = Length in bytes of the input buffer
179 * OutputBuffer = Buffer into which data will be written by the driver
180 * OutputBufferLength = Length in bytes of the output buffer
181 * InternalDeviceIoControl = Determines weather
182 * IRP_MJ_INTERNAL_DEVICE_CONTROL or
183 * IRP_MJ_DEVICE_CONTROL will be used
184 * Event = Event used to notify the caller of completion
185 * IoStatusBlock (OUT) = Storage for the result of the operation
186 * RETURNS: The IRP allocated on success, or
191 PIO_STACK_LOCATION StackPtr;
194 DPRINT("IoBuildDeviceIoRequest(IoControlCode %x, DeviceObject %x, "
195 "InputBuffer %x, InputBufferLength %x, OutputBuffer %x, "
196 "OutputBufferLength %x, InternalDeviceIoControl %x "
197 "Event %x, IoStatusBlock %x\n",IoControlCode,DeviceObject,
198 InputBuffer,InputBufferLength,OutputBuffer,OutputBufferLength,
199 InternalDeviceIoControl,Event,IoStatusBlock);
201 Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
207 Irp->UserEvent = Event;
208 Irp->UserIosb = IoStatusBlock;
209 DPRINT("Irp->UserIosb %x\n", Irp->UserIosb);
210 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
212 StackPtr = IoGetNextIrpStackLocation(Irp);
213 StackPtr->MajorFunction = InternalDeviceIoControl ?
214 IRP_MJ_INTERNAL_DEVICE_CONTROL : IRP_MJ_DEVICE_CONTROL;
215 StackPtr->MinorFunction = 0;
217 StackPtr->Control = 0;
218 StackPtr->DeviceObject = DeviceObject;
219 StackPtr->FileObject = NULL;
220 StackPtr->CompletionRoutine = NULL;
221 StackPtr->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
222 StackPtr->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
223 StackPtr->Parameters.DeviceIoControl.OutputBufferLength =
226 switch (IO_METHOD_FROM_CTL_CODE(IoControlCode))
228 case METHOD_BUFFERED:
229 DPRINT("Using METHOD_BUFFERED!\n");
231 if (InputBufferLength > OutputBufferLength)
233 BufferLength = InputBufferLength;
237 BufferLength = OutputBufferLength;
241 Irp->AssociatedIrp.SystemBuffer = (PVOID)
242 ExAllocatePoolWithTag(NonPagedPool,BufferLength, TAG_SYS_BUF);
244 if (Irp->AssociatedIrp.SystemBuffer == NULL)
251 if (InputBuffer && InputBufferLength)
253 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
257 Irp->UserBuffer = OutputBuffer;
260 case METHOD_IN_DIRECT:
261 DPRINT("Using METHOD_IN_DIRECT!\n");
263 /* build input buffer (control buffer) */
264 if (InputBuffer && InputBufferLength)
266 Irp->AssociatedIrp.SystemBuffer = (PVOID)
267 ExAllocatePoolWithTag(NonPagedPool,InputBufferLength,
270 if (Irp->AssociatedIrp.SystemBuffer == NULL)
276 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
281 /* build output buffer (data transfer buffer) */
282 if (OutputBuffer && OutputBufferLength)
284 Irp->MdlAddress = IoAllocateMdl(OutputBuffer,
289 MmProbeAndLockPages (Irp->MdlAddress,UserMode,IoReadAccess);
293 case METHOD_OUT_DIRECT:
294 DPRINT("Using METHOD_OUT_DIRECT!\n");
296 /* build input buffer (control buffer) */
297 if (InputBuffer && InputBufferLength)
299 Irp->AssociatedIrp.SystemBuffer = (PVOID)
300 ExAllocatePoolWithTag(NonPagedPool,InputBufferLength,
303 if (Irp->AssociatedIrp.SystemBuffer==NULL)
309 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
314 /* build output buffer (data transfer buffer) */
315 if (OutputBuffer && OutputBufferLength)
317 Irp->MdlAddress = IoAllocateMdl(OutputBuffer,
322 MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoWriteAccess);
327 DPRINT("Using METHOD_NEITHER!\n");
329 Irp->UserBuffer = OutputBuffer;
330 StackPtr->Parameters.DeviceIoControl.Type3InputBuffer = InputBuffer;
339 IoBuildSynchronousFsdRequest(ULONG MajorFunction,
340 PDEVICE_OBJECT DeviceObject,
343 PLARGE_INTEGER StartingOffset,
345 PIO_STATUS_BLOCK IoStatusBlock)
347 * FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
350 * MajorFunction = Major function code, one of IRP_MJ_READ,
351 * IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, IRP_MJ_SHUTDOWN
352 * DeviceObject = Target device object
353 * Buffer = Buffer containing data for a read or write
354 * Length = Length in bytes of the information to be transferred
355 * StartingOffset = Offset to begin the read/write from
356 * Event (OUT) = Will be set when the operation is complete
357 * IoStatusBlock (OUT) = Set to the status of the operation
358 * RETURNS: The IRP allocated on success, or
363 PIO_STACK_LOCATION StackPtr;
365 DPRINT("IoBuildSynchronousFsdRequest(MajorFunction %x, DeviceObject %x, "
366 "Buffer %x, Length %x, StartingOffset %x, Event %x, "
367 "IoStatusBlock %x\n",MajorFunction,DeviceObject,Buffer,Length,
368 StartingOffset,Event,IoStatusBlock);
370 Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
376 Irp->UserEvent = Event;
377 Irp->UserIosb = IoStatusBlock;
378 DPRINT("Irp->UserIosb %x\n", Irp->UserIosb);
379 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
381 StackPtr = IoGetNextIrpStackLocation(Irp);
382 StackPtr->MajorFunction = MajorFunction;
383 StackPtr->MinorFunction = 0;
385 StackPtr->Control = 0;
386 StackPtr->DeviceObject = DeviceObject;
387 StackPtr->FileObject = NULL;
388 StackPtr->CompletionRoutine = NULL;
392 IoPrepareIrpBuffer(Irp,
399 if (MajorFunction == IRP_MJ_READ)
401 if (StartingOffset != NULL)
403 StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
407 StackPtr->Parameters.Read.ByteOffset.QuadPart = 0;
409 StackPtr->Parameters.Read.Length = Length;
413 if (StartingOffset!=NULL)
415 StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
419 StackPtr->Parameters.Write.ByteOffset.QuadPart = 0;
421 StackPtr->Parameters.Write.Length = Length;
429 IoBuildSynchronousFsdRequestWithMdl(ULONG MajorFunction,
430 PDEVICE_OBJECT DeviceObject,
432 PLARGE_INTEGER StartingOffset,
434 PIO_STATUS_BLOCK IoStatusBlock,
437 * FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
440 * MajorFunction = Major function code, one of IRP_MJ_READ,
441 * IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, IRP_MJ_SHUTDOWN
442 * DeviceObject = Target device object
443 * Buffer = Buffer containing data for a read or write
444 * Length = Length in bytes of the information to be transferred
445 * StartingOffset = Offset to begin the read/write from
446 * Event (OUT) = Will be set when the operation is complete
447 * IoStatusBlock (OUT) = Set to the status of the operation
448 * RETURNS: The IRP allocated on success, or
453 PIO_STACK_LOCATION StackPtr;
455 DPRINT("IoBuildSynchronousFsdRequestWithMdl(MajorFunction %x, "
457 "Mdl %x, StartingOffset %x, Event %x, "
458 "IoStatusBlock %x\n",MajorFunction,DeviceObject,Mdl,
459 StartingOffset,Event,IoStatusBlock);
461 Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
467 Irp->UserEvent = Event;
468 Irp->UserIosb = IoStatusBlock;
469 DPRINT("Irp->UserIosb %x\n", Irp->UserIosb);
470 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
473 Irp->Flags = IRP_PAGING_IO;
480 StackPtr = IoGetNextIrpStackLocation(Irp);
481 StackPtr->MajorFunction = MajorFunction;
482 StackPtr->MinorFunction = 0;
484 StackPtr->Control = 0;
485 StackPtr->DeviceObject = DeviceObject;
486 StackPtr->FileObject = NULL;
487 StackPtr->CompletionRoutine = NULL;
489 Irp->MdlAddress = Mdl;
490 /* FIXME: 'Irp->UserBuffer=NULL' was here from reactos but we need some
491 * buffer at 'Irp->UserBuffer' for fastfat.sys - what to use else?
493 Irp->UserBuffer = MmGetSystemAddressForMdl(Mdl);
494 Irp->AssociatedIrp.SystemBuffer = NULL;
496 if (MajorFunction == IRP_MJ_READ)
498 if (StartingOffset != NULL)
500 StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
504 StackPtr->Parameters.Read.ByteOffset.QuadPart = 0;
506 StackPtr->Parameters.Read.Length = MmGetMdlByteCount(Mdl);
510 if (StartingOffset!=NULL)
512 StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
516 StackPtr->Parameters.Write.ByteOffset.QuadPart = 0;
518 StackPtr->Parameters.Write.Length = MmGetMdlByteCount(Mdl);