1 #ifndef _SCAVENGR_H_ 2 #define _SCAVENGR_H_ 3 4 extern KMUTEX RxScavengerMutex; 5 6 #define RX_SCAVENGER_FINALIZATION_TIME_INTERVAL (10 * 1000 * 1000 * 10) 7 8 typedef struct _RX_SCAVENGER_ENTRY 9 { 10 LIST_ENTRY List; 11 UCHAR Type; 12 UCHAR Operation; 13 UCHAR State; 14 UCHAR Flags; 15 struct _RX_SCAVENGER_ENTRY *pContinuationEntry; 16 } RX_SCAVENGER_ENTRY, *PRX_SCAVENGER_ENTRY; 17 18 #define RxInitializeScavengerEntry(ScavengerEntry) \ 19 (ScavengerEntry)->State = 0; \ 20 (ScavengerEntry)->Flags = 0; \ 21 (ScavengerEntry)->Type = 0; \ 22 (ScavengerEntry)->Operation = 0; \ 23 InitializeListHead(&(ScavengerEntry)->List); \ 24 (ScavengerEntry)->pContinuationEntry = NULL 25 26 #define RxAcquireScavengerMutex() KeWaitForSingleObject(&RxScavengerMutex, Executive, KernelMode, FALSE, NULL) 27 #define RxReleaseScavengerMutex() KeReleaseMutex(&RxScavengerMutex, FALSE) 28 29 VOID 30 RxMarkFobxOnCleanup( 31 _In_ PFOBX pFobx, 32 _Out_ PBOOLEAN NeedPurge); 33 34 VOID 35 RxMarkFobxOnClose( 36 _In_ PFOBX Fobx); 37 38 NTSTATUS 39 RxPurgeRelatedFobxs( 40 PNET_ROOT NetRoot, 41 PRX_CONTEXT RxContext, 42 BOOLEAN AttemptFinalization, 43 PFCB PurgingFcb); 44 45 #define DONT_ATTEMPT_FINALIZE_ON_PURGE FALSE 46 #define ATTEMPT_FINALIZE_ON_PURGE TRUE 47 48 typedef enum _RDBSS_SCAVENGER_STATE 49 { 50 RDBSS_SCAVENGER_INACTIVE, 51 RDBSS_SCAVENGER_DORMANT, 52 RDBSS_SCAVENGER_ACTIVE, 53 RDBSS_SCAVENGER_SUSPENDED 54 } RDBSS_SCAVENGER_STATE, *PRDBSS_SCAVENGER_STATE; 55 56 typedef struct _RDBSS_SCAVENGER 57 { 58 RDBSS_SCAVENGER_STATE State; 59 LONG MaximumNumberOfDormantFiles; 60 volatile LONG NumberOfDormantFiles; 61 LARGE_INTEGER TimeLimit; 62 ULONG SrvCallsToBeFinalized; 63 ULONG NetRootsToBeFinalized; 64 ULONG VNetRootsToBeFinalized; 65 ULONG FcbsToBeFinalized; 66 ULONG SrvOpensToBeFinalized; 67 ULONG FobxsToBeFinalized; 68 LIST_ENTRY SrvCallFinalizationList; 69 LIST_ENTRY NetRootFinalizationList; 70 LIST_ENTRY VNetRootFinalizationList; 71 LIST_ENTRY FcbFinalizationList; 72 LIST_ENTRY SrvOpenFinalizationList; 73 LIST_ENTRY FobxFinalizationList; 74 LIST_ENTRY ClosePendingFobxsList; 75 RX_WORK_ITEM WorkItem; 76 KEVENT SyncEvent; 77 KEVENT ScavengeEvent; 78 PETHREAD CurrentScavengerThread; 79 PNET_ROOT CurrentNetRootForClosePendingProcessing; 80 PFCB CurrentFcbForClosePendingProcessing; 81 KEVENT ClosePendingProcessingSyncEvent; 82 } RDBSS_SCAVENGER, *PRDBSS_SCAVENGER; 83 84 #define RxInitializeRdbssScavenger(Scavenger, ScavengerTimeLimit) \ 85 (Scavenger)->State = RDBSS_SCAVENGER_INACTIVE; \ 86 (Scavenger)->SrvCallsToBeFinalized = 0; \ 87 (Scavenger)->NetRootsToBeFinalized = 0; \ 88 (Scavenger)->VNetRootsToBeFinalized = 0; \ 89 (Scavenger)->FcbsToBeFinalized = 0; \ 90 (Scavenger)->SrvOpensToBeFinalized = 0; \ 91 (Scavenger)->FobxsToBeFinalized = 0; \ 92 (Scavenger)->NumberOfDormantFiles = 0; \ 93 (Scavenger)->MaximumNumberOfDormantFiles = 50; \ 94 (Scavenger)->CurrentFcbForClosePendingProcessing = NULL; \ 95 (Scavenger)->CurrentNetRootForClosePendingProcessing = NULL; \ 96 if ((ScavengerTimeLimit).QuadPart == 0) \ 97 { \ 98 (Scavenger)->TimeLimit.QuadPart = RX_SCAVENGER_FINALIZATION_TIME_INTERVAL; \ 99 } \ 100 else \ 101 { \ 102 (Scavenger)->TimeLimit.QuadPart = (ScavengerTimeLimit).QuadPart; \ 103 } \ 104 KeInitializeEvent(&((Scavenger)->SyncEvent), NotificationEvent, FALSE); \ 105 KeInitializeEvent(&((Scavenger)->ScavengeEvent), SynchronizationEvent, TRUE); \ 106 KeInitializeEvent(&((Scavenger)->ClosePendingProcessingSyncEvent), NotificationEvent, FALSE); \ 107 InitializeListHead(&(Scavenger)->SrvCallFinalizationList); \ 108 InitializeListHead(&(Scavenger)->NetRootFinalizationList); \ 109 InitializeListHead(&(Scavenger)->VNetRootFinalizationList); \ 110 InitializeListHead(&(Scavenger)->SrvOpenFinalizationList); \ 111 InitializeListHead(&(Scavenger)->FcbFinalizationList); \ 112 InitializeListHead(&(Scavenger)->FobxFinalizationList); \ 113 InitializeListHead(&(Scavenger)->ClosePendingFobxsList) 114 115 typedef struct _PURGE_SYNCHRONIZATION_CONTEXT 116 { 117 LIST_ENTRY ContextsAwaitingPurgeCompletion; 118 BOOLEAN PurgeInProgress; 119 } PURGE_SYNCHRONIZATION_CONTEXT, *PPURGE_SYNCHRONIZATION_CONTEXT; 120 121 VOID 122 RxInitializePurgeSyncronizationContext( 123 _In_ PPURGE_SYNCHRONIZATION_CONTEXT PurgeSyncronizationContext); 124 125 BOOLEAN 126 RxScavengeRelatedFobxs( 127 _In_ PFCB Fcb); 128 129 VOID 130 RxScavengeFobxsForNetRoot( 131 PNET_ROOT NetRoot, 132 PFCB PurgingFcb, 133 BOOLEAN SynchronizeWithScavenger); 134 135 VOID 136 RxpMarkInstanceForScavengedFinalization( 137 PVOID Instance); 138 139 VOID 140 RxpUndoScavengerFinalizationMarking( 141 _In_ PVOID Instance); 142 143 BOOLEAN 144 RxScavengeVNetRoots( 145 _In_ PRDBSS_DEVICE_OBJECT RxDeviceObject); 146 147 #if (_WIN32_WINNT >= 0x0600) 148 VOID 149 RxSynchronizeWithScavenger( 150 _In_ PRX_CONTEXT RxContext, 151 _In_ PFCB Fcb); 152 #else 153 VOID 154 RxSynchronizeWithScavenger( 155 _In_ PRX_CONTEXT RxContext); 156 #endif 157 158 #endif 159