1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxDpc.hpp 8 9 Abstract: 10 11 This module implements a frameworks managed DPC that 12 can synchrononize with driver frameworks object locks. 13 14 Author: 15 16 17 18 Environment: 19 20 kernel mode only 21 22 Revision History: 23 24 25 --*/ 26 27 #ifndef _FXDPC_H_ 28 #define _FXDPC_H_ 29 30 // 31 // Driver Frameworks DPC Design: 32 // 33 // The driver frameworks provides an optional DPC wrapper object that allows 34 // the creation of a reference counted DPC object that can synchronize 35 // automatically with certain frameworks objects. 36 // 37 // This provides automatic synchronization between the DPC's execution, and the 38 // frameworks objects' event callbacks into the device driver. 39 // 40 // The WDFDPC object is designed to be re-useable, in which it can be re-linked 41 // into the DPC queue after firing. 42 // 43 // In many cases, the KDPC struct is embedded inside another structure that 44 // represents a device command block. These device command blocks are typically 45 // submitted to another device driver. So the calling driver, which is utilizing 46 // the driver frameworks would not likely have an opportunity to make 47 // changes to this. In order to support this, the caller can optionally supply 48 // a DPC object pointer to Initialize, and the WDFDPC object will use this 49 // embedded user supplied DPC object, and pass its address as the RawDpc 50 // parameter to the callback function. 51 // 52 // If the user does not supply a DPC pointer by passing NULL, then the 53 // internal DPC object is used, and RawDPC is NULL. 54 // 55 // Calling GetDpcPtr returns the DPC to be used, and could be 56 // the caller supplied DPC, or the embedded one depending on 57 // whether the caller supplied a user DPC pointer to Initialize. 58 // 59 // The GetDpcPtr allows linking of the WDFDPC object into various DPC 60 // lists by the driver. 61 // 62 63 class FxDpc : public FxNonPagedObject { 64 65 private: 66 67 KDPC m_Dpc; 68 69 // 70 // This is the Framework object who is associated with the DPC 71 // if supplied 72 // 73 FxObject* m_Object; 74 75 // 76 // This is the callback lock for the object this DPC will 77 // synchronize with 78 // 79 FxCallbackLock* m_CallbackLock; 80 81 // 82 // This is the object whose reference count actually controls 83 // the lifetime of the m_CallbackLock 84 // 85 FxObject* m_CallbackLockObject; 86 87 // 88 // This is the user supplied callback function 89 // 90 PFN_WDF_DPC m_Callback; 91 92 // Ensures only one of either Delete or Cleanup runs down the object 93 BOOLEAN m_RunningDown; 94 95 public: 96 static 97 _Must_inspect_result_ 98 NTSTATUS 99 _Create( 100 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 101 __in PWDF_DPC_CONFIG Config, 102 __in PWDF_OBJECT_ATTRIBUTES Attributes, 103 __in FxObject* ParentObject, 104 __out WDFDPC* Dpc 105 ); 106 107 FxDpc( 108 __in PFX_DRIVER_GLOBALS FxDriverGlobals 109 ); 110 111 virtual 112 ~FxDpc( 113 VOID 114 ); 115 116 KDPC* 117 GetDpcPtr( 118 VOID 119 ) 120 { 121 return &m_Dpc; 122 } 123 124 WDFOBJECT 125 GetObject( 126 VOID 127 ) 128 { 129 if (m_Object != NULL) { 130 return m_Object->GetObjectHandle(); 131 } 132 else { 133 return NULL; 134 } 135 } 136 137 /*++ 138 139 Routine Description: 140 141 Initialize the DPC using either the caller supplied DPC 142 struct, or if NULL, our own internal one. 143 144 Arguments: 145 146 Returns: 147 148 NTSTATUS 149 150 --*/ 151 _Must_inspect_result_ 152 NTSTATUS 153 Initialize( 154 __in PWDF_OBJECT_ATTRIBUTES Attributes, 155 __in PWDF_DPC_CONFIG Config, 156 __in FxObject* ParentObject, 157 __out WDFDPC* Dpc 158 ); 159 160 virtual 161 BOOLEAN 162 Dispose( 163 VOID 164 ); 165 166 BOOLEAN 167 Cancel( 168 __in BOOLEAN Wait 169 ); 170 171 VOID 172 DpcHandler( 173 __in PKDPC Dpc, 174 __in PVOID SystemArgument1, 175 __in PVOID SystemArgument2 176 ); 177 178 private: 179 180 // 181 // Called from Dispose, or cleanup list to perform final flushing of any 182 // outstanding DPC's and dereferencing of objects. 183 // 184 VOID 185 FlushAndRundown( 186 ); 187 188 static 189 KDEFERRED_ROUTINE 190 FxDpcThunk; 191 192 static 193 VOID 194 WorkItemThunk( 195 PDEVICE_OBJECT DeviceObject, 196 PVOID Context 197 ); 198 }; 199 200 #endif // _FXDPC_H_ 201 202