ReactOS 0.4.17-dev-650-gd0e71de
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
23VOID
26 IN PKNORMAL_ROUTINE *NormalRoutine,
27 IN PVOID *NormalContext,
30{
31 /* Free the IRP */
32 IoFreeIrp(CONTAINING_RECORD(Apc, IRP, Tail.Apc));
33}
34
35VOID
38{
39 /* Free the IRP */
40 IoFreeIrp(CONTAINING_RECORD(Apc, IRP, Tail.Apc));
41}
42
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 */
56
57 /* If this was a file opened for synch I/O, then unlock it */
59
60 /* Now dereference it and return */
63}
64
65VOID
68 IN PIRP Irp)
69{
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,
102 FALSE,
103 NULL);
104 }
105 }
106 else
107 {
108 /* We got preempted, so give up */
110 }
111}
112
113VOID
114NTAPI
116{
117 KIRQL OldIrql, LockIrql;
118 PETHREAD IrpThread;
119 PLIST_ENTRY IrpEntry;
120 PIO_ERROR_LOG_PACKET ErrorLogEntry;
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",
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 */
164 if (IopDeadIrp->CurrentLocation <= IopDeadIrp->StackCount)
165 {
166 /* Get the device object */
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 */
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
189VOID
190NTAPI
193{
194 PMDL Mdl;
196 "%s - Cleaning IRP %p for %p\n",
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_IOBUF);
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
236static
237VOID
239{
240 /* Check for UserIos */
241 if (Irp->UserIosb != NULL)
242 {
243 /* Use SEH to make sure we don't write somewhere invalid */
245 {
246#if defined(_WIN64) && defined(BUILD_WOW64_ENABLED)
247 PIO_STATUS_BLOCK32 Iosb32 = (PIO_STATUS_BLOCK32)Irp->UserIosb->Pointer;
248
249 /*
250 * If this is a 32-bit process, and UserIosb falls within the
251 * 32-bit address space, assume UserIosb->Pointer is a 32-bit IOSB
252 * that has to be filled.
253 */
254 if (Irp->RequestorMode == UserMode &&
255 /*
256 * This is an APC - we're running in the correct thread context,
257 * and Irp->Tail is trashed. Don't bother with getting the thread
258 * from the IRP then. The process mode still should be checked.
259 */
260 IoIs32bitProcess(NULL) &&
261 Iosb32 != NULL && (ULONG_PTR)Iosb32 <= MAXULONG)
262 {
263 InterlockedExchangePointer(&Irp->UserIosb->Pointer, NULL);
264
265 Iosb32->Information = Irp->IoStatus.Information;
266 Iosb32->Status = Irp->IoStatus.Status;
267 }
268 else
269#endif
270 {
271 *Irp->UserIosb = Irp->IoStatus;
272 }
273 }
275 {
276 /* Ignore any error */
277 }
278 _SEH2_END;
279 }
280}
281
282VOID
283NTAPI
285 IN PKNORMAL_ROUTINE* NormalRoutine,
286 IN PVOID* NormalContext,
289{
291 PIRP Irp;
292 PMDL Mdl, NextMdl;
293 PVOID Port = NULL, Key = NULL;
294 BOOLEAN SignaledCreateRequest = FALSE;
295
296 /* Get data from the APC */
298 Irp = CONTAINING_RECORD(Apc, IRP, Tail.Apc);
300 "%s - Completing IRP %p for %p\n",
302 Irp,
303 FileObject);
304
305 /* Sanity check */
306 ASSERT(Irp->IoStatus.Status != (NTSTATUS)0xFFFFFFFF);
307
308 /* Check if we have a file object */
309 if (*SystemArgument2)
310 {
311 /* Check if we're reparsing */
312 if ((Irp->IoStatus.Status == STATUS_REPARSE) &&
313 (Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT))
314 {
315 PREPARSE_DATA_BUFFER ReparseData;
316
318
322
323 IopDoNameTransmogrify(Irp, FileObject, ReparseData);
324 }
325 }
326
327 /* Handle Buffered case first */
328 if (Irp->Flags & IRP_BUFFERED_IO)
329 {
330 /* Check if we have an input buffer and if we succeeded */
331 if ((Irp->Flags & IRP_INPUT_OPERATION) &&
332 (Irp->IoStatus.Status != STATUS_VERIFY_REQUIRED) &&
333 !(NT_ERROR(Irp->IoStatus.Status)))
334 {
336 {
337 /* Copy the buffer back to the user */
338 RtlCopyMemory(Irp->UserBuffer,
339 Irp->AssociatedIrp.SystemBuffer,
340 Irp->IoStatus.Information);
341 }
343 {
344 /* Fail the IRP */
345 Irp->IoStatus.Status = _SEH2_GetExceptionCode();
346 }
347 _SEH2_END;
348 }
349
350 /* Also check if we should de-allocate it */
351 if (Irp->Flags & IRP_DEALLOCATE_BUFFER)
352 {
353 /* Deallocate it */
354 ExFreePool(Irp->AssociatedIrp.SystemBuffer);
355 }
356 }
357
358 /* Now we got rid of these two... */
360
361 /* Check if there's an MDL */
362 for (Mdl = Irp->MdlAddress; Mdl; Mdl = NextMdl)
363 {
364 /* Free it */
365 NextMdl = Mdl->Next;
366 IoFreeMdl(Mdl);
367 }
368
369 /* No MDLs left */
370 Irp->MdlAddress = NULL;
371
372 /*
373 * Check if either the request was completed without any errors
374 * (but warnings are OK!), or if it was completed with an error, but
375 * did return from a pending I/O Operation and is not synchronous.
376 */
377 if (!NT_ERROR(Irp->IoStatus.Status) ||
378 (Irp->PendingReturned &&
380 {
381 /* Get any information we need from the FO before we kill it */
382 if ((FileObject) && (FileObject->CompletionContext))
383 {
384 /* Save Completion Data */
385 Port = FileObject->CompletionContext->Port;
386 Key = FileObject->CompletionContext->Key;
387 }
388
390
391 /* Check if we have an event or a file object */
392 if (Irp->UserEvent)
393 {
394 /* At the very least, this is a PKEVENT, so signal it always */
395 KeSetEvent(Irp->UserEvent, 0, FALSE);
396
397 /* Check if we also have a File Object */
398 if (FileObject)
399 {
400 /* Check if this is an Asynch API */
401 if (!(Irp->Flags & IRP_SYNCHRONOUS_API))
402 {
403 /* Dereference the event */
404 ObDereferenceObject(Irp->UserEvent);
405 }
406
407 /*
408 * Now, if this is a Synch I/O File Object, then this event is
409 * NOT an actual Executive Event, so we won't dereference it,
410 * and instead, we will signal the File Object
411 */
412 if ((FileObject->Flags & FO_SYNCHRONOUS_IO) &&
413 !(Irp->Flags & IRP_OB_QUERY_NAME))
414 {
415 /* Signal the file object and set the status */
416 KeSetEvent(&FileObject->Event, 0, FALSE);
417 FileObject->FinalStatus = Irp->IoStatus.Status;
418 }
419
420 /*
421 * This could also be a create operation, in which case we want
422 * to make sure there's no APC fired.
423 */
424 if (Irp->Flags & IRP_CREATE_OPERATION)
425 {
426 /* Clear the APC Routine and remember this */
427 Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
428 SignaledCreateRequest = TRUE;
429 }
430 }
431 }
432 else if (FileObject)
433 {
434 /* Signal the file object and set the status */
435 KeSetEvent(&FileObject->Event, 0, FALSE);
436 FileObject->FinalStatus = Irp->IoStatus.Status;
437
438 /*
439 * This could also be a create operation, in which case we want
440 * to make sure there's no APC fired.
441 */
442 if (Irp->Flags & IRP_CREATE_OPERATION)
443 {
444 /* Clear the APC Routine and remember this */
445 Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
446 SignaledCreateRequest = TRUE;
447 }
448 }
449
450 /* Update transfer count for everything but create operation */
451 if (!(Irp->Flags & IRP_CREATE_OPERATION))
452 {
453 if (Irp->Flags & IRP_WRITE_OPERATION)
454 {
455 /* Update write transfer count */
457 (ULONG)Irp->IoStatus.Information);
458 }
459 else if (Irp->Flags & IRP_READ_OPERATION)
460 {
461 /* Update read transfer count */
463 (ULONG)Irp->IoStatus.Information);
464 }
465 else
466 {
467 /* Update other transfer count */
469 (ULONG)Irp->IoStatus.Information);
470 }
471 }
472
473 /* Now that we've signaled the events, de-associate the IRP */
475
476 /* Now check if a User APC Routine was requested */
477 if (Irp->Overlay.AsynchronousParameters.UserApcRoutine)
478 {
479 /* Initialize it */
480 KeInitializeApc(&Irp->Tail.Apc,
486 Overlay.AsynchronousParameters.UserApcRoutine,
487 Irp->RequestorMode,
488 Irp->
489 Overlay.AsynchronousParameters.UserApcContext);
490
491 /* Queue it */
492 KeInsertQueueApc(&Irp->Tail.Apc, Irp->UserIosb, NULL, 2);
493 }
494 else if ((Port) &&
495 (Irp->Overlay.AsynchronousParameters.UserApcContext))
496 {
497 /* We have an I/O Completion setup... create the special Overlay */
498 Irp->Tail.CompletionKey = Key;
499 Irp->Tail.Overlay.PacketType = IopCompletionPacketIrp;
500 KeInsertQueue(Port, &Irp->Tail.Overlay.ListEntry);
501 }
502 else
503 {
504 /* Free the IRP since we don't need it anymore */
505 IoFreeIrp(Irp);
506 }
507
508 /* Check if we have a file object that wasn't part of a create */
509 if ((FileObject) && !(SignaledCreateRequest))
510 {
511 /* Dereference it, since it's not needed anymore either */
513 }
514 }
515 else
516 {
517 /*
518 * Either we didn't return from the request, or we did return but this
519 * request was synchronous.
520 */
521 if ((Irp->PendingReturned) && (FileObject))
522 {
523 /* So we did return with a synch operation, was it the IRP? */
524 if (Irp->Flags & IRP_SYNCHRONOUS_API)
525 {
526 /* Yes, this IRP was synchronous, so return the I/O Status */
527 *Irp->UserIosb = Irp->IoStatus;
528
529 /* Now check if the user gave an event */
530 if (Irp->UserEvent)
531 {
532 /* Signal it */
533 KeSetEvent(Irp->UserEvent, 0, FALSE);
534 }
535 else
536 {
537 /* No event was given, so signal the FO instead */
538 KeSetEvent(&FileObject->Event, 0, FALSE);
539 }
540 }
541 else
542 {
543 /*
544 * It's not the IRP that was synchronous, it was the FO
545 * that was opened this way. Signal its event.
546 */
547 FileObject->FinalStatus = Irp->IoStatus.Status;
548 KeSetEvent(&FileObject->Event, 0, FALSE);
549 }
550 }
551
552 /* Now that we got here, we do this for incomplete I/Os as well */
553 if ((FileObject) && !(Irp->Flags & IRP_CREATE_OPERATION))
554 {
555 /* Dereference the File Object unless this was a create */
557 }
558
559 /*
560 * Check if this was an Executive Event (remember that we know this
561 * by checking if the IRP is synchronous)
562 */
563 if ((Irp->UserEvent) &&
564 (FileObject) &&
565 !(Irp->Flags & IRP_SYNCHRONOUS_API))
566 {
567 /* This isn't a PKEVENT, so dereference it */
568 ObDereferenceObject(Irp->UserEvent);
569 }
570
571 /* Now that we've signaled the events, de-associate the IRP */
573
574 /* Free the IRP as well */
575 IoFreeIrp(Irp);
576 }
577}
578
580NTAPI
582{
583 /* Our allocated stack size */
584 ReserveIrpAllocator->StackSize = 20;
585
586 /* Allocate the IRP now */
587 ReserveIrpAllocator->ReserveIrp = IoAllocateIrp(ReserveIrpAllocator->StackSize, FALSE);
588 /* If we cannot, abort system boot */
589 if (ReserveIrpAllocator->ReserveIrp == NULL)
590 {
591 return FALSE;
592 }
593
594 /* It's not in use */
595 ReserveIrpAllocator->ReserveIrpInUse = 0;
596 /* And init the event */
597 KeInitializeEvent(&ReserveIrpAllocator->WaitEvent, SynchronizationEvent, FALSE);
598
599 /* All good, keep booting */
600 return TRUE;
601}
602
603PIRP
604NTAPI
606{
607 /* If we need a stack size higher than what was allocated, then fail */
609 {
610 return NULL;
611 }
612
613 /* Now, wait until the IRP becomes available and reserve it immediately */
615 {
617 Executive,
619 FALSE,
620 NULL);
621 }
622
623 /* It's ours! Initialize it */
625
626 /* And return it to the caller */
628}
629
630VOID
632{
633 /* Mark we don't use the IRP anymore */
635
636 /* And set the event if someone is waiting on the IRP */
638}
639
640/* FUNCTIONS *****************************************************************/
641
642/*
643 * @implemented
644 */
645PIRP
646NTAPI
649{
650 PIRP Irp = NULL;
652 PKPRCB Prcb;
653 UCHAR Flags = 0;
656
657 /* Set Charge Quota Flag */
659
660 /* Get the PRCB */
661 Prcb = KeGetCurrentPrcb();
662
663 /* Figure out which Lookaside List to use */
664 if ((StackSize <= 8) && (ChargeQuota == FALSE || Prcb->LookasideIrpFloat > 0))
665 {
666 /* Set Fixed Size Flag */
668
669 /* See if we should use big list */
670 if (StackSize != 1)
671 {
672 Size = IoSizeOfIrp(8);
673 ListType = LookasideLargeIrpList;
674 }
675
676 /* Get the P List First */
677 List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[ListType].P;
678
679 /* Attempt allocation */
680 List->L.TotalAllocates++;
681 Irp = (PIRP)InterlockedPopEntrySList(&List->L.ListHead);
682
683 /* Check if the P List failed */
684 if (!Irp)
685 {
686 /* Let the balancer know */
687 List->L.AllocateMisses++;
688
689 /* Try the L List */
690 List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[ListType].L;
691 List->L.TotalAllocates++;
692 Irp = (PIRP)InterlockedPopEntrySList(&List->L.ListHead);
693 }
694 }
695
696 /* Check if we have to use the pool */
697 if (!Irp)
698 {
699 /* Did we try lookaside and fail? */
700 if (Flags & IRP_ALLOCATED_FIXED_SIZE) List->L.AllocateMisses++;
701
702 /* Check if we should charge quota */
703 if (ChargeQuota)
704 {
706 Size,
707 TAG_IRP);
708 }
709 else
710 {
711 /* Allocate the IRP with no quota charge */
713 }
714
715 /* Make sure it was sucessful */
716 if (!Irp) return NULL;
717 }
718 else if (Flags & IRP_QUOTA_CHARGED)
719 {
720 /* Decrement lookaside float */
723
724 /* In this case there is no charge quota */
725 Flags &= ~IRP_QUOTA_CHARGED;
726 }
727
728 /* Now Initialize it */
730
731 /* Set the Allocation Flags */
732 Irp->AllocationFlags = Flags;
733
734 /* Return it */
736 "%s - Allocated IRP %p with allocation flags %lx\n",
738 Irp,
739 Flags);
740 return Irp;
741}
742
743/*
744 * @implemented
745 */
746PIRP
747NTAPI
749{
750 LONG i;
751 PIRP Irp;
753
754 /* Try to get an IRP */
756 if (Irp)
757 return Irp;
758
759 /* If we fail, start looping till we may get one */
760 i = LONG_MAX;
761 do {
762 i--;
763
764 /* First, sleep for 10ms */
765 Sleep.QuadPart = -10 * 1000 * 10;
767
768 /* Then, retry allocation */
770 if (Irp)
771 return Irp;
772 } while (i > 0);
773
774 return Irp;
775}
776
777/*
778 * @implemented
779 */
780PIRP
781NTAPI
788{
789 PIRP Irp;
790 PIO_STACK_LOCATION StackPtr;
791
792 /* Allocate IRP */
793 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
794 if (!Irp) return NULL;
795
796 /* Get the Stack */
797 StackPtr = IoGetNextIrpStackLocation(Irp);
798
799 /* Write the Major function and then deal with it */
800 StackPtr->MajorFunction = (UCHAR)MajorFunction;
801
802 /* Do not handle the following here */
807 {
808 /* Check if this is Buffered IO */
809 if (DeviceObject->Flags & DO_BUFFERED_IO)
810 {
811 /* Allocate the System Buffer */
812 Irp->AssociatedIrp.SystemBuffer =
814 if (!Irp->AssociatedIrp.SystemBuffer)
815 {
816 /* Free the IRP and fail */
817 IoFreeIrp(Irp);
818 return NULL;
819 }
820
821 /* Set flags */
823
824 /* Handle special IRP_MJ_WRITE Case */
826 {
827 /* Copy the buffer data */
828 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, Buffer, Length);
829 }
830 else
831 {
832 /* Set the Input Operation flag and set this as a User Buffer */
833 Irp->Flags |= IRP_INPUT_OPERATION;
834 Irp->UserBuffer = Buffer;
835 }
836 }
837 else if (DeviceObject->Flags & DO_DIRECT_IO)
838 {
839 /* Use an MDL for Direct I/O */
840 Irp->MdlAddress = IoAllocateMdl(Buffer,
841 Length,
842 FALSE,
843 FALSE,
844 NULL);
845 if (!Irp->MdlAddress)
846 {
847 /* Free the IRP and fail */
848 IoFreeIrp(Irp);
849 return NULL;
850 }
851
852 /* Probe and Lock */
854 {
855 /* Do the probe */
856 MmProbeAndLockPages(Irp->MdlAddress,
860 }
862 {
863 /* Free the IRP and its MDL */
864 IoFreeMdl(Irp->MdlAddress);
865 IoFreeIrp(Irp);
866
867 /* Fail */
868 _SEH2_YIELD(return NULL);
869 }
870 _SEH2_END;
871 }
872 else
873 {
874 /* Neither, use the buffer */
875 Irp->UserBuffer = Buffer;
876 }
877
878 /* Check if this is a read */
880 {
881 /* Set the parameters for a read */
882 StackPtr->Parameters.Read.Length = Length;
883 StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
884 }
885 else if (MajorFunction == IRP_MJ_WRITE)
886 {
887 /* Otherwise, set write parameters */
888 StackPtr->Parameters.Write.Length = Length;
889 StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
890 }
891 }
892
893 /* Set the Current Thread and IOSB */
894 Irp->UserIosb = IoStatusBlock;
895 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
896
897 /* Return the IRP */
899 "%s - Built IRP %p with Major, Buffer, DO %lx %p %p\n",
901 Irp,
903 Buffer,
905 return Irp;
906}
907
908/*
909 * @implemented
910 */
911PIRP
912NTAPI
922{
923 PIRP Irp;
924 PIO_STACK_LOCATION StackPtr;
926
927 /* Allocate IRP */
928 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
929 if (!Irp) return NULL;
930
931 /* Get the Stack */
932 StackPtr = IoGetNextIrpStackLocation(Irp);
933
934 /* Set the DevCtl Type */
938
939 /* Set the IOCTL Data */
940 StackPtr->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
941 StackPtr->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
942 StackPtr->Parameters.DeviceIoControl.OutputBufferLength =
944
945 /* Handle the Methods */
947 {
948 /* Buffered I/O */
949 case METHOD_BUFFERED:
950
951 /* Select the right Buffer Length */
954
955 /* Make sure there is one */
956 if (BufferLength)
957 {
958 /* Allocate the System Buffer */
959 Irp->AssociatedIrp.SystemBuffer =
962 TAG_IOBUF);
963 if (!Irp->AssociatedIrp.SystemBuffer)
964 {
965 /* Free the IRP and fail */
966 IoFreeIrp(Irp);
967 return NULL;
968 }
969
970 /* Check if we got a buffer */
971 if (InputBuffer)
972 {
973 /* Copy into the System Buffer */
974 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
977 }
978
979 /* Write the flags */
981 if (OutputBuffer) Irp->Flags |= IRP_INPUT_OPERATION;
982
983 /* Save the Buffer */
984 Irp->UserBuffer = OutputBuffer;
985 }
986 else
987 {
988 /* Clear the Flags and Buffer */
989 Irp->Flags = 0;
990 Irp->UserBuffer = NULL;
991 }
992 break;
993
994 /* Direct I/O */
995 case METHOD_IN_DIRECT:
997
998 /* Check if we got an input buffer */
999 if (InputBuffer)
1000 {
1001 /* Allocate the System Buffer */
1002 Irp->AssociatedIrp.SystemBuffer =
1005 TAG_IOBUF);
1006 if (!Irp->AssociatedIrp.SystemBuffer)
1007 {
1008 /* Free the IRP and fail */
1009 IoFreeIrp(Irp);
1010 return NULL;
1011 }
1012
1013 /* Copy into the System Buffer */
1014 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
1017
1018 /* Write the flags */
1020 }
1021 else
1022 {
1023 /* Clear the flags */
1024 Irp->Flags = 0;
1025 }
1026
1027 /* Check if we got an output buffer */
1028 if (OutputBuffer)
1029 {
1030 /* Allocate the System Buffer */
1031 Irp->MdlAddress = IoAllocateMdl(OutputBuffer,
1033 FALSE,
1034 FALSE,
1035 Irp);
1036 if (!Irp->MdlAddress)
1037 {
1038 /* Free the IRP and fail */
1039 IoFreeIrp(Irp);
1040 return NULL;
1041 }
1042
1043 /* Probe and Lock */
1044 _SEH2_TRY
1045 {
1046 /* Do the probe */
1047 MmProbeAndLockPages(Irp->MdlAddress,
1048 KernelMode,
1052 }
1054 {
1055 /* Free the MDL */
1056 IoFreeMdl(Irp->MdlAddress);
1057
1058 /* Free the input buffer and IRP */
1059 if (InputBuffer) ExFreePool(Irp->AssociatedIrp.SystemBuffer);
1060 IoFreeIrp(Irp);
1061
1062 /* Fail */
1063 _SEH2_YIELD(return NULL);
1064 }
1065 _SEH2_END;
1066 }
1067 break;
1068
1069 case METHOD_NEITHER:
1070
1071 /* Just save the Buffer */
1072 Irp->UserBuffer = OutputBuffer;
1073 StackPtr->Parameters.DeviceIoControl.Type3InputBuffer = InputBuffer;
1074 }
1075
1076 /* Now write the Event and IoSB */
1077 Irp->UserIosb = IoStatusBlock;
1078 Irp->UserEvent = Event;
1079
1080 /* Sync IRPs are queued to requestor thread's irp cancel/cleanup list */
1081 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
1083
1084 /* Return the IRP */
1086 "%s - Built IRP %p with IOCTL, Buffers, DO %lx %p %p %p\n",
1088 Irp,
1092 DeviceObject);
1093 return Irp;
1094}
1095
1096/*
1097 * @implemented
1098 */
1099PIRP
1100NTAPI
1103 IN PVOID Buffer,
1104 IN ULONG Length,
1108{
1109 PIRP Irp;
1110
1111 /* Do the big work to set up the IRP */
1114 Buffer,
1115 Length,
1117 IoStatusBlock );
1118 if (!Irp) return NULL;
1119
1120 /* Set the Event which makes it Syncronous */
1121 Irp->UserEvent = Event;
1122
1123 /* Sync IRPs are queued to requestor thread's irp cancel/cleanup list */
1125 return Irp;
1126}
1127
1128/*
1129 * @implemented
1130 */
1131BOOLEAN
1132NTAPI
1134{
1135 KIRQL OldIrql;
1138 "%s - Canceling IRP %p\n",
1140 Irp);
1141 ASSERT(Irp->Type == IO_TYPE_IRP);
1142
1143 /* Acquire the cancel lock and cancel the IRP */
1145 Irp->Cancel = TRUE;
1146
1147 /* Clear the cancel routine and get the old one */
1149 if (CancelRoutine)
1150 {
1151 /* We had a routine, make sure the IRP isn't completed */
1152 if (Irp->CurrentLocation > (Irp->StackCount + 1))
1153 {
1154 /* It is, bugcheck */
1155 KeBugCheckEx(CANCEL_STATE_IN_COMPLETED_IRP,
1156 (ULONG_PTR)Irp,
1158 0,
1159 0);
1160 }
1161
1162 /* Set the cancel IRQL And call the routine */
1163 Irp->CancelIrql = OldIrql;
1165 return TRUE;
1166 }
1167
1168 /* Otherwise, release the cancel lock and fail */
1170 return FALSE;
1171}
1172
1173/*
1174 * @implemented
1175 */
1176VOID
1177NTAPI
1179{
1180 KIRQL OldIrql;
1181 ULONG Retries = 3000;
1183 PLIST_ENTRY ListHead, NextEntry;
1184 PIRP Irp;
1185 PAGED_CODE();
1186
1187 /* Windows isn't using given thread, but using current. */
1189
1191 "%s - Canceling IRPs for Thread %p\n",
1193 Thread);
1194
1195 /* Raise to APC to protect the IrpList */
1197
1198 /* Start by cancelling all the IRPs in the current thread queue. */
1199 ListHead = &Thread->IrpList;
1200 NextEntry = ListHead->Flink;
1201 while (ListHead != NextEntry)
1202 {
1203 /* Get the IRP */
1204 Irp = CONTAINING_RECORD(NextEntry, IRP, ThreadListEntry);
1205
1206 /* Cancel it */
1208
1209 /* Move to the next entry */
1210 NextEntry = NextEntry->Flink;
1211 }
1212
1213 /* Wait 100 milliseconds */
1214 Interval.QuadPart = -1000000;
1215
1216 /* Wait till all the IRPs are completed or cancelled. */
1217 while (!IsListEmpty(&Thread->IrpList))
1218 {
1219 /* Now we can lower */
1221
1222 /* Wait a short while and then look if all our IRPs were completed. */
1224
1225 /*
1226 * Don't stay here forever if some broken driver doesn't complete
1227 * the IRP.
1228 */
1229 if (!(Retries--))
1230 {
1231 /* Print out a message and remove the IRP */
1232 DPRINT1("Broken driver did not complete!\n");
1234 }
1235
1236 /* Raise the IRQL Again */
1238 }
1239
1240 /* We're done, lower the IRQL */
1242}
1243
1244/*
1245 * @implemented
1246 */
1247#undef IoCallDriver
1249NTAPI
1251 IN PIRP Irp)
1252{
1253 /* Call fastcall */
1255}
1256
1257#define IoCallDriver IofCallDriver
1258
1259/*
1260 * @implemented
1261 */
1262#undef IoCompleteRequest
1263VOID
1264NTAPI
1267{
1268 /* Call the fastcall */
1270}
1271
1272#define IoCompleteRequest IofCompleteRequest
1273
1274/*
1275 * @implemented
1276 */
1277VOID
1278NTAPI
1280{
1281 /* This is the same as calling IoQueueThreadIrp */
1283}
1284
1285/*
1286 * @implemented
1287 */
1291 IN PIRP Irp)
1292{
1294 PIO_STACK_LOCATION StackPtr;
1295
1296 /* Make sure this is a valid IRP */
1297 ASSERT(Irp->Type == IO_TYPE_IRP);
1298
1299 /* Get the Driver Object */
1300 DriverObject = DeviceObject->DriverObject;
1301
1302 /* Decrease the current location and check if */
1303 Irp->CurrentLocation--;
1304 if (Irp->CurrentLocation <= 0)
1305 {
1306 /* This IRP ran out of stack, bugcheck */
1307 KeBugCheckEx(NO_MORE_IRP_STACK_LOCATIONS, (ULONG_PTR)Irp, 0, 0, 0);
1308 }
1309
1310 /* Now update the stack location */
1311 StackPtr = IoGetNextIrpStackLocation(Irp);
1312 Irp->Tail.Overlay.CurrentStackLocation = StackPtr;
1313
1314 /* Get the Device Object */
1315 StackPtr->DeviceObject = DeviceObject;
1316
1317 /* Call it */
1318 return DriverObject->MajorFunction[StackPtr->MajorFunction](DeviceObject,
1319 Irp);
1320}
1321
1323VOID
1325{
1329 IoStackLocation->Parameters.Others.Argument1 = 0;
1330 IoStackLocation->Parameters.Others.Argument2 = 0;
1331 IoStackLocation->Parameters.Others.Argument3 = 0;
1333}
1334
1335/*
1336 * @implemented
1337 */
1338VOID
1342{
1343 PIO_STACK_LOCATION StackPtr, LastStackPtr;
1348 PMDL Mdl, NextMdl;
1349 ULONG MasterCount;
1350 PIRP MasterIrp;
1351 ULONG Flags;
1353 PREPARSE_DATA_BUFFER DataBuffer = NULL;
1355 "%s - Completing IRP %p\n",
1357 Irp);
1358
1359 /* Make sure this IRP isn't getting completed twice or is invalid */
1360 if ((Irp->CurrentLocation) > (Irp->StackCount + 1))
1361 {
1362 /* Bugcheck */
1363 KeBugCheckEx(MULTIPLE_IRP_COMPLETE_REQUESTS, (ULONG_PTR)Irp, 0, 0, 0);
1364 }
1365
1366 /* Some sanity checks */
1367 ASSERT(Irp->Type == IO_TYPE_IRP);
1368 ASSERT(!Irp->CancelRoutine);
1369 ASSERT(Irp->IoStatus.Status != STATUS_PENDING);
1370 ASSERT(Irp->IoStatus.Status != (NTSTATUS)0xFFFFFFFF);
1371
1372 /* Get the last stack */
1373 LastStackPtr = (PIO_STACK_LOCATION)(Irp + 1);
1374 if (LastStackPtr->Control & SL_ERROR_RETURNED)
1375 {
1376 /* Get the error code */
1377 ErrorCode = PtrToUlong(LastStackPtr->Parameters.Others.Argument4);
1378 }
1379
1380 /*
1381 * Start the loop with the current stack and point the IRP to the next stack
1382 * and then keep incrementing the stack as we loop through. The IRP should
1383 * always point to the next stack location w.r.t the one currently being
1384 * analyzed, so completion routine code will see the appropriate value.
1385 * Because of this, we must loop until the current stack location is +1 of
1386 * the stack count, because when StackPtr is at the end, CurrentLocation is +1.
1387 */
1388 for (StackPtr = IoGetCurrentIrpStackLocation(Irp),
1389 Irp->CurrentLocation++,
1390 Irp->Tail.Overlay.CurrentStackLocation++;
1391 Irp->CurrentLocation <= (Irp->StackCount + 1);
1392 StackPtr++,
1393 Irp->CurrentLocation++,
1394 Irp->Tail.Overlay.CurrentStackLocation++)
1395 {
1396 /* Set Pending Returned */
1397 Irp->PendingReturned = StackPtr->Control & SL_PENDING_RETURNED;
1398
1399 /* Check if we failed */
1400 if (!NT_SUCCESS(Irp->IoStatus.Status))
1401 {
1402 /* Check if it was changed by a completion routine */
1403 if (Irp->IoStatus.Status != ErrorCode)
1404 {
1405 /* Update the error for the current stack */
1406 ErrorCode = Irp->IoStatus.Status;
1407 StackPtr->Control |= SL_ERROR_RETURNED;
1408 LastStackPtr->Parameters.Others.Argument4 = UlongToPtr(ErrorCode);
1409 LastStackPtr->Control |= SL_ERROR_RETURNED;
1410 }
1411 }
1412
1413 /* Check if there is a Completion Routine to Call */
1414 if ((NT_SUCCESS(Irp->IoStatus.Status) &&
1415 (StackPtr->Control & SL_INVOKE_ON_SUCCESS)) ||
1416 (!NT_SUCCESS(Irp->IoStatus.Status) &&
1417 (StackPtr->Control & SL_INVOKE_ON_ERROR)) ||
1418 (Irp->Cancel &&
1419 (StackPtr->Control & SL_INVOKE_ON_CANCEL)))
1420 {
1421 /* Clear the stack location */
1422 IopClearStackLocation(StackPtr);
1423
1424 /* Check for highest-level device completion routines */
1425 if (Irp->CurrentLocation == (Irp->StackCount + 1))
1426 {
1427 /* Clear the DO, since the current stack location is invalid */
1429 }
1430 else
1431 {
1432 /* Otherwise, return the real one */
1434 }
1435
1436 /* Call the completion routine */
1438 Irp,
1439 StackPtr->Context);
1440
1441 /* Don't touch the Packet in this case, since it might be gone! */
1443 }
1444 else
1445 {
1446 /* Otherwise, check if this is a completed IRP */
1447 if ((Irp->CurrentLocation <= Irp->StackCount) &&
1448 (Irp->PendingReturned))
1449 {
1450 /* Mark it as pending */
1452 }
1453
1454 /* Clear the stack location */
1455 IopClearStackLocation(StackPtr);
1456 }
1457 }
1458
1459 /* Check if the IRP is an associated IRP */
1460 if (Irp->Flags & IRP_ASSOCIATED_IRP)
1461 {
1462 /* Get the master IRP and count */
1463 MasterIrp = Irp->AssociatedIrp.MasterIrp;
1464 MasterCount = InterlockedDecrement(&MasterIrp->AssociatedIrp.IrpCount);
1465
1466 /* Free the MDLs */
1467 for (Mdl = Irp->MdlAddress; Mdl; Mdl = NextMdl)
1468 {
1469 /* Go to the next one */
1470 NextMdl = Mdl->Next;
1471 IoFreeMdl(Mdl);
1472 }
1473
1474 /* Free the IRP itself */
1475 IoFreeIrp(Irp);
1476
1477 /* Complete the Master IRP */
1478 if (!MasterCount) IofCompleteRequest(MasterIrp, PriorityBoost);
1479 return;
1480 }
1481
1482 /* Check whether we have to reparse */
1483 if (Irp->IoStatus.Status == STATUS_REPARSE)
1484 {
1485 if (Irp->IoStatus.Information > IO_REMOUNT)
1486 {
1487 /* If that's a reparse tag we understand, save the buffer from deletion */
1488 if (Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT)
1489 {
1490 ASSERT(Irp->Tail.Overlay.AuxiliaryBuffer != NULL);
1491 DataBuffer = (PREPARSE_DATA_BUFFER)Irp->Tail.Overlay.AuxiliaryBuffer;
1492 Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
1493 }
1494 else
1495 {
1496 Irp->IoStatus.Status = STATUS_IO_REPARSE_TAG_NOT_HANDLED;
1497 }
1498 }
1499 }
1500
1501 /* Check if we have an auxiliary buffer */
1502 if (Irp->Tail.Overlay.AuxiliaryBuffer)
1503 {
1504 /* Free it */
1505 ExFreePool(Irp->Tail.Overlay.AuxiliaryBuffer);
1506 Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
1507 }
1508
1509 /* Check if this is a Paging I/O or Close Operation */
1510 if (Irp->Flags & (IRP_PAGING_IO | IRP_CLOSE_OPERATION))
1511 {
1512 /* Handle a Close Operation or Sync Paging I/O */
1514 {
1515 /* Set the I/O Status and Signal the Event */
1517 *Irp->UserIosb = Irp->IoStatus;
1518 KeSetEvent(Irp->UserEvent, PriorityBoost, FALSE);
1519
1520 /* Free the IRP for a Paging I/O Only, Close is handled by us */
1521 if (Flags)
1522 {
1523 /* If we were using the reserve IRP, then call the appropriate
1524 * free function (to make the IRP available again)
1525 */
1527 {
1529 }
1530 /* Otherwise, free for real! */
1531 else
1532 {
1533 IoFreeIrp(Irp);
1534 }
1535 }
1536 }
1537 else
1538 {
1539#if 0
1540 /* Page 166 */
1541 KeInitializeApc(&Irp->Tail.Apc
1542 &Irp->Tail.Overlay.Thread->Tcb,
1543 Irp->ApcEnvironment,
1544 IopCompletePageWrite,
1545 NULL,
1546 NULL,
1547 KernelMode,
1548 NULL);
1549 KeInsertQueueApc(&Irp->Tail.Apc,
1550 NULL,
1551 NULL,
1553#else
1554 /* Not implemented yet. */
1555 UNIMPLEMENTED_DBGBREAK("Not supported!\n");
1556#endif
1557 }
1558
1559 /* Get out of here */
1560 return;
1561 }
1562
1563 /* Unlock MDL Pages, page 167. */
1564 Mdl = Irp->MdlAddress;
1565 while (Mdl)
1566 {
1568 Mdl = Mdl->Next;
1569 }
1570
1571 /* Check if we should exit because of a Deferred I/O (page 168) */
1572 if ((Irp->Flags & IRP_DEFER_IO_COMPLETION) && !(Irp->PendingReturned))
1573 {
1574 /* Restore the saved reparse buffer for the caller */
1575 if (Irp->IoStatus.Status == STATUS_REPARSE &&
1576 Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT)
1577 {
1578 Irp->Tail.Overlay.AuxiliaryBuffer = (PCHAR)DataBuffer;
1579 }
1580
1581 /*
1582 * Return without queuing the completion APC, since the caller will
1583 * take care of doing its own optimized completion at PASSIVE_LEVEL.
1584 */
1585 return;
1586 }
1587
1588 /* Get the thread and file object */
1589 Thread = Irp->Tail.Overlay.Thread;
1590 FileObject = Irp->Tail.Overlay.OriginalFileObject;
1591
1592 /* Make sure the IRP isn't canceled */
1593 if (!Irp->Cancel)
1594 {
1595 /* Initialize the APC */
1596 KeInitializeApc(&Irp->Tail.Apc,
1597 &Thread->Tcb,
1598 Irp->ApcEnvironment,
1600 NULL,
1601 NULL,
1602 KernelMode,
1603 NULL);
1604
1605 /* Queue it */
1606 KeInsertQueueApc(&Irp->Tail.Apc,
1607 FileObject,
1608 DataBuffer,
1610 }
1611 else
1612 {
1613 /* The IRP just got canceled... does a thread still own it? */
1614 if (Thread)
1615 {
1616 /* Yes! There is still hope! Initialize the APC */
1617 KeInitializeApc(&Irp->Tail.Apc,
1618 &Thread->Tcb,
1619 Irp->ApcEnvironment,
1621 NULL,
1622 NULL,
1623 KernelMode,
1624 NULL);
1625
1626 /* Queue it */
1627 KeInsertQueueApc(&Irp->Tail.Apc,
1628 FileObject,
1629 DataBuffer,
1631 }
1632 else
1633 {
1634 /* Nothing left for us to do, kill it */
1635 ASSERT(Irp->Cancel);
1637 }
1638 }
1639}
1640
1642NTAPI
1644 IN PIRP Irp,
1646{
1647 if (Irp->PendingReturned)
1650}
1651
1652/*
1653 * @implemented
1654 */
1655BOOLEAN
1656NTAPI
1658 IN PIRP Irp)
1659{
1660 KEVENT Event;
1662
1663 /* Check if next stack location is available */
1664 if (Irp->CurrentLocation > Irp->StackCount || Irp->CurrentLocation <= 1)
1665 {
1666 /* No more stack location */
1667 return FALSE;
1668 }
1669
1670 /* Initialize event */
1672
1673 /* Copy stack location for next driver */
1675
1676 /* Set a completion routine, which will signal the event */
1678
1679 /* Call next driver */
1681
1682 /* Check if irp is pending */
1683 if (Status == STATUS_PENDING)
1684 {
1685 /* Yes, wait for its completion */
1687 }
1688
1689 /* Return success */
1690 return TRUE;
1691}
1692
1693/*
1694 * @implemented
1695 */
1696VOID
1697NTAPI
1699{
1702 PKPRCB Prcb;
1704 "%s - Freeing IRPs %p\n",
1706 Irp);
1707
1708 /* Make sure the Thread IRP list is empty and that it OK to free it */
1709 ASSERT(Irp->Type == IO_TYPE_IRP);
1710 ASSERT(IsListEmpty(&Irp->ThreadListEntry));
1711 ASSERT(Irp->CurrentLocation >= Irp->StackCount);
1712
1713 /* Get the PRCB */
1714 Prcb = KeGetCurrentPrcb();
1715
1716 /* If this was a lookaside alloc, increment lookaside float */
1717 if (Irp->AllocationFlags & IRP_LOOKASIDE_ALLOCATION)
1718 {
1719 Irp->AllocationFlags &= ~IRP_LOOKASIDE_ALLOCATION;
1721 }
1722
1723 /* If this was a pool alloc, free it with the pool */
1724 if (!(Irp->AllocationFlags & IRP_ALLOCATED_FIXED_SIZE))
1725 {
1726 /* Free it */
1728 }
1729 else
1730 {
1731 /* Check if this was a Big IRP */
1732 if (Irp->StackCount != 1) ListType = LookasideLargeIrpList;
1733
1734 /* Use the P List */
1735 List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[ListType].P;
1736 List->L.TotalFrees++;
1737
1738 /* Check if the Free was within the Depth or not */
1739 if (ExQueryDepthSList(&List->L.ListHead) >= List->L.Depth)
1740 {
1741 /* Let the balancer know */
1742 List->L.FreeMisses++;
1743
1744 /* Use the L List */
1745 List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[ListType].L;
1746 List->L.TotalFrees++;
1747
1748 /* Check if the Free was within the Depth or not */
1749 if (ExQueryDepthSList(&List->L.ListHead) >= List->L.Depth)
1750 {
1751 /* All lists failed, use the pool */
1752 List->L.FreeMisses++;
1754 Irp = NULL;
1755 }
1756 }
1757
1758 /* The free was within the Depth */
1759 if (Irp)
1760 {
1761 /* Remove the association with the process */
1762 if (Irp->AllocationFlags & IRP_QUOTA_CHARGED)
1763 {
1765 Irp->AllocationFlags &= ~IRP_QUOTA_CHARGED;
1766 }
1767
1768 /* Add it to the lookaside list */
1769 InterlockedPushEntrySList(&List->L.ListHead,
1770 (PSLIST_ENTRY)Irp);
1771 }
1772 }
1773}
1774
1775/*
1776 * @implemented
1777 */
1781{
1783 ULONG Flags;
1784
1785 /* Get the flags */
1786 Flags = Irp->Flags;
1787
1788 /* Check what priority it has */
1790 {
1791 /* High priority */
1793 }
1794 else if (Flags & IRP_PAGING_IO)
1795 {
1796 /* Normal priority */
1798 }
1799 else
1800 {
1801 /* Invalid -- not a paging IRP */
1803 }
1804
1805 /* Return the priority */
1806 return Priority;
1807}
1808
1809/*
1810 * @implemented
1811 */
1813NTAPI
1815{
1816 /* Return the requestor process */
1817 if (Irp->Tail.Overlay.Thread)
1818 {
1819 if (Irp->ApcEnvironment == OriginalApcEnvironment)
1820 {
1821 return Irp->Tail.Overlay.Thread->ThreadsProcess;
1822 }
1823 else if (Irp->ApcEnvironment == AttachedApcEnvironment)
1824 {
1825 return (PEPROCESS)Irp->Tail.Overlay.Thread->Tcb.ApcState.Process;
1826 }
1827 }
1828
1829 return NULL;
1830}
1831
1832/*
1833 * @implemented
1834 */
1835ULONG
1836NTAPI
1838{
1840
1841 /* Return the requestor process' id */
1843 if (Process) return PtrToUlong(Process->UniqueProcessId);
1844
1845 return 0;
1846}
1847
1848/*
1849 * @implemented
1850 */
1852NTAPI
1854 OUT PULONG pSessionId)
1855{
1857
1858 /* Return the session */
1859 if (Irp->Tail.Overlay.Thread)
1860 {
1861 Process = Irp->Tail.Overlay.Thread->ThreadsProcess;
1862 *pSessionId = MmGetSessionId(Process);
1863 return STATUS_SUCCESS;
1864 }
1865
1866 *pSessionId = (ULONG)-1;
1867 return STATUS_UNSUCCESSFUL;
1868}
1869
1870/*
1871 * @implemented
1872 */
1873PIRP
1874NTAPI
1876{
1877 /* Return the IRP */
1878 return (PIRP)PsGetCurrentThread()->TopLevelIrp;
1879}
1880
1881/*
1882 * @implemented
1883 */
1884VOID
1885NTAPI
1889{
1890 /* Clear it */
1892 "%s - Initializing IRP %p\n",
1894 Irp);
1896
1897 /* Set the Header and other data */
1898 Irp->Type = IO_TYPE_IRP;
1899 Irp->Size = PacketSize;
1900 Irp->StackCount = StackSize;
1901 Irp->CurrentLocation = StackSize + 1;
1902 Irp->ApcEnvironment = KeGetCurrentThread()->ApcStateIndex;
1903 Irp->Tail.Overlay.CurrentStackLocation = (PIO_STACK_LOCATION)(Irp + 1) + StackSize;
1904
1905 /* Initialize the Thread List */
1906 InitializeListHead(&Irp->ThreadListEntry);
1907}
1908
1909/*
1910 * @implemented
1911 */
1912BOOLEAN
1913NTAPI
1915{
1916 BOOLEAN SynchIO;
1917 BOOLEAN ForceAsync;
1918
1919 /* If the IRP requests synchronous paging I/O, if the file object was opened
1920 for synchronous I/O, if the IRP_SYNCHRONOUS_API flag is set in the IRP
1921 the operation is synchronous */
1923 (Irp->Flags & IRP_SYNCHRONOUS_API) || (Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO);
1924
1925 /* If the IRP requests asynchronous paging I/O, the operation is asynchronous,
1926 even if one of the above conditions is true */
1927 ForceAsync = (Irp->Flags & IRP_PAGING_IO) && !(Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO);
1928
1929 /* Check the flags */
1930 if (SynchIO && !ForceAsync)
1931 {
1932 /* Synch API or Paging I/O is OK, as is Sync File I/O */
1933 return TRUE;
1934 }
1935
1936 /* Otherwise, it is an asynchronous operation. */
1937 return FALSE;
1938}
1939
1940/*
1941 * @unimplemented
1942 */
1943BOOLEAN
1944NTAPI
1946 IN PREPARSE_DATA_BUFFER ReparseBuffer)
1947{
1949 return FALSE;
1950}
1951
1952/*
1953 * @implemented
1954 */
1955PIRP
1956NTAPI
1959{
1960 PIRP AssocIrp;
1962 "%s - Associating IRP %p\n",
1964 Irp);
1965
1966 /* Allocate the IRP */
1967 AssocIrp = IoAllocateIrp(StackSize, FALSE);
1968 if (!AssocIrp) return NULL;
1969
1970 /* Set the Flags */
1971 AssocIrp->Flags |= IRP_ASSOCIATED_IRP;
1972
1973 /* Set the Thread */
1974 AssocIrp->Tail.Overlay.Thread = Irp->Tail.Overlay.Thread;
1975
1976 /* Associate them */
1977 AssocIrp->AssociatedIrp.MasterIrp = Irp;
1978 return AssocIrp;
1979}
1980
1981/*
1982 * @implemented
1983 */
1984VOID
1985NTAPI
1987{
1989 "%s - Queueing IRP %p\n",
1991 Irp);
1992
1993 /* Use our inlined routine */
1995}
1996
1997/*
1998 * @implemented
1999 * Reference: Chris Cant's "Writing WDM Device Drivers"
2000 */
2001VOID
2002NTAPI
2005{
2006 UCHAR AllocationFlags;
2008 "%s - Reusing IRP %p\n",
2010 Irp);
2011
2012 /* Make sure it's OK to reuse it */
2013 ASSERT(!Irp->CancelRoutine);
2014 ASSERT(IsListEmpty(&Irp->ThreadListEntry));
2015
2016 /* Get the old flags */
2017 AllocationFlags = Irp->AllocationFlags;
2018
2019 /* Reinitialize the IRP */
2020 IoInitializeIrp(Irp, Irp->Size, Irp->StackCount);
2021
2022 /* Duplicate the data */
2023 Irp->IoStatus.Status = Status;
2024 Irp->AllocationFlags = AllocationFlags;
2025}
2026
2027/*
2028 * @implemented
2029 */
2030VOID
2031NTAPI
2033{
2034 /* Set the IRP */
2035 PsGetCurrentThread()->TopLevelIrp = (ULONG_PTR)Irp;
2036}
2037
2038#if defined (_WIN64)
2039/*
2040 * @implemented
2041 */
2042BOOLEAN
2043NTAPI
2044IoIs32bitProcess(
2046{
2047 PETHREAD pThread;
2048 PEPROCESS pProcess;
2049
2050 if (Irp == NULL)
2051 {
2052 pThread = PsGetCurrentThread();
2053 }
2054 else
2055 {
2056 /* If it's a kernel mode IRP, it could not have originated from WOW64 */
2057 if (Irp->RequestorMode == KernelMode ||
2058 (PVOID)Irp->UserIosb > MmHighestUserAddress)
2059 {
2060 return FALSE;
2061 }
2062
2063 pThread = Irp->Tail.Overlay.Thread;
2064 }
2065
2066 pProcess = CONTAINING_RECORD(pThread->Tcb.Process, EPROCESS, Pcb);
2067
2068 /* FIXME: A two-part hack: delay setting Process->Wow64Process, so 64-bit
2069 NTDLL can use IO to init stuff. */
2070 if (pProcess->Wow64Process == UlongToPtr(1))
2071 {
2072 return FALSE;
2073 }
2074
2075 return pProcess->Wow64Process != NULL;
2076}
2077#endif
struct _IO_STACK_LOCATION * PIO_STACK_LOCATION
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
static ULONG StackSize
Definition: StackOverflow.c:21
unsigned char BOOLEAN
Definition: actypes.h:127
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedExchange
Definition: armddk.h:54
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
DECLSPEC_NORETURN VOID NTAPI KeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
Definition: debug.c:485
PVOID MmHighestUserAddress
Definition: libsupp.c:23
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:291
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
Definition: bufpool.h:45
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define LONG_MAX
Definition: limits.h:30
#define __FUNCTION__
Definition: types.h:116
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
#define UlongToPtr(u)
Definition: config.h:106
#define ULONG_PTR
Definition: config.h:101
#define PtrToUlong(u)
Definition: config.h:107
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeDelayExecutionThread(mode, foo, t)
Definition: env_spec_w32.h:484
LONG NTAPI KeReadStateEvent(IN PKEVENT Event)
Definition: eventobj.c:121
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
#define IoFreeMdl
Definition: fxmdl.h:89
#define IoAllocateMdl
Definition: fxmdl.h:88
Status
Definition: gdiplustypes.h:24
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
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
#define KeGetCurrentThread
Definition: hal.h:55
CPPORT Port[4]
Definition: headless.c:38
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
FORCEINLINE VOID IopQueueIrpToThread(IN PIRP Irp)
Definition: io_x.h:49
static __inline VOID IopUpdateTransferCount(IN IOP_TRANSFER_TYPE Type, IN ULONG TransferCount)
Definition: io_x.h:116
static __inline VOID IopUnlockFileObject(IN PFILE_OBJECT FileObject)
Definition: io_x.h:36
FORCEINLINE VOID IopUnQueueIrpFromThread(IN PIRP Irp)
Definition: io_x.h:66
IoMarkIrpPending(Irp)
IoSetCancelRoutine(Irp, CancelRoutine)
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
if(dx< 0)
Definition: linetemp.h:194
#define PCHAR
Definition: match.c:90
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:931
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1435
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define IO_METHOD_FROM_CTL_CODE(C)
Definition: mup.h:11
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1197
#define KernelMode
Definition: asm.h:38
#define UserMode
Definition: asm.h:39
@ AttachedApcEnvironment
Definition: ketypes.h:912
@ OriginalApcEnvironment
Definition: ketypes.h:911
@ CurrentApcEnvironment
Definition: ketypes.h:913
VOID(NTAPI * PKNORMAL_ROUTINE)(IN PVOID NormalContext OPTIONAL, IN PVOID SystemArgument1 OPTIONAL, IN PVOID SystemArgument2 OPTIONAL)
Definition: ketypes.h:888
enum _PP_NPAGED_LOOKASIDE_NUMBER PP_NPAGED_LOOKASIDE_NUMBER
@ LookasideLargeIrpList
Definition: mmtypes.h:169
@ LookasideSmallIrpList
Definition: mmtypes.h:168
DWORD Interval
Definition: netstat.c:28
#define METHOD_NEITHER
Definition: nt_native.h:597
#define FASTCALL
Definition: nt_native.h:50
#define METHOD_OUT_DIRECT
Definition: nt_native.h:596
#define METHOD_BUFFERED
Definition: nt_native.h:594
#define METHOD_IN_DIRECT
Definition: nt_native.h:595
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
@ NotificationEvent
@ SynchronizationEvent
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:100
#define IoCopyCurrentIrpStackLocationToNext(Irp)
Definition: ntifs_ex.h:413
#define IO_DRIVER_CANCEL_TIMEOUT
Definition: ntiologc.h:80
VOID NTAPI IopDoNameTransmogrify(IN PIRP Irp, IN PFILE_OBJECT FileObject, IN PREPARSE_DATA_BUFFER DataBuffer)
Definition: file.c:167
@ IopWriteTransfer
Definition: io.h:261
@ IopReadTransfer
Definition: io.h:260
@ IopOtherTransfer
Definition: io.h:262
#define IO_IRP_DEBUG
Definition: io.h:19
@ IopCompletionPacketIrp
Definition: io.h:270
#define IOTRACE(x, fmt,...)
Definition: io.h:47
#define IsIrpSynchronous(Irp, FileObject)
Definition: io.h:120
VOID NTAPI ExReturnPoolQuota(IN PVOID P)
Definition: expool.c:1852
ULONG NTAPI MmGetSessionId(IN PEPROCESS Process)
Definition: session.c:179
VOID NTAPI IoWriteErrorLogEntry(IN PVOID ElEntry)
Definition: error.c:628
PVOID NTAPI IoAllocateErrorLogEntry(IN PVOID IoObject, IN UCHAR EntrySize)
Definition: error.c:528
NTSTATUS FASTCALL IofCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1290
VOID NTAPI IoCancelThreadIo(IN PETHREAD Thread)
Definition: irp.c:1178
VOID NTAPI IoInitializeIrp(IN PIRP Irp, IN USHORT PacketSize, IN CCHAR StackSize)
Definition: irp.c:1886
VOID NTAPI IoQueueThreadIrp(IN PIRP Irp)
Definition: irp.c:1986
VOID FASTCALL IofCompleteRequest(IN PIRP Irp, IN CCHAR PriorityBoost)
Definition: irp.c:1340
ULONG NTAPI IoGetRequestorProcessId(IN PIRP Irp)
Definition: irp.c:1837
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:1101
VOID NTAPI IopAbortIrpKernelApc(IN PKAPC Apc)
Definition: irp.c:37
VOID NTAPI IoEnqueueIrp(IN PIRP Irp)
Definition: irp.c:1279
#define IoCompleteRequest
Definition: irp.c:1272
VOID NTAPI IopCompleteRequest(IN PKAPC Apc, IN PKNORMAL_ROUTINE *NormalRoutine, IN PVOID *NormalContext, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2)
Definition: irp.c:284
BOOLEAN NTAPI IopInitializeReserveIrp(IN PRESERVE_IRP_ALLOCATOR ReserveIrpAllocator)
Definition: irp.c:581
FORCEINLINE VOID IopClearStackLocation(IN PIO_STACK_LOCATION IoStackLocation)
Definition: irp.c:1324
VOID NTAPI IopFreeIrpKernelApc(IN PKAPC Apc, IN PKNORMAL_ROUTINE *NormalRoutine, IN PVOID *NormalContext, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2)
Definition: irp.c:25
NTSTATUS NTAPI IopCleanupFailedIrp(IN PFILE_OBJECT FileObject, IN PKEVENT EventObject OPTIONAL, IN PVOID Buffer OPTIONAL)
Definition: irp.c:45
BOOLEAN NTAPI IoIsOperationSynchronous(IN PIRP Irp)
Definition: irp.c:1914
BOOLEAN NTAPI IoIsValidNameGraftingBuffer(IN PIRP Irp, IN PREPARSE_DATA_BUFFER ReparseBuffer)
Definition: irp.c:1945
PIRP IopDeadIrp
Definition: irp.c:18
PIRP NTAPI IopAllocateReserveIrp(IN CCHAR StackSize)
Definition: irp.c:605
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:647
VOID NTAPI IopDisassociateThreadIrp(VOID)
Definition: irp.c:115
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:782
PEPROCESS NTAPI IoGetRequestorProcess(IN PIRP Irp)
Definition: irp.c:1814
VOID NTAPI IopAbortInterruptedIrp(IN PKEVENT EventObject, IN PIRP Irp)
Definition: irp.c:67
PIRP NTAPI IopAllocateIrpMustSucceed(IN CCHAR StackSize)
Definition: irp.c:748
static VOID IopWriteAsyncUserIosb(PIRP Irp)
Definition: irp.c:238
VOID NTAPI IoReuseIrp(IN OUT PIRP Irp, IN NTSTATUS Status)
Definition: irp.c:2003
NTSTATUS NTAPI IopSynchronousCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: irp.c:1643
BOOLEAN NTAPI IoCancelIrp(IN PIRP Irp)
Definition: irp.c:1133
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:913
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1875
VOID IopFreeReserveIrp(IN CCHAR PriorityBoost)
Definition: irp.c:631
IO_PAGING_PRIORITY FASTCALL IoGetPagingIoPriority(IN PIRP Irp)
Definition: irp.c:1780
BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1657
#define IoCallDriver
Definition: irp.c:1257
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2032
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1698
VOID NTAPI IopCleanupIrp(IN PIRP Irp, IN PFILE_OBJECT FileObject)
Definition: irp.c:191
PIRP NTAPI IoMakeAssociatedIrp(IN PIRP Irp, IN CCHAR StackSize)
Definition: irp.c:1957
NTSTATUS NTAPI IoGetRequestorSessionId(IN PIRP Irp, OUT PULONG pSessionId)
Definition: irp.c:1853
RESERVE_IRP_ALLOCATOR IopReserveIrpAllocator
Definition: irp.c:19
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
BOOLEAN NTAPI KeInsertQueueApc(IN PKAPC Apc, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN KPRIORITY PriorityBoost)
Definition: apc.c:735
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
LONG NTAPI KeInsertQueue(IN PKQUEUE Queue, IN PLIST_ENTRY Entry)
Definition: queue.c:198
#define STATUS_REPARSE
Definition: ntstatus.h:136
#define STATUS_IO_REPARSE_TAG_NOT_HANDLED
Definition: ntstatus.h:879
VOID NTAPI ObDereferenceObjectDeferDelete(IN PVOID Object)
Definition: obref.c:357
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:207
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _REPARSE_DATA_BUFFER * PREPARSE_DATA_BUFFER
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
_In_ PVOID Context
Definition: storport.h:2269
Key()
Definition: map_test.cpp:305
KTHREAD Tcb
Definition: pstypes.h:1198
LIST_ENTRY IrpList
Definition: pstypes.h:1239
NTSTATUS ErrorCode
Definition: iotypes.h:2007
struct _IO_STACK_LOCATION::@4477::@4516 Others
PFILE_OBJECT FileObject
Definition: iotypes.h:3171
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3225
union _IO_STACK_LOCATION::@1709 Parameters
struct _IO_STACK_LOCATION::@4477::@4481 Read
PIO_COMPLETION_ROUTINE CompletionRoutine
Definition: iotypes.h:3316
struct _IO_STACK_LOCATION::@4477::@4482 Write
struct _IO_STACK_LOCATION::@1709::@1710 DeviceIoControl
union _IRP::@1711 AssociatedIrp
Definition: ketypes.h:615
PP_LOOKASIDE_LIST PPLookasideList[16]
Definition: ketypes.h:728
LONG LookasideIrpFloat
Definition: ketypes.h:759
PKPROCESS Process
Definition: ketypes.h:2055
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _GENERAL_LOOKASIDE * P
Definition: ketypes.h:1015
struct _GENERAL_LOOKASIDE * L
Definition: ketypes.h:1016
USHORT ReparseDataLength
Definition: shellext.h:166
volatile LONG ReserveIrpInUse
Definition: io.h:503
KEVENT WaitEvent
Definition: io.h:504
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:726
#define TAG_IOBUF
Definition: tag.h:86
#define STATUS_PENDING
Definition: telnetd.h:14
#define MAXULONG
Definition: typedefs.h:251
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char UCHAR
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char CCHAR
Definition: typedefs.h:51
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define NT_ERROR(Status)
Definition: umtypes.h:106
_In_ PIO_STACK_LOCATION IoStackLocation
Definition: usbdlib.h:265
#define TAG_IRP
Definition: vfat.h:548
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_In_ UCHAR MajorFunction
Definition: wdfdevice.h:1703
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3777
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY _In_ WDF_INTERRUPT_PRIORITY Priority
Definition: wdfinterrupt.h:655
_In_ WDFREQUEST _In_ size_t _In_ size_t _In_ ULONG IoControlCode
Definition: wdfio.h:325
_In_ WDFREQUEST _In_ size_t OutputBufferLength
Definition: wdfio.h:320
_In_ WDFREQUEST _In_ size_t _In_ size_t InputBufferLength
Definition: wdfio.h:322
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
_In_ WDFREQUEST _In_ NTSTATUS _In_ CCHAR PriorityBoost
Definition: wdfrequest.h:1016
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
#define FORCEINLINE
Definition: wdftypes.h:67
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
FORCEINLINE USHORT ExQueryDepthSList(_In_ PSLIST_HEADER SListHead)
Definition: exfuncs.h:153
#define ExAllocatePoolWithQuotaTag(a, b, c)
Definition: exfuncs.h:530
struct LOOKASIDE_ALIGN _NPAGED_LOOKASIDE_LIST * PNPAGED_LOOKASIDE_LIST
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
_In_opt_ PDRIVER_CANCEL CancelRoutine
Definition: iofuncs.h:2744
#define IoSizeOfIrp(_StackSize)
_In_ USHORT PacketSize
Definition: iofuncs.h:1058
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID _In_ ULONG _In_ BOOLEAN InternalDeviceIoControl
Definition: iofuncs.h:720
_Must_inspect_result_ _In_ BOOLEAN ChargeQuota
Definition: iofuncs.h:651
#define SL_PENDING_RETURNED
Definition: iotypes.h:3327
#define IRP_CLASS_CACHE_OPERATION
enum _IO_PAGING_PRIORITY IO_PAGING_PRIORITY
#define IRP_DEALLOCATE_BUFFER
#define IRP_CLOSE_OPERATION
#define IO_TYPE_IRP
#define IRP_SYNCHRONOUS_API
#define IRP_QUOTA_CHARGED
#define SL_ERROR_RETURNED
Definition: iotypes.h:3328
#define IRP_INPUT_OPERATION
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_PAGING_IO
#define IRP_OB_QUERY_NAME
@ IoPagingPriorityNormal
Definition: iotypes.h:2823
@ IoPagingPriorityHigh
Definition: iotypes.h:2824
@ IoPagingPriorityInvalid
Definition: iotypes.h:2822
#define IRP_WRITE_OPERATION
#define POOL_QUOTA_FAIL_INSTEAD_OF_RAISE
DRIVER_CANCEL * PDRIVER_CANCEL
Definition: iotypes.h:2761
#define SL_INVOKE_ON_ERROR
Definition: iotypes.h:3331
#define IRP_CREATE_OPERATION
#define IRP_DEFER_IO_COMPLETION
#define IRP_ASSOCIATED_IRP
* PFILE_OBJECT
Definition: iotypes.h:1998
#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE
Definition: iotypes.h:7216
#define SL_INVOKE_ON_CANCEL
Definition: iotypes.h:3329
#define IRP_MJ_FLUSH_BUFFERS
#define IRP_READ_OPERATION
#define IRP_LOOKASIDE_ALLOCATION
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
#define IRP_ALLOCATED_FIXED_SIZE
#define IO_REPARSE_TAG_MOUNT_POINT
Definition: iotypes.h:7234
#define FO_SYNCHRONOUS_IO
Definition: iotypes.h:1776
#define IRP_MJ_SHUTDOWN
#define IO_REMOUNT
Definition: iotypes.h:544
#define IRP_MJ_POWER
#define IRP_BUFFERED_IO
#define IRP_SYNCHRONOUS_PAGING_IO
#define SL_INVOKE_ON_SUCCESS
Definition: iotypes.h:3330
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
@ Suspended
Definition: ketypes.h:472
@ Executive
Definition: ketypes.h:467
@ IoReadAccess
Definition: ketypes.h:931
@ IoWriteAccess
Definition: ketypes.h:932
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:756
@ LockQueueIoCompletionLock
Definition: ketypes.h:737
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:757
#define ObDereferenceObject
Definition: obfuncs.h:203
#define InterlockedPushEntrySList(SListHead, SListEntry)
Definition: rtlfuncs.h:3406
#define InterlockedPopEntrySList(SListHead)
Definition: rtlfuncs.h:3409
#define PSLIST_ENTRY
Definition: rtltypes.h:134