1 /*++
2
3 Copyright (c) Microsoft Corporation
4
5 Module Name:
6
7 FxIoTargetSelf.cpp
8
9 Abstract:
10
11 This module implements the IO Target APIs
12
13 Author:
14
15
16
17
18 Environment:
19
20 Both kernel and user mode
21
22 Revision History:
23
24 --*/
25
26
27 #include "../fxtargetsshared.hpp"
28
29 extern "C" {
30 #if defined(EVENT_TRACING)
31 #include "FxIoTargetSelf.tmh"
32 #endif
33 }
34
FxIoTargetSelf(_In_ PFX_DRIVER_GLOBALS FxDriverGlobals,_In_ USHORT ObjectSize)35 FxIoTargetSelf::FxIoTargetSelf(
36 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,
37 _In_ USHORT ObjectSize
38 ) :
39 FxIoTarget(FxDriverGlobals, ObjectSize, FX_TYPE_IO_TARGET_SELF),
40 m_DispatchQueue(NULL)
41 {
42 }
43
~FxIoTargetSelf()44 FxIoTargetSelf::~FxIoTargetSelf()
45 {
46 }
47
48 FxIoQueue*
GetDispatchQueue(UCHAR MajorFunction)49 FxIoTargetSelf::GetDispatchQueue(
50 UCHAR MajorFunction
51 )
52 /*++
53 Routine Description:
54 Returns a pointer to the queue to which an IO sent to the Self
55 io target must be sent to
56
57 Arguments:
58
59 MajorFunction - IRP_MJ_READ, IRP_MJ_WRITE, or IRP_MJ_DEVICE_CONTROL
60
61 Returns:
62
63 FxIoQueue*
64
65 --*/
66 {
67 if (m_DispatchQueue != NULL) {
68 return m_DispatchQueue;
69 }
70
71 return m_Device->m_PkgIo->GetDispatchQueue(MajorFunction);
72 }
73
74 VOID
Send(_In_ MdIrp Irp)75 FxIoTargetSelf::Send(
76 _In_ MdIrp Irp
77 )
78 /*++
79 Routine Description:
80 send an MdIrp to the Self IO Target.
81
82 Arguments:
83
84 MdIrp for IRP_MJ_READ, IRP_MJ_WRITE, or IRP_MJ_DEVICE_CONTROL
85
86 Returns:
87
88 VOID
89
90 Implementation Note:
91
92 Function body inspired by WdfDeviceWdmDispatchIrpToIoQueue API.
93
94 --*/
95 {
96 FxIrp irp(Irp);
97 FxIoQueue* queue;
98 NTSTATUS status;
99 UCHAR majorFunction;
100 FxIoInCallerContext* ioInCallerCtx;
101
102 #if (FX_CORE_MODE == FX_CORE_USER_MODE)
103
104 //
105 // Prepare the request to forward to the inteternal target.
106 //
107 (static_cast<IWudfIoIrp2*>(Irp))->PrepareToForwardToSelf();
108
109 #else
110 //
111 // Set Next Stack Location
112 //
113 irp.SetNextIrpStackLocation();
114
115 //
116 // Set Device Object.
117 //
118 irp.SetCurrentDeviceObject(m_Device->GetDeviceObject());
119 #endif
120
121 majorFunction = irp.GetMajorFunction();
122
123 //
124 // Retrieve Queue
125 //
126 queue = GetDispatchQueue(majorFunction);
127
128 if (queue == NULL) {
129 DoTraceLevelMessage(
130 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
131 "Send WDFIOTARGET %p, No Dispatch Queue Found for Major Function %d",
132 GetObjectHandle(), majorFunction);
133 status = STATUS_INVALID_DEVICE_STATE;
134 goto Fail;
135 }
136
137 //
138 // Only read/writes/ctrls/internal_ctrls IRPs are allowed to be sent to
139 // Self IO Target
140 //
141 if (m_Device->GetDispatchPackage(majorFunction) != m_Device->m_PkgIo) {
142 status = STATUS_INVALID_PARAMETER;
143 DoTraceLevelMessage(
144 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
145 "Only Read/Write/Control/Internal-Control IRPs can be "
146 "forwarded to Self IO Target 0x%p, %!IRPMJ!, "
147 "IRP_MN %x, Device 0x%p, %!STATUS!",
148 GetHandle(), majorFunction, irp.GetMinorFunction(),
149 m_Device->GetObjectHandle(), status);
150 FxVerifierDbgBreakPoint(GetDriverGlobals());
151 goto Fail;
152 }
153
154 //
155 // Retrieve the InContextCallback function
156 //
157 ioInCallerCtx = m_Device->m_PkgIo->GetIoInCallerContextCallback(
158 queue->GetCxDeviceInfo());
159
160 //
161 // DispatchStep2 will convert the IRP into a WDFREQUEST, queue it and if
162 // possible dispatch the request to the driver.
163 // If a failure occurs, DispatchStep2 completes teh Irp
164 //
165 (VOID) m_Device->m_PkgIo->DispatchStep2(Irp, ioInCallerCtx, queue);
166 return;
167
168 Fail:
169
170 irp.SetStatus(status);
171 irp.SetInformation(0);
172 irp.CompleteRequest(IO_NO_INCREMENT);
173
174 return;
175 }
176
177