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