1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 FxMessageDispatchUm.cpp
8
9 Abstract:
10
11 Implements the host process dispatcher object. See header file for
12 details.
13
14 Author:
15
16
17
18 Environment:
19
20 User mode only
21
22 Revision History:
23
24
25
26 --*/
27
28 #include "fxmin.hpp"
29 #include "fxldrum.h"
30
31 extern "C"
32 {
33 #include "FxMessageDispatchUm.tmh"
34 }
35
36 // {cba20727-0910-4a8a-aada-c31d5cf5bf20}
37 extern const GUID IID_FxMessageDispatch =
38 {0xcba20727, 0x0910, 0x4a8a, { 0xaa, 0xda, 0xc3, 0x1d, 0x5c, 0xf5, 0xbf, 0x20 }};
39
40 //
41 // Manager functions.
42 //
43 NTSTATUS
_CreateAndInitialize(_In_ PFX_DRIVER_GLOBALS DriverGlobals,_In_ FxDevice * Device,_Out_ FxMessageDispatch ** ppWudfDispatcher)44 FxMessageDispatch::_CreateAndInitialize(
45 _In_ PFX_DRIVER_GLOBALS DriverGlobals,
46 _In_ FxDevice* Device,
47 _Out_ FxMessageDispatch ** ppWudfDispatcher
48 )
49 {
50 HRESULT hr = S_OK;
51 FxMessageDispatch * pWudfDispatcher = NULL;
52 NTSTATUS status;
53
54 *ppWudfDispatcher = NULL;
55
56 pWudfDispatcher = new (DriverGlobals) FxMessageDispatch(Device);
57 if (NULL == pWudfDispatcher) {
58 hr = E_OUTOFMEMORY;
59 DoTraceLevelMessage(DriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
60 "Memory allocation failure. Cannot create Dispatcher object.\n");
61 goto Done;
62 }
63
64 *ppWudfDispatcher = pWudfDispatcher;
65
66 Done:
67
68 if (FAILED(hr)) {
69 status = Device->NtStatusFromHr(hr);
70 }
71 else {
72 status = STATUS_SUCCESS;
73 }
74
75 return status;
76 }
77
78 //
79 // IUnknown
80 //
81 ULONG
AddRef()82 FxMessageDispatch::AddRef()
83 {
84 LONG cRefs = InterlockedIncrement( &m_cRefs );
85
86 //
87 // This allows host to manage the lifetime of FxDevice.
88 //
89 m_Device->ADDREF(this);
90
91 return cRefs;
92 }
93
94
95 ULONG
Release()96 FxMessageDispatch::Release()
97 {
98 LONG cRefs = InterlockedDecrement( &m_cRefs );
99
100 if (0 == cRefs) {
101 //
102 // The lifetime of this object is controlled by FxDevice
103 // object (the container object), and not by this ref count. FxDevice
104 // will delete this object in its destructior.
105 //
106 DO_NOTHING();
107 }
108
109 //
110 // This allows host to manage the lifetime of FxDevice. If this is the last
111 // release on FxDevice, FxDevice will e deleted and this object will be
112 // deleted as part of FxDevice destructor.
113 //
114 m_Device->RELEASE(this);
115
116 return cRefs;
117 }
118
119 HRESULT
QueryInterface(_In_ const IID & iid,_Out_ void ** ppv)120 FxMessageDispatch::QueryInterface(
121 _In_ const IID& iid,
122 _Out_ void ** ppv
123 )
124 {
125 if ( NULL == ppv ) {
126 return E_INVALIDARG;
127 }
128
129 if ( iid == IID_IUnknown) {
130 *ppv = static_cast<IUnknown *> (this);
131 }
132 else if ( iid == IID_IFxMessageDispatch ) {
133 *ppv = static_cast<IFxMessageDispatch *> (this);
134 }
135 else if ( iid == IID_IFxMessageDispatch2 ) {
136 *ppv = static_cast<IFxMessageDispatch2 *> (this);
137 }
138 else if ( iid == IID_FxMessageDispatch ) {
139 *ppv = this;
140 }
141 else {
142 *ppv = NULL;
143 return E_NOINTERFACE;
144 }
145
146 this->AddRef();
147 return S_OK;
148 }
149
150 //
151 // IFxMessageDispatch
152 //
153 void
DispatchPnP(_In_ IWudfIrp * pIrp)154 FxMessageDispatch::DispatchPnP(
155 _In_ IWudfIrp * pIrp
156 )
157 {
158 IWudfPnpIrp * pIPnpIrp = NULL;
159
160 HRESULT hrQI = pIrp->QueryInterface(IID_IWudfPnpIrp, (PVOID*)&pIPnpIrp);
161 FX_VERIFY(INTERNAL, CHECK_QI(hrQI, pIPnpIrp));
162
163 if (IRP_MJ_POWER == pIPnpIrp->GetMajorFunction()) {
164 GetDriverObject()->MajorFunction[IRP_MJ_POWER](GetDeviceObject(),
165 pIrp,
166 NULL);
167 }
168 else {
169 GetDriverObject()->MajorFunction[IRP_MJ_PNP](GetDeviceObject(),
170 pIrp,
171 NULL);
172 }
173
174 SAFE_RELEASE(pIPnpIrp);
175 }
176
177 void
CreateFile(_In_ IWudfIoIrp * pCreateIrp)178 FxMessageDispatch::CreateFile(
179 _In_ IWudfIoIrp * pCreateIrp
180 )
181 {
182 GetDriverObject()->MajorFunction[IRP_MJ_CREATE](GetDeviceObject(),
183 pCreateIrp,
184 NULL);
185 }
186
187 void
DeviceControl(_In_ IWudfIoIrp * pIrp,_In_opt_ IUnknown * pFxContext)188 FxMessageDispatch::DeviceControl(
189 _In_ IWudfIoIrp * pIrp,
190 _In_opt_ IUnknown * pFxContext
191 )
192 {
193 GetDriverObject()->MajorFunction[IRP_MJ_DEVICE_CONTROL](GetDeviceObject(),
194 pIrp,
195 pFxContext);
196 }
197
198 void
ReadFile(_In_ IWudfIoIrp * pIrp,_In_opt_ IUnknown * pFxContext)199 FxMessageDispatch::ReadFile(
200 _In_ IWudfIoIrp * pIrp,
201 _In_opt_ IUnknown * pFxContext
202 )
203 {
204 GetDriverObject()->MajorFunction[IRP_MJ_READ](GetDeviceObject(), pIrp, pFxContext);
205 }
206
207 void
WriteFile(_In_ IWudfIoIrp * pIrp,_In_opt_ IUnknown * pFxContext)208 FxMessageDispatch::WriteFile(
209 _In_ IWudfIoIrp * pIrp,
210 _In_opt_ IUnknown * pFxContext
211 )
212 {
213 GetDriverObject()->MajorFunction[IRP_MJ_WRITE](GetDeviceObject(), pIrp, pFxContext);
214 }
215
216 void
CleanupFile(_In_ IWudfIoIrp * pIrp,_In_ IUnknown * pFxContext)217 FxMessageDispatch::CleanupFile(
218 _In_ IWudfIoIrp * pIrp,
219 _In_ IUnknown * pFxContext
220 )
221 {
222 GetDriverObject()->MajorFunction[IRP_MJ_CLEANUP](GetDeviceObject(), pIrp, pFxContext);
223 }
224
225 void
CloseFile(_In_ IWudfIoIrp * pIrp,_In_ IUnknown * pFxContext)226 FxMessageDispatch::CloseFile(
227 _In_ IWudfIoIrp * pIrp,
228 _In_ IUnknown * pFxContext
229 )
230 {
231 GetDriverObject()->MajorFunction[IRP_MJ_CLOSE](GetDeviceObject(), pIrp, pFxContext);
232 }
233
234 void
FlushBuffers(_In_ IWudfIoIrp * pIrp,_In_opt_ IUnknown * pFxContext)235 FxMessageDispatch::FlushBuffers(
236 _In_ IWudfIoIrp * pIrp,
237 _In_opt_ IUnknown * pFxContext
238 )
239 {
240 GetDriverObject()->MajorFunction[IRP_MJ_FLUSH_BUFFERS](GetDeviceObject(),
241 pIrp,
242 pFxContext);
243 }
244
245 void
QueryInformationFile(_In_ IWudfIoIrp * pIrp,_In_opt_ IUnknown * pFxContext)246 FxMessageDispatch::QueryInformationFile(
247 _In_ IWudfIoIrp * pIrp,
248 _In_opt_ IUnknown * pFxContext
249 )
250 {
251 GetDriverObject()->MajorFunction[IRP_MJ_QUERY_INFORMATION](
252 GetDeviceObject(),
253 pIrp,
254 pFxContext
255 );
256 }
257
258 void
SetInformationFile(_In_ IWudfIoIrp * pIrp,_In_opt_ IUnknown * pFxContext)259 FxMessageDispatch::SetInformationFile(
260 _In_ IWudfIoIrp * pIrp,
261 _In_opt_ IUnknown * pFxContext
262 )
263 {
264 GetDriverObject()->MajorFunction[IRP_MJ_SET_INFORMATION](GetDeviceObject(),
265 pIrp,
266 pFxContext);
267 }
268
269 VOID
GetPreferredTransferMode(_Out_ UMINT::WDF_DEVICE_IO_BUFFER_RETRIEVAL * RetrievalMode,_Out_ UMINT::WDF_DEVICE_IO_TYPE * RWPreference,_Out_ UMINT::WDF_DEVICE_IO_TYPE * IoctlPreference)270 FxMessageDispatch::GetPreferredTransferMode(
271 _Out_ UMINT::WDF_DEVICE_IO_BUFFER_RETRIEVAL *RetrievalMode,
272 _Out_ UMINT::WDF_DEVICE_IO_TYPE *RWPreference,
273 _Out_ UMINT::WDF_DEVICE_IO_TYPE *IoctlPreference
274 )
275 {
276 FxDevice::GetPreferredTransferMode(GetDeviceObject(),
277 RetrievalMode,
278 (WDF_DEVICE_IO_TYPE*)RWPreference,
279 (WDF_DEVICE_IO_TYPE*)IoctlPreference);
280 }
281
282 ULONG
GetDirectTransferThreshold(VOID)283 FxMessageDispatch::GetDirectTransferThreshold(
284 VOID
285 )
286 {
287 return m_Device->GetDirectTransferThreshold();
288 }
289
290 NTSTATUS
ProcessWmiPowerQueryOrSetData(_In_ RdWmiPowerAction Action,_Out_ BOOLEAN * QueryResult)291 FxMessageDispatch::ProcessWmiPowerQueryOrSetData(
292 _In_ RdWmiPowerAction Action,
293 _Out_ BOOLEAN *QueryResult
294 )
295 {
296 return m_Device->ProcessWmiPowerQueryOrSetData(Action, QueryResult);
297 }
298
299 WUDF_INTERFACE_CONTEXT
RemoteInterfaceArrival(_In_ LPCGUID pDeviceInterfaceGuid,_In_ PCWSTR pSymbolicLink)300 FxMessageDispatch::RemoteInterfaceArrival(
301 _In_ LPCGUID pDeviceInterfaceGuid,
302 _In_ PCWSTR pSymbolicLink
303 )
304 {
305 return FxDevice::RemoteInterfaceArrival(GetDeviceObject(),
306 pDeviceInterfaceGuid,
307 pSymbolicLink);
308 }
309
310 void
RemoteInterfaceRemoval(_In_ WUDF_INTERFACE_CONTEXT RemoteInterfaceID)311 FxMessageDispatch::RemoteInterfaceRemoval(
312 _In_ WUDF_INTERFACE_CONTEXT RemoteInterfaceID
313 )
314 {
315 FxDevice::RemoteInterfaceRemoval(GetDeviceObject(),
316 RemoteInterfaceID);
317 }
318
319 BOOL
TransportQueryID(_In_ DWORD Id,_In_ PVOID DataBuffer,_In_ SIZE_T cbDataBufferSize)320 FxMessageDispatch::TransportQueryID(
321 _In_ DWORD Id,
322 _In_ PVOID DataBuffer,
323 _In_ SIZE_T cbDataBufferSize
324 )
325 {
326 return FxDevice::TransportQueryId(GetDeviceObject(),
327 Id,
328 DataBuffer,
329 cbDataBufferSize);
330 }
331
332 void
PoFxDevicePowerRequired(void)333 FxMessageDispatch::PoFxDevicePowerRequired(
334 void
335 )
336 {
337 FxDevice::PoFxDevicePowerRequired(GetDeviceObject());
338 }
339
340 void
PoFxDevicePowerNotRequired(void)341 FxMessageDispatch::PoFxDevicePowerNotRequired(
342 void
343 )
344 {
345 FxDevice::PoFxDevicePowerNotRequired(GetDeviceObject());
346 }
347
348 //
349 // Additional public functions.
350 //
351
352 //
353 // Returns the Dispatcher object from the given interface without
354 // incrementing the refcount.
355 //
356 FxMessageDispatch*
_GetObjFromItf(_In_ IFxMessageDispatch * pIFxMessageDispatch)357 FxMessageDispatch::_GetObjFromItf(
358 _In_ IFxMessageDispatch* pIFxMessageDispatch
359 )
360 {
361 FxMessageDispatch * pWudfDispatcher = NULL;
362 HRESULT hrQI = pIFxMessageDispatch->QueryInterface(
363 IID_FxMessageDispatch,
364 reinterpret_cast<void**>(&pWudfDispatcher)
365 );
366 FX_VERIFY(INTERNAL, CHECK_QI(hrQI, pWudfDispatcher));
367 pWudfDispatcher->Release(); //release the reference taken by QI
368 return pWudfDispatcher;
369 }
370
371 //
372 // Returns the specified interface from the given object without
373 // incrementing the refcount.
374 //
375 IFxMessageDispatch*
_GetDispatcherItf(_In_ FxMessageDispatch * pWudfDispatcher)376 FxMessageDispatch::_GetDispatcherItf(
377 _In_ FxMessageDispatch* pWudfDispatcher
378 )
379 {
380 IFxMessageDispatch * pIFxMessageDispatch = NULL;
381 HRESULT hrQI = pWudfDispatcher->QueryInterface(IID_IFxMessageDispatch,
382 (PVOID*)&pIFxMessageDispatch);
383 FX_VERIFY(INTERNAL, CHECK_QI(hrQI, pIFxMessageDispatch));
384 pIFxMessageDispatch->Release(); //release the reference taken by QI
385 return pIFxMessageDispatch;
386 }
387