1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7     FxIrp.hpp
8 
9 Abstract:
10 
11     This module implements a class for handling irps.
12 
13 Author:
14 
15 
16 
17 Environment:
18 
19     Both kernel and user mode
20 
21 Revision History:
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
83 
84 
85 
86 
87     // A function for when not assigning
88 
89     MdIrp
90     GetIrp(
91         VOID
92         );
93 
94 
95     VOID
96     CompleteRequest(
97         __in_opt CCHAR PriorityBoost=IO_NO_INCREMENT
98         );
99 
100 
101     NTSTATUS
102     CallDriver(
103         __in MdDeviceObject DeviceObject
104         );
105 
106 
107 
108 
109 
110 
111 
112     NTSTATUS
113     PoCallDriver(
114         __in MdDeviceObject DeviceObject
115         );
116 
117 
118     VOID
119     StartNextPowerIrp(
120         );
121 
122     MdCompletionRoutine
123     GetNextCompletionRoutine(
124         VOID
125         );
126 
127     VOID
128     SetCompletionRoutine(
129         __in MdCompletionRoutine CompletionRoutine,
130         __in PVOID Context,
131         __in BOOLEAN InvokeOnSuccess = TRUE,
132         __in BOOLEAN InvokeOnError = TRUE,
133         __in BOOLEAN InvokeOnCancel = TRUE
134         );
135 
136     VOID
137     SetCompletionRoutineEx(
138         __in MdDeviceObject DeviceObject,
139         __in MdCompletionRoutine CompletionRoutine,
140         __in PVOID Context,
141         __in BOOLEAN InvokeOnSuccess = TRUE,
142         __in BOOLEAN InvokeOnError = TRUE,
143         __in BOOLEAN InvokeOnCancel = TRUE
144         );
145 
146     MdCancelRoutine
147     SetCancelRoutine(
148         __in_opt MdCancelRoutine  CancelRoutine
149         );
150 
151     //
152     // SendIrpSynchronously achieves synchronous behavior by waiting on an
153     // event after submitting the IRP. The event creation can fail in UM, but
154     // not in KM. Hence, in UM the return code could either indicate event
155     // creation failure or it could indicate the status set on the IRP by the
156     // lower driver. In KM, the return code only indicates the status set on
157     // the IRP by the lower lower, because event creation cannot fail.
158     //
159     CHECK_RETURN_IF_USER_MODE
160     NTSTATUS
161     SendIrpSynchronously(
162         __in MdDeviceObject DeviceObject
163         );
164 
165 
166     VOID
167     CopyCurrentIrpStackLocationToNext(
168         VOID
169         );
170 
171     VOID
172     CopyToNextIrpStackLocation(
173         __in PIO_STACK_LOCATION Stack
174         );
175 
176     VOID
177     SetNextIrpStackLocation(
178         VOID
179     );
180 
181     UCHAR
182     GetMajorFunction(
183         VOID
184         );
185 
186     UCHAR
187     GetMinorFunction(
188         VOID
189         );
190 
191     UCHAR
192     GetCurrentStackFlags(
193         VOID
194         );
195 
196     MdFileObject
197     GetCurrentStackFileObject(
198         VOID
199         );
200 
201     KPROCESSOR_MODE
202     GetRequestorMode(
203         VOID
204         );
205 
206     VOID
207     SetContext(
208         __in ULONG Index,
209         __in PVOID Value
210         );
211 
212     VOID
213     SetSystemBuffer(
214         __in PVOID Value
215         );
216 
217     VOID
218     SetUserBuffer(
219         __in PVOID Value
220         );
221 
222     VOID
223     SetMdlAddress(
224         __in PMDL Value
225         );
226 
227     VOID
228     SetFlags(
229         __in ULONG Flags
230         );
231 
232     PVOID
233     GetContext(
234         __in ULONG Index
235         );
236 
237     ULONG
238     GetFlags(
239         VOID
240         );
241 
242     PIO_STACK_LOCATION
243     GetCurrentIrpStackLocation(
244         VOID
245         );
246 
247 
248     PIO_STACK_LOCATION
249     GetNextIrpStackLocation(
250         VOID
251         );
252 
253     static
254     PIO_STACK_LOCATION
255     _GetAndClearNextStackLocation(
256         __in MdIrp Irp
257         );
258 
259 
260     VOID
261     SkipCurrentIrpStackLocation(
262         VOID
263         );
264 
265 
266     VOID
267     MarkIrpPending(
268         );
269 
270 
271     BOOLEAN
272     PendingReturned(
273         );
274 
275 
276     VOID
277     PropagatePendingReturned(
278         VOID
279         );
280 
281 
282     VOID
283     SetStatus(
284         __in NTSTATUS Status
285         );
286 
287 
288     NTSTATUS
289     GetStatus(
290         );
291 
292 
293     BOOLEAN
294     Cancel(
295         VOID
296         );
297 
298     VOID
299     SetCancel(
300         __in BOOLEAN Cancel
301         );
302 
303 
304     BOOLEAN
305     IsCanceled(
306         );
307 
308 
309     KIRQL
310     GetCancelIrql(
311         );
312 
313 
314     VOID
315     SetInformation(
316         __in ULONG_PTR Information
317         );
318 
319 
320     ULONG_PTR
321     GetInformation(
322         );
323 
324 
325     CCHAR
326     GetCurrentIrpStackLocationIndex(
327         );
328 
329     CCHAR
330     GetStackCount(
331         );
332 
333     PLIST_ENTRY
334     ListEntry(
335         );
336 
337 
338     PVOID
339     GetSystemBuffer(
340         );
341 
342     PVOID
343     GetOutputBuffer(
344         );
345 
346     PMDL
347     GetMdl(
348         );
349 
350     PMDL*
351     GetMdlAddressPointer(
352         );
353 
354     PVOID
355     GetUserBuffer(
356         );
357 
358     VOID
359     Reuse(
360         __in NTSTATUS Status = STATUS_SUCCESS
361         );
362 
363     //
364     // Methods for IO_STACK_LOCATION members
365     //
366 
367     VOID
368     SetMajorFunction(
369         __in UCHAR MajorFunction
370         );
371 
372 
373     VOID
374     SetMinorFunction(
375         __in UCHAR MinorFunction
376         );
377 
378     //
379     // Get Methods for IO_STACK_LOCATION.Parameters.Power
380     //
381 
382     SYSTEM_POWER_STATE_CONTEXT
383     GetParameterPowerSystemPowerStateContext(
384         );
385 
386 
387     POWER_STATE_TYPE
388     GetParameterPowerType(
389         );
390 
391     POWER_STATE
392     GetParameterPowerState(
393         );
394 
395 
396     DEVICE_POWER_STATE
397     GetParameterPowerStateDeviceState(
398         );
399 
400 
401     SYSTEM_POWER_STATE
402     GetParameterPowerStateSystemState(
403         );
404 
405 
406     POWER_ACTION
407     GetParameterPowerShutdownType(
408         );
409 
410 
411     MdFileObject
412     GetFileObject(
413         VOID
414         );
415 
416 
417     //
418     // Get/Set Method for IO_STACK_LOCATION.Parameters.QueryDeviceRelations
419     //
420 
421     DEVICE_RELATION_TYPE
422     GetParameterQDRType(
423         );
424 
425     VOID
426     SetParameterQDRType(
427         __in DEVICE_RELATION_TYPE DeviceRelation
428         );
429 
430     //
431     // Get/Set Methods for IO_STACK_LOCATION.Parameters.DeviceCapabilities
432     //
433 
434     PDEVICE_CAPABILITIES
435     GetParameterDeviceCapabilities(
436         );
437 
438     VOID
439     SetCurrentDeviceObject(
440         __in MdDeviceObject  DeviceObject
441         );
442 
443     MdDeviceObject
444     GetDeviceObject(
445         VOID
446         );
447 
448     VOID
449     SetParameterDeviceCapabilities(
450         __in PDEVICE_CAPABILITIES DeviceCapabilities
451         );
452 
453 
454     //
455     // Get/Set Methods for IO_STACK_LOCATION.Parameters.Write.ByteOffset.QuadPart
456     //
457 
458     LONGLONG
459     GetParameterWriteByteOffsetQuadPart(
460         );
461 
462 
463     VOID
464     SetNextParameterWriteByteOffsetQuadPart(
465         __in LONGLONG DeviceOffset
466         );
467 
468     //
469     // Get/Set Methods for IO_STACK_LOCATION.Parameters.Write.Length
470     //
471 
472     ULONG
473     GetCurrentParameterWriteLength(
474         );
475 
476     VOID
477     SetNextParameterWriteLength(
478         __in ULONG IoLength
479         );
480 
481     PVOID*
482     GetNextStackParameterOthersArgument1Pointer(
483         );
484 
485     VOID
486     SetNextStackParameterOthersArgument1(
487         __in PVOID Argument1
488         );
489 
490     PVOID*
491     GetNextStackParameterOthersArgument2Pointer(
492         );
493 
494     PVOID*
495     GetNextStackParameterOthersArgument4Pointer(
496         );
497 
498     //
499     // Get/Set Methods for IO_STACK_LOCATION.Parameters.StartDevice
500     //
501 
502     PCM_RESOURCE_LIST
503     GetParameterAllocatedResources(
504         );
505 
506 
507     VOID
508     SetParameterAllocatedResources(
509         __in PCM_RESOURCE_LIST AllocatedResources
510         );
511 
512 
513     PCM_RESOURCE_LIST
514     GetParameterAllocatedResourcesTranslated(
515         );
516 
517 
518     VOID
519     SetParameterAllocatedResourcesTranslated(
520         __in PCM_RESOURCE_LIST AllocatedResourcesTranslated
521         );
522 
523     //
524     // Get Method for IO_STACK_LOCATION.Parameters.QueryDeviceText
525     //
526 
527     LCID
528     GetParameterQueryDeviceTextLocaleId(
529         );
530 
531 
532     DEVICE_TEXT_TYPE
533     GetParameterQueryDeviceTextType(
534         );
535 
536     //
537     // Get Method for IO_STACK_LOCATION.Parameters.SetLock
538     //
539 
540     BOOLEAN
541     GetParameterSetLockLock(
542         );
543 
544     //
545     // Get Method for IO_STACK_LOCATION.Parameters.QueryId
546     //
547 
548     BUS_QUERY_ID_TYPE
549     GetParameterQueryIdType(
550         );
551 
552     //
553     // Get/Set Methods for IO_STACK_LOCATION.Parameters.QueryInterface
554     //
555 
556     PINTERFACE
557     GetParameterQueryInterfaceInterface(
558         );
559 
560 
561     const GUID*
562     GetParameterQueryInterfaceType(
563         );
564 
565 
566     USHORT
567     GetParameterQueryInterfaceVersion(
568         );
569 
570 
571     USHORT
572     GetParameterQueryInterfaceSize(
573         );
574 
575 
576     PVOID
577     GetParameterQueryInterfaceInterfaceSpecificData(
578         );
579 
580     VOID
581     SetParameterQueryInterfaceInterface(
582         __in PINTERFACE Interface
583         );
584 
585     VOID
586     SetParameterQueryInterfaceType(
587         __in const GUID* InterfaceType
588         );
589 
590     VOID
591     SetParameterQueryInterfaceVersion(
592         __in USHORT Version
593         );
594 
595     VOID
596     SetParameterQueryInterfaceSize(
597         __in USHORT Size
598         );
599 
600     VOID
601     SetParameterQueryInterfaceInterfaceSpecificData(
602         __in PVOID InterfaceSpecificData
603         );
604 
605     //
606     // Get Method for IO_STACK_LOCATION.Parameters.UsageNotification
607     //
608 
609     DEVICE_USAGE_NOTIFICATION_TYPE
610     GetParameterUsageNotificationType(
611         );
612 
613 
614     BOOLEAN
615     GetParameterUsageNotificationInPath(
616         );
617 
618 
619     VOID
620     SetParameterUsageNotificationInPath(
621         __in BOOLEAN InPath
622         );
623 
624 
625     BOOLEAN
626     GetNextStackParameterUsageNotificationInPath(
627         );
628 
629     ULONG
630     GetParameterIoctlCode(
631         VOID
632         );
633 
634     ULONG
635     GetParameterIoctlCodeBufferMethod(
636         VOID
637         );
638 
639     ULONG
640     GetParameterIoctlInputBufferLength(
641         VOID
642         );
643 
644     ULONG
645     GetParameterIoctlOutputBufferLength(
646         VOID
647         );
648 
649     PVOID
650     GetParameterIoctlType3InputBuffer(
651         VOID
652         );
653 
654     //
655     // Set Methods for IO_STACK_LOCATION.Parameters.DeviceControl members
656     //
657 
658     VOID
659     SetParameterIoctlCode(
660         __in ULONG DeviceIoControlCode
661         );
662 
663     VOID
664     SetParameterIoctlInputBufferLength(
665         __in ULONG InputBufferLength
666         );
667 
668     VOID
669     SetParameterIoctlOutputBufferLength(
670         __in ULONG OutputBufferLength
671         );
672 
673     VOID
674     SetParameterIoctlType3InputBuffer(
675         __in PVOID Type3InputBuffer
676         );
677 
678     ULONG
679     GetParameterReadLength(
680         VOID
681         );
682 
683     ULONG
684     GetParameterWriteLength(
685         VOID
686         );
687 
688     VOID
689     SetNextStackFlags(
690         __in UCHAR Flags
691         );
692 
693     VOID
694     SetNextStackFileObject(
695         _In_ MdFileObject FileObject
696         );
697 
698     PVOID
699     GetCurrentParametersPointer(
700         VOID
701         );
702 
703     //
704     // Methods for IO_STACK_LOCATION
705     //
706 
707     VOID
708     ClearNextStack(
709         VOID
710         );
711 
712     VOID
713     ClearNextStackLocation(
714         VOID
715         );
716 
717     VOID
718     InitNextStackUsingStack(
719         __in FxIrp* Irp
720         );
721 
722     ULONG
723     GetCurrentFlags(
724         VOID
725         );
726 
727     VOID
728     FreeIrp(
729         VOID
730         );
731 
732     MdEThread
733     GetThread(
734         VOID
735         );
736 
737     BOOLEAN
738     Is32bitProcess(
739         VOID
740         );
741 
742 private:
743 
744     static
745     NTSTATUS
746     _IrpSynchronousCompletion(
747         __in MdDeviceObject DeviceObject,
748         __in MdIrp OriginalIrp,
749         __in PVOID Context
750         );
751 
752 public:
753 
754     _Must_inspect_result_
755     static
756     MdIrp
757     AllocateIrp(
758         _In_ CCHAR StackSize,
759         _In_opt_ FxDevice* Device = NULL
760         );
761 
762     static
763     MdIrp
764     GetIrpFromListEntry(
765         __in PLIST_ENTRY Ple
766         );
767 
768     _Must_inspect_result_
769     static
770     NTSTATUS
771     RequestPowerIrp(
772         __in MdDeviceObject  DeviceObject,
773         __in UCHAR  MinorFunction,
774         __in POWER_STATE  PowerState,
775         __in MdRequestPowerComplete  CompletionFunction,
776         __in PVOID  Context
777         );
778 
779     PIO_STATUS_BLOCK
780     GetStatusBlock(
781         VOID
782         );
783 
784     PVOID
785     GetDriverContext(
786         );
787 
788     ULONG
789     GetDriverContextSize(
790         );
791 
792     VOID
793     CopyParameters(
794         _Out_ PWDF_REQUEST_PARAMETERS Parameters
795         );
796 
797     VOID
798     CopyStatus(
799         _Out_ PIO_STATUS_BLOCK StatusBlock
800         );
801 
802     BOOLEAN
803     HasStack(
804         _In_ UCHAR StackCount
805         );
806 
807     BOOLEAN
808     IsCurrentIrpStackLocationValid(
809         VOID
810         );
811 
812 #if (FX_CORE_MODE == FX_CORE_USER_MODE)
813 
814     IWudfIoIrp*
815     GetIoIrp(
816         VOID
817         );
818 
819     IWudfPnpIrp*
820     GetPnpIrp(
821         VOID
822         );
823 #endif
824 
825 };
826 
827 //
828 // FxAutoIrp adds value to FxIrp by automatically freeing the associated MdIrp
829 // when it goes out of scope
830 //
831 struct FxAutoIrp : public FxIrp {
832 
833     FxAutoIrp(
834         __in_opt MdIrp Irp = NULL
835         ) :
836         FxIrp(Irp)
837     {
838     }
839 
840 
841     ~FxAutoIrp();
842 };
843 
844 #endif //  _FXIRP_H_
845