1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7     FxIrpKm.hpp
8 
9 Abstract:
10 
11     This module implements km definitions for FxIrp functions.
12 
13 Author:
14 
15 
16 
17 Environment:
18 
19     Kernel mode only
20 
21 Revision History:
22 
23 --*/
24 
25 //
26 // All the functions in this file should use __inline so that KMDF gets
27 // inlining. FxIrp.hpp does not use __inline on the functions because it
28 // doesn't work for UMDF (see comments in FxIrp.hpp).
29 //
30 
31 #ifndef _FXIRPKM_HPP_
32 #define _FXIRPKM_HPP_
33 
34 typedef PIRP MdIrp;
35 
36 typedef DRIVER_CANCEL MdCancelRoutineType, *MdCancelRoutine;
37 typedef IO_COMPLETION_ROUTINE MdCompletionRoutineType, *MdCompletionRoutine;
38 typedef REQUEST_POWER_COMPLETE MdRequestPowerCompleteType, *MdRequestPowerComplete;
39 
40 typedef
41 NTSTATUS
42 (*PFX_COMPLETION_ROUTINE)(
43     __in FxDevice *Device,
44     __in FxIrp *Irp,
45     __in PVOID Context
46     );
47 
48 typedef
49 VOID
50 (*PFX_CANCEL_ROUTINE)(
51     __in FxDevice *Device,
52     __in FxIrp *Irp,
53     __in PVOID CancelContext
54     );
55 
56 #include "fxirp.hpp"
57 
58 
59 
60 __inline
61 MdIrp
62 FxIrp::GetIrp(
63     VOID
64     )
65 {
66     return m_Irp;
67 }
68 
69 __inline
70 MdIrp
71 FxIrp::SetIrp(
72     MdIrp irp
73     )
74 {
75     MdIrp old = m_Irp;
76     m_Irp = irp;
77     return old;
78 }
79 
80 __inline
81 VOID
82 FxIrp::CompleteRequest(
83     __in CCHAR PriorityBoost
84     )
85 {
86     IoCompleteRequest(m_Irp, PriorityBoost);
87     m_Irp = NULL;
88 }
89 
90 __inline
91 NTSTATUS
92 FxIrp::CallDriver(
93     __in MdDeviceObject DeviceObject
94     )
95 {
96     return IoCallDriver(DeviceObject, m_Irp);
97 }
98 
99 __inline
100 NTSTATUS
101 FxIrp::PoCallDriver(
102     __in MdDeviceObject DeviceObject
103     )
104 {
105     return ::PoCallDriver(DeviceObject, m_Irp);
106 }
107 
108 __inline
109 VOID
110 FxIrp::StartNextPowerIrp(
111     )
112 {
113     PoStartNextPowerIrp(m_Irp);
114 }
115 
116 __inline
117 MdCompletionRoutine
118 FxIrp::GetNextCompletionRoutine(
119     VOID
120     )
121 {
122     return this->GetNextIrpStackLocation()->CompletionRoutine;
123 }
124 
125 
126 __inline
127 VOID
128 FxIrp::SetCompletionRoutine(
129     __in MdCompletionRoutine CompletionRoutine,
130     __in PVOID Context,
131     __in BOOLEAN InvokeOnSuccess,
132     __in BOOLEAN InvokeOnError,
133     __in BOOLEAN InvokeOnCancel
134     )
135 {
136     IoSetCompletionRoutine(
137         m_Irp,
138         CompletionRoutine,
139         Context,
140         InvokeOnSuccess,
141         InvokeOnError,
142         InvokeOnCancel
143         );
144 }
145 
146 __inline
147 VOID
148 FxIrp::SetCompletionRoutineEx(
149     __in MdDeviceObject DeviceObject,
150     __in MdCompletionRoutine CompletionRoutine,
151     __in PVOID Context,
152     __in BOOLEAN InvokeOnSuccess,
153     __in BOOLEAN InvokeOnError,
154     __in BOOLEAN InvokeOnCancel
155     )
156 {
157     if (!NT_SUCCESS(IoSetCompletionRoutineEx(
158             DeviceObject,
159             m_Irp,
160             CompletionRoutine,
161             Context,
162             InvokeOnSuccess,
163             InvokeOnError,
164             InvokeOnCancel))) {
165 
166         IoSetCompletionRoutine(
167             m_Irp,
168             CompletionRoutine,
169             Context,
170             InvokeOnSuccess,
171             InvokeOnError,
172             InvokeOnCancel
173             );
174     }
175 }
176 
177 __inline
178 MdCancelRoutine
179 FxIrp::SetCancelRoutine(
180     __in_opt MdCancelRoutine  CancelRoutine
181     )
182 {
183     return IoSetCancelRoutine(m_Irp, CancelRoutine);
184 }
185 
186 __inline
187 NTSTATUS
188 STDCALL
189 FxIrp::_IrpSynchronousCompletion(
190     __in MdDeviceObject DeviceObject,
191     __in PIRP OriginalIrp,
192     __in PVOID Context
193     )
194 {
195     FxCREvent* event = (FxCREvent*) Context;
196 
197     UNREFERENCED_PARAMETER(DeviceObject);
198 
199     if (OriginalIrp->PendingReturned) {
200         //
201         // No need to propagate the pending returned bit since we are handling
202         // the request synchronously
203         //
204         event->Set();
205     }
206 
207     return STATUS_MORE_PROCESSING_REQUIRED;
208 }
209 
210 __inline
211 NTSTATUS
212 FxIrp::SendIrpSynchronously(
213     __in MdDeviceObject DeviceObject
214     )
215 {
216     NTSTATUS status;
217     FxCREvent event;
218 
219     SetCompletionRoutine(_IrpSynchronousCompletion,
220                          event.GetSelfPointer(),
221                          TRUE,
222                          TRUE,
223                          TRUE);
224 
225     status = CallDriver(DeviceObject);
226 
227     if (status == STATUS_PENDING) {
228         event.EnterCRAndWaitAndLeave();
229         status = m_Irp->IoStatus.Status;
230     }
231 
232     return status;
233 }
234 
235 __inline
236 VOID
237 FxIrp::CopyToNextIrpStackLocation(
238     __in PIO_STACK_LOCATION Stack
239     )
240 {
241   PIO_STACK_LOCATION nextIrpSp = IoGetNextIrpStackLocation(m_Irp);
242 
243   RtlCopyMemory(nextIrpSp,
244           Stack,
245           FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine)
246           );
247   nextIrpSp->Control = 0;
248 }
249 
250 
251 __inline
252 VOID
253 FxIrp::CopyCurrentIrpStackLocationToNext(
254     VOID
255     )
256 {
257     IoCopyCurrentIrpStackLocationToNext(m_Irp);
258 }
259 
260 __inline
261 VOID
262 FxIrp::SetNextIrpStackLocation(
263     VOID
264     )
265 {
266     IoSetNextIrpStackLocation(m_Irp);
267 }
268 
269 __inline
270 UCHAR
271 FxIrp::GetMajorFunction(
272     VOID
273     )
274 {
275     return IoGetCurrentIrpStackLocation(m_Irp)->MajorFunction;
276 }
277 
278 __inline
279 UCHAR
280 FxIrp::GetMinorFunction(
281     VOID
282     )
283 {
284     return IoGetCurrentIrpStackLocation(m_Irp)->MinorFunction;
285 }
286 
287 __inline
288 UCHAR
289 FxIrp::GetCurrentStackFlags(
290     VOID
291     )
292 {
293     return IoGetCurrentIrpStackLocation(m_Irp)->Flags;
294 }
295 
296 __inline
297 MdFileObject
298 FxIrp::GetCurrentStackFileObject(
299     VOID
300     )
301 {
302     return IoGetCurrentIrpStackLocation(m_Irp)->FileObject;
303 }
304 
305 __inline
306 KPROCESSOR_MODE
307 FxIrp::GetRequestorMode(
308     VOID
309     )
310 {
311     return m_Irp->RequestorMode;
312 }
313 
314 __inline
315 VOID
316 FxIrp::SetContext(
317     __in ULONG Index,
318     __in PVOID Value
319     )
320 {
321     m_Irp->Tail.Overlay.DriverContext[Index] = Value;
322 }
323 
324 __inline
325 PVOID
326 FxIrp::GetContext(
327     __in ULONG Index
328     )
329 {
330     return m_Irp->Tail.Overlay.DriverContext[Index];
331 }
332 
333 __inline
334 VOID
335 FxIrp::SetFlags(
336     __in ULONG Flags
337     )
338 {
339     m_Irp->Flags = Flags;
340 }
341 
342 __inline
343 ULONG
344 FxIrp::GetFlags(
345     VOID
346     )
347 {
348     return m_Irp->Flags;
349 }
350 
351 __inline
352 PIO_STACK_LOCATION
353 FxIrp::GetCurrentIrpStackLocation(
354     VOID
355     )
356 {
357     return IoGetCurrentIrpStackLocation(m_Irp);
358 }
359 
360 __inline
361 PIO_STACK_LOCATION
362 FxIrp::GetNextIrpStackLocation(
363     VOID
364     )
365 {
366     return IoGetNextIrpStackLocation(m_Irp);
367 }
368 
369 PIO_STACK_LOCATION
370 __inline
371 FxIrp::_GetAndClearNextStackLocation(
372     __in MdIrp Irp
373     )
374 {
375     RtlZeroMemory(IoGetNextIrpStackLocation(Irp),
376                   FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine));
377     return IoGetNextIrpStackLocation(Irp);
378 }
379 
380 __inline
381 VOID
382 FxIrp::SkipCurrentIrpStackLocation(
383     VOID
384     )
385 {
386 
387 
388 
389 
390 
391 
392     IoSkipCurrentIrpStackLocation(m_Irp);
393 }
394 
395 __inline
396 VOID
397 FxIrp::MarkIrpPending(
398     )
399 {
400     IoMarkIrpPending(m_Irp);
401 }
402 
403 __inline
404 BOOLEAN
405 FxIrp::PendingReturned(
406     )
407 {
408     return m_Irp->PendingReturned;
409 }
410 
411 __inline
412 VOID
413 FxIrp::PropagatePendingReturned(
414     VOID
415     )
416 {
417     if (PendingReturned() && m_Irp->CurrentLocation <= m_Irp->StackCount) {
418         MarkIrpPending();
419     }
420 }
421 
422 __inline
423 VOID
424 FxIrp::SetStatus(
425     __in NTSTATUS Status
426     )
427 {
428     m_Irp->IoStatus.Status = Status;
429 }
430 
431 __inline
432 NTSTATUS
433 FxIrp::GetStatus(
434     )
435 {
436     return m_Irp->IoStatus.Status;
437 }
438 
439 __inline
440 BOOLEAN
441 FxIrp::Cancel(
442     VOID
443     )
444 {
445     return IoCancelIrp(m_Irp);
446 }
447 
448 __inline
449 VOID
450 FxIrp::SetCancel(
451     __in BOOLEAN Cancel
452     )
453 {
454     m_Irp->Cancel = Cancel;
455 }
456 
457 __inline
458 BOOLEAN
459 FxIrp::IsCanceled(
460     )
461 {
462     return m_Irp->Cancel ? TRUE : FALSE;
463 }
464 
465 __inline
466 KIRQL
467 FxIrp::GetCancelIrql(
468     )
469 {
470     return m_Irp->CancelIrql;
471 }
472 
473 __inline
474 VOID
475 FxIrp::SetInformation(
476     ULONG_PTR Information
477     )
478 {
479     m_Irp->IoStatus.Information = Information;
480 }
481 
482 __inline
483 ULONG_PTR
484 FxIrp::GetInformation(
485     )
486 {
487     return m_Irp->IoStatus.Information;
488 }
489 
490 __inline
491 CCHAR
492 FxIrp::GetCurrentIrpStackLocationIndex(
493     )
494 {
495     return m_Irp->CurrentLocation;
496 }
497 
498 __inline
499 CCHAR
500 FxIrp::GetStackCount(
501     )
502 {
503     return m_Irp->StackCount;
504 }
505 
506 __inline
507 PLIST_ENTRY
508 FxIrp::ListEntry(
509     )
510 {
511     return &m_Irp->Tail.Overlay.ListEntry;
512 }
513 
514 __inline
515 PVOID
516 FxIrp::GetSystemBuffer(
517     )
518 {
519     return m_Irp->AssociatedIrp.SystemBuffer;
520 }
521 
522 __inline
523 PVOID
524 FxIrp::GetOutputBuffer(
525     )
526 {
527     //
528     // In kernel mode, for buffered I/O, the output and input buffers are
529     // at same location.
530     //
531     return GetSystemBuffer();
532 }
533 
534 __inline
535 VOID
536 FxIrp::SetSystemBuffer(
537     __in PVOID Value
538     )
539 {
540     m_Irp->AssociatedIrp.SystemBuffer = Value;
541 }
542 
543 
544 __inline
545 PMDL
546 FxIrp::GetMdl(
547     )
548 {
549     return m_Irp->MdlAddress;
550 }
551 
552 __inline
553 PMDL*
554 FxIrp::GetMdlAddressPointer(
555     )
556 {
557     return &m_Irp->MdlAddress;
558 }
559 
560 __inline
561 VOID
562 FxIrp::SetMdlAddress(
563     __in PMDL Value
564     )
565 {
566     m_Irp->MdlAddress = Value;
567 }
568 
569 
570 __inline
571 PVOID
572 FxIrp::GetUserBuffer(
573     )
574 {
575     return m_Irp->UserBuffer;
576 }
577 
578 
579 __inline
580 VOID
581 FxIrp::SetUserBuffer(
582     __in PVOID Value
583     )
584 {
585     m_Irp->UserBuffer = Value;
586 }
587 
588 __inline
589 VOID
590 FxIrp::Reuse(
591     __in NTSTATUS Status
592     )
593 {
594     IoReuseIrp(m_Irp, Status);
595 }
596 
597 __inline
598 VOID
599 FxIrp::SetMajorFunction(
600     __in UCHAR MajorFunction
601     )
602 {
603     this->GetNextIrpStackLocation()->MajorFunction = MajorFunction;
604 }
605 
606 __inline
607 VOID
608 FxIrp::SetMinorFunction(
609     __in UCHAR MinorFunction
610     )
611 {
612     this->GetNextIrpStackLocation()->MinorFunction = MinorFunction;
613 }
614 
615 __inline
616 SYSTEM_POWER_STATE_CONTEXT
617 FxIrp::GetParameterPowerSystemPowerStateContext(
618     )
619 {
620     return (this->GetCurrentIrpStackLocation())->
621         Parameters.Power.SystemPowerStateContext;
622 }
623 
624 __inline
625 POWER_STATE_TYPE
626 FxIrp::GetParameterPowerType(
627     )
628 {
629     return (this->GetCurrentIrpStackLocation())->Parameters.Power.Type;
630 }
631 
632 __inline
633 POWER_STATE
634 FxIrp::GetParameterPowerState(
635     )
636 {
637     return (this->GetCurrentIrpStackLocation())->Parameters.Power.State;
638 }
639 
640 __inline
641 DEVICE_POWER_STATE
642 FxIrp::GetParameterPowerStateDeviceState(
643     )
644 {
645     return (this->GetCurrentIrpStackLocation())->
646         Parameters.Power.State.DeviceState;
647 }
648 
649 __inline
650 SYSTEM_POWER_STATE
651 FxIrp::GetParameterPowerStateSystemState(
652     )
653 {
654     return (this->GetCurrentIrpStackLocation())->
655         Parameters.Power.State.SystemState;
656 }
657 
658 __inline
659 POWER_ACTION
660 FxIrp::GetParameterPowerShutdownType(
661     )
662 {
663     return (this->GetCurrentIrpStackLocation())->
664         Parameters.Power.ShutdownType;
665 }
666 
667 __inline
668 DEVICE_RELATION_TYPE
669 FxIrp::GetParameterQDRType(
670     )
671 {
672     return (this->GetCurrentIrpStackLocation())->
673         Parameters.QueryDeviceRelations.Type;
674 }
675 
676 __inline
677 VOID
678 FxIrp::SetParameterQDRType(
679     DEVICE_RELATION_TYPE DeviceRelation
680 	)
681 {
682      this->GetNextIrpStackLocation()->
683         Parameters.QueryDeviceRelations.Type = DeviceRelation;
684 }
685 
686 __inline
687 PDEVICE_CAPABILITIES
688 FxIrp::GetParameterDeviceCapabilities(
689     )
690 {
691     return this->GetCurrentIrpStackLocation()->
692         Parameters.DeviceCapabilities.Capabilities;
693 }
694 
695 __inline
696 MdDeviceObject
697 FxIrp::GetDeviceObject(
698     VOID
699     )
700 {
701   return this->GetCurrentIrpStackLocation()->DeviceObject;
702 }
703 
704 __inline
705 VOID
706 FxIrp::SetCurrentDeviceObject(
707     __in MdDeviceObject DeviceObject
708     )
709 {
710   this->GetCurrentIrpStackLocation()->DeviceObject = DeviceObject;
711 }
712 
713 __inline
714 VOID
715 FxIrp::SetParameterDeviceCapabilities(
716     __in PDEVICE_CAPABILITIES DeviceCapabilities
717     )
718 {
719     this->GetNextIrpStackLocation()->
720         Parameters.DeviceCapabilities.Capabilities = DeviceCapabilities;
721 }
722 
723 __inline
724 LONGLONG
725 FxIrp::GetParameterWriteByteOffsetQuadPart(
726     )
727 {
728     return this->GetCurrentIrpStackLocation()->
729         Parameters.Write.ByteOffset.QuadPart;
730 }
731 
732 __inline
733 VOID
734 FxIrp::SetNextParameterWriteByteOffsetQuadPart(
735     __in LONGLONG DeviceOffset
736     )
737 {
738     this->GetNextIrpStackLocation()->
739         Parameters.Write.ByteOffset.QuadPart = DeviceOffset;
740 }
741 
742 __inline
743 VOID
744 FxIrp::SetNextParameterWriteLength(
745     __in ULONG IoLength
746     )
747 {
748     this->GetNextIrpStackLocation()->
749         Parameters.Write.Length = IoLength;
750 }
751 
752 __inline
753 PVOID*
754 FxIrp::GetNextStackParameterOthersArgument1Pointer(
755     )
756 {
757     PIO_STACK_LOCATION nextStack;
758 
759     nextStack = this->GetNextIrpStackLocation();
760 
761     return &nextStack->Parameters.Others.Argument1;
762 }
763 
764 __inline
765 VOID
766 FxIrp::SetNextStackParameterOthersArgument1(
767     __in PVOID Argument1
768     )
769 {
770     this->GetNextIrpStackLocation()->
771         Parameters.Others.Argument1 = Argument1;
772 }
773 
774 __inline
775 PVOID*
776 FxIrp::GetNextStackParameterOthersArgument2Pointer(
777     )
778 {
779     PIO_STACK_LOCATION nextStack;
780 
781     nextStack = this->GetNextIrpStackLocation();
782 
783     return &nextStack->Parameters.Others.Argument2;
784 }
785 
786 __inline
787 PVOID*
788 FxIrp::GetNextStackParameterOthersArgument4Pointer(
789     )
790 {
791     PIO_STACK_LOCATION nextStack;
792 
793     nextStack = this->GetNextIrpStackLocation();
794 
795     return &nextStack->Parameters.Others.Argument4;
796 }
797 
798 __inline
799 PCM_RESOURCE_LIST
800 FxIrp::GetParameterAllocatedResources(
801     )
802 {
803     return this->GetCurrentIrpStackLocation()->
804         Parameters.StartDevice.AllocatedResources;
805 }
806 
807 __inline
808 VOID
809 FxIrp::SetParameterAllocatedResources(
810     __in PCM_RESOURCE_LIST AllocatedResources
811     )
812 {
813     this->GetNextIrpStackLocation()->
814         Parameters.StartDevice.AllocatedResources = AllocatedResources;
815 }
816 
817 __inline
818 PCM_RESOURCE_LIST
819 FxIrp::GetParameterAllocatedResourcesTranslated(
820     )
821 {
822     return this->GetCurrentIrpStackLocation()->
823         Parameters.StartDevice.AllocatedResourcesTranslated;
824 }
825 
826 __inline
827 VOID
828 FxIrp::SetParameterAllocatedResourcesTranslated(
829     __in PCM_RESOURCE_LIST AllocatedResourcesTranslated
830     )
831 {
832     this->GetNextIrpStackLocation()->
833         Parameters.StartDevice.AllocatedResourcesTranslated =
834             AllocatedResourcesTranslated;
835 }
836 
837 __inline
838 LCID
839 FxIrp::GetParameterQueryDeviceTextLocaleId(
840     )
841 {
842     return this->GetCurrentIrpStackLocation()->
843         Parameters.QueryDeviceText.LocaleId;
844 }
845 
846 __inline
847 DEVICE_TEXT_TYPE
848 FxIrp::GetParameterQueryDeviceTextType(
849     )
850 {
851     return this->GetCurrentIrpStackLocation()->
852         Parameters.QueryDeviceText.DeviceTextType;
853 }
854 
855 __inline
856 BOOLEAN
857 FxIrp::GetParameterSetLockLock(
858     )
859 {
860     return this->GetCurrentIrpStackLocation()->Parameters.SetLock.Lock;
861 }
862 
863 __inline
864 BUS_QUERY_ID_TYPE
865 FxIrp::GetParameterQueryIdType(
866     )
867 {
868     return this->GetCurrentIrpStackLocation()->Parameters.QueryId.IdType;
869 }
870 
871 __inline
872 PINTERFACE
873 FxIrp::GetParameterQueryInterfaceInterface(
874     )
875 {
876     return this->GetCurrentIrpStackLocation()->
877         Parameters.QueryInterface.Interface;
878 }
879 
880 __inline
881 const GUID*
882 FxIrp::GetParameterQueryInterfaceType(
883     )
884 {
885     return this->GetCurrentIrpStackLocation()->
886         Parameters.QueryInterface.InterfaceType;
887 }
888 
889 __inline
890 MdFileObject
891 FxIrp::GetFileObject(
892     VOID
893     )
894 {
895     return this->GetCurrentIrpStackLocation()->FileObject;
896 }
897 
898 __inline
899 USHORT
900 FxIrp::GetParameterQueryInterfaceVersion(
901     )
902 {
903     return this->GetCurrentIrpStackLocation()->Parameters.QueryInterface.Version;
904 }
905 
906 __inline
907 USHORT
908 FxIrp::GetParameterQueryInterfaceSize(
909     )
910 {
911     return this->GetCurrentIrpStackLocation()->Parameters.QueryInterface.Size;
912 }
913 
914 __inline
915 PVOID
916 FxIrp::GetParameterQueryInterfaceInterfaceSpecificData(
917     )
918 {
919     return this->GetCurrentIrpStackLocation()->
920         Parameters.QueryInterface.InterfaceSpecificData;
921 }
922 
923 __inline
924 DEVICE_USAGE_NOTIFICATION_TYPE
925 FxIrp::GetParameterUsageNotificationType(
926     )
927 {
928     return this->GetCurrentIrpStackLocation()->
929         Parameters.UsageNotification.Type;
930 }
931 
932 __inline
933 BOOLEAN
934 FxIrp::GetParameterUsageNotificationInPath(
935     )
936 {
937     return this->GetCurrentIrpStackLocation()->
938         Parameters.UsageNotification.InPath;
939 }
940 
941 __inline
942 VOID
943 FxIrp::SetParameterUsageNotificationInPath(
944     __in BOOLEAN InPath
945     )
946 {
947     this->GetNextIrpStackLocation()->
948         Parameters.UsageNotification.InPath = InPath;
949 }
950 
951 __inline
952 BOOLEAN
953 FxIrp::GetNextStackParameterUsageNotificationInPath(
954     )
955 {
956     return this->GetNextIrpStackLocation()->
957         Parameters.UsageNotification.InPath;
958 }
959 
960 
961 
962 __inline
963 ULONG
964 FxIrp::GetParameterIoctlCode(
965     VOID
966     )
967 {
968     return this->GetCurrentIrpStackLocation()->
969         Parameters.DeviceIoControl.IoControlCode;
970 }
971 
972 __inline
973 ULONG
974 FxIrp::GetParameterIoctlCodeBufferMethod(
975     VOID
976     )
977 {
978     return METHOD_FROM_CTL_CODE(GetParameterIoctlCode());
979 }
980 
981 __inline
982 ULONG
983 FxIrp::GetParameterIoctlOutputBufferLength(
984     VOID
985     )
986 {
987     return this->GetCurrentIrpStackLocation()->
988         Parameters.DeviceIoControl.OutputBufferLength;
989 }
990 
991 __inline
992 ULONG
993 FxIrp::GetParameterIoctlInputBufferLength(
994     VOID
995     )
996 {
997     return this->GetCurrentIrpStackLocation()->
998         Parameters.DeviceIoControl.InputBufferLength;
999 }
1000 
1001 __inline
1002 VOID
1003 FxIrp::SetParameterIoctlCode(
1004     __in ULONG DeviceIoControlCode
1005     )
1006 {
1007     this->GetNextIrpStackLocation()->
1008         Parameters.DeviceIoControl.IoControlCode = DeviceIoControlCode;
1009 }
1010 
1011 __inline
1012 VOID
1013 FxIrp::SetParameterIoctlInputBufferLength(
1014     __in ULONG InputBufferLength
1015     )
1016 {
1017     this->GetNextIrpStackLocation()->
1018         Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
1019 }
1020 
1021 __inline
1022 VOID
1023 FxIrp::SetParameterIoctlOutputBufferLength(
1024     __in ULONG OutputBufferLength
1025     )
1026 {
1027     this->GetNextIrpStackLocation()->
1028         Parameters.DeviceIoControl.OutputBufferLength = OutputBufferLength;
1029 }
1030 
1031 __inline
1032 VOID
1033 FxIrp::SetParameterIoctlType3InputBuffer(
1034     __in PVOID Type3InputBuffer
1035     )
1036 {
1037     this->GetNextIrpStackLocation()->
1038         Parameters.DeviceIoControl.Type3InputBuffer = Type3InputBuffer;
1039 }
1040 
1041 __inline
1042 PVOID
1043 FxIrp::GetParameterIoctlType3InputBuffer(
1044     VOID
1045     )
1046 {
1047     return this->GetCurrentIrpStackLocation()->
1048                Parameters.DeviceIoControl.Type3InputBuffer;
1049 }
1050 
1051 __inline
1052 VOID
1053 FxIrp::SetParameterQueryInterfaceInterface(
1054     __in PINTERFACE Interface
1055     )
1056 {
1057     this->GetNextIrpStackLocation()->
1058         Parameters.QueryInterface.Interface = Interface;
1059 }
1060 
1061 __inline
1062 VOID
1063 FxIrp::SetParameterQueryInterfaceType(
1064     __in const GUID* InterfaceType
1065     )
1066 {
1067     this->GetNextIrpStackLocation()->
1068         Parameters.QueryInterface.InterfaceType = InterfaceType;
1069 }
1070 
1071 __inline
1072 VOID
1073 FxIrp::SetParameterQueryInterfaceVersion(
1074     __in USHORT Version
1075     )
1076 {
1077     this->GetNextIrpStackLocation()->Parameters.QueryInterface.Version = Version;
1078 }
1079 
1080 __inline
1081 VOID
1082 FxIrp::SetParameterQueryInterfaceSize(
1083     __in USHORT Size
1084     )
1085 {
1086     this->GetNextIrpStackLocation()->Parameters.QueryInterface.Size = Size;
1087 }
1088 
1089 __inline
1090 VOID
1091 FxIrp::SetParameterQueryInterfaceInterfaceSpecificData(
1092     __in PVOID InterfaceSpecificData
1093     )
1094 {
1095     this->GetNextIrpStackLocation()->
1096         Parameters.QueryInterface.InterfaceSpecificData = InterfaceSpecificData;
1097 }
1098 
1099 __inline
1100 VOID
1101 FxIrp::SetNextStackFlags(
1102     __in UCHAR Flags
1103     )
1104 {
1105     this->GetNextIrpStackLocation()->Flags = Flags;
1106 }
1107 
1108 __inline
1109 VOID
1110 FxIrp::SetNextStackFileObject(
1111     _In_ MdFileObject FileObject
1112     )
1113 {
1114     this->GetNextIrpStackLocation()->FileObject = FileObject;
1115 }
1116 
1117 
1118 __inline
1119 VOID
1120 FxIrp::ClearNextStack(
1121     VOID
1122     )
1123 {
1124     PIO_STACK_LOCATION stack;
1125 
1126     stack = this->GetNextIrpStackLocation();
1127     RtlZeroMemory(stack, sizeof(IO_STACK_LOCATION));
1128 }
1129 
1130 
1131 
1132 
1133 __inline
1134 VOID
1135 FxIrp::ClearNextStackLocation(
1136     VOID
1137     )
1138 {
1139     RtlZeroMemory(this->GetNextIrpStackLocation(),
1140                   FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine));
1141 }
1142 
1143 __inline
1144 VOID
1145 FxIrp::InitNextStackUsingStack(
1146     __in FxIrp* Irp
1147     )
1148 {
1149     PIO_STACK_LOCATION srcStack, destStack;
1150 
1151     srcStack = Irp->GetCurrentIrpStackLocation();
1152     destStack = this->GetNextIrpStackLocation();
1153 
1154     *destStack = *srcStack;
1155 }
1156 
1157 _Must_inspect_result_
1158 __inline
1159 MdIrp
1160 FxIrp::AllocateIrp(
1161     _In_ CCHAR StackSize,
1162     _In_opt_ FxDevice* Device
1163     )
1164 {
1165     UNREFERENCED_PARAMETER(Device);
1166 
1167     return IoAllocateIrp(StackSize, FALSE);
1168 }
1169 
1170 __inline
1171 MdIrp
1172 FxIrp::GetIrpFromListEntry(
1173     __in PLIST_ENTRY Ple
1174     )
1175 {
1176     return CONTAINING_RECORD(Ple, IRP, Tail.Overlay.ListEntry);
1177 }
1178 
1179 __inline
1180 ULONG
1181 FxIrp::GetParameterReadLength(
1182     VOID
1183     )
1184 {
1185   return this->GetCurrentIrpStackLocation()->Parameters.Read.Length;
1186 }
1187 
1188 __inline
1189 ULONG
1190 FxIrp::GetParameterWriteLength(
1191     VOID
1192     )
1193 {
1194   return this->GetCurrentIrpStackLocation()->Parameters.Write.Length;
1195 }
1196 
1197 _Must_inspect_result_
1198 __inline
1199 NTSTATUS
1200 FxIrp::RequestPowerIrp(
1201     __in MdDeviceObject  DeviceObject,
1202     __in UCHAR  MinorFunction,
1203     __in POWER_STATE  PowerState,
1204     __in MdRequestPowerComplete  CompletionFunction,
1205     __in PVOID  Context
1206     )
1207 {
1208     //
1209     // Prefast enforces that NULL is passed for IRP parameter (last parameter)
1210     // since the IRP might complete before the function returns.
1211     //
1212     return PoRequestPowerIrp(
1213         DeviceObject,
1214         MinorFunction,
1215         PowerState,
1216         CompletionFunction,
1217         Context,
1218         NULL);
1219 }
1220 
1221 __inline
1222 ULONG
1223 FxIrp::GetCurrentFlags(
1224     VOID
1225     )
1226 {
1227     return (this->GetCurrentIrpStackLocation())->Flags;
1228 }
1229 
1230 __inline
1231 PVOID
1232 FxIrp::GetCurrentParametersPointer(
1233     VOID
1234     )
1235 {
1236     return &(this->GetCurrentIrpStackLocation())->Parameters;
1237 }
1238 
1239 __inline
1240 MdEThread
1241 FxIrp::GetThread(
1242     VOID
1243     )
1244 {
1245     return  m_Irp->Tail.Overlay.Thread;
1246 }
1247 
1248 __inline
1249 BOOLEAN
1250 FxIrp::Is32bitProcess(
1251     VOID
1252     )
1253 {
1254 
1255 #if defined(_WIN64)
1256 
1257 #if BUILD_WOW64_ENABLED
1258 
1259     return IoIs32bitProcess(m_Irp);
1260 
1261 #else // BUILD_WOW64_ENABLED
1262 
1263     return FALSE;
1264 
1265 #endif // BUILD_WOW64_ENABLED
1266 
1267 #else // defined(_WIN64)
1268 
1269     return TRUE;
1270 
1271 #endif // defined(_WIN64)
1272 
1273 }
1274 
1275 __inline
1276 VOID
1277 FxIrp::FreeIrp(
1278     VOID
1279     )
1280 {
1281     IoFreeIrp(m_Irp);
1282 }
1283 
1284 __inline
1285 PIO_STATUS_BLOCK
1286 FxIrp::GetStatusBlock(
1287     VOID
1288     )
1289 {
1290     return &m_Irp->IoStatus;
1291 }
1292 
1293 __inline
1294 PVOID
1295 FxIrp::GetDriverContext(
1296     VOID
1297     )
1298 {
1299     return m_Irp->Tail.Overlay.DriverContext;
1300 }
1301 
1302 __inline
1303 ULONG
1304 FxIrp::GetDriverContextSize(
1305     VOID
1306     )
1307 {
1308     return sizeof(m_Irp->Tail.Overlay.DriverContext);
1309 }
1310 
1311 __inline
1312 VOID
1313 FxIrp::CopyParameters(
1314     _Out_ PWDF_REQUEST_PARAMETERS Parameters
1315     )
1316 {
1317     RtlMoveMemory(&Parameters->Parameters,
1318                   GetCurrentParametersPointer(),
1319                   sizeof(Parameters->Parameters));
1320 }
1321 
1322 __inline
1323 VOID
1324 FxIrp::CopyStatus(
1325     _Out_ PIO_STATUS_BLOCK StatusBlock
1326     )
1327 {
1328     RtlCopyMemory(StatusBlock,
1329                   GetStatusBlock(),
1330                   sizeof(*StatusBlock));
1331 }
1332 
1333 __inline
1334 BOOLEAN
1335 FxIrp::HasStack(
1336     _In_ UCHAR StackCount
1337     )
1338 {
1339     return (GetCurrentIrpStackLocationIndex() >= StackCount);
1340 }
1341 
1342 __inline
1343 BOOLEAN
1344 FxIrp::IsCurrentIrpStackLocationValid(
1345     VOID
1346     )
1347 {
1348     return (GetCurrentIrpStackLocationIndex() <= GetStackCount());
1349 }
1350 
1351 __inline
1352 FxAutoIrp::~FxAutoIrp()
1353 {
1354     if (m_Irp != NULL) {
1355         IoFreeIrp(m_Irp);
1356     }
1357 }
1358 
1359 #endif // _FXIRPKM_HPP
1360