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 output buffer (control buffer) */
264 if (OutputBuffer && OutputBufferLength)
266 Irp->AssociatedIrp.SystemBuffer = (PVOID)
267 ExAllocatePoolWithTag(NonPagedPool,OutputBufferLength,
271 if (Irp->AssociatedIrp.SystemBuffer == NULL)
276 Irp->UserBuffer = OutputBuffer;
279 /* build input buffer (data transfer buffer) */
280 if (InputBuffer && InputBufferLength)
282 Irp->MdlAddress = IoAllocateMdl(InputBuffer,
287 MmProbeAndLockPages (Irp->MdlAddress,UserMode,IoReadAccess);
291 case METHOD_OUT_DIRECT:
292 DPRINT("Using METHOD_OUT_DIRECT!\n");
294 /* build input buffer (control buffer) */
295 if (InputBuffer && InputBufferLength)
297 Irp->AssociatedIrp.SystemBuffer = (PVOID)
298 ExAllocatePoolWithTag(NonPagedPool,InputBufferLength,
301 if (Irp->AssociatedIrp.SystemBuffer==NULL)
307 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
312 /* build output buffer (data transfer buffer) */
313 if (OutputBuffer && OutputBufferLength)
315 Irp->MdlAddress = IoAllocateMdl(OutputBuffer,
320 MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoWriteAccess);
325 DPRINT("Using METHOD_NEITHER!\n");
327 Irp->UserBuffer = OutputBuffer;
328 StackPtr->Parameters.DeviceIoControl.Type3InputBuffer = InputBuffer;
337 IoBuildSynchronousFsdRequest(ULONG MajorFunction,
338 PDEVICE_OBJECT DeviceObject,
341 PLARGE_INTEGER StartingOffset,
343 PIO_STATUS_BLOCK IoStatusBlock)
345 * FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
348 * MajorFunction = Major function code, one of IRP_MJ_READ,
349 * IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, IRP_MJ_SHUTDOWN
350 * DeviceObject = Target device object
351 * Buffer = Buffer containing data for a read or write
352 * Length = Length in bytes of the information to be transferred
353 * StartingOffset = Offset to begin the read/write from
354 * Event (OUT) = Will be set when the operation is complete
355 * IoStatusBlock (OUT) = Set to the status of the operation
356 * RETURNS: The IRP allocated on success, or
361 PIO_STACK_LOCATION StackPtr;
363 DPRINT("IoBuildSynchronousFsdRequest(MajorFunction %x, DeviceObject %x, "
364 "Buffer %x, Length %x, StartingOffset %x, Event %x, "
365 "IoStatusBlock %x\n",MajorFunction,DeviceObject,Buffer,Length,
366 StartingOffset,Event,IoStatusBlock);
368 Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
374 Irp->UserEvent = Event;
375 Irp->UserIosb = IoStatusBlock;
376 DPRINT("Irp->UserIosb %x\n", Irp->UserIosb);
377 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
379 StackPtr = IoGetNextIrpStackLocation(Irp);
380 StackPtr->MajorFunction = MajorFunction;
381 StackPtr->MinorFunction = 0;
383 StackPtr->Control = 0;
384 StackPtr->DeviceObject = DeviceObject;
385 StackPtr->FileObject = NULL;
386 StackPtr->CompletionRoutine = NULL;
390 IoPrepareIrpBuffer(Irp,
397 if (MajorFunction == IRP_MJ_READ)
399 if (StartingOffset != NULL)
401 StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
405 StackPtr->Parameters.Read.ByteOffset.QuadPart = 0;
407 StackPtr->Parameters.Read.Length = Length;
411 if (StartingOffset!=NULL)
413 StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
417 StackPtr->Parameters.Write.ByteOffset.QuadPart = 0;
419 StackPtr->Parameters.Write.Length = Length;
427 IoBuildSynchronousFsdRequestWithMdl(ULONG MajorFunction,
428 PDEVICE_OBJECT DeviceObject,
430 PLARGE_INTEGER StartingOffset,
432 PIO_STATUS_BLOCK IoStatusBlock,
435 * FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
438 * MajorFunction = Major function code, one of IRP_MJ_READ,
439 * IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, IRP_MJ_SHUTDOWN
440 * DeviceObject = Target device object
441 * Buffer = Buffer containing data for a read or write
442 * Length = Length in bytes of the information to be transferred
443 * StartingOffset = Offset to begin the read/write from
444 * Event (OUT) = Will be set when the operation is complete
445 * IoStatusBlock (OUT) = Set to the status of the operation
446 * RETURNS: The IRP allocated on success, or
451 PIO_STACK_LOCATION StackPtr;
453 DPRINT("IoBuildSynchronousFsdRequestWithMdl(MajorFunction %x, "
455 "Mdl %x, StartingOffset %x, Event %x, "
456 "IoStatusBlock %x\n",MajorFunction,DeviceObject,Mdl,
457 StartingOffset,Event,IoStatusBlock);
459 Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
465 Irp->UserEvent = Event;
466 Irp->UserIosb = IoStatusBlock;
467 DPRINT("Irp->UserIosb %x\n", Irp->UserIosb);
468 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
471 Irp->Flags = IRP_PAGING_IO;
478 StackPtr = IoGetNextIrpStackLocation(Irp);
479 StackPtr->MajorFunction = MajorFunction;
480 StackPtr->MinorFunction = 0;
482 StackPtr->Control = 0;
483 StackPtr->DeviceObject = DeviceObject;
484 StackPtr->FileObject = NULL;
485 StackPtr->CompletionRoutine = NULL;
487 Irp->MdlAddress = Mdl;
488 /* FIXME: 'Irp->UserBuffer=NULL' was here from reactos but we need some
489 * buffer at 'Irp->UserBuffer' for fastfat.sys - what to use else?
491 Irp->UserBuffer = MmGetSystemAddressForMdl(Mdl);
492 Irp->AssociatedIrp.SystemBuffer = NULL;
494 if (MajorFunction == IRP_MJ_READ)
496 if (StartingOffset != NULL)
498 StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
502 StackPtr->Parameters.Read.ByteOffset.QuadPart = 0;
504 StackPtr->Parameters.Read.Length = MmGetMdlByteCount(Mdl);
508 if (StartingOffset!=NULL)
510 StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
514 StackPtr->Parameters.Write.ByteOffset.QuadPart = 0;
516 StackPtr->Parameters.Write.Length = MmGetMdlByteCount(Mdl);