1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7     FxDriver.hpp
8 
9 Abstract:
10 
11     This is the definition of the FxDriver object.
12 
13 Author:
14 
15 
16 
17 Environment:
18 
19     Both kernel and user mode
20 
21 Revision History:
22 
23 --*/
24 
25 #ifndef _FXDRIVER_H_
26 #define _FXDRIVER_H_
27 
28 #include "fxdrivercallbacks.hpp"
29 
30 
31 //
32 // Unique value to retrieve the FxDriver* from the PDEVICE_OBJECT.
33 //
34 #define FX_TRACE_INFO_ID   (FxDriver::_GetTraceInfoExtension)
35 
36 //
37 // Structure to hold WMI Callback info
38 //
39 struct FxTraceInfo {
40     MdDriverObject           DriverObject;
41     PFN_WDF_TRACE_CALLBACK   Callback;
42     PVOID                    Context;
43 };
44 
45 //
46 // Unique value to retrieve the FxDriver* from the MdDriverObject.  Use a value
47 // that is not exposed to the driver writer through the dispatch table or WDM.
48 //
49 #define FX_DRIVER_ID ((PVOID)FxDriver::GetFxDriver)
50 
51 //
52 // The following are support classes for FxDriver
53 //
54 class FxDriver : public FxNonPagedObject, public IFxHasCallbacks
55 {
56 friend class FxDevice;
57 friend class FxPackage;
58 friend class FxWmiIrpHandler;
59 
60 private:
61 
62     MxDriverObject m_DriverObject;
63     UNICODE_STRING m_RegistryPath;
64 
65     BOOLEAN m_DebuggerConnected;
66 
67     //
68     // Callbacks to device driver
69     //
70     FxDriverDeviceAdd m_DriverDeviceAdd;
71 
72     //
73     // This represents any constraints on callbacks
74     // to the device driver that may be inherited
75     // by child devices and their objects
76     //
77     WDF_EXECUTION_LEVEL       m_ExecutionLevel;
78     WDF_SYNCHRONIZATION_SCOPE m_SynchronizationScope;
79 
80     //
81     // Frameworks objects that raise event callbacks into the device
82     // driver provide spinlock and mutex based callback locks
83     // to allow proper synchronization between the driver and
84     // these callbacks.
85     //
86     // Some events must be passive level, while others at dispatch
87     // level, thus the need for two locks.
88     //
89     // The objects internal state is protected by the FxNonPagedObject
90     // lock inherited by the object, and is different from the callback
91     // locks.
92     //
93     FxCallbackMutexLock m_CallbackMutexLock;
94 
95     //
96     // These pointers allow the proper lock to be acquired
97     // based on the configuration with a minimal of runtime
98     // checks. This is configured by ConfigureConstraints()
99     //
100     FxCallbackLock* m_CallbackLockPtr;
101     FxObject*       m_CallbackLockObjectPtr;
102 
103     //
104     // This is the Driver-wide configuration
105     //
106     WDF_DRIVER_CONFIG m_Config;
107 
108     //
109     // Deferred Disposal List
110     //
111     FxDisposeList*    m_DisposeList;
112 
113 #if FX_IS_USER_MODE
114     //
115     // A handle to the driver service parameters key.
116     // The framework does not have permission to open it with
117     // write access from user mode, so we keep a pre-opened one.
118     //
119     HKEY m_DriverParametersKey;
120 #endif
121 
122 private:
123 
124     static
125     MdDriverAddDeviceType AddDevice;
126 
127 public:
128 
129     // This is public to allow the C function FxCoreDriverUnload to call it
130     FxDriverUnload              m_DriverUnload;
131 
132     FxDriver(
133         __in MdDriverObject DriverObject,
134         __in PWDF_DRIVER_CONFIG DriverConfig,
135         __in PFX_DRIVER_GLOBALS FxDriverGlobals
136         );
137 
138     ~FxDriver();
139 
140     static
141     VOID
142     _InitializeDriverName(
143         __in PFX_DRIVER_GLOBALS Globals,
144         __in PCUNICODE_STRING RegistryPath
145         );
146 
147     static
148     VOID
149     _InitializeTag(
150         __in PFX_DRIVER_GLOBALS Globals,
151         __in PWDF_DRIVER_CONFIG Config
152         );
153 
154     static
155     FxDriver*
156     GetFxDriver(
157         __in MdDriverObject DriverObject
158         );
159 
160     _Must_inspect_result_
161     NTSTATUS
162     AllocateDriverObjectExtensionAndStoreFxDriver(
163         VOID
164         );
165 
166 
167 
168 
169 
170 
171 
172 
173 
174 
175 
176 
177 
178 
179 
180 
181 
182 
183 
184 
185 
186 
187 
188 
189 
190 
191 
192 
193 
194 
195 
196 
197 
198 
199 
200     __inline
201     WDFDRIVER
GetHandle(VOID)202     GetHandle(
203         VOID
204         )
205     {
206         return (WDFDRIVER) GetObjectHandle();
207     }
208 
209 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
210 
211     _Must_inspect_result_
212     NTSTATUS
213     AddDevice(
214         __in MdDeviceObject PhysicalDeviceObject
215         );
216 
217 #else
218 
219     _Must_inspect_result_
220     NTSTATUS
221     FxDriver::AddDevice(
222         _In_  IWudfDeviceStack *        DevStack,
223         _In_  LPCWSTR                   KernelDeviceName,
224         _In_opt_ HKEY                   PdoKey,
225         _In_  LPCWSTR                   ServiceName,
226         _In_  LPCWSTR                   DevInstanceID,
227         _In_  ULONG                     DriverID
228         );
229 #endif
230 
231     VOID
232     InitializeInternal(
233         VOID
234         );
235 
236     _Must_inspect_result_
237     FxString *
238     GetRegistryPath(
239         VOID
240         );
241 
242     PUNICODE_STRING
GetRegistryPathUnicodeString(VOID)243     GetRegistryPathUnicodeString(
244         VOID
245         )
246     {
247         return &m_RegistryPath;
248     }
249 
250     __inline
251     MdDriverObject
GetDriverObject(VOID)252     GetDriverObject(
253         VOID
254         )
255     {
256         return m_DriverObject.GetObject();
257     }
258 
259     _Must_inspect_result_
260     NTSTATUS
261     Initialize(
262         __in PCUNICODE_STRING RegistryPath,
263         __in PWDF_DRIVER_CONFIG Config,
264         __in_opt PWDF_OBJECT_ATTRIBUTES DriverAttributes
265         );
266 
267     //
268     // The following methods support the callback constraints
269     // and handle locking and deferral
270     //
271     VOID
272     ConfigureConstraints(
273         __in_opt PWDF_OBJECT_ATTRIBUTES DriverAttributes
274         );
275 
276     //
277     // IFxHasCallbacks Support
278     //
279 
280     virtual
281     VOID
GetConstraints(__out WDF_EXECUTION_LEVEL * ExecutionLevel,__out WDF_SYNCHRONIZATION_SCOPE * SynchronizationScope)282     GetConstraints(
283         __out WDF_EXECUTION_LEVEL*       ExecutionLevel,
284         __out WDF_SYNCHRONIZATION_SCOPE* SynchronizationScope
285         ) {
286 
287         if (ExecutionLevel != NULL) {
288             *ExecutionLevel = m_ExecutionLevel;
289         }
290 
291         if (SynchronizationScope != NULL) {
292             *SynchronizationScope = m_SynchronizationScope;
293         }
294     }
295 
296     virtual
297     FxCallbackLock*
GetCallbackLockPtr(__deref_out FxObject ** LockObject)298     GetCallbackLockPtr(
299         __deref_out FxObject** LockObject
300         ) {
301 
302         if (LockObject != NULL) {
303             *LockObject = m_CallbackLockObjectPtr;
304         }
305 
306         return m_CallbackLockPtr;
307     }
308 
309     //
310     // IFxAssociation Support
311     //
312     virtual
313     NTSTATUS
QueryInterface(__inout FxQueryInterfaceParams * Params)314     QueryInterface(
315         __inout FxQueryInterfaceParams* Params
316         )
317     {
318         switch (Params->Type) {
319         case FX_TYPE_DRIVER:
320             *Params->Object = (FxDriver*) this;
321             break;
322 
323         default:
324             return FxNonPagedObject::QueryInterface(Params); // __super call
325         }
326 
327         return STATUS_SUCCESS;
328     }
329 
330     virtual
331     VOID
DeleteObject(VOID)332     DeleteObject(
333         VOID
334         )
335     {
336         //
337         // If diposed at > PASSIVE, we will cause a deadlock in FxDriver::Dispose
338         // when we call into  the dispose list to wait for empty when we are in
339         // the context of the dispose list's work item.
340         //
341         ASSERT(Mx::MxGetCurrentIrql() == PASSIVE_LEVEL);
342 
343         FxNonPagedObject::DeleteObject(); // __super call
344     }
345 
346     virtual
347     BOOLEAN
348     Dispose(
349         VOID
350         );
351 
352     __inline
353     FxDisposeList*
GetDisposeList()354     GetDisposeList(
355         )
356     {
357         return m_DisposeList;
358     }
359 
360     __inline
361     PFN_WDF_DRIVER_DEVICE_ADD
GetDriverDeviceAddMethod()362     GetDriverDeviceAddMethod(
363         )
364     {
365         return m_DriverDeviceAdd.Method;
366     }
367 
368     static
369     MdDriverUnloadType Unload;
370 
371 #if FX_IS_USER_MODE
372 private:
373 
374     //
375     // Open the handle to the driver service parameters key
376     // that we keep opened for use from user mode.
377     //
378     NTSTATUS
379     OpenParametersKey(
380         VOID
381         );
382 
383     VOID
384     ClearDriverObjectFxDriver(
385         VOID
386         );
387 
388 public:
389 
390     __inline
391     HKEY
GetDriverParametersKey(VOID)392     GetDriverParametersKey(
393         VOID
394         )
395     {
396         return m_DriverParametersKey;
397     }
398 #endif
399 
400 #if (FX_CORE_MODE == FX_CORE_USER_MODE)
401 
402     VOID
SetDriverObjectFlag(_In_ FxDriverObjectUmFlags Flag)403     SetDriverObjectFlag(
404         _In_ FxDriverObjectUmFlags Flag
405         )
406     {
407         m_DriverObject.SetDriverObjectFlag(Flag);
408     }
409 
410     BOOLEAN
IsDriverObjectFlagSet(_In_ FxDriverObjectUmFlags Flag)411     IsDriverObjectFlagSet(
412         _In_ FxDriverObjectUmFlags Flag
413         )
414     {
415         return m_DriverObject.IsDriverObjectFlagSet(Flag);
416     }
417 
418 #endif
419 
420 };
421 
422 #endif // _FXDRIVER_H_
423