阅读:1050回复:0
求助:这段代码看不懂,请大牛帮忙指点一下!
filespy里的一段代码,红色的部分会执行吗?经过前面的
ASSERT(FlagOn(pContext->Flags,CTXFL_InExtensionList)); RtlInterlockedClearBitsDiscardReturn(&pContext->Flags,CTXFL_InExtensionList); 到这里pContext->Flags已经是CTXFL_InExtensionList了啊: VOID SpyDeleteAllContexts ( IN PDEVICE_OBJECT DeviceObject ) /*++ Routine Description: This will free all existing contexts for the given device Arguments: DeviceObject - Device to operate on Return Value: None. --*/ { PFILESPY_DEVICE_EXTENSION devExt = DeviceObject->DeviceExtension; PLIST_ENTRY link; PSPY_STREAM_CONTEXT pContext; PFSRTL_PER_STREAM_CONTEXT ctxCtrl; LIST_ENTRY localHead; ULONG deleteNowCount = 0; ULONG deleteDeferredCount = 0; ULONG deleteInCallbackCount = 0; PAGED_CODE(); ASSERT(IS_FILESPY_DEVICE_OBJECT(DeviceObject)); INC_STATS(TotalContextDeleteAlls); InitializeListHead( &localHead ); try { // // Acquire list lock // SpyAcquireContextLockExclusive( devExt ); // // Walk the list of contexts and release each one // while (!IsListEmpty( &devExt->CtxList )) { // // Unlink from top of list // link = RemoveHeadList( &devExt->CtxList ); pContext = CONTAINING_RECORD( link, SPY_STREAM_CONTEXT, ExtensionLink ); // // Mark that we are unlinked from the list. We need to do this // because of the race condition between this routine and the // deleteCallback from the FS. // ASSERT(FlagOn(pContext->Flags,CTXFL_InExtensionList)); RtlInterlockedClearBitsDiscardReturn(&pContext->Flags,CTXFL_InExtensionList);//经过这步下面的判断还有什么用? // // Try and remove ourselves from the File Systems context control // structure. Note that the file system could be trying to tear // down their context control right now. If they are then we // will get a NULL back from this call. This is OK because it // just means that they are going to free the memory, not us. // NOTE: This will be safe because we are holding the ContextLock // exclusively. If this were happening then they would be // blocked in the callback routine on this lock which // means the file system has not freed the memory for // this yet. // if (FlagOn(pContext->Flags,CTXFL_InStreamList)) { ctxCtrl = FsRtlRemovePerStreamContext( pContext->ContextCtrl.InstanceId, devExt,//removes a per-stream context structure from the list of per-stream contexts associated with a file stream. pContext->ContextCtrl.InstanceId ); // // Always clear the flag wether we found it in the list or // not. We can have the flag set and not be in the list if // after we acquired the context list lock we context swapped // and the file system is right now in SpyDeleteContextCallback // waiting on the list lock. // RtlInterlockedClearBitsDiscardReturn(&pContext->Flags,CTXFL_InStreamList); // // Handle wether we were still attached to the file or not. // if (NULL != ctxCtrl) { ASSERT(pContext == CONTAINING_RECORD(ctxCtrl,SPY_STREAM_CONTEXT,ContextCtrl)); // // To save time we don't do the free now (with the lock // held). We link into a local list and then free it // later (in this routine). We can do this because it // is no longer on any list. // InsertHeadList( &localHead, &pContext->ExtensionLink ); } else { // // The context is in the process of being freed by the file // system. Don't do anything with it here, it will be // freed in the callback. // INC_STATS(TotalContextsNotFoundInStreamList); INC_LOCAL_STATS(deleteInCallbackCount); } } } } finally { SpyReleaseContextLock( devExt ); } // // We have removed everything from the list and released the list lock. // Go through and figure out what entries we can free and then do it. // while (!IsListEmpty( &localHead )) { // // Get next entry of the list and get our context back // link = RemoveHeadList( &localHead ); pContext = CONTAINING_RECORD( link, SPY_STREAM_CONTEXT, ExtensionLink ); // // Decrement the USE count and see if we can free it now // ASSERT(pContext->UseCount > 0); if (InterlockedDecrement( &pContext->UseCount ) <= 0) {//如果流上下文引用计数为0,则释放他 // // No one is using it, free it now // SpyFreeContext( pContext );//调用ExFreePool、UseCount减1 INC_STATS(TotalContextNonDeferredFrees); INC_LOCAL_STATS(deleteNowCount); } else { // // Someone still has a pointer to it, it will get deleted // later when they release // INC_LOCAL_STATS(deleteDeferredCount); SPY_LOG_PRINT( SPYDEBUG_TRACE_CONTEXT_OPS, ("FileSpy!SpyDeleteAllContexts: DEFERRED (%p) Fl=%02x Use=%d \"%wZ\"\n", pContext, pContext->Flags, pContext->UseCount, &pContext->Name) ); } } SPY_LOG_PRINT( SPYDEBUG_TRACE_CONTEXT_OPS, ("FileSpy!SpyDeleteAllContexts: %3d deleted now, %3d deferred, %3d close contention \"%wZ\"\n", deleteNowCount, deleteDeferredCount, deleteInCallbackCount, &devExt->DeviceName) ); } |
|