lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
阅读:5508回复:12

FFS File System Driver for Windows(源代码)

楼主#
更多 发布于:2007-01-11 11:54
FFS File System Driver for Windows(源代码)
附件名称/大小 下载次数 最后更新
ffsdrv-0[1].5-src.zip (215KB)  729 2007-01-11 11:54

最新喜欢:

snoxsnox
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
沙发#
发布于:2007-01-16 11:17
有没有大俠看过这个代码是干什么的?
不过看这个程序处理Create看起来考虑得很周全.代码风格也挺不错的

NTSTATUS
FFSCreateFile(
    PFFS_IRP_CONTEXT IrpContext,
    PFFS_VCB         Vcb)
{
    NTSTATUS            Status = STATUS_UNSUCCESSFUL;
    PIO_STACK_LOCATION  IrpSp;
    PFFS_FCB            Fcb = NULL;
    PFFS_MCB            FFSMcb = NULL;

    PFFS_FCB            ParentFcb = NULL;
    PFFS_MCB            ParentMcb = NULL;

    BOOLEAN             bParentFcbCreated = FALSE;

    PFFS_CCB            Ccb = NULL;
    PFFSv1_INODE        dinode1;
    PFFSv2_INODE        dinode2;
    BOOLEAN             VcbResourceAcquired = FALSE;
    BOOLEAN             bDir = FALSE;
    BOOLEAN             bFcbAllocated = FALSE;
    BOOLEAN             bCreated = FALSE;
    UNICODE_STRING      FileName;
    PIRP                Irp;

    ULONG               Options;
    ULONG               CreateDisposition;

    BOOLEAN             OpenDirectory;
    BOOLEAN             OpenTargetDirectory;
    BOOLEAN             CreateDirectory;
    BOOLEAN             SequentialOnly;
    BOOLEAN             NoIntermediateBuffering;
    BOOLEAN             IsPagingFile;
    BOOLEAN             DirectoryFile;
    BOOLEAN             NonDirectoryFile;
    BOOLEAN             NoEaKnowledge;
    BOOLEAN             DeleteOnClose;
    BOOLEAN             TemporaryFile;
    BOOLEAN             CaseSensitive;

    ACCESS_MASK         DesiredAccess;
    ULONG               ShareAccess;


    Irp = IrpContext->Irp;
    IrpSp = IoGetCurrentIrpStackLocation(Irp);

    Options  = IrpSp->Parameters.Create.Options;

    DirectoryFile = IsFlagOn(Options, FILE_DIRECTORY_FILE);
    OpenTargetDirectory = IsFlagOn(IrpSp->Flags, SL_OPEN_TARGET_DIRECTORY);

    NonDirectoryFile = IsFlagOn(Options, FILE_NON_DIRECTORY_FILE);
    SequentialOnly = IsFlagOn(Options, FILE_SEQUENTIAL_ONLY);
    NoIntermediateBuffering = IsFlagOn(Options, FILE_NO_INTERMEDIATE_BUFFERING);
    NoEaKnowledge = IsFlagOn(Options, FILE_NO_EA_KNOWLEDGE);
    DeleteOnClose = IsFlagOn(Options, FILE_DELETE_ON_CLOSE);

    CaseSensitive = IsFlagOn(IrpSp->Flags, SL_CASE_SENSITIVE);

    TemporaryFile = IsFlagOn(IrpSp->Parameters.Create.FileAttributes,
            FILE_ATTRIBUTE_TEMPORARY);

    CreateDisposition = (Options >> 24) & 0x000000ff;

    IsPagingFile = IsFlagOn(IrpSp->Flags, SL_OPEN_PAGING_FILE);

    CreateDirectory = (BOOLEAN)(DirectoryFile &&
            ((CreateDisposition == FILE_CREATE) ||
             (CreateDisposition == FILE_OPEN_IF)));

    OpenDirectory   = (BOOLEAN)(DirectoryFile &&
            ((CreateDisposition == FILE_OPEN) ||
             (CreateDisposition == FILE_OPEN_IF)));

    DesiredAccess = IrpSp->Parameters.Create.SecurityContext->DesiredAccess;
    ShareAccess   = IrpSp->Parameters.Create.ShareAccess;

    FileName.Buffer = NULL;

    __try
    {
        ExAcquireResourceExclusiveLite(
                &Vcb->MainResource, TRUE);

        VcbResourceAcquired = TRUE;

        if (Irp->Overlay.AllocationSize.HighPart)
        {
            Status = STATUS_INVALID_PARAMETER;
            __leave;
        }

        if (FS_VERSION == 1)
        {
            if (!(dinode1 = ExAllocatePoolWithTag(
                            PagedPool, DINODE1_SIZE, 'EInd')))
            {
                __leave;
            }

            RtlZeroMemory(dinode1, sizeof(DINODE1_SIZE));
        }
        else
        {
            if (!(dinode2 = ExAllocatePoolWithTag(
                            PagedPool, DINODE2_SIZE, 'EInd')))
            {
                __leave;
            }

            RtlZeroMemory(dinode2, sizeof(DINODE2_SIZE));
        }


        FileName.MaximumLength = IrpSp->FileObject->FileName.MaximumLength;
        FileName.Length = IrpSp->FileObject->FileName.Length;

        FileName.Buffer = ExAllocatePool(PagedPool, FileName.MaximumLength);
        if (!FileName.Buffer)
        {  
            Status = STATUS_INSUFFICIENT_RESOURCES;
            __leave;
        }

        RtlZeroMemory(FileName.Buffer, FileName.MaximumLength);
        RtlCopyMemory(FileName.Buffer, IrpSp->FileObject->FileName.Buffer, FileName.Length);

        if (IrpSp->FileObject->RelatedFileObject)
        {
            ParentFcb = (PFFS_FCB)(IrpSp->FileObject->RelatedFileObject->FsContext);
        }

        if ((FileName.Length > sizeof(WCHAR)) &&
                (FileName.Buffer[1] == L'\\') &&
                (FileName.Buffer[0] == L'\\')) {

            FileName.Length -= sizeof(WCHAR);

            RtlMoveMemory(&FileName.Buffer[0],
                    &FileName.Buffer[1],
                    FileName.Length);

            //
            //  Bad Name if there are still beginning backslashes.
            //

            if ((FileName.Length > sizeof(WCHAR)) &&
                    (FileName.Buffer[1] == L'\\') &&
                    (FileName.Buffer[0] == L'\\'))
            {

                Status = STATUS_OBJECT_NAME_INVALID;

                __leave;
            }
        }

        if (IsFlagOn(Options, FILE_OPEN_BY_FILE_ID))
        {
            Status = STATUS_NOT_IMPLEMENTED;
            __leave;
        }

        FFSPrint((DBG_INFO, "FFSCreateFile: %S (NameLen=%xh) Paging=%xh Option: %xh.\n",
                    FileName.Buffer, FileName.Length, IsPagingFile, IrpSp->Parameters.Create.Options));

        if (ParentFcb)
        {
            ParentMcb = ParentFcb->FFSMcb;
        }

        if (FS_VERSION == 1)
        {
            Status = FFSv1LookupFileName(
                        Vcb,
                        &FileName,
                        ParentMcb,
                        &FFSMcb,
                        dinode1);
        }
        else
        {
            Status = FFSv2LookupFileName(
                        Vcb,
                        &FileName,
                        ParentMcb,
                        &FFSMcb,
                        dinode2);
        }

        if (!NT_SUCCESS(Status))
        {
            UNICODE_STRING  PathName;
            UNICODE_STRING  RealName;
            UNICODE_STRING  RemainName;

            LONG            i = 0;


            PathName = FileName;

            FFSPrint((DBG_INFO, "FFSCreateFile: File %S will be created.\n", PathName.Buffer));

            FFSMcb = NULL;

            if (PathName.Buffer[PathName.Length / 2 - 1] == L'\\')
            {
                if (DirectoryFile)
                {
                    PathName.Length -= 2;
                    PathName.Buffer[PathName.Length / 2] = 0;
                }
                else
                {
                    Status = STATUS_NOT_A_DIRECTORY;
                    __leave;
                }
            }

            if (!ParentMcb)
            {
                if (PathName.Buffer[0] != L'\\')
                {
                    Status = STATUS_OBJECT_PATH_NOT_FOUND;
                    __leave;
                }
                else
                {
                    ParentMcb = Vcb->McbTree;
                }
            }

Dissecting:

            FsRtlDissectName(PathName, &RealName, &RemainName);

            if (((RemainName.Length != 0) && (RemainName.Buffer[0] == L'\\')) ||
                    (RealName.Length >= 256 * sizeof(WCHAR)))
            {
                Status = STATUS_OBJECT_NAME_INVALID;
                __leave;
            }

            if (RemainName.Length != 0)
            {
                PFFS_MCB   RetMcb;

                if (FS_VERSION == 1)
                {
                    Status = FFSv1LookupFileName(
                                Vcb,
                                &RealName,
                                ParentMcb,
                                &RetMcb,
                                dinode1);
                }
                else
                {
                    Status = FFSv2LookupFileName(
                                Vcb,
                                &RealName,
                                ParentMcb,
                                &RetMcb,
                                dinode2);
                }

                if (!NT_SUCCESS(Status))
                {
                    Status = STATUS_OBJECT_PATH_NOT_FOUND;
                    __leave;
                }

                ParentMcb = RetMcb;
                PathName  = RemainName;

                goto Dissecting;
            }

            if (FsRtlDoesNameContainWildCards(&RealName))
            {
                Status = STATUS_OBJECT_NAME_INVALID;
                __leave;
            }

            ParentFcb = ParentMcb->FFSFcb;

            if (!ParentFcb)
            {
                if (FS_VERSION == 1)
                {
                    PFFSv1_INODE pTmpInode = ExAllocatePool(PagedPool,
                            DINODE1_SIZE);
                    if (!pTmpInode)
                    {
                        Status = STATUS_INSUFFICIENT_RESOURCES;
                        __leave;
                    }

                    if(!FFSv1LoadInode(Vcb, ParentMcb->Inode, pTmpInode))
                    {
                        Status = STATUS_OBJECT_PATH_NOT_FOUND;
                        __leave;
                    }

                    ParentFcb = FFSv1AllocateFcb(Vcb, ParentMcb, pTmpInode);

                    if (!ParentFcb)
                    {
                        ExFreePool(pTmpInode);
                        Status = STATUS_INSUFFICIENT_RESOURCES;
                        __leave;
                    }
                }
                else
                {
                    PFFSv2_INODE pTmpInode = ExAllocatePool(PagedPool,
                            DINODE2_SIZE);
                    if (!pTmpInode)
                    {
                        Status = STATUS_INSUFFICIENT_RESOURCES;
                        __leave;
                    }

                    if(!FFSv2LoadInode(Vcb, ParentMcb->Inode, pTmpInode))
                    {
                        Status = STATUS_OBJECT_PATH_NOT_FOUND;
                        __leave;
                    }

                    ParentFcb = FFSv2AllocateFcb(Vcb, ParentMcb, pTmpInode);

                    if (!ParentFcb)
                    {
                        ExFreePool(pTmpInode);
                        Status = STATUS_INSUFFICIENT_RESOURCES;
                        __leave;
                    }
                }

                bParentFcbCreated = TRUE;
                ParentFcb->ReferenceCount++;
            }

            // We need to create a new one ?
            if ((CreateDisposition == FILE_CREATE) ||
                    (CreateDisposition == FILE_OPEN_IF) ||
                    (CreateDisposition == FILE_OVERWRITE_IF))
            {
                if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
                {
                    Status = STATUS_MEDIA_WRITE_PROTECTED;
                    __leave;
                }

                if (IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED))
                {
                    IoSetHardErrorOrVerifyDevice(IrpContext->Irp,
                            Vcb->Vpb->RealDevice);
                    SetFlag(Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME);

                    FFSRaiseStatus(IrpContext, STATUS_MEDIA_WRITE_PROTECTED);
                }

                if (DirectoryFile)
                {
                    if (TemporaryFile)
                    {
                        Status = STATUS_INVALID_PARAMETER;
                        __leave;
                    }
                }

                if (!ParentFcb)
                {
                    Status = STATUS_OBJECT_PATH_NOT_FOUND;
                    __leave;
                }

                if (DirectoryFile)
                {
                    if (ParentFcb->FFSMcb->Inode == FFS_ROOT_INO)
                    {
                        if ((RealName.Length == 0x10) &&
                                memcmp(RealName.Buffer, L"Recycled\0", 0x10) == 0)
                        {
                            SetFlag(IrpSp->Parameters.Create.FileAttributes,
                                    FILE_ATTRIBUTE_READONLY);
                        }
                    }

                    Status = FFSCreateInode(
                                IrpContext,
                                Vcb,
                                ParentFcb,
                                DT_DIR,
                                IrpSp->Parameters.Create.FileAttributes,
                                &RealName);
                }
                else
                {
                    Status = FFSCreateInode(
                                IrpContext,
                                Vcb,
                                ParentFcb,
                                DT_REG,
                                IrpSp->Parameters.Create.FileAttributes,
                                &RealName);
                }

                if (NT_SUCCESS(Status))
                {
                    bCreated = TRUE;

                    Irp->IoStatus.Information = FILE_CREATED;

                    if (FS_VERSION == 1)
                    {
                        Status = FFSv1LookupFileName(
                                    Vcb,
                                    &RealName,
                                    ParentMcb,
                                    &FFSMcb,
                                    dinode1);
                    }
                    else
                    {
                        Status = FFSv2LookupFileName(
                                    Vcb,
                                    &RealName,
                                    ParentMcb,
                                    &FFSMcb,
                                    dinode2);
                    }

                    if (NT_SUCCESS(Status))
                    {
                        if (DirectoryFile)
                        {
                            FFSNotifyReportChange(
                                IrpContext,
                                Vcb,
                                ParentFcb,
                                FILE_NOTIFY_CHANGE_DIR_NAME,
                                FILE_ACTION_ADDED);
                        }
                        else
                        {
                            FFSNotifyReportChange(
                                IrpContext,
                                Vcb,
                                ParentFcb,
                                FILE_NOTIFY_CHANGE_FILE_NAME,
                                FILE_ACTION_ADDED);
                        }
                    }
                    else
                    {
                        FFSBreakPoint();
                    }
                }
                else
                {
                    FFSBreakPoint();
                }
            }
            else if (OpenTargetDirectory)
            {
                if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
                {
                    Status = STATUS_MEDIA_WRITE_PROTECTED;
                    __leave;
                }

                if (!ParentFcb)
                {
                    Status = STATUS_OBJECT_PATH_NOT_FOUND;
                    __leave;
                }

                RtlZeroMemory(IrpSp->FileObject->FileName.Buffer,
                        IrpSp->FileObject->FileName.MaximumLength);
                IrpSp->FileObject->FileName.Length = RealName.Length;

                RtlCopyMemory(IrpSp->FileObject->FileName.Buffer,
                        RealName.Buffer,
                        RealName.Length);

                Fcb = ParentFcb;

                Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
                Status = STATUS_SUCCESS;
            }
            else
            {
                Status = STATUS_OBJECT_NAME_NOT_FOUND;
                __leave;
            }
        }
        else // File / Dir already exists.
        {
            if (OpenTargetDirectory)
            {
                if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
                {
                    Status = STATUS_MEDIA_WRITE_PROTECTED;
                    __leave;
                }

                Irp->IoStatus.Information = FILE_EXISTS;
                Status = STATUS_SUCCESS;

                RtlZeroMemory(IrpSp->FileObject->FileName.Buffer,
                        IrpSp->FileObject->FileName.MaximumLength);
                IrpSp->FileObject->FileName.Length = FFSMcb->ShortName.Length;

                RtlCopyMemory(IrpSp->FileObject->FileName.Buffer,
                        FFSMcb->ShortName.Buffer,
                        FFSMcb->ShortName.Length);

                //Let Mcb pointer to it's parent
                FFSMcb = FFSMcb->Parent;

                goto Openit;
            }

            // We can not create if one exists
            if (CreateDisposition == FILE_CREATE)
            {
                Irp->IoStatus.Information = FILE_EXISTS;
                Status = STATUS_OBJECT_NAME_COLLISION;
                __leave;
            }

            if(IsFlagOn(FFSMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
            {
                if ((CreateDisposition != FILE_OPEN) &&
                        (CreateDisposition != FILE_OPEN_IF))
                {

                    Status = STATUS_OBJECT_NAME_COLLISION;
                    __leave;
                }

                if (NonDirectoryFile)
                {
                    Status = STATUS_FILE_IS_A_DIRECTORY;
                    __leave;
                }

                if (FFSMcb->Inode == FFS_ROOT_INO)
                {
                    if (DeleteOnClose)
                    {
                        Status = STATUS_CANNOT_DELETE;
                        __leave;
                    }

                    if (OpenTargetDirectory)
                    {
                        Status = STATUS_INVALID_PARAMETER;
                        __leave;
                    }
                }
            }

            Irp->IoStatus.Information = FILE_OPENED;
        }

Openit:

        if (FFSMcb)
        {
            Fcb = FFSMcb->FFSFcb;

            if (!Fcb)
            {
                if (FS_VERSION == 1)
                {
                    Fcb = FFSv1AllocateFcb(Vcb, FFSMcb, dinode1);
                    bFcbAllocated = TRUE;
                }
                else
                {
                    Fcb = FFSv2AllocateFcb(Vcb, FFSMcb, dinode2);
                    bFcbAllocated = TRUE;
                }
            }
        }

        if (Fcb)
        {
            if (IsFlagOn(Fcb->Flags, FCB_FILE_DELETED))
            {
                Status = STATUS_FILE_DELETED;
                __leave;
            }

            if (FlagOn(Fcb->Flags, FCB_DELETE_PENDING))
            {
                Status = STATUS_DELETE_PENDING;
                __leave;
            }

            if (bCreated)
            {
                //
                //  This file is just created.
                //

                if (DirectoryFile)
                {
                    UNICODE_STRING EntryName;
                    USHORT  NameBuf[6];

                    RtlZeroMemory(&NameBuf, 6 * sizeof(USHORT));

                    EntryName.Length = EntryName.MaximumLength = 2;
                    EntryName.Buffer = &NameBuf[0];
                    NameBuf[0] = (USHORT)'.';

                    FFSAddEntry(IrpContext, Vcb, Fcb,
                            DT_DIR,
                            Fcb->FFSMcb->Inode,
                            &EntryName);

                    if (FS_VERSION == 1)
                    {
                        FFSv1SaveInode(IrpContext, Vcb,
                                Fcb->FFSMcb->Inode,
                                Fcb->dinode1);
                    }
                    else
                    {
                        FFSv2SaveInode(IrpContext, Vcb,
                                Fcb->FFSMcb->Inode,
                                Fcb->dinode2);
                    }

                    EntryName.Length = EntryName.MaximumLength = 4;
                    EntryName.Buffer = &NameBuf[0];
                    NameBuf[0] = NameBuf[1] = (USHORT)'.';

                    FFSAddEntry(IrpContext, Vcb, Fcb,
                            DT_DIR,
                            Fcb->FFSMcb->Parent->Inode,
                            &EntryName);

                    if (FS_VERSION == 1)
                    {
                        FFSv1SaveInode(IrpContext, Vcb,
                                Fcb->FFSMcb->Inode,
                                Fcb->dinode1);
                    }
                    else
                    {
                        FFSv2SaveInode(IrpContext, Vcb,
                                Fcb->FFSMcb->Inode,
                                Fcb->dinode2);
                    }
                }
                else
                {
                    if (!FFSExpandFile(
                                IrpContext, Vcb, Fcb,
                                &(Irp->Overlay.AllocationSize)))
                    {
                        Status = STATUS_INSUFFICIENT_RESOURCES;
                        __leave;
                    }
                }
            }
            else
            {
                //
                //  This file alreayd exists.
                //

                if (DeleteOnClose)
                {
                    if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
                    {
                        Status = STATUS_MEDIA_WRITE_PROTECTED;
                        __leave;
                    }

                    if (IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED))
                    {
                        Status = STATUS_MEDIA_WRITE_PROTECTED;

                        IoSetHardErrorOrVerifyDevice(IrpContext->Irp,
                                Vcb->Vpb->RealDevice);

                        SetFlag(Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME);

                        FFSRaiseStatus(IrpContext, STATUS_MEDIA_WRITE_PROTECTED);
                    }

                    SetFlag(Fcb->Flags, FCB_DELETE_ON_CLOSE);
                }
                else
                {
                    //
                    // Just to Open file (Open/OverWrite ...)
                    //

                    if ((!IsDirectory(Fcb)) && (IsFlagOn(IrpSp->FileObject->Flags,
                                    FO_NO_INTERMEDIATE_BUFFERING)))
                    {
                        Fcb->Header.IsFastIoPossible = FastIoIsPossible;

                        if (IsFlagOn(IrpSp->FileObject->Flags, FO_CACHE_SUPPORTED) &&
                                (Fcb->SectionObject.DataSectionObject != NULL))
                        {
                            if (Fcb->NonCachedOpenCount == Fcb->OpenHandleCount)
                            {
                                /* IsFlagOn(FileObject->Flags, FO_FILE_MODIFIED) */

                                if(!IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
                                {
                                    CcFlushCache(&Fcb->SectionObject, NULL, 0, NULL);
                                    ClearFlag(Fcb->Flags, FCB_FILE_MODIFIED);
                                }

                                CcPurgeCacheSection(&Fcb->SectionObject,
                                        NULL,
                                        0,
                                        FALSE);
                            }
                        }
                    }
                }
            }

            if (!IsDirectory(Fcb))
            {
                if (!IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
                {
                    if ((CreateDisposition == FILE_SUPERSEDE) && !IsPagingFile)
                    {
                        DesiredAccess |= DELETE;
                    }
                    else if (((CreateDisposition == FILE_OVERWRITE) ||
                                (CreateDisposition == FILE_OVERWRITE_IF)) && !IsPagingFile)
                    {
                        DesiredAccess |= (FILE_WRITE_DATA | FILE_WRITE_EA |
                                FILE_WRITE_ATTRIBUTES);
                    }
                }
            }

            if (Fcb->OpenHandleCount > 0)
            {
                Status = IoCheckShareAccess(DesiredAccess,
                        ShareAccess,
                        IrpSp->FileObject,
                        &(Fcb->ShareAccess),
                        TRUE);

                if (!NT_SUCCESS(Status))
                {
                    __leave;
                }
            }
            else
            {
                IoSetShareAccess(DesiredAccess,
                        ShareAccess,
                        IrpSp->FileObject,
                        &(Fcb->ShareAccess));
            }

            Ccb = FFSAllocateCcb();

            Fcb->OpenHandleCount++;
            Fcb->ReferenceCount++;

            if (IsFlagOn(IrpSp->FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING))
            {
                Fcb->NonCachedOpenCount++;
            }

            Vcb->OpenFileHandleCount++;
            Vcb->ReferenceCount++;

            IrpSp->FileObject->FsContext = (void*)Fcb;
            IrpSp->FileObject->FsContext2 = (void*) Ccb;
            IrpSp->FileObject->PrivateCacheMap = NULL;
            IrpSp->FileObject->SectionObjectPointer = &(Fcb->SectionObject);
            IrpSp->FileObject->Vpb = Vcb->Vpb;

            Status = STATUS_SUCCESS;

            FFSPrint((DBG_INFO, "FFSCreateFile: %s OpenCount: %u ReferCount: %u\n",
                        Fcb->AnsiFileName.Buffer, Fcb->OpenHandleCount, Fcb->ReferenceCount));

            if (!IsDirectory(Fcb) && !NoIntermediateBuffering)
            {
                IrpSp->FileObject->Flags |= FO_CACHE_SUPPORTED;
            }

            if (!bCreated && !IsDirectory(Fcb))
            {
                if (DeleteOnClose ||
                        IsFlagOn(DesiredAccess, FILE_WRITE_DATA) ||
                        (CreateDisposition == FILE_OVERWRITE) ||
                        (CreateDisposition == FILE_OVERWRITE_IF))
                {
                    if (!MmFlushImageSection(&Fcb->SectionObject,
                                MmFlushForWrite))
                    {

                        Status = DeleteOnClose ? STATUS_CANNOT_DELETE :
                            STATUS_SHARING_VIOLATION;
                        __leave;
                    }
                }

                if ((CreateDisposition == FILE_SUPERSEDE) ||
                        (CreateDisposition == FILE_OVERWRITE) ||
                        (CreateDisposition == FILE_OVERWRITE_IF))
                {
                    BOOLEAN bRet;

                    if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
                    {
                        Status = STATUS_MEDIA_WRITE_PROTECTED;
                        __leave;
                    }

                    if (IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED))
                    {
                        IoSetHardErrorOrVerifyDevice(IrpContext->Irp,
                                Vcb->Vpb->RealDevice);
                        SetFlag(Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME);

                        FFSRaiseStatus(IrpContext, STATUS_MEDIA_WRITE_PROTECTED);
                    }

                    Status = FFSSupersedeOrOverWriteFile(IrpContext,
                            Vcb,
                            Fcb,
                            CreateDisposition);

                    if (NT_SUCCESS(Status))
                    {
                        __leave;
                    }

                    bRet = FFSExpandFile(IrpContext,
                            Vcb,
                            Fcb,
                            &(Irp->Overlay.AllocationSize));

                    if (!bRet)
                    {
                        Status = STATUS_DISK_FULL;
                        __leave;
                    }

                    FFSNotifyReportChange(
                            IrpContext,
                            Vcb,
                            Fcb,
                            FILE_NOTIFY_CHANGE_LAST_WRITE |
                            FILE_NOTIFY_CHANGE_ATTRIBUTES |
                            FILE_NOTIFY_CHANGE_SIZE,
                            FILE_ACTION_MODIFIED);


                    if (CreateDisposition == FILE_SUPERSEDE)
                    {
                        Irp->IoStatus.Information = FILE_SUPERSEDED;
                    }
                    else
                    {
                        Irp->IoStatus.Information = FILE_OVERWRITTEN;
                    }
                }
            }
        }
    }

    __finally
    {
        if (FileName.Buffer)
            ExFreePool(FileName.Buffer);

        if (bParentFcbCreated)
        {
            ParentFcb->ReferenceCount--;
        }

        if (VcbResourceAcquired)
        {
            ExReleaseResourceForThreadLite(
                    &Vcb->MainResource,
                    ExGetCurrentResourceThread());
        }

        if (!bFcbAllocated)
        {
            if (FS_VERSION == 1)
            {
                if (dinode1)
                    ExFreePool(dinode1);
            }
            else
            {
                if (dinode2)
                    ExFreePool(dinode2);
            }
        }
        else
        {
            if (FS_VERSION == 1)
            {
                if (!Fcb && dinode1)
                    ExFreePool(dinode1);
            }
            else
            {
                if (!Fcb && dinode2)
                    ExFreePool(dinode2);
            }
        }
    }

    return Status;
}
summersun77
驱动牛犊
驱动牛犊
  • 注册日期2007-01-10
  • 最后登录2007-05-14
  • 粉丝0
  • 关注0
  • 积分150分
  • 威望16点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-01-16 12:01
是个磁盘挂接程序吧,好用的主!  就是工程中有大量韩文无法阅读!  
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
地板#
发布于:2007-01-16 13:15
韩国人都能弄一个很不错的开源工程,中国人也要做一个更好的出来...
nangfeng
驱动牛犊
驱动牛犊
  • 注册日期2006-06-03
  • 最后登录2014-07-23
  • 粉丝0
  • 关注0
  • 积分14分
  • 威望183点
  • 贡献值0点
  • 好评度51点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2007-01-16 13:57
引用第3楼lsxredrain2007-01-16 13:15发表的“”:
韩国人都能弄一个很不错的开源工程,中国人也要做一个更好的出来...

中国人也有,matt wu 实现的Ext2fsd
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
5楼#
发布于:2007-01-16 15:12
http://www.fs-driver.org/index.html http://ext2fsd.sourceforge.net/projects/projects.htm#ext2fsd
这个?
2002-06-20之后好象就开始不开源了.而且看不到一个汉字!
韩国人这个工程是用subversion做的开源工程,相对来说影响会更大一些.
如果tooflat大侠同意的话,以他的工程为基础做一个文件过滤的(cvs或着svn)工程,逐步完善,
再结合驱网大牛们翻译的Windows NT 文件系统内幕,理论结合实践,那样才能取得更好的效果.
没有实际的工程来看书是没有太大动力的.
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
6楼#
发布于:2007-01-24 15:39
看了这段代码和Filespy和FileMon等代码,发现都是用的RtlCopyMemory来进行拷贝,之前还会调用RtlZeroMemory
而tooflat用了很多的wcslen,wcscpy,
现在tooflat大虾的过滤驱动不是很稳定,是不是和这个有关呢?
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
7楼#
发布于:2007-01-24 15:48
Rtl之类会有irql的考虑

wslen之类没有,就需要非常注意了,否则会出问题..
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
8楼#
发布于:2007-01-24 15:58
3x,
Filespy,filemon取文件名是不会出错的,但是tooflat的sfilter如果只取系统盘的文件名,其他什么都不做也会出错,不知道是不是这里的原因,
我在网上看到一些资料说wcscpy会导致一些莫名其妙的错误,不知是真是假。 wcscpy哪怕只有十万分之一的出错可能,相对正个操作系统的读写来说也是很大的。
想请教一下,在sfilter驱动程序中调用Rtl之类函数,irql条件是不是都是满足的?
ldljlzw
驱动中牛
驱动中牛
  • 注册日期2002-03-16
  • 最后登录2014-01-02
  • 粉丝1
  • 关注0
  • 积分1021分
  • 威望372点
  • 贡献值0点
  • 好评度187点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2007-01-25 09:47
引用第4楼nangfeng2007-01-16 13:57发表的“”:

中国人也有,matt wu 实现的Ext2fsd


Ext2fsd 是中国人搞的???难道他不懂汉语,我真有点怀疑你是不是搞错了!!
要不.....,我最看不起明明是中国人却要装成洋鬼子!!!
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
10楼#
发布于:2007-01-25 14:08
下面是这个代码中几个典型的错误处理机制,哪位大侠能不能给Sfilter也加件SEH外衣或者挑几个例子讲解一下在Sfilter中应该怎样加SEH?谢谢!
__try
    {
        __try
        {
            FsRtlEnterFileSystem();

            if (!IrpContext->IsTopLevel)
            {
                IoSetTopLevelIrp((PIRP) FSRTL_FSP_TOP_LEVEL_IRP);
            }

            FFSDispatchRequest(IrpContext);
        }
        __except (FFSExceptionFilter(IrpContext, GetExceptionInformation()))
        {
            FFSExceptionHandler(IrpContext);
        }
    }
    __finally
    {
        IoSetTopLevelIrp(NULL);

        FsRtlExitFileSystem();
    }
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
11楼#
发布于:2007-01-25 14:17
他注册了专门的CacheManager函数,是不是也有可能移植到Sfilter中来呢?
//
    // Initialize the Cache Manager callbacks
    //

    CacheManagerCallbacks = &(FFSGlobal->CacheManagerCallbacks);
    CacheManagerCallbacks->AcquireForLazyWrite  = FFSAcquireForLazyWrite;
    CacheManagerCallbacks->ReleaseFromLazyWrite = FFSReleaseFromLazyWrite;
    CacheManagerCallbacks->AcquireForReadAhead  = FFSAcquireForReadAhead;
    CacheManagerCallbacks->ReleaseFromReadAhead = FFSReleaseFromReadAhead;

    FFSGlobal->CacheManagerNoOpCallbacks.AcquireForLazyWrite  = FFSNoOpAcquire;
    FFSGlobal->CacheManagerNoOpCallbacks.ReleaseFromLazyWrite = FFSNoOpRelease;
    FFSGlobal->CacheManagerNoOpCallbacks.AcquireForReadAhead  = FFSNoOpAcquire;
    FFSGlobal->CacheManagerNoOpCallbacks.ReleaseFromReadAhead = FFSNoOpRelease;
qianjunhua
驱动小牛
驱动小牛
  • 注册日期2003-12-08
  • 最后登录2013-02-27
  • 粉丝11
  • 关注0
  • 积分712分
  • 威望1052点
  • 贡献值1点
  • 好评度57点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2007-12-25 11:44
这个代码嘛 也没有啥的!比fat32 处理的多点,比ntfs 处理的少点的一个自己处理irp_mj_create的一个函数
游客

返回顶部