lovehunterboy
驱动小牛
驱动小牛
  • 注册日期2008-05-29
  • 最后登录2010-04-16
  • 粉丝2
  • 关注0
  • 积分67分
  • 威望463点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1050回复:0

求助:这段代码看不懂,请大牛帮忙指点一下!

楼主#
更多 发布于:2008-09-16 21:09
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) );
}
游客

返回顶部