ReactOS  0.4.12-dev-43-g63b00d8
irp.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/io/iomgr/irp.c
5  * PURPOSE: IRP Handling Functions
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  * Gunnar Dalsnes
8  * Filip Navara (navaraf@reactos.org)
9  * Pierre Schweitzer (pierre@reactos.org)
10  */
11 
12 /* INCLUDES ****************************************************************/
13 
14 #include <ntoskrnl.h>
15 #define NDEBUG
16 #include <debug.h>
17 
20 
21 /* PRIVATE FUNCTIONS ********************************************************/
22 
23 VOID
24 NTAPI
26  IN PKNORMAL_ROUTINE *NormalRoutine,
27  IN PVOID *NormalContext,
30 {
31  /* Free the IRP */
32  IoFreeIrp(CONTAINING_RECORD(Apc, IRP, Tail.Apc));
33 }
34 
35 VOID
36 NTAPI
38 {
39  /* Free the IRP */
40  IoFreeIrp(CONTAINING_RECORD(Apc, IRP, Tail.Apc));
41 }
42 
44 NTAPI
46  IN PKEVENT EventObject OPTIONAL,
47  IN PVOID Buffer OPTIONAL)
48 {
49  PAGED_CODE();
50 
51  /* Dereference the event */
52  if (EventObject) ObDereferenceObject(EventObject);
53 
54  /* Free a buffer, if any */
55  if (Buffer) ExFreePool(Buffer);
56 
57  /* If this was a file opened for synch I/O, then unlock it */
58  if (FileObject->Flags & FO_SYNCHRONOUS_IO) IopUnlockFileObject(FileObject);
59 
60  /* Now dereference it and return */
61  ObDereferenceObject(FileObject);
63 }
64 
65 VOID
66 NTAPI
68  IN PIRP Irp)
69 {
70  KIRQL OldIrql;
71  BOOLEAN CancelResult;
73  PAGED_CODE();
74 
75  /* Raise IRQL to APC */
76  KeRaiseIrql(APC_LEVEL, &OldIrql);
77 
78  /* Check if nobody completed it yet */
79  if (!KeReadStateEvent(EventObject))
80  {
81  /* First, cancel it */
82  CancelResult = IoCancelIrp(Irp);
83  KeLowerIrql(OldIrql);
84 
85  /* Check if we cancelled it */
86  if (CancelResult)
87  {
88  /* Wait for the IRP to be cancelled */
89  Wait.QuadPart = -100000;
90  while (!KeReadStateEvent(EventObject))
91  {
92  /* Delay indefintely */
94  }
95  }
96  else
97  {
98  /* No cancellation done, so wait for the I/O system to kill it */
99  KeWaitForSingleObject(EventObject,
100  Executive,
101  KernelMode,
102  FALSE,
103  NULL);
104  }
105  }
106  else
107  {
108  /* We got preempted, so give up */
109  KeLowerIrql(OldIrql);
110  }
111 }
112 
113 VOID
114 NTAPI
116 {
117  KIRQL OldIrql, LockIrql;
118  PETHREAD IrpThread;
119  PLIST_ENTRY IrpEntry;
120  PIO_ERROR_LOG_PACKET ErrorLogEntry;
122  PIO_STACK_LOCATION IoStackLocation;
123 
124  /* First, raise to APC to protect IrpList */
125  KeRaiseIrql(APC_LEVEL, &OldIrql);
126 
127  /* Get the Thread and check the list */
128  IrpThread = PsGetCurrentThread();
129  if (IsListEmpty(&IrpThread->IrpList))
130  {
131  /* It got completed now, so quit */
132  KeLowerIrql(OldIrql);
133  return;
134  }
135 
136  /* Ensure no one will come disturb */
138 
139  /* Get the misbehaving IRP */
140  IrpEntry = IrpThread->IrpList.Flink;
141  IopDeadIrp = CONTAINING_RECORD(IrpEntry, IRP, ThreadListEntry);
143  "%s - Deassociating IRP %p for %p\n",
144  __FUNCTION__,
145  IopDeadIrp,
146  IrpThread);
147 
148  /* Don't cancel the IRP if it's already been completed far */
149  if (IopDeadIrp->CurrentLocation == (IopDeadIrp->StackCount + 2))
150  {
151  /* Return */
153  KeLowerIrql(OldIrql);
154  return;
155  }
156 
157  /* Disown the IRP! */
158  IopDeadIrp->Tail.Overlay.Thread = NULL;
159  RemoveHeadList(&IrpThread->IrpList);
160  InitializeListHead(&IopDeadIrp->ThreadListEntry);
161 
162  /* Get the stack location and check if it's valid */
163  IoStackLocation = IoGetCurrentIrpStackLocation(IopDeadIrp);
164  if (IopDeadIrp->CurrentLocation <= IopDeadIrp->StackCount)
165  {
166  /* Get the device object */
167  DeviceObject = IoStackLocation->DeviceObject;
168  }
169 
171  /* Lower IRQL now, since we have the pointers we need */
172  KeLowerIrql(OldIrql);
173 
174  /* Check if we can send an Error Log Entry*/
175  if (DeviceObject)
176  {
177  /* Allocate an entry */
178  ErrorLogEntry = IoAllocateErrorLogEntry(DeviceObject,
179  sizeof(IO_ERROR_LOG_PACKET));
180  if (ErrorLogEntry)
181  {
182  /* Write the entry */
183  ErrorLogEntry->ErrorCode = IO_DRIVER_CANCEL_TIMEOUT;
184  IoWriteErrorLogEntry(ErrorLogEntry);
185  }
186  }
187 }
188 
189 VOID
190 NTAPI
193 {
194  PMDL Mdl;
196  "%s - Cleaning IRP %p for %p\n",
197  __FUNCTION__,
198  Irp,
199  FileObject);
200 
201  /* Check if there's an MDL */
202  while ((Mdl = Irp->MdlAddress))
203  {
204  /* Clear all of them */
205  Irp->MdlAddress = Mdl->Next;
206  IoFreeMdl(Mdl);
207  }
208 
209  /* Check if the IRP has system buffer */
210  if (Irp->Flags & IRP_DEALLOCATE_BUFFER)
211  {
212  /* Free the buffer */
213  ExFreePoolWithTag(Irp->AssociatedIrp.SystemBuffer, TAG_SYS_BUF);
214  }
215 
216  /* Check if this IRP has a user event, a file object, and is async */
217  if ((Irp->UserEvent) &&
218  !(Irp->Flags & IRP_SYNCHRONOUS_API) &&
219  (FileObject))
220  {
221  /* Dereference the User Event */
222  ObDereferenceObject(Irp->UserEvent);
223  }
224 
225  /* Check if we have a file object and this isn't a create operation */
226  if ((FileObject) && !(Irp->Flags & IRP_CREATE_OPERATION))
227  {
228  /* Dereference the file object */
229  ObDereferenceObject(FileObject);
230  }
231 
232  /* Free the IRP */
233  IoFreeIrp(Irp);
234 }
235 
236 VOID
237 NTAPI
239  IN PKNORMAL_ROUTINE* NormalRoutine,
240  IN PVOID* NormalContext,
243 {
245  PIRP Irp;
246  PMDL Mdl, NextMdl;
247  PVOID Port = NULL, Key = NULL;
248  BOOLEAN SignaledCreateRequest = FALSE;
249 
250  /* Get data from the APC */
251  FileObject = (PFILE_OBJECT)*SystemArgument1;
252  Irp = CONTAINING_RECORD(Apc, IRP, Tail.Apc);
254  "%s - Completing IRP %p for %p\n",
255  __FUNCTION__,
256  Irp,
257  FileObject);
258 
259  /* Sanity check */
260  ASSERT(Irp->IoStatus.Status != (NTSTATUS)0xFFFFFFFF);
261 
262  /* Check if we have a file object */
263  if (*SystemArgument2)
264  {
265  /* Check if we're reparsing */
266  if ((Irp->IoStatus.Status == STATUS_REPARSE) &&
267  (Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT))
268  {
269  PREPARSE_DATA_BUFFER ReparseData;
270 
271  ReparseData = (PREPARSE_DATA_BUFFER)*SystemArgument2;
272 
276 
277  IopDoNameTransmogrify(Irp, FileObject, ReparseData);
278  }
279  }
280 
281  /* Handle Buffered case first */
282  if (Irp->Flags & IRP_BUFFERED_IO)
283  {
284  /* Check if we have an input buffer and if we succeeded */
285  if ((Irp->Flags & IRP_INPUT_OPERATION) &&
286  (Irp->IoStatus.Status != STATUS_VERIFY_REQUIRED) &&
287  !(NT_ERROR(Irp->IoStatus.Status)))
288  {
289  _SEH2_TRY
290  {
291  /* Copy the buffer back to the user */
292  RtlCopyMemory(Irp->UserBuffer,
293  Irp->AssociatedIrp.SystemBuffer,
294  Irp->IoStatus.Information);
295  }
297  {
298  /* Fail the IRP */
299  Irp->IoStatus.Status = _SEH2_GetExceptionCode();
300  }
301  _SEH2_END;
302  }
303 
304  /* Also check if we should de-allocate it */
305  if (Irp->Flags & IRP_DEALLOCATE_BUFFER)
306  {
307  /* Deallocate it */
308  ExFreePool(Irp->AssociatedIrp.SystemBuffer);
309  }
310  }
311 
312  /* Now we got rid of these two... */
313  Irp->Flags &= ~(IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER);
314 
315  /* Check if there's an MDL */
316  for (Mdl = Irp->MdlAddress; Mdl; Mdl = NextMdl)
317  {
318  /* Free it */
319  NextMdl = Mdl->Next;
320  IoFreeMdl(Mdl);
321  }
322 
323  /* No MDLs left */
324  Irp->MdlAddress = NULL;
325 
326  /*
327  * Check if either the request was completed without any errors
328  * (but warnings are OK!), or if it was completed with an error, but
329  * did return from a pending I/O Operation and is not synchronous.
330  */
331  if (!NT_ERROR(Irp->IoStatus.Status) ||
332  (Irp->PendingReturned &&
333  !IsIrpSynchronous(Irp, FileObject)))
334  {
335  /* Get any information we need from the FO before we kill it */
336  if ((FileObject) && (FileObject->CompletionContext))
337  {
338  /* Save Completion Data */
339  Port = FileObject->CompletionContext->Port;
340  Key = FileObject->CompletionContext->Key;
341  }
342 
343  /* Check for UserIos */
344  if (Irp->UserIosb != NULL)
345  {
346  /* Use SEH to make sure we don't write somewhere invalid */
347  _SEH2_TRY
348  {
349  /* Save the IOSB Information */
350  *Irp->UserIosb = Irp->IoStatus;
351  }
353  {
354  /* Ignore any error */
355  }
356  _SEH2_END;
357  }
358 
359  /* Check if we have an event or a file object */
360  if (Irp->UserEvent)
361  {
362  /* At the very least, this is a PKEVENT, so signal it always */
363  KeSetEvent(Irp->UserEvent, 0, FALSE);
364 
365  /* Check if we also have a File Object */
366  if (FileObject)
367  {
368  /* Check if this is an Asynch API */
369  if (!(Irp->Flags & IRP_SYNCHRONOUS_API))
370  {
371  /* Dereference the event */
372  ObDereferenceObject(Irp->UserEvent);
373  }
374 
375  /*
376  * Now, if this is a Synch I/O File Object, then this event is
377  * NOT an actual Executive Event, so we won't dereference it,
378  * and instead, we will signal the File Object
379  */
380  if ((FileObject->Flags & FO_SYNCHRONOUS_IO) &&
381  !(Irp->Flags & IRP_OB_QUERY_NAME))
382  {
383  /* Signal the file object and set the status */
384  KeSetEvent(&FileObject->Event, 0, FALSE);
385  FileObject->FinalStatus = Irp->IoStatus.Status;
386  }
387 
388  /*
389  * This could also be a create operation, in which case we want
390  * to make sure there's no APC fired.
391  */
392  if (Irp->Flags & IRP_CREATE_OPERATION)
393  {
394  /* Clear the APC Routine and remember this */
395  Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
396  SignaledCreateRequest = TRUE;
397  }
398  }
399  }
400  else if (FileObject)
401  {
402  /* Signal the file object and set the status */
403  KeSetEvent(&FileObject->Event, 0, FALSE);
404  FileObject->FinalStatus = Irp->IoStatus.Status;
405 
406  /*
407  * This could also be a create operation, in which case we want
408  * to make sure there's no APC fired.
409  */
410  if (Irp->Flags & IRP_CREATE_OPERATION)
411  {
412  /* Clear the APC Routine and remember this */
413  Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
414  SignaledCreateRequest = TRUE;
415  }
416  }
417 
418  /* Update transfer count for everything but create operation */
419  if (!(Irp->Flags & IRP_CREATE_OPERATION))
420  {
421  if (Irp->Flags & IRP_WRITE_OPERATION)
422  {
423  /* Update write transfer count */
425  (ULONG)Irp->IoStatus.Information);
426  }
427  else if (Irp->Flags & IRP_READ_OPERATION)
428  {
429  /* Update read transfer count */
431  (ULONG)Irp->IoStatus.Information);
432  }
433  else
434  {
435  /* Update other transfer count */
437  (ULONG)Irp->IoStatus.Information);
438  }
439  }
440 
441  /* Now that we've signaled the events, de-associate the IRP */
443 
444  /* Now check if a User APC Routine was requested */
445  if (Irp->Overlay.AsynchronousParameters.UserApcRoutine)
446  {
447  /* Initialize it */
448  KeInitializeApc(&Irp->Tail.Apc,
453  (PKNORMAL_ROUTINE)Irp->
454  Overlay.AsynchronousParameters.UserApcRoutine,
455  Irp->RequestorMode,
456  Irp->
457  Overlay.AsynchronousParameters.UserApcContext);
458 
459  /* Queue it */
460  KeInsertQueueApc(&Irp->Tail.Apc, Irp->UserIosb, NULL, 2);
461  }
462  else if ((Port) &&
463  (Irp->Overlay.AsynchronousParameters.UserApcContext))
464  {
465  /* We have an I/O Completion setup... create the special Overlay */
466  Irp->Tail.CompletionKey = Key;
467  Irp->Tail.Overlay.PacketType = IopCompletionPacketIrp;
468  KeInsertQueue(Port, &Irp->Tail.Overlay.ListEntry);
469  }
470  else
471  {
472  /* Free the IRP since we don't need it anymore */
473  IoFreeIrp(Irp);
474  }
475 
476  /* Check if we have a file object that wasn't part of a create */
477  if ((FileObject) && !(SignaledCreateRequest))
478  {
479  /* Dereference it, since it's not needed anymore either */
480  ObDereferenceObjectDeferDelete(FileObject);
481  }
482  }
483  else
484  {
485  /*
486  * Either we didn't return from the request, or we did return but this
487  * request was synchronous.
488  */
489  if ((Irp->PendingReturned) && (FileObject))
490  {
491  /* So we did return with a synch operation, was it the IRP? */
492  if (Irp->Flags & IRP_SYNCHRONOUS_API)
493  {
494  /* Yes, this IRP was synchronous, so return the I/O Status */
495  *Irp->UserIosb = Irp->IoStatus;
496 
497  /* Now check if the user gave an event */
498  if (Irp->UserEvent)
499  {
500  /* Signal it */
501  KeSetEvent(Irp->UserEvent, 0, FALSE);
502  }
503  else
504  {
505  /* No event was given, so signal the FO instead */
506  KeSetEvent(&FileObject->Event, 0, FALSE);
507  }
508  }
509  else
510  {
511  /*
512  * It's not the IRP that was synchronous, it was the FO
513  * that was opened this way. Signal its event.
514  */
515  FileObject->FinalStatus = Irp->IoStatus.Status;
516  KeSetEvent(&FileObject->Event, 0, FALSE);
517  }
518  }
519 
520  /* Now that we got here, we do this for incomplete I/Os as well */
521  if ((FileObject) && !(Irp->Flags & IRP_CREATE_OPERATION))
522  {
523  /* Dereference the File Object unless this was a create */
524  ObDereferenceObjectDeferDelete(FileObject);
525  }
526 
527  /*
528  * Check if this was an Executive Event (remember that we know this
529  * by checking if the IRP is synchronous)
530  */
531  if ((Irp->UserEvent) &&
532  (FileObject) &&
533  !(Irp->Flags & IRP_SYNCHRONOUS_API))
534  {
535  /* This isn't a PKEVENT, so dereference it */
536  ObDereferenceObject(Irp->UserEvent);
537  }
538 
539  /* Now that we've signaled the events, de-associate the IRP */
541 
542  /* Free the IRP as well */
543  IoFreeIrp(Irp);
544  }
545 }
546 
547 BOOLEAN
548 NTAPI
550 {
551  /* Our allocated stack size */
552  ReserveIrpAllocator->StackSize = 20;
553 
554  /* Allocate the IRP now */
555  ReserveIrpAllocator->ReserveIrp = IoAllocateIrp(ReserveIrpAllocator->StackSize, FALSE);
556  /* If we cannot, abort system boot */
557  if (ReserveIrpAllocator->ReserveIrp == NULL)
558  {
559  return FALSE;
560  }
561 
562  /* It's not in use */
563  ReserveIrpAllocator->ReserveIrpInUse = 0;
564  /* And init the event */
565  KeInitializeEvent(&ReserveIrpAllocator->WaitEvent, SynchronizationEvent, FALSE);
566 
567  /* All good, keep booting */
568  return TRUE;
569 }
570 
571 PIRP
572 NTAPI
574 {
575  /* If we need a stack size higher than what was allocated, then fail */
576  if (StackSize > IopReserveIrpAllocator.StackSize)
577  {
578  return NULL;
579  }
580 
581  /* Now, wait until the IRP becomes available and reserve it immediately */
582  while (InterlockedExchange(&IopReserveIrpAllocator.ReserveIrpInUse, 1) == 1)
583  {
584  KeWaitForSingleObject(&IopReserveIrpAllocator.WaitEvent,
585  Executive,
586  KernelMode,
587  FALSE,
588  NULL);
589  }
590 
591  /* It's ours! Initialize it */
592  IoInitializeIrp(IopReserveIrpAllocator.ReserveIrp, IoSizeOfIrp(StackSize), StackSize);
593 
594  /* And return it to the caller */
595  return IopReserveIrpAllocator.ReserveIrp;
596 }
597 
598 VOID
600 {
601  /* Mark we don't use the IRP anymore */
602  InterlockedExchange(&IopReserveIrpAllocator.ReserveIrpInUse, 0);
603 
604  /* And set the event if someone is waiting on the IRP */
605  KeSetEvent(&IopReserveIrpAllocator.WaitEvent, PriorityBoost, FALSE);
606 }
607 
608 /* FUNCTIONS *****************************************************************/
609 
610 /*
611  * @implemented
612  */
613 PIRP
614 NTAPI
617 {
618  PIRP Irp = NULL;
619  USHORT Size = IoSizeOfIrp(StackSize);
620  PKPRCB Prcb;
621  UCHAR Flags = 0;
624 
625  /* Set Charge Quota Flag */
626  if (ChargeQuota) Flags |= IRP_QUOTA_CHARGED;
627 
628  /* Get the PRCB */
629  Prcb = KeGetCurrentPrcb();
630 
631  /* Figure out which Lookaside List to use */
632  if ((StackSize <= 8) && (ChargeQuota == FALSE || Prcb->LookasideIrpFloat > 0))
633  {
634  /* Set Fixed Size Flag */
635  Flags |= IRP_ALLOCATED_FIXED_SIZE;
636 
637  /* See if we should use big list */
638  if (StackSize != 1)
639  {
640  Size = IoSizeOfIrp(8);
641  ListType = LookasideLargeIrpList;
642  }
643 
644  /* Get the P List First */
645  List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[ListType].P;
646 
647  /* Attempt allocation */
648  List->L.TotalAllocates++;
649  Irp = (PIRP)InterlockedPopEntrySList(&List->L.ListHead);
650 
651  /* Check if the P List failed */
652  if (!Irp)
653  {
654  /* Let the balancer know */
655  List->L.AllocateMisses++;
656 
657  /* Try the L List */
658  List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[ListType].L;
659  List->L.TotalAllocates++;
660  Irp = (PIRP)InterlockedPopEntrySList(&List->L.ListHead);
661  }
662  }
663 
664  /* Check if we have to use the pool */
665  if (!Irp)
666  {
667  /* Did we try lookaside and fail? */
668  if (Flags & IRP_ALLOCATED_FIXED_SIZE) List->L.AllocateMisses++;
669 
670  /* Check if we should charge quota */
671  if (ChargeQuota)
672  {
674  Size,
675  TAG_IRP);
676  }
677  else
678  {
679  /* Allocate the IRP with no quota charge */
681  }
682 
683  /* Make sure it was sucessful */
684  if (!Irp) return NULL;
685  }
686  else if (Flags & IRP_QUOTA_CHARGED)
687  {
688  /* Decrement lookaside float */
690  Flags |= IRP_LOOKASIDE_ALLOCATION;
691 
692  /* In this case there is no charge quota */
693  Flags &= ~IRP_QUOTA_CHARGED;
694  }
695 
696  /* Now Initialize it */
697  IoInitializeIrp(Irp, Size, StackSize);
698 
699  /* Set the Allocation Flags */
700  Irp->AllocationFlags = Flags;
701 
702  /* Return it */
704  "%s - Allocated IRP %p with allocation flags %lx\n",
705  __FUNCTION__,
706  Irp,
707  Flags);
708  return Irp;
709 }
710 
711 /*
712  * @implemented
713  */
714 PIRP
715 NTAPI
717 {
718  LONG i;
719  PIRP Irp;
721 
722  /* Try to get an IRP */
723  Irp = IoAllocateIrp(StackSize, FALSE);
724  if (Irp)
725  return Irp;
726 
727  /* If we fail, start looping till we may get one */
728  i = LONG_MAX;
729  do {
730  i--;
731 
732  /* First, sleep for 10ms */
733  Sleep.QuadPart = -10 * 1000 * 10;
735 
736  /* Then, retry allocation */
737  Irp = IoAllocateIrp(StackSize, FALSE);
738  if (Irp)
739  return Irp;
740  } while (i > 0);
741 
742  return Irp;
743 }
744 
745 /*
746  * @implemented
747  */
748 PIRP
749 NTAPI
752  IN PVOID Buffer,
753  IN ULONG Length,
756 {
757  PIRP Irp;
758  PIO_STACK_LOCATION StackPtr;
759 
760  /* Allocate IRP */
761  Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
762  if (!Irp) return NULL;
763 
764  /* Get the Stack */
765  StackPtr = IoGetNextIrpStackLocation(Irp);
766 
767  /* Write the Major function and then deal with it */
768  StackPtr->MajorFunction = (UCHAR)MajorFunction;
769 
770  /* Do not handle the following here */
771  if ((MajorFunction != IRP_MJ_FLUSH_BUFFERS) &&
772  (MajorFunction != IRP_MJ_SHUTDOWN) &&
773  (MajorFunction != IRP_MJ_PNP) &&
774  (MajorFunction != IRP_MJ_POWER))
775  {
776  /* Check if this is Buffered IO */
777  if (DeviceObject->Flags & DO_BUFFERED_IO)
778  {
779  /* Allocate the System Buffer */
780  Irp->AssociatedIrp.SystemBuffer =
782  if (!Irp->AssociatedIrp.SystemBuffer)
783  {
784  /* Free the IRP and fail */
785  IoFreeIrp(Irp);
786  return NULL;
787  }
788 
789  /* Set flags */
790  Irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
791 
792  /* Handle special IRP_MJ_WRITE Case */
793  if (MajorFunction == IRP_MJ_WRITE)
794  {
795  /* Copy the buffer data */
796  RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, Buffer, Length);
797  }
798  else
799  {
800  /* Set the Input Operation flag and set this as a User Buffer */
801  Irp->Flags |= IRP_INPUT_OPERATION;
802  Irp->UserBuffer = Buffer;
803  }
804  }
805  else if (DeviceObject->Flags & DO_DIRECT_IO)
806  {
807  /* Use an MDL for Direct I/O */
808  Irp->MdlAddress = IoAllocateMdl(Buffer,
809  Length,
810  FALSE,
811  FALSE,
812  NULL);
813  if (!Irp->MdlAddress)
814  {
815  /* Free the IRP and fail */
816  IoFreeIrp(Irp);
817  return NULL;
818  }
819 
820  /* Probe and Lock */
821  _SEH2_TRY
822  {
823  /* Do the probe */
824  MmProbeAndLockPages(Irp->MdlAddress,
825  KernelMode,
826  MajorFunction == IRP_MJ_READ ?
828  }
830  {
831  /* Free the IRP and its MDL */
832  IoFreeMdl(Irp->MdlAddress);
833  IoFreeIrp(Irp);
834 
835  /* Fail */
836  _SEH2_YIELD(return NULL);
837  }
838  _SEH2_END;
839  }
840  else
841  {
842  /* Neither, use the buffer */
843  Irp->UserBuffer = Buffer;
844  }
845 
846  /* Check if this is a read */
847  if (MajorFunction == IRP_MJ_READ)
848  {
849  /* Set the parameters for a read */
850  StackPtr->Parameters.Read.Length = Length;
851  StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
852  }
853  else if (MajorFunction == IRP_MJ_WRITE)
854  {
855  /* Otherwise, set write parameters */
856  StackPtr->Parameters.Write.Length = Length;
857  StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
858  }
859  }
860 
861  /* Set the Current Thread and IOSB */
862  Irp->UserIosb = IoStatusBlock;
863  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
864 
865  /* Return the IRP */
867  "%s - Built IRP %p with Major, Buffer, DO %lx %p %p\n",
868  __FUNCTION__,
869  Irp,
870  MajorFunction,
871  Buffer,
872  DeviceObject);
873  return Irp;
874 }
875 
876 /*
877  * @implemented
878  */
879 PIRP
880 NTAPI
888  IN PKEVENT Event,
890 {
891  PIRP Irp;
892  PIO_STACK_LOCATION StackPtr;
894 
895  /* Allocate IRP */
896  Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
897  if (!Irp) return NULL;
898 
899  /* Get the Stack */
900  StackPtr = IoGetNextIrpStackLocation(Irp);
901 
902  /* Set the DevCtl Type */
903  StackPtr->MajorFunction = InternalDeviceIoControl ?
906 
907  /* Set the IOCTL Data */
908  StackPtr->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
909  StackPtr->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
910  StackPtr->Parameters.DeviceIoControl.OutputBufferLength =
912 
913  /* Handle the Methods */
914  switch (IO_METHOD_FROM_CTL_CODE(IoControlCode))
915  {
916  /* Buffered I/O */
917  case METHOD_BUFFERED:
918 
919  /* Select the right Buffer Length */
920  BufferLength = InputBufferLength > OutputBufferLength ?
922 
923  /* Make sure there is one */
924  if (BufferLength)
925  {
926  /* Allocate the System Buffer */
927  Irp->AssociatedIrp.SystemBuffer =
929  BufferLength,
930  TAG_SYS_BUF);
931  if (!Irp->AssociatedIrp.SystemBuffer)
932  {
933  /* Free the IRP and fail */
934  IoFreeIrp(Irp);
935  return NULL;
936  }
937 
938  /* Check if we got a buffer */
939  if (InputBuffer)
940  {
941  /* Copy into the System Buffer */
942  RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
943  InputBuffer,
944  InputBufferLength);
945  }
946 
947  /* Write the flags */
948  Irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
949  if (OutputBuffer) Irp->Flags |= IRP_INPUT_OPERATION;
950 
951  /* Save the Buffer */
952  Irp->UserBuffer = OutputBuffer;
953  }
954  else
955  {
956  /* Clear the Flags and Buffer */
957  Irp->Flags = 0;
958  Irp->UserBuffer = NULL;
959  }
960  break;
961 
962  /* Direct I/O */
963  case METHOD_IN_DIRECT:
964  case METHOD_OUT_DIRECT:
965 
966  /* Check if we got an input buffer */
967  if (InputBuffer)
968  {
969  /* Allocate the System Buffer */
970  Irp->AssociatedIrp.SystemBuffer =
972  InputBufferLength,
973  TAG_SYS_BUF);
974  if (!Irp->AssociatedIrp.SystemBuffer)
975  {
976  /* Free the IRP and fail */
977  IoFreeIrp(Irp);
978  return NULL;
979  }
980 
981  /* Copy into the System Buffer */
982  RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
983  InputBuffer,
984  InputBufferLength);
985 
986  /* Write the flags */
987  Irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
988  }
989  else
990  {
991  /* Clear the flags */
992  Irp->Flags = 0;
993  }
994 
995  /* Check if we got an output buffer */
996  if (OutputBuffer)
997  {
998  /* Allocate the System Buffer */
999  Irp->MdlAddress = IoAllocateMdl(OutputBuffer,
1000  OutputBufferLength,
1001  FALSE,
1002  FALSE,
1003  Irp);
1004  if (!Irp->MdlAddress)
1005  {
1006  /* Free the IRP and fail */
1007  IoFreeIrp(Irp);
1008  return NULL;
1009  }
1010 
1011  /* Probe and Lock */
1012  _SEH2_TRY
1013  {
1014  /* Do the probe */
1015  MmProbeAndLockPages(Irp->MdlAddress,
1016  KernelMode,
1017  IO_METHOD_FROM_CTL_CODE(IoControlCode) ==
1020  }
1022  {
1023  /* Free the MDL */
1024  IoFreeMdl(Irp->MdlAddress);
1025 
1026  /* Free the input buffer and IRP */
1027  if (InputBuffer) ExFreePool(Irp->AssociatedIrp.SystemBuffer);
1028  IoFreeIrp(Irp);
1029 
1030  /* Fail */
1031  _SEH2_YIELD(return NULL);
1032  }
1033  _SEH2_END;
1034  }
1035  break;
1036 
1037  case METHOD_NEITHER:
1038 
1039  /* Just save the Buffer */
1040  Irp->UserBuffer = OutputBuffer;
1041  StackPtr->Parameters.DeviceIoControl.Type3InputBuffer = InputBuffer;
1042  }
1043 
1044  /* Now write the Event and IoSB */
1045  Irp->UserIosb = IoStatusBlock;
1046  Irp->UserEvent = Event;
1047 
1048  /* Sync IRPs are queued to requestor thread's irp cancel/cleanup list */
1049  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
1050  IoQueueThreadIrp(Irp);
1051 
1052  /* Return the IRP */
1054  "%s - Built IRP %p with IOCTL, Buffers, DO %lx %p %p %p\n",
1055  __FUNCTION__,
1056  Irp,
1057  IoControlCode,
1058  InputBuffer,
1059  OutputBuffer,
1060  DeviceObject);
1061  return Irp;
1062 }
1063 
1064 /*
1065  * @implemented
1066  */
1067 PIRP
1068 NTAPI
1071  IN PVOID Buffer,
1072  IN ULONG Length,
1074  IN PKEVENT Event,
1076 {
1077  PIRP Irp;
1078 
1079  /* Do the big work to set up the IRP */
1080  Irp = IoBuildAsynchronousFsdRequest(MajorFunction,
1081  DeviceObject,
1082  Buffer,
1083  Length,
1084  StartingOffset,
1085  IoStatusBlock );
1086  if (!Irp) return NULL;
1087 
1088  /* Set the Event which makes it Syncronous */
1089  Irp->UserEvent = Event;
1090 
1091  /* Sync IRPs are queued to requestor thread's irp cancel/cleanup list */
1092  IoQueueThreadIrp(Irp);
1093  return Irp;
1094 }
1095 
1096 /*
1097  * @implemented
1098  */
1099 BOOLEAN
1100 NTAPI
1102 {
1103  KIRQL OldIrql;
1106  "%s - Canceling IRP %p\n",
1107  __FUNCTION__,
1108  Irp);
1109  ASSERT(Irp->Type == IO_TYPE_IRP);
1110 
1111  /* Acquire the cancel lock and cancel the IRP */
1112  IoAcquireCancelSpinLock(&OldIrql);
1113  Irp->Cancel = TRUE;
1114 
1115  /* Clear the cancel routine and get the old one */
1116  CancelRoutine = IoSetCancelRoutine(Irp, NULL);
1117  if (CancelRoutine)
1118  {
1119  /* We had a routine, make sure the IRP isn't completed */
1120  if (Irp->CurrentLocation > (Irp->StackCount + 1))
1121  {
1122  /* It is, bugcheck */
1123  KeBugCheckEx(CANCEL_STATE_IN_COMPLETED_IRP,
1124  (ULONG_PTR)Irp,
1125  (ULONG_PTR)CancelRoutine,
1126  0,
1127  0);
1128  }
1129 
1130  /* Set the cancel IRQL And call the routine */
1131  Irp->CancelIrql = OldIrql;
1133  return TRUE;
1134  }
1135 
1136  /* Otherwise, release the cancel lock and fail */
1137  IoReleaseCancelSpinLock(OldIrql);
1138  return FALSE;
1139 }
1140 
1141 /*
1142  * @implemented
1143  */
1144 VOID
1145 NTAPI
1147 {
1148  KIRQL OldIrql;
1149  ULONG Retries = 3000;
1151  PLIST_ENTRY ListHead, NextEntry;
1152  PIRP Irp;
1153  PAGED_CODE();
1154 
1155  /* Windows isn't using given thread, but using current. */
1156  Thread = PsGetCurrentThread();
1157 
1159  "%s - Canceling IRPs for Thread %p\n",
1160  __FUNCTION__,
1161  Thread);
1162 
1163  /* Raise to APC to protect the IrpList */
1164  KeRaiseIrql(APC_LEVEL, &OldIrql);
1165 
1166  /* Start by cancelling all the IRPs in the current thread queue. */
1167  ListHead = &Thread->IrpList;
1168  NextEntry = ListHead->Flink;
1169  while (ListHead != NextEntry)
1170  {
1171  /* Get the IRP */
1172  Irp = CONTAINING_RECORD(NextEntry, IRP, ThreadListEntry);
1173 
1174  /* Cancel it */
1175  IoCancelIrp(Irp);
1176 
1177  /* Move to the next entry */
1178  NextEntry = NextEntry->Flink;
1179  }
1180 
1181  /* Wait 100 milliseconds */
1182  Interval.QuadPart = -1000000;
1183 
1184  /* Wait till all the IRPs are completed or cancelled. */
1185  while (!IsListEmpty(&Thread->IrpList))
1186  {
1187  /* Now we can lower */
1188  KeLowerIrql(OldIrql);
1189 
1190  /* Wait a short while and then look if all our IRPs were completed. */
1192 
1193  /*
1194  * Don't stay here forever if some broken driver doesn't complete
1195  * the IRP.
1196  */
1197  if (!(Retries--))
1198  {
1199  /* Print out a message and remove the IRP */
1200  DPRINT1("Broken driver did not complete!\n");
1202  }
1203 
1204  /* Raise the IRQL Again */
1205  KeRaiseIrql(APC_LEVEL, &OldIrql);
1206  }
1207 
1208  /* We're done, lower the IRQL */
1209  KeLowerIrql(OldIrql);
1210 }
1211 
1212 /*
1213  * @implemented
1214  */
1215 #undef IoCallDriver
1216 NTSTATUS
1217 NTAPI
1219  IN PIRP Irp)
1220 {
1221  /* Call fastcall */
1222  return IofCallDriver(DeviceObject, Irp);
1223 }
1224 
1225 #define IoCallDriver IofCallDriver
1226 
1227 /*
1228  * @implemented
1229  */
1230 #undef IoCompleteRequest
1231 VOID
1232 NTAPI
1235 {
1236  /* Call the fastcall */
1237  IofCompleteRequest(Irp, PriorityBoost);
1238 }
1239 
1240 #define IoCompleteRequest IofCompleteRequest
1241 
1242 /*
1243  * @implemented
1244  */
1245 VOID
1246 NTAPI
1248 {
1249  /* This is the same as calling IoQueueThreadIrp */
1250  IoQueueThreadIrp(Irp);
1251 }
1252 
1253 /*
1254  * @implemented
1255  */
1256 NTSTATUS
1257 FASTCALL
1259  IN PIRP Irp)
1260 {
1262  PIO_STACK_LOCATION StackPtr;
1263 
1264  /* Make sure this is a valid IRP */
1265  ASSERT(Irp->Type == IO_TYPE_IRP);
1266 
1267  /* Get the Driver Object */
1268  DriverObject = DeviceObject->DriverObject;
1269 
1270  /* Decrease the current location and check if */
1271  Irp->CurrentLocation--;
1272  if (Irp->CurrentLocation <= 0)
1273  {
1274  /* This IRP ran out of stack, bugcheck */
1275  KeBugCheckEx(NO_MORE_IRP_STACK_LOCATIONS, (ULONG_PTR)Irp, 0, 0, 0);
1276  }
1277 
1278  /* Now update the stack location */
1279  StackPtr = IoGetNextIrpStackLocation(Irp);
1280  Irp->Tail.Overlay.CurrentStackLocation = StackPtr;
1281 
1282  /* Get the Device Object */
1283  StackPtr->DeviceObject = DeviceObject;
1284 
1285  /* Call it */
1286  return DriverObject->MajorFunction[StackPtr->MajorFunction](DeviceObject,
1287  Irp);
1288 }
1289 
1291 VOID
1293 {
1294  IoStackLocation->MinorFunction = 0;
1295  IoStackLocation->Flags = 0;
1296  IoStackLocation->Control &= SL_ERROR_RETURNED;
1297  IoStackLocation->Parameters.Others.Argument1 = 0;
1298  IoStackLocation->Parameters.Others.Argument2 = 0;
1299  IoStackLocation->Parameters.Others.Argument3 = 0;
1300  IoStackLocation->FileObject = NULL;
1301 }
1302 
1303 /*
1304  * @implemented
1305  */
1306 VOID
1307 FASTCALL
1310 {
1311  PIO_STACK_LOCATION StackPtr, LastStackPtr;
1314  PETHREAD Thread;
1315  NTSTATUS Status;
1316  PMDL Mdl, NextMdl;
1317  ULONG MasterCount;
1318  PIRP MasterIrp;
1319  ULONG Flags;
1321  PREPARSE_DATA_BUFFER DataBuffer = NULL;
1323  "%s - Completing IRP %p\n",
1324  __FUNCTION__,
1325  Irp);
1326 
1327  /* Make sure this IRP isn't getting completed twice or is invalid */
1328  if ((Irp->CurrentLocation) > (Irp->StackCount + 1))
1329  {
1330  /* Bugcheck */
1331  KeBugCheckEx(MULTIPLE_IRP_COMPLETE_REQUESTS, (ULONG_PTR)Irp, 0, 0, 0);
1332  }
1333 
1334  /* Some sanity checks */
1335  ASSERT(Irp->Type == IO_TYPE_IRP);
1336  ASSERT(!Irp->CancelRoutine);
1337  ASSERT(Irp->IoStatus.Status != STATUS_PENDING);
1338  ASSERT(Irp->IoStatus.Status != (NTSTATUS)0xFFFFFFFF);
1339 
1340  /* Get the last stack */
1341  LastStackPtr = (PIO_STACK_LOCATION)(Irp + 1);
1342  if (LastStackPtr->Control & SL_ERROR_RETURNED)
1343  {
1344  /* Get the error code */
1345  ErrorCode = PtrToUlong(LastStackPtr->Parameters.Others.Argument4);
1346  }
1347 
1348  /*
1349  * Start the loop with the current stack and point the IRP to the next stack
1350  * and then keep incrementing the stack as we loop through. The IRP should
1351  * always point to the next stack location w.r.t the one currently being
1352  * analyzed, so completion routine code will see the appropriate value.
1353  * Because of this, we must loop until the current stack location is +1 of
1354  * the stack count, because when StackPtr is at the end, CurrentLocation is +1.
1355  */
1356  for (StackPtr = IoGetCurrentIrpStackLocation(Irp),
1357  Irp->CurrentLocation++,
1358  Irp->Tail.Overlay.CurrentStackLocation++;
1359  Irp->CurrentLocation <= (Irp->StackCount + 1);
1360  StackPtr++,
1361  Irp->CurrentLocation++,
1362  Irp->Tail.Overlay.CurrentStackLocation++)
1363  {
1364  /* Set Pending Returned */
1365  Irp->PendingReturned = StackPtr->Control & SL_PENDING_RETURNED;
1366 
1367  /* Check if we failed */
1368  if (!NT_SUCCESS(Irp->IoStatus.Status))
1369  {
1370  /* Check if it was changed by a completion routine */
1371  if (Irp->IoStatus.Status != ErrorCode)
1372  {
1373  /* Update the error for the current stack */
1374  ErrorCode = Irp->IoStatus.Status;
1375  StackPtr->Control |= SL_ERROR_RETURNED;
1376  LastStackPtr->Parameters.Others.Argument4 = UlongToPtr(ErrorCode);
1377  LastStackPtr->Control |= SL_ERROR_RETURNED;
1378  }
1379  }
1380 
1381  /* Check if there is a Completion Routine to Call */
1382  if ((NT_SUCCESS(Irp->IoStatus.Status) &&
1383  (StackPtr->Control & SL_INVOKE_ON_SUCCESS)) ||
1384  (!NT_SUCCESS(Irp->IoStatus.Status) &&
1385  (StackPtr->Control & SL_INVOKE_ON_ERROR)) ||
1386  (Irp->Cancel &&
1387  (StackPtr->Control & SL_INVOKE_ON_CANCEL)))
1388  {
1389  /* Clear the stack location */
1390  IopClearStackLocation(StackPtr);
1391 
1392  /* Check for highest-level device completion routines */
1393  if (Irp->CurrentLocation == (Irp->StackCount + 1))
1394  {
1395  /* Clear the DO, since the current stack location is invalid */
1396  DeviceObject = NULL;
1397  }
1398  else
1399  {
1400  /* Otherwise, return the real one */
1401  DeviceObject = IoGetCurrentIrpStackLocation(Irp)->DeviceObject;
1402  }
1403 
1404  /* Call the completion routine */
1405  Status = StackPtr->CompletionRoutine(DeviceObject,
1406  Irp,
1407  StackPtr->Context);
1408 
1409  /* Don't touch the Packet in this case, since it might be gone! */
1410  if (Status == STATUS_MORE_PROCESSING_REQUIRED) return;
1411  }
1412  else
1413  {
1414  /* Otherwise, check if this is a completed IRP */
1415  if ((Irp->CurrentLocation <= Irp->StackCount) &&
1416  (Irp->PendingReturned))
1417  {
1418  /* Mark it as pending */
1419  IoMarkIrpPending(Irp);
1420  }
1421 
1422  /* Clear the stack location */
1423  IopClearStackLocation(StackPtr);
1424  }
1425  }
1426 
1427  /* Check if the IRP is an associated IRP */
1428  if (Irp->Flags & IRP_ASSOCIATED_IRP)
1429  {
1430  /* Get the master IRP and count */
1431  MasterIrp = Irp->AssociatedIrp.MasterIrp;
1432  MasterCount = InterlockedDecrement(&MasterIrp->AssociatedIrp.IrpCount);
1433 
1434  /* Free the MDLs */
1435  for (Mdl = Irp->MdlAddress; Mdl; Mdl = NextMdl)
1436  {
1437  /* Go to the next one */
1438  NextMdl = Mdl->Next;
1439  IoFreeMdl(Mdl);
1440  }
1441 
1442  /* Free the IRP itself */
1443  IoFreeIrp(Irp);
1444 
1445  /* Complete the Master IRP */
1446  if (!MasterCount) IofCompleteRequest(MasterIrp, PriorityBoost);
1447  return;
1448  }
1449 
1450  /* Check whether we have to reparse */
1451  if (Irp->IoStatus.Status == STATUS_REPARSE)
1452  {
1453  if (Irp->IoStatus.Information > IO_REMOUNT)
1454  {
1455  /* If that's a reparse tag we understand, save the buffer from deletion */
1456  if (Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT)
1457  {
1458  ASSERT(Irp->Tail.Overlay.AuxiliaryBuffer != NULL);
1459  DataBuffer = (PREPARSE_DATA_BUFFER)Irp->Tail.Overlay.AuxiliaryBuffer;
1460  Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
1461  }
1462  else
1463  {
1464  Irp->IoStatus.Status = STATUS_IO_REPARSE_TAG_NOT_HANDLED;
1465  }
1466  }
1467  }
1468 
1469  /* Check if we have an auxiliary buffer */
1470  if (Irp->Tail.Overlay.AuxiliaryBuffer)
1471  {
1472  /* Free it */
1473  ExFreePool(Irp->Tail.Overlay.AuxiliaryBuffer);
1474  Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
1475  }
1476 
1477  /* Check if this is a Paging I/O or Close Operation */
1478  if (Irp->Flags & (IRP_PAGING_IO | IRP_CLOSE_OPERATION))
1479  {
1480  /* Handle a Close Operation or Sync Paging I/O */
1481  if (Irp->Flags & (IRP_SYNCHRONOUS_PAGING_IO | IRP_CLOSE_OPERATION))
1482  {
1483  /* Set the I/O Status and Signal the Event */
1484  Flags = Irp->Flags & (IRP_SYNCHRONOUS_PAGING_IO | IRP_PAGING_IO);
1485  *Irp->UserIosb = Irp->IoStatus;
1486  KeSetEvent(Irp->UserEvent, PriorityBoost, FALSE);
1487 
1488  /* Free the IRP for a Paging I/O Only, Close is handled by us */
1489  if (Flags)
1490  {
1491  /* If we were using the reserve IRP, then call the appropriate
1492  * free function (to make the IRP available again)
1493  */
1494  if (Irp == IopReserveIrpAllocator.ReserveIrp)
1495  {
1496  IopFreeReserveIrp(PriorityBoost);
1497  }
1498  /* Otherwise, free for real! */
1499  else
1500  {
1501  IoFreeIrp(Irp);
1502  }
1503  }
1504  }
1505  else
1506  {
1507 #if 0
1508  /* Page 166 */
1509  KeInitializeApc(&Irp->Tail.Apc
1510  &Irp->Tail.Overlay.Thread->Tcb,
1511  Irp->ApcEnvironment,
1512  IopCompletePageWrite,
1513  NULL,
1514  NULL,
1515  KernelMode,
1516  NULL);
1517  KeInsertQueueApc(&Irp->Tail.Apc,
1518  NULL,
1519  NULL,
1520  PriorityBoost);
1521 #else
1522  /* Not implemented yet. */
1523  UNIMPLEMENTED_DBGBREAK("Not supported!\n");
1524 #endif
1525  }
1526 
1527  /* Get out of here */
1528  return;
1529  }
1530 
1531  /* Unlock MDL Pages, page 167. */
1532  Mdl = Irp->MdlAddress;
1533  while (Mdl)
1534  {
1535  MmUnlockPages(Mdl);
1536  Mdl = Mdl->Next;
1537  }
1538 
1539  /* Check if we should exit because of a Deferred I/O (page 168) */
1540  if ((Irp->Flags & IRP_DEFER_IO_COMPLETION) && !(Irp->PendingReturned))
1541  {
1542  /* Restore the saved reparse buffer for the caller */
1543  if (Irp->IoStatus.Status == STATUS_REPARSE &&
1544  Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT)
1545  {
1546  Irp->Tail.Overlay.AuxiliaryBuffer = (PCHAR)DataBuffer;
1547  }
1548 
1549  /*
1550  * Return without queuing the completion APC, since the caller will
1551  * take care of doing its own optimized completion at PASSIVE_LEVEL.
1552  */
1553  return;
1554  }
1555 
1556  /* Get the thread and file object */
1557  Thread = Irp->Tail.Overlay.Thread;
1558  FileObject = Irp->Tail.Overlay.OriginalFileObject;
1559 
1560  /* Make sure the IRP isn't canceled */
1561  if (!Irp->Cancel)
1562  {
1563  /* Initialize the APC */
1564  KeInitializeApc(&Irp->Tail.Apc,
1565  &Thread->Tcb,
1566  Irp->ApcEnvironment,
1568  NULL,
1569  NULL,
1570  KernelMode,
1571  NULL);
1572 
1573  /* Queue it */
1574  KeInsertQueueApc(&Irp->Tail.Apc,
1575  FileObject,
1576  DataBuffer,
1577  PriorityBoost);
1578  }
1579  else
1580  {
1581  /* The IRP just got canceled... does a thread still own it? */
1582  if (Thread)
1583  {
1584  /* Yes! There is still hope! Initialize the APC */
1585  KeInitializeApc(&Irp->Tail.Apc,
1586  &Thread->Tcb,
1587  Irp->ApcEnvironment,
1589  NULL,
1590  NULL,
1591  KernelMode,
1592  NULL);
1593 
1594  /* Queue it */
1595  KeInsertQueueApc(&Irp->Tail.Apc,
1596  FileObject,
1597  DataBuffer,
1598  PriorityBoost);
1599  }
1600  else
1601  {
1602  /* Nothing left for us to do, kill it */
1603  ASSERT(Irp->Cancel);
1604  IopCleanupIrp(Irp, FileObject);
1605  }
1606  }
1607 }
1608 
1609 NTSTATUS
1610 NTAPI
1612  IN PIRP Irp,
1613  IN PVOID Context)
1614 {
1615  if (Irp->PendingReturned)
1618 }
1619 
1620 /*
1621  * @implemented
1622  */
1623 BOOLEAN
1624 NTAPI
1626  IN PIRP Irp)
1627 {
1628  KEVENT Event;
1629  NTSTATUS Status;
1630 
1631  /* Check if next stack location is available */
1632  if (Irp->CurrentLocation < Irp->StackCount)
1633  {
1634  /* No more stack location */
1635  return FALSE;
1636  }
1637 
1638  /* Initialize event */
1640 
1641  /* Copy stack location for next driver */
1643 
1644  /* Set a completion routine, which will signal the event */
1646 
1647  /* Call next driver */
1648  Status = IoCallDriver(DeviceObject, Irp);
1649 
1650  /* Check if irp is pending */
1651  if (Status == STATUS_PENDING)
1652  {
1653  /* Yes, wait for its completion */
1655  }
1656 
1657  /* Return success */
1658  return TRUE;
1659 }
1660 
1661 /*
1662  * @implemented
1663  */
1664 VOID
1665 NTAPI
1667 {
1670  PKPRCB Prcb;
1672  "%s - Freeing IRPs %p\n",
1673  __FUNCTION__,
1674  Irp);
1675 
1676  /* Make sure the Thread IRP list is empty and that it OK to free it */
1677  ASSERT(Irp->Type == IO_TYPE_IRP);
1678  ASSERT(IsListEmpty(&Irp->ThreadListEntry));
1679  ASSERT(Irp->CurrentLocation >= Irp->StackCount);
1680 
1681  /* Get the PRCB */
1682  Prcb = KeGetCurrentPrcb();
1683 
1684  /* If this was a lookaside alloc, increment lookaside float */
1685  if (Irp->AllocationFlags & IRP_LOOKASIDE_ALLOCATION)
1686  {
1687  Irp->AllocationFlags &= ~IRP_LOOKASIDE_ALLOCATION;
1689  }
1690 
1691  /* If this was a pool alloc, free it with the pool */
1692  if (!(Irp->AllocationFlags & IRP_ALLOCATED_FIXED_SIZE))
1693  {
1694  /* Free it */
1695  ExFreePoolWithTag(Irp, TAG_IRP);
1696  }
1697  else
1698  {
1699  /* Check if this was a Big IRP */
1700  if (Irp->StackCount != 1) ListType = LookasideLargeIrpList;
1701 
1702  /* Use the P List */
1703  List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[ListType].P;
1704  List->L.TotalFrees++;
1705 
1706  /* Check if the Free was within the Depth or not */
1707  if (ExQueryDepthSList(&List->L.ListHead) >= List->L.Depth)
1708  {
1709  /* Let the balancer know */
1710  List->L.FreeMisses++;
1711 
1712  /* Use the L List */
1713  List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[ListType].L;
1714  List->L.TotalFrees++;
1715 
1716  /* Check if the Free was within the Depth or not */
1717  if (ExQueryDepthSList(&List->L.ListHead) >= List->L.Depth)
1718  {
1719  /* All lists failed, use the pool */
1720  List->L.FreeMisses++;
1721  ExFreePoolWithTag(Irp, TAG_IRP);
1722  Irp = NULL;
1723  }
1724  }
1725 
1726  /* The free was within the Depth */
1727  if (Irp)
1728  {
1729  /* Remove the association with the process */
1730  if (Irp->AllocationFlags & IRP_QUOTA_CHARGED)
1731  {
1732  ExReturnPoolQuota(Irp);
1733  Irp->AllocationFlags &= ~IRP_QUOTA_CHARGED;
1734  }
1735 
1736  /* Add it to the lookaside list */
1737  InterlockedPushEntrySList(&List->L.ListHead,
1738  (PSLIST_ENTRY)Irp);
1739  }
1740  }
1741 }
1742 
1743 /*
1744  * @implemented
1745  */
1747 FASTCALL
1749 {
1751  ULONG Flags;
1752 
1753  /* Get the flags */
1754  Flags = Irp->Flags;
1755 
1756  /* Check what priority it has */
1757  if (Flags & IRP_CLASS_CACHE_OPERATION)
1758  {
1759  /* High priority */
1760  Priority = IoPagingPriorityHigh;
1761  }
1762  else if (Flags & IRP_PAGING_IO)
1763  {
1764  /* Normal priority */
1765  Priority = IoPagingPriorityNormal;
1766  }
1767  else
1768  {
1769  /* Invalid -- not a paging IRP */
1770  Priority = IoPagingPriorityInvalid;
1771  }
1772 
1773  /* Return the priority */
1774  return Priority;
1775 }
1776 
1777 /*
1778  * @implemented
1779  */
1780 PEPROCESS
1781 NTAPI
1783 {
1784  /* Return the requestor process */
1785  if (Irp->Tail.Overlay.Thread)
1786  {
1787  if (Irp->ApcEnvironment == OriginalApcEnvironment)
1788  {
1789  return Irp->Tail.Overlay.Thread->ThreadsProcess;
1790  }
1791  else if (Irp->ApcEnvironment == AttachedApcEnvironment)
1792  {
1793  return (PEPROCESS)Irp->Tail.Overlay.Thread->Tcb.ApcState.Process;
1794  }
1795  }
1796 
1797  return NULL;
1798 }
1799 
1800 /*
1801  * @implemented
1802  */
1803 ULONG
1804 NTAPI
1806 {
1808 
1809  /* Return the requestor process' id */
1810  Process = IoGetRequestorProcess(Irp);
1811  if (Process) return PtrToUlong(Process->UniqueProcessId);
1812 
1813  return 0;
1814 }
1815 
1816 /*
1817  * @implemented
1818  */
1819 NTSTATUS
1820 NTAPI
1822  OUT PULONG pSessionId)
1823 {
1825 
1826  /* Return the session */
1827  if (Irp->Tail.Overlay.Thread)
1828  {
1829  Process = Irp->Tail.Overlay.Thread->ThreadsProcess;
1830  *pSessionId = MmGetSessionId(Process);
1831  return STATUS_SUCCESS;
1832  }
1833 
1834  *pSessionId = (ULONG)-1;
1835  return STATUS_UNSUCCESSFUL;
1836 }
1837 
1838 /*
1839  * @implemented
1840  */
1841 PIRP
1842 NTAPI
1844 {
1845  /* Return the IRP */
1846  return (PIRP)PsGetCurrentThread()->TopLevelIrp;
1847 }
1848 
1849 /*
1850  * @implemented
1851  */
1852 VOID
1853 NTAPI
1856  IN CCHAR StackSize)
1857 {
1858  /* Clear it */
1860  "%s - Initializing IRP %p\n",
1861  __FUNCTION__,
1862  Irp);
1863  RtlZeroMemory(Irp, PacketSize);
1864 
1865  /* Set the Header and other data */
1866  Irp->Type = IO_TYPE_IRP;
1867  Irp->Size = PacketSize;
1868  Irp->StackCount = StackSize;
1869  Irp->CurrentLocation = StackSize + 1;
1870  Irp->ApcEnvironment = KeGetCurrentThread()->ApcStateIndex;
1871  Irp->Tail.Overlay.CurrentStackLocation = (PIO_STACK_LOCATION)(Irp + 1) + StackSize;
1872 
1873  /* Initialize the Thread List */
1874  InitializeListHead(&Irp->ThreadListEntry);
1875 }
1876 
1877 /*
1878  * @implemented
1879  */
1880 BOOLEAN
1881 NTAPI
1883 {
1884  BOOLEAN SynchIO;
1885  BOOLEAN ForceAsync;
1886 
1887  /* If the IRP requests synchronous paging I/O, if the file object was opened
1888  for synchronous I/O, if the IRP_SYNCHRONOUS_API flag is set in the IRP
1889  the operation is synchronous */
1890  SynchIO = (IoGetCurrentIrpStackLocation(Irp)->FileObject->Flags & FO_SYNCHRONOUS_IO) ||
1891  (Irp->Flags & IRP_SYNCHRONOUS_API) || (Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO);
1892 
1893  /* If the IRP requests asynchronous paging I/O, the operation is asynchronous,
1894  even if one of the above conditions is true */
1895  ForceAsync = (Irp->Flags & IRP_PAGING_IO) && !(Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO);
1896 
1897  /* Check the flags */
1898  if (SynchIO && !ForceAsync)
1899  {
1900  /* Synch API or Paging I/O is OK, as is Sync File I/O */
1901  return TRUE;
1902  }
1903 
1904  /* Otherwise, it is an asynchronous operation. */
1905  return FALSE;
1906 }
1907 
1908 /*
1909  * @unimplemented
1910  */
1911 BOOLEAN
1912 NTAPI
1914  IN PREPARSE_DATA_BUFFER ReparseBuffer)
1915 {
1916  UNIMPLEMENTED;
1917  return FALSE;
1918 }
1919 
1920 /*
1921  * @implemented
1922  */
1923 PIRP
1924 NTAPI
1926  IN CCHAR StackSize)
1927 {
1928  PIRP AssocIrp;
1930  "%s - Associating IRP %p\n",
1931  __FUNCTION__,
1932  Irp);
1933 
1934  /* Allocate the IRP */
1935  AssocIrp = IoAllocateIrp(StackSize, FALSE);
1936  if (!AssocIrp) return NULL;
1937 
1938  /* Set the Flags */
1939  AssocIrp->Flags |= IRP_ASSOCIATED_IRP;
1940 
1941  /* Set the Thread */
1942  AssocIrp->Tail.Overlay.Thread = Irp->Tail.Overlay.Thread;
1943 
1944  /* Associate them */
1945  AssocIrp->AssociatedIrp.MasterIrp = Irp;
1946  return AssocIrp;
1947 }
1948 
1949 /*
1950  * @implemented
1951  */
1952 VOID
1953 NTAPI
1955 {
1957  "%s - Queueing IRP %p\n",
1958  __FUNCTION__,
1959  Irp);
1960 
1961  /* Use our inlined routine */
1962  IopQueueIrpToThread(Irp);
1963 }
1964 
1965 /*
1966  * @implemented
1967  * Reference: Chris Cant's "Writing WDM Device Drivers"
1968  */
1969 VOID
1970 NTAPI
1972  IN NTSTATUS Status)
1973 {
1974  UCHAR AllocationFlags;
1976  "%s - Reusing IRP %p\n",
1977  __FUNCTION__,
1978  Irp);
1979 
1980  /* Make sure it's OK to reuse it */
1981  ASSERT(!Irp->CancelRoutine);
1982  ASSERT(IsListEmpty(&Irp->ThreadListEntry));
1983 
1984  /* Get the old flags */
1985  AllocationFlags = Irp->AllocationFlags;
1986 
1987  /* Reinitialize the IRP */
1988  IoInitializeIrp(Irp, Irp->Size, Irp->StackCount);
1989 
1990  /* Duplicate the data */
1991  Irp->IoStatus.Status = Status;
1992  Irp->AllocationFlags = AllocationFlags;
1993 }
1994 
1995 /*
1996  * @implemented
1997  */
1998 VOID
1999 NTAPI
2001 {
2002  /* Set the IRP */
2003  PsGetCurrentThread()->TopLevelIrp = (ULONG_PTR)Irp;
2004 }
2005 
2006 #if defined (_WIN64)
2007 BOOLEAN
2008 NTAPI
2009 IoIs32bitProcess(
2010  IN PIRP Irp OPTIONAL)
2011 {
2012  UNIMPLEMENTED;
2013  return FALSE;
2014 }
2015 #endif
VOID NTAPI IopCompleteRequest(IN PKAPC Apc, IN PKNORMAL_ROUTINE *NormalRoutine, IN PVOID *NormalContext, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2)
Definition: irp.c:238
VOID NTAPI KeInitializeApc(IN PKAPC Apc, IN PKTHREAD Thread, IN KAPC_ENVIRONMENT TargetEnvironment, IN PKKERNEL_ROUTINE KernelRoutine, IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL, IN PKNORMAL_ROUTINE NormalRoutine, IN KPROCESSOR_MODE Mode, IN PVOID Context)
Definition: apc.c:651
PEPROCESS NTAPI IoGetRequestorProcess(IN PIRP Irp)
Definition: irp.c:1782
NTSTATUS NTAPI IoGetRequestorSessionId(IN PIRP Irp, OUT PULONG pSessionId)
Definition: irp.c:1821
CPPORT Port[4]
Definition: headless.c:34
VOID NTAPI IoCancelThreadIo(IN PETHREAD Thread)
Definition: irp.c:1146
#define IN
Definition: typedefs.h:38
DRIVER_CANCEL * PDRIVER_CANCEL
Definition: iotypes.h:2404
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:736
#define IRP_OB_QUERY_NAME
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4418
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define IRP_ALLOCATED_FIXED_SIZE
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ULONG Key
Definition: fatprocs.h:2697
PVOID NTAPI ExAllocatePoolWithQuotaTag(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag)
Definition: expool.c:2823
#define SL_PENDING_RETURNED
Definition: iotypes.h:2968
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG IoControlCode
Definition: fltkernel.h:1383
RESERVE_IRP_ALLOCATOR IopReserveIrpAllocator
Definition: irp.c:19
#define IRP_CLOSE_OPERATION
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:282
_Must_inspect_result_ _In_ BOOLEAN ChargeQuota
Definition: iofuncs.h:649
#define IRP_MJ_FLUSH_BUFFERS
static __inline VOID IopUpdateTransferCount(IN IOP_TRANSFER_TYPE Type, IN ULONG TransferCount)
Definition: io_x.h:111
VOID NTAPI IoReuseIrp(IN OUT PIRP Irp, IN NTSTATUS Status)
Definition: irp.c:1971
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
IO_PAGING_PRIORITY FASTCALL IoGetPagingIoPriority(IN PIRP Irp)
Definition: irp.c:1748
VOID NTAPI IopAbortInterruptedIrp(IN PKEVENT EventObject, IN PIRP Irp)
Definition: irp.c:67
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:51
#define IRP_CLASS_CACHE_OPERATION
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1069
#define IRP_QUOTA_CHARGED
#define IRP_MJ_SHUTDOWN
_In_ PIRP Irp
Definition: csq.h:116
VOID NTAPI IopAbortIrpKernelApc(IN PKAPC Apc)
Definition: irp.c:37
BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1625
#define TAG_IRP
Definition: vfat.h:547
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID _In_ ULONG _In_ BOOLEAN InternalDeviceIoControl
Definition: iofuncs.h:713
LONG NTSTATUS
Definition: precomp.h:26
KTHREAD Tcb
Definition: pstypes.h:1034
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1062
#define STATUS_IO_REPARSE_TAG_NOT_HANDLED
Definition: ntstatus.h:743
_In_ KPRIORITY Priority
Definition: kefuncs.h:516
VOID NTAPI IopFreeIrpKernelApc(IN PKAPC Apc, IN PKNORMAL_ROUTINE *NormalRoutine, IN PVOID *NormalContext, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2)
Definition: irp.c:25
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ ULONG _In_ ULONG OutputBufferLength
Definition: fltkernel.h:1374
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1439
#define IO_DRIVER_CANCEL_TIMEOUT
Definition: ntiologc.h:80
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
BOOLEAN NTAPI IoIsValidNameGraftingBuffer(IN PIRP Irp, IN PREPARSE_DATA_BUFFER ReparseBuffer)
Definition: irp.c:1913
PIRP NTAPI IopAllocateReserveIrp(IN CCHAR StackSize)
Definition: irp.c:573
IRP
Definition: iotypes.h:2462
BOOLEAN NTAPI IoIsOperationSynchronous(IN PIRP Irp)
Definition: irp.c:1882
VOID NTAPI IoEnqueueIrp(IN PIRP Irp)
Definition: irp.c:1247
VOID NTAPI IoQueueThreadIrp(IN PIRP Irp)
Definition: irp.c:1954
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
IoSetCancelRoutine(Irp, CancelRoutine)
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define FASTCALL
Definition: nt_native.h:50
VOID NTAPI IoInitializeIrp(IN PIRP Irp, IN USHORT PacketSize, IN CCHAR StackSize)
Definition: irp.c:1854
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
VOID NTAPI IoWriteErrorLogEntry(IN PVOID ElEntry)
Definition: error.c:620
LONG LookasideIrpFloat
Definition: ketypes.h:655
HANDLE UniqueProcessId
Definition: pstypes.h:1198
#define PAGED_CODE()
Definition: video.h:57
PSLIST_ENTRY WINAPI InterlockedPopEntrySList(PSLIST_HEADER ListHead)
Definition: interlocked.c:55
CHAR InputBuffer[80]
Definition: conmgr.c:33
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
struct LOOKASIDE_ALIGN _NPAGED_LOOKASIDE_LIST * PNPAGED_LOOKASIDE_LIST
_SEH2_TRY
Definition: create.c:4250
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
#define METHOD_IN_DIRECT
Definition: nt_native.h:595
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define FO_SYNCHRONOUS_IO
Definition: iotypes.h:1732
#define IO_REPARSE_TAG_MOUNT_POINT
Definition: iotypes.h:6874
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
UCHAR KIRQL
Definition: env_spec_w32.h:591
NTSTATUS ErrorCode
Definition: iotypes.h:1963
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
PP_LOOKASIDE_LIST PPLookasideList[16]
Definition: ketypes.h:624
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define METHOD_NEITHER
Definition: nt_native.h:597
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
long LONG
Definition: pedump.c:60
VOID NTAPI ObDereferenceObjectDeferDelete(IN PVOID Object)
Definition: obref.c:360
_In_ ULONG BufferLength
Definition: usbdlib.h:225
NTSTATUS NTAPI KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Interval OPTIONAL)
Definition: wait.c:283
_In_ CCHAR PriorityBoost
Definition: iofuncs.h:763
#define IRP_ASSOCIATED_IRP
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:434
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
_In_opt_ PDRIVER_CANCEL CancelRoutine
Definition: iofuncs.h:2696
unsigned char BOOLEAN
NTSTATUS NTAPI IopSynchronousCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: irp.c:1611
ULONG NTAPI IoGetRequestorProcessId(IN PIRP Irp)
Definition: irp.c:1805
smooth NULL
Definition: ftsmooth.c:416
#define FORCEINLINE
Definition: ntbasedef.h:221
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IoCompleteRequest
Definition: irp.c:1240
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
Definition: bufpool.h:45
FORCEINLINE VOID IopQueueIrpToThread(IN PIRP Irp)
Definition: io_x.h:49
PIO_COMPLETION_ROUTINE CompletionRoutine
Definition: iotypes.h:2957
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID OutputBuffer
Definition: iofuncs.h:713
PIRP NTAPI IoMakeAssociatedIrp(IN PIRP Irp, IN CCHAR StackSize)
Definition: irp.c:1925
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _IO_STACK_LOCATION * PIO_STACK_LOCATION
#define PtrToUlong(p)
Definition: basetsd.h:83
#define PCHAR
Definition: match.c:90
PVOID NTAPI IoAllocateErrorLogEntry(IN PVOID IoObject, IN UCHAR EntrySize)
Definition: error.c:520
DWORD Interval
Definition: netstat.c:30
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:227
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
VOID FASTCALL IofCompleteRequest(IN PIRP Irp, IN CCHAR PriorityBoost)
Definition: irp.c:1308
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
enum _IO_PAGING_PRIORITY IO_PAGING_PRIORITY
#define METHOD_OUT_DIRECT
Definition: nt_native.h:596
#define UlongToPtr(ul)
Definition: basetsd.h:98
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
LIST_ENTRY List
Definition: psmgr.c:57
if(!(yy_init))
Definition: macro.lex.yy.c:717
#define IRP_LOOKASIDE_ALLOCATION
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
#define STATUS_PENDING
Definition: ntstatus.h:82
char CCHAR
Definition: typedefs.h:50
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
#define IO_IRP_DEBUG
Definition: io.h:19
#define IRP_READ_OPERATION
volatile LONG ReserveIrpInUse
Definition: io.h:524
PIRP NTAPI IoBuildAsynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:750
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2866
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
VOID NTAPI ExReturnPoolQuota(IN PVOID P)
Definition: expool.c:1700
#define PSLIST_ENTRY
Definition: rtltypes.h:130
FORCEINLINE USHORT ExQueryDepthSList(_In_ PSLIST_HEADER SListHead)
Definition: exfuncs.h:153
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
#define NT_ERROR(Status)
Definition: umtypes.h:106
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
* PFILE_OBJECT
Definition: iotypes.h:1954
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
#define SL_INVOKE_ON_ERROR
Definition: iotypes.h:2972
#define IOTRACE(x, fmt,...)
Definition: io.h:47
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
struct _GENERAL_LOOKASIDE * L
Definition: ketypes.h:760
#define LONG_MAX
Definition: limits.h:43
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned char UCHAR
Definition: xmlstorage.h:181
#define IRP_MJ_POWER
USHORT ReparseDataLength
Definition: shellext.h:122
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define IO_TYPE_IRP
#define InterlockedDecrement
Definition: armddk.h:52
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
NTSTATUS NTAPI IopCleanupFailedIrp(IN PFILE_OBJECT FileObject, IN PKEVENT EventObject OPTIONAL, IN PVOID Buffer OPTIONAL)
Definition: irp.c:45
Definition: ketypes.h:535
Definition: typedefs.h:117
NTKERNELAPI PSLIST_ENTRY FASTCALL InterlockedPushEntrySList(IN PSLIST_HEADER ListHead, IN PSLIST_ENTRY ListEntry)
Definition: interlocked.c:82
_In_ USHORT _In_ CCHAR StackSize
Definition: iofuncs.h:1056
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ ULONG InputBufferLength
Definition: fltkernel.h:1372
#define InterlockedExchange
Definition: armddk.h:54
PIRP IopDeadIrp
Definition: irp.c:18
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
Status
Definition: gdiplustypes.h:24
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
VOID IopFreeReserveIrp(IN CCHAR PriorityBoost)
Definition: irp.c:599
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
FORCEINLINE VOID IopUnQueueIrpFromThread(IN PIRP Irp)
Definition: io_x.h:65
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
PFILE_OBJECT FileObject
Definition: iotypes.h:2812
_SEH2_END
Definition: create.c:4424
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define IRP_INPUT_OPERATION
#define IRP_BUFFERED_IO
#define InterlockedIncrement
Definition: armddk.h:53
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:935
_In_ USHORT PacketSize
Definition: iofuncs.h:1056
struct _GENERAL_LOOKASIDE * P
Definition: ketypes.h:759
unsigned short USHORT
Definition: pedump.c:61
#define IO_METHOD_FROM_CTL_CODE(C)
Definition: mup.h:16
#define SL_INVOKE_ON_SUCCESS
Definition: iotypes.h:2971
#define IoSizeOfIrp(_StackSize)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define METHOD_BUFFERED
Definition: nt_native.h:594
LONG NTAPI KeInsertQueue(IN PKQUEUE Queue, IN PLIST_ENTRY Entry)
Definition: queue.c:198
#define STATUS_REPARSE
Definition: ntstatus.h:83
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int * PULONG
Definition: retypes.h:1
PIRP NTAPI IopAllocateIrpMustSucceed(IN CCHAR StackSize)
Definition: irp.c:716
#define IRP_PAGING_IO
BOOLEAN NTAPI KeInsertQueueApc(IN PKAPC Apc, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN KPRIORITY PriorityBoost)
Definition: apc.c:735
static __inline VOID IopUnlockFileObject(IN PFILE_OBJECT FileObject)
Definition: io_x.h:36
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define DPRINT1
Definition: precomp.h:8
#define IRP_MJ_READ
Definition: rdpdr.c:46
BOOLEAN NTAPI IoCancelIrp(IN PIRP Irp)
Definition: irp.c:1101
#define IRP_DEALLOCATE_BUFFER
KEVENT WaitEvent
Definition: io.h:525
#define IsIrpSynchronous(Irp, FileObject)
Definition: io.h:116
FORCEINLINE VOID IopClearStackLocation(IN PIO_STACK_LOCATION IoStackLocation)
Definition: irp.c:1292
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define OUT
Definition: typedefs.h:39
LONG NTAPI KeReadStateEvent(IN PKEVENT Event)
Definition: eventobj.c:120
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define SL_INVOKE_ON_CANCEL
Definition: iotypes.h:2970
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2180
enum _PP_NPAGED_LOOKASIDE_NUMBER PP_NPAGED_LOOKASIDE_NUMBER
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
#define TAG_SYS_BUF
Definition: tag.h:80
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
VOID NTAPI IopDoNameTransmogrify(IN PIRP Irp, IN PFILE_OBJECT FileObject, IN PREPARSE_DATA_BUFFER DataBuffer)
Definition: file.c:170
#define IRP_SYNCHRONOUS_API
#define ULONG_PTR
Definition: config.h:101
#define IRP_CREATE_OPERATION
ULONG NTAPI MmGetSessionId(IN PEPROCESS Process)
Definition: session.c:180
#define SL_ERROR_RETURNED
Definition: iotypes.h:2969
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define POOL_QUOTA_FAIL_INSTEAD_OF_RAISE
#define __FUNCTION__
Definition: compiler.h:205
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
BOOLEAN NTAPI IopInitializeReserveIrp(IN PRESERVE_IRP_ALLOCATOR ReserveIrpAllocator)
Definition: irp.c:549
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define IRP_DEFER_IO_COMPLETION
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
VOID(NTAPI * PKNORMAL_ROUTINE)(IN PVOID NormalContext OPTIONAL, IN PVOID SystemArgument1 OPTIONAL, IN PVOID SystemArgument2 OPTIONAL)
Definition: ketypes.h:632
#define IO_REMOUNT
Definition: iotypes.h:511
#define IRP_WRITE_OPERATION
#define KeGetCurrentThread
Definition: hal.h:44
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2710
VOID NTAPI IopDisassociateThreadIrp(VOID)
Definition: irp.c:115
IoMarkIrpPending(Irp)
#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE
Definition: iotypes.h:6856
LIST_ENTRY IrpList
Definition: pstypes.h:1075
#define APC_LEVEL
Definition: env_spec_w32.h:695
NTSTATUS FASTCALL IofCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1258
struct _REPARSE_DATA_BUFFER * PREPARSE_DATA_BUFFER
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:107
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define IRP_SYNCHRONOUS_PAGING_IO
LONGLONG QuadPart
Definition: typedefs.h:112
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
IN BOOLEAN Wait
Definition: fatprocs.h:1529
VOID NTAPI IopCleanupIrp(IN PIRP Irp, IN PFILE_OBJECT FileObject)
Definition: irp.c:191
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68