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 *****************************************************************/
29 NTSTATUS IoPrepareIrpBuffer(PIRP Irp,
30 PDEVICE_OBJECT DeviceObject,
35 * FUNCTION: Prepares the buffer to be used for an IRP
38 Irp->UserBuffer = Buffer;
39 if (DeviceObject->Flags & DO_BUFFERED_IO)
41 DPRINT("Doing buffer i/o\n");
42 Irp->AssociatedIrp.SystemBuffer =
43 (PVOID)ExAllocatePoolWithTag(NonPagedPool,Length, TAG_SYS_BUF);
44 if (Irp->AssociatedIrp.SystemBuffer==NULL)
47 return(STATUS_NOT_IMPLEMENTED);
49 /* FIXME: should copy buffer in on other ops */
50 if (MajorFunction == IRP_MJ_WRITE)
52 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, Buffer, Length);
55 if (DeviceObject->Flags & DO_DIRECT_IO)
57 DPRINT("Doing direct i/o\n");
59 Irp->MdlAddress = MmCreateMdl(NULL,Buffer,Length);
60 if (MajorFunction == IRP_MJ_READ)
62 MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoWriteAccess);
66 MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoReadAccess);
68 Irp->UserBuffer = NULL;
69 Irp->AssociatedIrp.SystemBuffer = NULL;
71 return(STATUS_SUCCESS);
76 IoBuildAsynchronousFsdRequest(ULONG MajorFunction,
77 PDEVICE_OBJECT DeviceObject,
80 PLARGE_INTEGER StartingOffset,
81 PIO_STATUS_BLOCK IoStatusBlock)
83 * FUNCTION: Allocates and sets up an IRP to be sent to lower level drivers
85 * MajorFunction = One of IRP_MJ_READ, IRP_MJ_WRITE,
86 * IRP_MJ_FLUSH_BUFFERS or IRP_MJ_SHUTDOWN
87 * DeviceObject = Device object to send the irp to
88 * Buffer = Buffer into which data will be read or written
89 * Length = Length in bytes of the irp to be allocated
90 * StartingOffset = Starting offset on the device
91 * IoStatusBlock (OUT) = Storage for the result of the operation
92 * RETURNS: The IRP allocated on success, or
97 PIO_STACK_LOCATION StackPtr;
99 DPRINT("IoBuildAsynchronousFsdRequest(MajorFunction %x, DeviceObject %x, "
100 "Buffer %x, Length %x, StartingOffset %x, "
101 "IoStatusBlock %x\n",MajorFunction,DeviceObject,Buffer,Length,
102 StartingOffset,IoStatusBlock);
104 Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
110 Irp->UserIosb = IoStatusBlock;
111 DPRINT("Irp->UserIosb %x\n", Irp->UserIosb);
112 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
114 StackPtr = IoGetNextIrpStackLocation(Irp);
115 StackPtr->MajorFunction = MajorFunction;
116 StackPtr->MinorFunction = 0;
118 StackPtr->Control = 0;
119 StackPtr->DeviceObject = DeviceObject;
120 StackPtr->FileObject = NULL;
121 StackPtr->CompletionRoutine = NULL;
125 IoPrepareIrpBuffer(Irp,
132 if (MajorFunction == IRP_MJ_READ)
134 StackPtr->Parameters.Read.Length = Length;
135 if (StartingOffset!=NULL)
137 StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
141 StackPtr->Parameters.Read.ByteOffset.u.LowPart = 0;
142 StackPtr->Parameters.Read.ByteOffset.u.LowPart = 0;
145 else if (MajorFunction == IRP_MJ_WRITE)
147 StackPtr->Parameters.Write.Length = Length;
148 if (StartingOffset!=NULL)
150 StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
154 StackPtr->Parameters.Write.ByteOffset.QuadPart = 0;
158 Irp->UserIosb = IoStatusBlock;
163 #endif /* LIBCAPTIVE */
166 IoBuildDeviceIoControlRequest(ULONG IoControlCode,
167 PDEVICE_OBJECT DeviceObject,
169 ULONG InputBufferLength,
171 ULONG OutputBufferLength,
172 BOOLEAN InternalDeviceIoControl,
174 PIO_STATUS_BLOCK IoStatusBlock)
176 * FUNCTION: Allocates and sets up an IRP to be sent to drivers
178 * IoControlCode = Device io control code
179 * DeviceObject = Device object to send the irp to
180 * InputBuffer = Buffer from which data will be read by the driver
181 * InputBufferLength = Length in bytes of the input buffer
182 * OutputBuffer = Buffer into which data will be written by the driver
183 * OutputBufferLength = Length in bytes of the output buffer
184 * InternalDeviceIoControl = Determines weather
185 * IRP_MJ_INTERNAL_DEVICE_CONTROL or
186 * IRP_MJ_DEVICE_CONTROL will be used
187 * Event = Event used to notify the caller of completion
188 * IoStatusBlock (OUT) = Storage for the result of the operation
189 * RETURNS: The IRP allocated on success, or
194 PIO_STACK_LOCATION StackPtr;
197 DPRINT("IoBuildDeviceIoRequest(IoControlCode %x, DeviceObject %x, "
198 "InputBuffer %x, InputBufferLength %x, OutputBuffer %x, "
199 "OutputBufferLength %x, InternalDeviceIoControl %x "
200 "Event %x, IoStatusBlock %x\n",IoControlCode,DeviceObject,
201 InputBuffer,InputBufferLength,OutputBuffer,OutputBufferLength,
202 InternalDeviceIoControl,Event,IoStatusBlock);
204 Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
210 Irp->UserEvent = Event;
211 Irp->UserIosb = IoStatusBlock;
212 DPRINT("Irp->UserIosb %x\n", Irp->UserIosb);
213 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
215 StackPtr = IoGetNextIrpStackLocation(Irp);
216 StackPtr->MajorFunction = InternalDeviceIoControl ?
217 IRP_MJ_INTERNAL_DEVICE_CONTROL : IRP_MJ_DEVICE_CONTROL;
218 StackPtr->MinorFunction = 0;
220 StackPtr->Control = 0;
221 StackPtr->DeviceObject = DeviceObject;
222 StackPtr->FileObject = NULL;
223 StackPtr->CompletionRoutine = NULL;
224 StackPtr->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
225 StackPtr->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
226 StackPtr->Parameters.DeviceIoControl.OutputBufferLength =
229 switch (IO_METHOD_FROM_CTL_CODE(IoControlCode))
231 case METHOD_BUFFERED:
232 DPRINT("Using METHOD_BUFFERED!\n");
234 if (InputBufferLength > OutputBufferLength)
236 BufferLength = InputBufferLength;
240 BufferLength = OutputBufferLength;
244 Irp->AssociatedIrp.SystemBuffer = (PVOID)
245 ExAllocatePoolWithTag(NonPagedPool,BufferLength, TAG_SYS_BUF);
247 if (Irp->AssociatedIrp.SystemBuffer == NULL)
254 if (InputBuffer && InputBufferLength)
256 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
260 Irp->UserBuffer = OutputBuffer;
263 case METHOD_IN_DIRECT:
264 DPRINT("Using METHOD_IN_DIRECT!\n");
266 /* build input buffer (control buffer) */
267 if (InputBuffer && InputBufferLength)
269 Irp->AssociatedIrp.SystemBuffer = (PVOID)
270 ExAllocatePoolWithTag(NonPagedPool,InputBufferLength,
273 if (Irp->AssociatedIrp.SystemBuffer == NULL)
279 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
284 /* build output buffer (data transfer buffer) */
285 if (OutputBuffer && OutputBufferLength)
287 Irp->MdlAddress = IoAllocateMdl(OutputBuffer,
292 MmProbeAndLockPages (Irp->MdlAddress,UserMode,IoReadAccess);
296 case METHOD_OUT_DIRECT:
297 DPRINT("Using METHOD_OUT_DIRECT!\n");
299 /* build input buffer (control buffer) */
300 if (InputBuffer && InputBufferLength)
302 Irp->AssociatedIrp.SystemBuffer = (PVOID)
303 ExAllocatePoolWithTag(NonPagedPool,InputBufferLength,
306 if (Irp->AssociatedIrp.SystemBuffer==NULL)
312 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
317 /* build output buffer (data transfer buffer) */
318 if (OutputBuffer && OutputBufferLength)
320 Irp->MdlAddress = IoAllocateMdl(OutputBuffer,
325 MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoWriteAccess);
330 DPRINT("Using METHOD_NEITHER!\n");
332 Irp->UserBuffer = OutputBuffer;
333 StackPtr->Parameters.DeviceIoControl.Type3InputBuffer = InputBuffer;
343 IoBuildSynchronousFsdRequest(ULONG MajorFunction,
344 PDEVICE_OBJECT DeviceObject,
347 PLARGE_INTEGER StartingOffset,
349 PIO_STATUS_BLOCK IoStatusBlock)
351 * FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
354 * MajorFunction = Major function code, one of IRP_MJ_READ,
355 * IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, IRP_MJ_SHUTDOWN
356 * DeviceObject = Target device object
357 * Buffer = Buffer containing data for a read or write
358 * Length = Length in bytes of the information to be transferred
359 * StartingOffset = Offset to begin the read/write from
360 * Event (OUT) = Will be set when the operation is complete
361 * IoStatusBlock (OUT) = Set to the status of the operation
362 * RETURNS: The IRP allocated on success, or
367 PIO_STACK_LOCATION StackPtr;
369 DPRINT("IoBuildSynchronousFsdRequest(MajorFunction %x, DeviceObject %x, "
370 "Buffer %x, Length %x, StartingOffset %x, Event %x, "
371 "IoStatusBlock %x\n",MajorFunction,DeviceObject,Buffer,Length,
372 StartingOffset,Event,IoStatusBlock);
374 Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
380 Irp->UserEvent = Event;
381 Irp->UserIosb = IoStatusBlock;
382 DPRINT("Irp->UserIosb %x\n", Irp->UserIosb);
383 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
385 StackPtr = IoGetNextIrpStackLocation(Irp);
386 StackPtr->MajorFunction = MajorFunction;
387 StackPtr->MinorFunction = 0;
389 StackPtr->Control = 0;
390 StackPtr->DeviceObject = DeviceObject;
391 StackPtr->FileObject = NULL;
392 StackPtr->CompletionRoutine = NULL;
396 IoPrepareIrpBuffer(Irp,
403 if (MajorFunction == IRP_MJ_READ)
405 if (StartingOffset != NULL)
407 StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
411 StackPtr->Parameters.Read.ByteOffset.QuadPart = 0;
413 StackPtr->Parameters.Read.Length = Length;
417 if (StartingOffset!=NULL)
419 StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
423 StackPtr->Parameters.Write.ByteOffset.QuadPart = 0;
425 StackPtr->Parameters.Write.Length = Length;
433 IoBuildSynchronousFsdRequestWithMdl(ULONG MajorFunction,
434 PDEVICE_OBJECT DeviceObject,
436 PLARGE_INTEGER StartingOffset,
438 PIO_STATUS_BLOCK IoStatusBlock,
441 * FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
444 * MajorFunction = Major function code, one of IRP_MJ_READ,
445 * IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, IRP_MJ_SHUTDOWN
446 * DeviceObject = Target device object
447 * Buffer = Buffer containing data for a read or write
448 * Length = Length in bytes of the information to be transferred
449 * StartingOffset = Offset to begin the read/write from
450 * Event (OUT) = Will be set when the operation is complete
451 * IoStatusBlock (OUT) = Set to the status of the operation
452 * RETURNS: The IRP allocated on success, or
457 PIO_STACK_LOCATION StackPtr;
459 DPRINT("IoBuildSynchronousFsdRequestWithMdl(MajorFunction %x, "
461 "Mdl %x, StartingOffset %x, Event %x, "
462 "IoStatusBlock %x\n",MajorFunction,DeviceObject,Mdl,
463 StartingOffset,Event,IoStatusBlock);
465 Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
471 Irp->UserEvent = Event;
472 Irp->UserIosb = IoStatusBlock;
473 DPRINT("Irp->UserIosb %x\n", Irp->UserIosb);
474 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
477 Irp->Flags = IRP_PAGING_IO;
484 StackPtr = IoGetNextIrpStackLocation(Irp);
485 StackPtr->MajorFunction = MajorFunction;
486 StackPtr->MinorFunction = 0;
488 StackPtr->Control = 0;
489 StackPtr->DeviceObject = DeviceObject;
490 StackPtr->FileObject = NULL;
491 StackPtr->CompletionRoutine = NULL;
493 Irp->MdlAddress = Mdl;
494 Irp->UserBuffer = NULL;
495 Irp->AssociatedIrp.SystemBuffer = NULL;
497 if (MajorFunction == IRP_MJ_READ)
499 if (StartingOffset != NULL)
501 StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
505 StackPtr->Parameters.Read.ByteOffset.QuadPart = 0;
507 StackPtr->Parameters.Read.Length = MmGetMdlByteCount(Mdl);
511 if (StartingOffset!=NULL)
513 StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
517 StackPtr->Parameters.Write.ByteOffset.QuadPart = 0;
519 StackPtr->Parameters.Write.Length = MmGetMdlByteCount(Mdl);
525 #endif /* LIBCAPTIVE */