1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxTransactionedList.hpp 8 9 Abstract: 10 11 This module defines the abstract FxTransactionedList class. 12 13 Author: 14 15 16 17 Environment: 18 19 Both kernel and user mode 20 21 Revision History: 22 23 --*/ 24 25 #ifndef _FXTRANSACTIONEDLIST_H_ 26 #define _FXTRANSACTIONEDLIST_H_ 27 28 enum FxListTransactionAction { 29 FxTransactionActionNothing = 1, 30 FxTransactionActionAdd, 31 FxTransactionActionRemove, 32 }; 33 34 struct FxTransactionedEntry { 35 friend FxTransactionedList; 36 FxTransactionedEntryFxTransactionedEntry37 FxTransactionedEntry( 38 __in_opt FxObject* Object = NULL 39 ) 40 { 41 m_Transaction = FxTransactionActionNothing; 42 m_TransactionedObject = Object; 43 InitializeListHead(&m_ListLink); 44 InitializeListHead(&m_TransactionLink); 45 } 46 47 VOID SetTransactionedObjectFxTransactionedEntry48 SetTransactionedObject( 49 __in FxObject* Object 50 ) 51 { 52 m_TransactionedObject = Object; 53 } 54 55 FxObject* GetTransactionedObjectFxTransactionedEntry56 GetTransactionedObject( 57 VOID 58 ) 59 { 60 return m_TransactionedObject; 61 } 62 63 static 64 FxTransactionedEntry* _FromEntryFxTransactionedEntry65 _FromEntry( 66 __in PLIST_ENTRY Entry 67 ) 68 { 69 return CONTAINING_RECORD(Entry, FxTransactionedEntry, m_ListLink); 70 } 71 72 FxListTransactionAction GetTransactionActionFxTransactionedEntry73 GetTransactionAction( 74 VOID 75 ) 76 { 77 return m_Transaction; 78 } 79 80 private: 81 LIST_ENTRY m_ListLink; 82 83 LIST_ENTRY m_TransactionLink; 84 85 FxListTransactionAction m_Transaction; 86 87 FxObject* m_TransactionedObject; 88 }; 89 90 class FxTransactionedList : public FxStump { 91 public: 92 FxTransactionedList(); 93 94 ~FxTransactionedList(); 95 96 VOID 97 LockForEnum( 98 __in PFX_DRIVER_GLOBALS FxDriverGlobals 99 ); 100 101 VOID 102 UnlockFromEnum( 103 __in PFX_DRIVER_GLOBALS FxDriverGlobals 104 ); 105 106 NTSTATUS 107 Add( 108 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 109 __in FxTransactionedEntry* Entry 110 ); 111 112 VOID 113 Remove( 114 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 115 __in FxTransactionedEntry* Entry 116 ); 117 118 _Must_inspect_result_ 119 FxTransactionedEntry* 120 GetNextEntry( 121 __in_opt FxTransactionedEntry* Entry 122 ); 123 124 BOOLEAN 125 Deleting( 126 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 127 __in_opt MxEvent* DeleteDoneEvent 128 ); 129 130 protected: 131 virtual 132 VOID 133 AcquireLock( 134 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 135 __out PKIRQL Irql 136 ) =0; 137 138 virtual 139 VOID 140 ReleaseLock( 141 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 142 __in KIRQL Irql 143 ) =0; 144 145 virtual 146 _Must_inspect_result_ 147 NTSTATUS ProcessAdd(__in FxTransactionedEntry * Entry)148 ProcessAdd( 149 __in FxTransactionedEntry* Entry 150 ) 151 { 152 UNREFERENCED_PARAMETER(Entry); 153 154 return STATUS_SUCCESS; 155 } 156 157 virtual 158 VOID EntryAdded(__in FxTransactionedEntry * Entry)159 EntryAdded( 160 __in FxTransactionedEntry* Entry 161 ) 162 { 163 UNREFERENCED_PARAMETER(Entry); 164 } 165 166 virtual 167 VOID EntryRemoved(__in FxTransactionedEntry * Entry)168 EntryRemoved( 169 __in FxTransactionedEntry* Entry 170 ) 171 { 172 UNREFERENCED_PARAMETER(Entry); 173 } 174 175 virtual 176 BOOLEAN Compare(__in FxTransactionedEntry * Entry,__in PVOID Data)177 Compare( 178 __in FxTransactionedEntry* Entry, 179 __in PVOID Data 180 ) 181 { 182 UNREFERENCED_PARAMETER(Entry); 183 UNREFERENCED_PARAMETER(Data); 184 185 return TRUE; 186 } 187 188 VOID 189 SearchForAndRemove( 190 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 191 __in PVOID EntryData 192 ); 193 194 _Must_inspect_result_ 195 FxTransactionedEntry* 196 GetNextEntryLocked( 197 __in_opt FxTransactionedEntry* Entry 198 ); 199 200 BOOLEAN 201 RemoveLocked( 202 __in FxTransactionedEntry* Entry 203 ); 204 205 VOID 206 ProcessTransactionList( 207 __in PLIST_ENTRY ReleaseHead 208 ); 209 210 VOID 211 ProcessObjectsToRelease( 212 __in PLIST_ENTRY ReleaseHead 213 ); 214 215 protected: 216 LIST_ENTRY m_ListHead; 217 218 LIST_ENTRY m_TransactionHead; 219 220 MxEvent* m_DeletingDoneEvent; 221 222 ULONG m_ListLockedRecursionCount; 223 224 BOOLEAN m_DeleteOnRemove; 225 226 BOOLEAN m_Deleting; 227 228 // 229 // The base class does not use this field, but to save space in the size of 230 // the derived structures, we place it here after the BOOLEANs and there is 231 // minimal structure byte packing. 232 // 233 UCHAR m_Retries; 234 }; 235 236 237 class FxSpinLockTransactionedList : public FxTransactionedList { 238 239 public: 240 FxSpinLockTransactionedList(); 241 242 protected: 243 244 __drv_raisesIRQL(DISPATCH_LEVEL) 245 __drv_maxIRQL(DISPATCH_LEVEL) 246 virtual 247 VOID 248 AcquireLock( 249 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 250 __out PKIRQL Irql 251 ); 252 253 __drv_requiresIRQL(DISPATCH_LEVEL) 254 virtual 255 VOID 256 ReleaseLock( 257 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 258 __in __drv_restoresIRQL KIRQL Irql 259 ); 260 261 MxLock m_ListLock; 262 }; 263 264 class FxWaitLockTransactionedList : public FxTransactionedList { 265 266 public: 267 FxWaitLockTransactionedList(__in PFX_DRIVER_GLOBALS FxDriverGlobals)268 FxWaitLockTransactionedList( 269 __in PFX_DRIVER_GLOBALS FxDriverGlobals 270 ) 271 { 272 UNREFERENCED_PARAMETER(FxDriverGlobals); 273 } 274 275 __inline 276 NTSTATUS 277 #ifdef _MSC_VER 278 #pragma prefast(suppress:__WARNING_UNMATCHED_DEFN, "_Must_inspect_result_ not needed in kernel mode as the function always succeeds"); 279 #endif Initialize(VOID)280 Initialize( 281 VOID 282 ) 283 { 284 return m_StateChangeListLock.Initialize(); 285 } 286 287 protected: 288 virtual 289 _Acquires_lock_(_Global_critical_region_) 290 VOID 291 AcquireLock( 292 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 293 __out PKIRQL Irql 294 ); 295 296 virtual 297 _Releases_lock_(_Global_critical_region_) 298 VOID 299 ReleaseLock( 300 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 301 __in KIRQL Irql 302 ); 303 304 FxWaitLockInternal m_StateChangeListLock; 305 }; 306 307 #endif // _FXTRANSACTIONEDLIST_H_ 308