ReactOS  0.4.14-dev-608-gd495a4f
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,
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 */
59 
60  /* Now dereference it and return */
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 */
77 
78  /* Check if nobody completed it yet */
79  if (!KeReadStateEvent(EventObject))
80  {
81  /* First, cancel it */
82  CancelResult = IoCancelIrp(Irp);
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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... */
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 &&
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,
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 */
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 */
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 */
577  {
578  return NULL;
579  }
580 
581  /* Now, wait until the IRP becomes available and reserve it immediately */
583  {
585  Executive,
586  KernelMode,
587  FALSE,
588  NULL);
589  }
590 
591  /* It's ours! Initialize it */
593 
594  /* And return it to the caller */
596 }
597 
598 VOID
600 {
601  /* Mark we don't use the IRP anymore */
603 
604  /* And set the event if someone is waiting on the IRP */
606 }
607 
608 /* FUNCTIONS *****************************************************************/
609 
610 /*
611  * @implemented
612  */
613 PIRP
614 NTAPI
617 {
618  PIRP Irp = NULL;
620  PKPRCB Prcb;
621  UCHAR Flags = 0;
624 
625  /* Set Charge Quota Flag */
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 */
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 */
691 
692  /* In this case there is no charge quota */
694  }
695 
696  /* Now Initialize it */
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 */
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 */
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 */
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 */
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 */
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 */
897  if (!Irp) return NULL;
898 
899  /* Get the Stack */
900  StackPtr = IoGetNextIrpStackLocation(Irp);
901 
902  /* Set the DevCtl Type */
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 */
915  {
916  /* Buffered I/O */
917  case METHOD_BUFFERED:
918 
919  /* Select the right Buffer Length */
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,
945  }
946 
947  /* Write the flags */
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 =
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,
985 
986  /* Write the flags */
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,
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,
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();
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,
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 */
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 */
1113  Irp->Cancel = TRUE;
1114 
1115  /* Clear the cancel routine and get the old one */
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,
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 */
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. */
1157 
1159  "%s - Canceling IRPs for Thread %p\n",
1160  __FUNCTION__,
1161  Thread);
1162 
1163  /* Raise to APC to protect the IrpList */
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 */
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 */
1206  }
1207 
1208  /* We're done, lower the IRQL */
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 */
1238 }
1239 
1240 #define IoCompleteRequest IofCompleteRequest
1241 
1242 /*
1243  * @implemented
1244  */
1245 VOID
1246 NTAPI
1248 {
1249  /* This is the same as calling IoQueueThreadIrp */
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 */
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 */
1402  }
1403 
1404  /* Call the completion routine */
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 */
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 */
1482  {
1483  /* Set the I/O Status and Signal the Event */
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  */
1495  {
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);
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 */
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 */
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++;
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  {
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 */
1758  {
1759  /* High priority */
1761  }
1762  else if (Flags & IRP_PAGING_IO)
1763  {
1764  /* Normal priority */
1766  }
1767  else
1768  {
1769  /* Invalid -- not a paging IRP */
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 */
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);
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 */
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 */
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:2405
#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:790
#define IRP_OB_QUERY_NAME
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
#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:2931
#define SL_PENDING_RETURNED
Definition: iotypes.h:2969
_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:68
#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:542
#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:2463
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
#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:1733
#define IO_REPARSE_TAG_MOUNT_POINT
Definition: iotypes.h:6875
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
UCHAR KIRQL
Definition: env_spec_w32.h:591
NTSTATUS ErrorCode
Definition: iotypes.h:1964
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
PP_LOOKASIDE_LIST PPLookasideList[16]
Definition: ketypes.h:624
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#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:435
#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:2958
_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
#define UlongToPtr(u)
Definition: config.h:106
#define PtrToUlong(u)
Definition: config.h:107
struct _IO_STACK_LOCATION * PIO_STACK_LOCATION
#define PCHAR
Definition: match.c:90
PVOID NTAPI IoAllocateErrorLogEntry(IN PVOID IoObject, IN UCHAR EntrySize)
Definition: error.c:520
DWORD Interval
Definition: netstat.c:33
_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 _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
LIST_ENTRY List
Definition: psmgr.c:57
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define IRP_LOOKASIDE_ALLOCATION
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#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:2867
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:1798
#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:1955
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
#define SL_INVOKE_ON_ERROR
Definition: iotypes.h:2973
#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:166
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:2813
_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:11
#define SL_INVOKE_ON_SUCCESS
Definition: iotypes.h:2972
#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
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
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:2971
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2181
enum _PP_NPAGED_LOOKASIDE_NUMBER PP_NPAGED_LOOKASIDE_NUMBER
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
#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:2970
#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 _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:512
#define IRP_WRITE_OPERATION
#define KeGetCurrentThread
Definition: hal.h:44
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2938
VOID NTAPI IopDisassociateThreadIrp(VOID)
Definition: irp.c:115
IoMarkIrpPending(Irp)
#define __FUNCTION__
Definition: types.h:112
#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE
Definition: iotypes.h:6857
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
#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