q065700
驱动牛犊
驱动牛犊
  • 注册日期2007-11-09
  • 最后登录2008-05-08
  • 粉丝0
  • 关注0
  • 积分530分
  • 威望54点
  • 贡献值0点
  • 好评度53点
  • 原创分0分
  • 专家分0分
阅读:2851回复:5

漏文件,不知道原因,请兄弟们帮忙看看

楼主#
更多 发布于:2008-02-19 15:26
用下面的代码不知道为什么会漏掉文件有的时候。

if (NT_SUCCESS(Status) && (STATUS_REPARSE != Status) && SfIsObjectFile(FileObject))
        {
            PFILE_CONTEXT FileCtxPtr2 = NULL;
            BOOLEAN NewElement = FALSE;
            
                      
            FileCtxPtr->FsContext = FileObject->FsContext;
            
            ExAcquireFastMutex(&DevExt->FsCtxTableMutex);
        
                        FileCtxPtr2 = RtlLookupElementGenericTable(&DevExt->FsCtxTable, FileCtxPtr);
            if (FileCtxPtr2)
            {
               ++FileCtxPtr2->RefCount;
                
                KdPrint(("SfCreate2: FileCtxPtr2->Name = %s\n", FileCtxPtr2->Name));
            }
            else
            {
                
                FileCtxPtr2 = RtlInsertElementGenericTable( &DevExt->FsCtxTable,
                                                            FileCtxPtr,
                                                            sizeof(FILE_CONTEXT),
                                                            &NewElement  //设置为False,返回以个空的指针
                                                            );
                
                FileCtxPtr2->RefCount = 1;
                
                ASSERT(FileName);
                
                strcpy(FileCtxPtr2->Name, fullPathName);
                KdPrint(("SfCreate: FileCtxPtr2->Name = %s\n", FileCtxPtr2->Name));

                KeInitializeEvent(&FileCtxPtr2->Event, SynchronizationEvent, TRUE);
            
            }
            
            FileCtxPtr2->DeleteOnClose = DeleteOnClose;
            
            ExReleaseFastMutex(&DevExt->FsCtxTableMutex);
            
            KeWaitForSingleObject(&FileCtxPtr2->Event, Executive, KernelMode, FALSE, NULL);
            
            KeSetEvent(&FileCtxPtr2->Event, IO_NO_INCREMENT, FALSE);
AlexSho
驱动牛犊
驱动牛犊
  • 注册日期2008-01-10
  • 最后登录2017-12-01
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望164点
  • 贡献值0点
  • 好评度45点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2008-02-19 17:32
Close是怎么处理的。
q065700
驱动牛犊
驱动牛犊
  • 注册日期2007-11-09
  • 最后登录2008-05-08
  • 粉丝0
  • 关注0
  • 积分530分
  • 威望54点
  • 贡献值0点
  • 好评度53点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2008-02-22 09:41
    //
    //  Log (if it is turned on) and pass the request on.
    //
    //
    // We only care about volume filter device object
    //

    if (!DevExt->DiskDeviceObject)
    {
        IoSkipCurrentIrpStackLocation(Irp);
        return IoCallDriver(DevExt->AttachedToDeviceObject, Irp);
    }
    
    if (((FileObject->Flags & FO_STREAM_FILE) == FO_STREAM_FILE) ||
        (FileObject->SectionObjectPointer &&
        (CcGetFileObjectFromSectionPtrs(FileObject->SectionObjectPointer) == FileObject)))
    {
    }
    else
    {
        FileCtxHdr.FsContext = FileObject->FsContext;
        
        ExAcquireFastMutex(&DevExt->FsCtxTableMutex);
        FileCtxPtr = RtlLookupElementGenericTable(&DevExt->FsCtxTable, &FileCtxHdr);
        if (FileCtxPtr)
        {
            //KdPrint(("SfClose: %s\n", FileCtxPtr->Name));

            if (FileCtxPtr->RefCount > 0)
                --FileCtxPtr->RefCount;
            
            if ((0 == FileCtxPtr->RefCount) &&
                (!FileObject->SectionObjectPointer ||
                (!FileObject->SectionObjectPointer->DataSectionObject &&
                !FileObject->SectionObjectPointer->ImageSectionObject)))
            {
                //KdPrint(("SfClose: %s\n", FileCtxPtr->Name));

                RtlDeleteElementGenericTable(&DevExt->FsCtxTable, &FileCtxHdr);
            }
        }
        ExReleaseFastMutex(&DevExt->FsCtxTableMutex);
    }
    
    IoSkipCurrentIrpStackLocation(Irp);
    return IoCallDriver(DevExt->AttachedToDeviceObject, Irp);
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
地板#
发布于:2008-02-22 10:46
可能你的系统里面装有其他过滤驱动,建议对FO_STREAM_FILE的单独计数。如果不用支持2K的话,直接用PerStreamContexts更简单,又高效。

FO_STREAM_FILE的单独计数参考下面的代码:

DispatchCreate:

STATUS_CONTINUE_COMPLETION = FsfForwardIrpSyncronously(devExt->NLExtHeader.AttachedToDeviceObject, Irp);
if (NT_SUCCESS(status) && (status != STATUS_REPARSE)) {

    PFO_CONTEXT         foctx;
    NTSTATUS            localStatus;

    foctx = (PFO_CONTEXT) ExAllocateFromPagedLookasideList(&gFsfFoContextLookasideList);
    if (!foctx) {
        break;
    }

    foctx->FileObject = irpSp->FileObject;

    genericTableIdx = GetGenericTableIndex(irpSp->FileObject->FsContext);
    ctxHdr.FsContext = irpSp->FileObject->FsContext;

    ExAcquireFastMutex(&devExt->FsContextMutex[genericTableIdx]);
    ctxPtr = RtlInsertElementGenericTable(
        &devExt->FsContextTable[genericTableIdx], &ctxHdr,
        sizeof(FS_CONTEXT), &newElement);
    ASSERTLINE(ctxPtr);
    if (!ctxPtr) {
        ExReleaseFastMutex(&devExt->FsContextMutex[genericTableIdx]);
        ExFreeToPagedLookasideList(&gFsfFoContextLookasideList, foctx);
        break;
    }

    if (newElement) {
        ctxPtr->RefCount = 1;
        InitializeListHead(&ctxPtr->List);
    } else {
        ++ctxPtr->RefCount;
    }
    InsertHeadList(&ctxPtr->List, &foctx->Entry);
    ExReleaseFastMutex(&devExt->FsContextMutex[genericTableIdx]);
}


DispatchClose:
    genericTableIdx = GetGenericTableIndex(irpSp->FileObject->FsContext);
    ctxHdr.FsContext = irpSp->FileObject->FsContext;

    ExAcquireFastMutex(&devExt->FsContextMutex[genericTableIdx]);
    ctxPtr = RtlLookupElementGenericTable(&devExt->FsContextTable[genericTableIdx], &ctxHdr);
    if (ctxPtr) {

        PLIST_ENTRY        entry;

        for (entry = ctxPtr->List.Flink;
            entry != &ctxPtr->List;
            entry = entry->Flink) {                

            if (((PFO_CONTEXT) entry)->FileObject == irpSp->FileObject) {
                RemoveEntryList(entry);
                ExFreeToPagedLookasideList(&gFsfFoContextLookasideList, entry);
                if ((irpSp->FileObject->Flags & FO_STREAM_FILE) == FO_STREAM_FILE) {
                    --ctxPtr->RefCount;
                }
                break;
            }
        }

        if (((irpSp->FileObject->Flags & FO_STREAM_FILE) != FO_STREAM_FILE)
            && (!irpSp->FileObject->SectionObjectPointer
                || (CcGetFileObjectFromSectionPtrs(irpSp->FileObject->SectionObjectPointer) != irpSp->FileObject))) {

            if (ctxPtr->RefCount > 0) {
                --ctxPtr->RefCount;
            }
        }

        if ((0 == ctxPtr->RefCount)
            && (!irpSp->FileObject->SectionObjectPointer
                || (!irpSp->FileObject->SectionObjectPointer->DataSectionObject
                    && !irpSp->FileObject->SectionObjectPointer->ImageSectionObject))) {

            while (!IsListEmpty(&ctxPtr->List)) {    

                entry = RemoveHeadList(&ctxPtr->List);
                ExFreeToPagedLookasideList(&gFsfFoContextLookasideList, entry);
            }

            RtlDeleteElementGenericTable(&devExt->FsContextTable[genericTableIdx], ctxPtr);
        }
    }
    ExReleaseFastMutex(&devExt->FsContextMutex[genericTableIdx]);
  
q065700
驱动牛犊
驱动牛犊
  • 注册日期2007-11-09
  • 最后登录2008-05-08
  • 粉丝0
  • 关注0
  • 积分530分
  • 威望54点
  • 贡献值0点
  • 好评度53点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2008-02-22 11:30
去试试,谢谢了先
sundyhyb
驱动牛犊
驱动牛犊
  • 注册日期2008-08-22
  • 最后登录2013-10-09
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望208点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2012-07-17 09:43
非常荣幸能看到tooflat 老大的提示!

tooflat 老大,能不能说清楚一点呀?

比如GetGenericTableIndex,是什么函数?Google都找不到说明.
还有PFO_CONTEXT  是怎么自己定义的么?关键元素是什么?等等
缺失一环,就不知道怎么用.

盼望老大能给个比较完全的说明
驱网无线,快乐无限
游客

返回顶部