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);
75 IoBuildAsynchronousFsdRequest(ULONG MajorFunction,
76 PDEVICE_OBJECT DeviceObject,
79 PLARGE_INTEGER StartingOffset,
80 PIO_STATUS_BLOCK IoStatusBlock)
82 * FUNCTION: Allocates and sets up an IRP to be sent to lower level drivers
84 * MajorFunction = One of IRP_MJ_READ, IRP_MJ_WRITE,
85 * IRP_MJ_FLUSH_BUFFERS or IRP_MJ_SHUTDOWN
86 * DeviceObject = Device object to send the irp to
87 * Buffer = Buffer into which data will be read or written
88 * Length = Length in bytes of the irp to be allocated
89 * StartingOffset = Starting offset on the device
90 * IoStatusBlock (OUT) = Storage for the result of the operation
91 * RETURNS: The IRP allocated on success, or
96 PIO_STACK_LOCATION StackPtr;
98 DPRINT("IoBuildAsynchronousFsdRequest(MajorFunction %x, DeviceObject %x, "
99 "Buffer %x, Length %x, StartingOffset %x, "
100 "IoStatusBlock %x\n",MajorFunction,DeviceObject,Buffer,Length,
101 StartingOffset,IoStatusBlock);
103 Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
109 Irp->UserIosb = IoStatusBlock;
110 DPRINT("Irp->UserIosb %x\n", Irp->UserIosb);
111 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
113 StackPtr = IoGetNextIrpStackLocation(Irp);
114 StackPtr->MajorFunction = MajorFunction;
115 StackPtr->MinorFunction = 0;
117 StackPtr->Control = 0;
118 StackPtr->DeviceObject = DeviceObject;
119 StackPtr->FileObject = NULL;
120 StackPtr->CompletionRoutine = NULL;
124 IoPrepareIrpBuffer(Irp,
131 if (MajorFunction == IRP_MJ_READ)
133 StackPtr->Parameters.Read.Length = Length;
134 if (StartingOffset!=NULL)
136 StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
140 StackPtr->Parameters.Read.ByteOffset.u.LowPart = 0;
141 StackPtr->Parameters.Read.ByteOffset.u.LowPart = 0;
144 else if (MajorFunction == IRP_MJ_WRITE)
146 StackPtr->Parameters.Write.Length = Length;
147 if (StartingOffset!=NULL)
149 StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
153 StackPtr->Parameters.Write.ByteOffset.QuadPart = 0;
157 Irp->UserIosb = IoStatusBlock;
162 #endif /* LIBCAPTIVE */
165 IoBuildDeviceIoControlRequest(ULONG IoControlCode,
166 PDEVICE_OBJECT DeviceObject,
168 ULONG InputBufferLength,
170 ULONG OutputBufferLength,
171 BOOLEAN InternalDeviceIoControl,
173 PIO_STATUS_BLOCK IoStatusBlock)
175 * FUNCTION: Allocates and sets up an IRP to be sent to drivers
177 * IoControlCode = Device io control code
178 * DeviceObject = Device object to send the irp to
179 * InputBuffer = Buffer from which data will be read by the driver
180 * InputBufferLength = Length in bytes of the input buffer
181 * OutputBuffer = Buffer into which data will be written by the driver
182 * OutputBufferLength = Length in bytes of the output buffer
183 * InternalDeviceIoControl = Determines weather
184 * IRP_MJ_INTERNAL_DEVICE_CONTROL or
185 * IRP_MJ_DEVICE_CONTROL will be used
186 * Event = Event used to notify the caller of completion
187 * IoStatusBlock (OUT) = Storage for the result of the operation
188 * RETURNS: The IRP allocated on success, or
193 PIO_STACK_LOCATION StackPtr;
196 DPRINT("IoBuildDeviceIoRequest(IoControlCode %x, DeviceObject %x, "
197 "InputBuffer %x, InputBufferLength %x, OutputBuffer %x, "
198 "OutputBufferLength %x, InternalDeviceIoControl %x "
199 "Event %x, IoStatusBlock %x\n",IoControlCode,DeviceObject,
200 InputBuffer,InputBufferLength,OutputBuffer,OutputBufferLength,
201 InternalDeviceIoControl,Event,IoStatusBlock);
203 Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
209 Irp->UserEvent = Event;
210 Irp->UserIosb = IoStatusBlock;
211 DPRINT("Irp->UserIosb %x\n", Irp->UserIosb);
212 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
214 StackPtr = IoGetNextIrpStackLocation(Irp);
215 StackPtr->MajorFunction = InternalDeviceIoControl ?
216 IRP_MJ_INTERNAL_DEVICE_CONTROL : IRP_MJ_DEVICE_CONTROL;
217 StackPtr->MinorFunction = 0;
219 StackPtr->Control = 0;
220 StackPtr->DeviceObject = DeviceObject;
221 StackPtr->FileObject = NULL;
222 StackPtr->CompletionRoutine = NULL;
223 StackPtr->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
224 StackPtr->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
225 StackPtr->Parameters.DeviceIoControl.OutputBufferLength =
228 switch (IO_METHOD_FROM_CTL_CODE(IoControlCode))
230 case METHOD_BUFFERED:
231 DPRINT("Using METHOD_BUFFERED!\n");
233 if (InputBufferLength > OutputBufferLength)
235 BufferLength = InputBufferLength;
239 BufferLength = OutputBufferLength;
243 Irp->AssociatedIrp.SystemBuffer = (PVOID)
244 ExAllocatePoolWithTag(NonPagedPool,BufferLength, TAG_SYS_BUF);
246 if (Irp->AssociatedIrp.SystemBuffer == NULL)
253 if (InputBuffer && InputBufferLength)
255 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
259 Irp->UserBuffer = OutputBuffer;
262 case METHOD_IN_DIRECT:
263 DPRINT("Using METHOD_IN_DIRECT!\n");
265 /* build input buffer (control buffer) */
266 if (InputBuffer && InputBufferLength)
268 Irp->AssociatedIrp.SystemBuffer = (PVOID)
269 ExAllocatePoolWithTag(NonPagedPool,InputBufferLength,
272 if (Irp->AssociatedIrp.SystemBuffer == NULL)
278 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
283 /* build output buffer (data transfer buffer) */
284 if (OutputBuffer && OutputBufferLength)
286 Irp->MdlAddress = IoAllocateMdl(OutputBuffer,
291 MmProbeAndLockPages (Irp->MdlAddress,UserMode,IoReadAccess);
295 case METHOD_OUT_DIRECT:
296 DPRINT("Using METHOD_OUT_DIRECT!\n");
298 /* build input buffer (control buffer) */
299 if (InputBuffer && InputBufferLength)
301 Irp->AssociatedIrp.SystemBuffer = (PVOID)
302 ExAllocatePoolWithTag(NonPagedPool,InputBufferLength,
305 if (Irp->AssociatedIrp.SystemBuffer==NULL)
311 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
316 /* build output buffer (data transfer buffer) */
317 if (OutputBuffer && OutputBufferLength)
319 Irp->MdlAddress = IoAllocateMdl(OutputBuffer,
324 MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoWriteAccess);
329 DPRINT("Using METHOD_NEITHER!\n");
331 Irp->UserBuffer = OutputBuffer;
332 StackPtr->Parameters.DeviceIoControl.Type3InputBuffer = InputBuffer;
341 IoBuildSynchronousFsdRequest(ULONG MajorFunction,
342 PDEVICE_OBJECT DeviceObject,
345 PLARGE_INTEGER StartingOffset,
347 PIO_STATUS_BLOCK IoStatusBlock)
349 * FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
352 * MajorFunction = Major function code, one of IRP_MJ_READ,
353 * IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, IRP_MJ_SHUTDOWN
354 * DeviceObject = Target device object
355 * Buffer = Buffer containing data for a read or write
356 * Length = Length in bytes of the information to be transferred
357 * StartingOffset = Offset to begin the read/write from
358 * Event (OUT) = Will be set when the operation is complete
359 * IoStatusBlock (OUT) = Set to the status of the operation
360 * RETURNS: The IRP allocated on success, or
365 PIO_STACK_LOCATION StackPtr;
367 DPRINT("IoBuildSynchronousFsdRequest(MajorFunction %x, DeviceObject %x, "
368 "Buffer %x, Length %x, StartingOffset %x, Event %x, "
369 "IoStatusBlock %x\n",MajorFunction,DeviceObject,Buffer,Length,
370 StartingOffset,Event,IoStatusBlock);
372 Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
378 Irp->UserEvent = Event;
379 Irp->UserIosb = IoStatusBlock;
380 DPRINT("Irp->UserIosb %x\n", Irp->UserIosb);
381 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
383 StackPtr = IoGetNextIrpStackLocation(Irp);
384 StackPtr->MajorFunction = MajorFunction;
385 StackPtr->MinorFunction = 0;
387 StackPtr->Control = 0;
388 StackPtr->DeviceObject = DeviceObject;
389 StackPtr->FileObject = NULL;
390 StackPtr->CompletionRoutine = NULL;
394 IoPrepareIrpBuffer(Irp,
401 if (MajorFunction == IRP_MJ_READ)
403 if (StartingOffset != NULL)
405 StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
409 StackPtr->Parameters.Read.ByteOffset.QuadPart = 0;
411 StackPtr->Parameters.Read.Length = Length;
415 if (StartingOffset!=NULL)
417 StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
421 StackPtr->Parameters.Write.ByteOffset.QuadPart = 0;
423 StackPtr->Parameters.Write.Length = Length;
431 IoBuildSynchronousFsdRequestWithMdl(ULONG MajorFunction,
432 PDEVICE_OBJECT DeviceObject,
434 PLARGE_INTEGER StartingOffset,
436 PIO_STATUS_BLOCK IoStatusBlock,
439 * FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
442 * MajorFunction = Major function code, one of IRP_MJ_READ,
443 * IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, IRP_MJ_SHUTDOWN
444 * DeviceObject = Target device object
445 * Buffer = Buffer containing data for a read or write
446 * Length = Length in bytes of the information to be transferred
447 * StartingOffset = Offset to begin the read/write from
448 * Event (OUT) = Will be set when the operation is complete
449 * IoStatusBlock (OUT) = Set to the status of the operation
450 * RETURNS: The IRP allocated on success, or
455 PIO_STACK_LOCATION StackPtr;
457 DPRINT("IoBuildSynchronousFsdRequestWithMdl(MajorFunction %x, "
459 "Mdl %x, StartingOffset %x, Event %x, "
460 "IoStatusBlock %x\n",MajorFunction,DeviceObject,Mdl,
461 StartingOffset,Event,IoStatusBlock);
463 Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
469 Irp->UserEvent = Event;
470 Irp->UserIosb = IoStatusBlock;
471 DPRINT("Irp->UserIosb %x\n", Irp->UserIosb);
472 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
475 Irp->Flags = IRP_PAGING_IO;
482 StackPtr = IoGetNextIrpStackLocation(Irp);
483 StackPtr->MajorFunction = MajorFunction;
484 StackPtr->MinorFunction = 0;
486 StackPtr->Control = 0;
487 StackPtr->DeviceObject = DeviceObject;
488 StackPtr->FileObject = NULL;
489 StackPtr->CompletionRoutine = NULL;
491 Irp->MdlAddress = Mdl;
492 /* FIXME: 'Irp->UserBuffer=NULL' was here from reactos but we need some
493 * buffer at 'Irp->UserBuffer' for fastfat.sys - what to use else?
495 Irp->UserBuffer = MmGetSystemAddressForMdl(Mdl);
496 Irp->AssociatedIrp.SystemBuffer = NULL;
498 if (MajorFunction == IRP_MJ_READ)
500 if (StartingOffset != NULL)
502 StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
506 StackPtr->Parameters.Read.ByteOffset.QuadPart = 0;
508 StackPtr->Parameters.Read.Length = MmGetMdlByteCount(Mdl);
512 if (StartingOffset!=NULL)
514 StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
518 StackPtr->Parameters.Write.ByteOffset.QuadPart = 0;
520 StackPtr->Parameters.Write.Length = MmGetMdlByteCount(Mdl);