sundyhyb
驱动牛犊
驱动牛犊
  • 注册日期2008-08-22
  • 最后登录2013-10-09
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望208点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1883回复:5

sfcreate漏文件,请大家群策群立!

楼主#
更多 发布于:2012-07-17 12:06
我想获得sfwrite中写文件中的数据,按照常规做发首先要
在sfcreate中获得创建的文件名,并调用RtlInsertElementGenericTable(打开的文件名不管),
可是测试时,应用层大量创建文件时,在sfcreate中总是漏掉一部分文件.请大家帮我看看有什么解决办法.
sfcreate中部分代码是:
...

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);
  ...
 
奇怪的是在这个地方
            if (FileCtxPtr2)
            {
              ++FileCtxPtr2->RefCount;    
                KdPrint(("SfCreate2: FileCtxPtr2->Name = %s\n", FileCtxPtr2->Name));
            }
FileCtxPtr2->Name中存放的可能是其他文件名,与本次sfCreate中获得的文件名并不相同.
比如本次sfcreate中获得的文件名原本是d:\aa\aa064.txt,
FileCtxPtr2->Name中存放的却可能是d:\aa\aa032.txt
 
百思不得其解!
驱网无线,快乐无限
sundyhyb
驱动牛犊
驱动牛犊
  • 注册日期2008-08-22
  • 最后登录2013-10-09
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望208点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2012-07-17 12:11
Close的地方是这样处理的


    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);
驱网无线,快乐无限
sundyhyb
驱动牛犊
驱动牛犊
  • 注册日期2008-08-22
  • 最后登录2013-10-09
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望208点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2012-07-17 12:15
在一个贴中tooflat大哥是这样提示的:
可能你的系统里面装有其他过滤驱动,建议对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]);
驱网无线,快乐无限
sundyhyb
驱动牛犊
驱动牛犊
  • 注册日期2008-08-22
  • 最后登录2013-10-09
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望208点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2012-07-17 12:22
但是
PFO_CONTEXT         foctx;是怎么定义的?
GetGenericTableIndex是哪里的函数?
等这些细节问题,有人能提示一下么?

或者有朋友能给出其他解决方法么?
驱网无线,快乐无限
sundyhyb
驱动牛犊
驱动牛犊
  • 注册日期2008-08-22
  • 最后登录2013-10-09
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望208点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2012-07-18 16:13
好冷清呀,自己顶一下.
希望大牛们能回帖!
驱网无线,快乐无限
sundyhyb
驱动牛犊
驱动牛犊
  • 注册日期2008-08-22
  • 最后登录2013-10-09
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望208点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2012-07-19 14:51
顶一下!
驱网无线,快乐无限
游客

返回顶部