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