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.u.LowPart = 0;
144 StackPtr->Parameters.Read.ByteOffset.u.LowPart = 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;
160 Irp->UserIosb = IoStatusBlock;
170 IoBuildDeviceIoControlRequest(ULONG IoControlCode,
171 PDEVICE_OBJECT DeviceObject,
173 ULONG InputBufferLength,
175 ULONG OutputBufferLength,
176 BOOLEAN InternalDeviceIoControl,
178 PIO_STATUS_BLOCK IoStatusBlock)
180 * FUNCTION: Allocates and sets up an IRP to be sent to drivers
182 * IoControlCode = Device io control code
183 * DeviceObject = Device object to send the irp to
184 * InputBuffer = Buffer from which data will be read by the driver
185 * InputBufferLength = Length in bytes of the input buffer
186 * OutputBuffer = Buffer into which data will be written by the driver
187 * OutputBufferLength = Length in bytes of the output buffer
188 * InternalDeviceIoControl = Determines weather
189 * IRP_MJ_INTERNAL_DEVICE_CONTROL or
190 * IRP_MJ_DEVICE_CONTROL will be used
191 * Event = Event used to notify the caller of completion
192 * IoStatusBlock (OUT) = Storage for the result of the operation
193 * RETURNS: The IRP allocated on success, or
198 PIO_STACK_LOCATION StackPtr;
201 DPRINT("IoBuildDeviceIoRequest(IoControlCode %x, DeviceObject %x, "
202 "InputBuffer %x, InputBufferLength %x, OutputBuffer %x, "
203 "OutputBufferLength %x, InternalDeviceIoControl %x "
204 "Event %x, IoStatusBlock %x\n",IoControlCode,DeviceObject,
205 InputBuffer,InputBufferLength,OutputBuffer,OutputBufferLength,
206 InternalDeviceIoControl,Event,IoStatusBlock);
208 Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
214 Irp->UserEvent = Event;
215 Irp->UserIosb = IoStatusBlock;
216 DPRINT("Irp->UserIosb %x\n", Irp->UserIosb);
217 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
219 StackPtr = IoGetNextIrpStackLocation(Irp);
220 StackPtr->MajorFunction = InternalDeviceIoControl ?
221 IRP_MJ_INTERNAL_DEVICE_CONTROL : IRP_MJ_DEVICE_CONTROL;
222 StackPtr->MinorFunction = 0;
224 StackPtr->Control = 0;
225 StackPtr->DeviceObject = DeviceObject;
226 StackPtr->FileObject = NULL;
227 StackPtr->CompletionRoutine = NULL;
228 StackPtr->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
229 StackPtr->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
230 StackPtr->Parameters.DeviceIoControl.OutputBufferLength =
233 switch (IO_METHOD_FROM_CTL_CODE(IoControlCode))
235 case METHOD_BUFFERED:
236 DPRINT("Using METHOD_BUFFERED!\n");
238 if (InputBufferLength > OutputBufferLength)
240 BufferLength = InputBufferLength;
244 BufferLength = OutputBufferLength;
248 Irp->AssociatedIrp.SystemBuffer = (PVOID)
249 ExAllocatePoolWithTag(NonPagedPool,BufferLength, TAG_SYS_BUF);
251 if (Irp->AssociatedIrp.SystemBuffer == NULL)
258 if (InputBuffer && InputBufferLength)
260 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
264 Irp->UserBuffer = OutputBuffer;
267 case METHOD_IN_DIRECT:
268 DPRINT("Using METHOD_IN_DIRECT!\n");
270 /* build output buffer (control buffer) */
271 if (OutputBuffer && OutputBufferLength)
273 Irp->AssociatedIrp.SystemBuffer = (PVOID)
274 ExAllocatePoolWithTag(NonPagedPool,OutputBufferLength,
278 if (Irp->AssociatedIrp.SystemBuffer == NULL)
283 Irp->UserBuffer = OutputBuffer;
286 /* build input buffer (data transfer buffer) */
287 if (InputBuffer && InputBufferLength)
289 Irp->MdlAddress = IoAllocateMdl(InputBuffer,
294 MmProbeAndLockPages (Irp->MdlAddress,UserMode,IoReadAccess);
298 case METHOD_OUT_DIRECT:
299 DPRINT("Using METHOD_OUT_DIRECT!\n");
301 /* build input buffer (control buffer) */
302 if (InputBuffer && InputBufferLength)
304 Irp->AssociatedIrp.SystemBuffer = (PVOID)
305 ExAllocatePoolWithTag(NonPagedPool,InputBufferLength,
308 if (Irp->AssociatedIrp.SystemBuffer==NULL)
314 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
319 /* build output buffer (data transfer buffer) */
320 if (OutputBuffer && OutputBufferLength)
322 Irp->MdlAddress = IoAllocateMdl(OutputBuffer,
327 MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoWriteAccess);
332 DPRINT("Using METHOD_NEITHER!\n");
334 Irp->UserBuffer = OutputBuffer;
335 StackPtr->Parameters.DeviceIoControl.Type3InputBuffer = InputBuffer;
347 IoBuildSynchronousFsdRequest(ULONG MajorFunction,
348 PDEVICE_OBJECT DeviceObject,
351 PLARGE_INTEGER StartingOffset,
353 PIO_STATUS_BLOCK IoStatusBlock)
355 * FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
358 * MajorFunction = Major function code, one of IRP_MJ_READ,
359 * IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, IRP_MJ_SHUTDOWN
360 * DeviceObject = Target device object
361 * Buffer = Buffer containing data for a read or write
362 * Length = Length in bytes of the information to be transferred
363 * StartingOffset = Offset to begin the read/write from
364 * Event (OUT) = Will be set when the operation is complete
365 * IoStatusBlock (OUT) = Set to the status of the operation
366 * RETURNS: The IRP allocated on success, or
372 DPRINT("IoBuildSynchronousFsdRequest(MajorFunction %x, DeviceObject %x, "
373 "Buffer %x, Length %x, StartingOffset %x, Event %x, "
374 "IoStatusBlock %x\n",MajorFunction,DeviceObject,Buffer,Length,
375 StartingOffset,Event,IoStatusBlock);
377 Irp = IoBuildAsynchronousFsdRequest(MajorFunction,
388 Irp->UserEvent = Event;
395 IoBuildSynchronousFsdRequestWithMdl(ULONG MajorFunction,
396 PDEVICE_OBJECT DeviceObject,
398 PLARGE_INTEGER StartingOffset,
400 PIO_STATUS_BLOCK IoStatusBlock,
403 * FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
406 * MajorFunction = Major function code, one of IRP_MJ_READ,
407 * IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, IRP_MJ_SHUTDOWN
408 * DeviceObject = Target device object
409 * Buffer = Buffer containing data for a read or write
410 * Length = Length in bytes of the information to be transferred
411 * StartingOffset = Offset to begin the read/write from
412 * Event (OUT) = Will be set when the operation is complete
413 * IoStatusBlock (OUT) = Set to the status of the operation
414 * RETURNS: The IRP allocated on success, or
419 PIO_STACK_LOCATION StackPtr;
421 DPRINT("IoBuildSynchronousFsdRequestWithMdl(MajorFunction %x, "
423 "Mdl %x, StartingOffset %x, Event %x, "
424 "IoStatusBlock %x\n",MajorFunction,DeviceObject,Mdl,
425 StartingOffset,Event,IoStatusBlock);
427 Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
433 Irp->UserEvent = Event;
434 Irp->UserIosb = IoStatusBlock;
435 DPRINT("Irp->UserIosb %x\n", Irp->UserIosb);
436 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
439 Irp->Flags = IRP_PAGING_IO;
446 StackPtr = IoGetNextIrpStackLocation(Irp);
447 StackPtr->MajorFunction = MajorFunction;
448 StackPtr->MinorFunction = 0;
450 StackPtr->Control = 0;
451 StackPtr->DeviceObject = DeviceObject;
452 StackPtr->FileObject = NULL;
453 StackPtr->CompletionRoutine = NULL;
455 Irp->MdlAddress = Mdl;
456 Irp->UserBuffer = NULL;
457 Irp->AssociatedIrp.SystemBuffer = NULL;
459 if (MajorFunction == IRP_MJ_READ)
461 if (StartingOffset != NULL)
463 StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
467 StackPtr->Parameters.Read.ByteOffset.QuadPart = 0;
469 StackPtr->Parameters.Read.Length = MmGetMdlByteCount(Mdl);
473 if (StartingOffset!=NULL)
475 StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
479 StackPtr->Parameters.Write.ByteOffset.QuadPart = 0;
481 StackPtr->Parameters.Write.Length = MmGetMdlByteCount(Mdl);