⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fileinfo.c

📁 I want to provide an example file system driver for Windows NT/2000/XP. For some time I have worked
💻 C
📖 第 1 页 / 共 2 页
字号:
                    Irp->IoStatus.Information = sizeof(FILE_ALL_INFORMATION);
                    Status = STATUS_BUFFER_OVERFLOW;
                    __leave;
                }

                FileNameInformation->FileNameLength = Fcb->FileName.Length;

                RtlCopyMemory(
                    FileNameInformation->FileName,
                    Fcb->FileName.Buffer,
                    Fcb->FileName.Length
                    );

                Irp->IoStatus.Information = sizeof(FILE_ALL_INFORMATION) +
                    Fcb->FileName.Length - sizeof(WCHAR);
                Status = STATUS_SUCCESS;
                __leave;
            }

        case FileNetworkOpenInformation:
            {
                PFILE_NETWORK_OPEN_INFORMATION Buffer;

                if (Length < sizeof(FILE_NETWORK_OPEN_INFORMATION))
                {
                    Status = STATUS_INFO_LENGTH_MISMATCH;
                    __leave;
                }

                Buffer = (PFILE_NETWORK_OPEN_INFORMATION) SystemBuffer;

/*
                typedef struct _FILE_NETWORK_OPEN_INFORMATION {
                    LARGE_INTEGER   CreationTime;
                    LARGE_INTEGER   LastAccessTime;
                    LARGE_INTEGER   LastWriteTime;
                    LARGE_INTEGER   ChangeTime;
                    LARGE_INTEGER   AllocationSize;
                    LARGE_INTEGER   EndOfFile;
                    ULONG           FileAttributes;
                } FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION;
*/

                Buffer->CreationTime.QuadPart = 0;

                Buffer->LastAccessTime.QuadPart = 0;

                Buffer->LastWriteTime.QuadPart = 0;

                Buffer->ChangeTime.QuadPart = 0;

                Buffer->AllocationSize.QuadPart =
                    be32_to_cpu(Fcb->romfs_inode->size);

                Buffer->EndOfFile.QuadPart =
                    be32_to_cpu(Fcb->romfs_inode->size);

                Buffer->FileAttributes = Fcb->FileAttributes;

                Irp->IoStatus.Information =
                    sizeof(FILE_NETWORK_OPEN_INFORMATION);
                Status = STATUS_SUCCESS;
                __leave;
            }

#if (VER_PRODUCTBUILD >= 2195)

        case FileAttributeTagInformation:
            {
                PFILE_ATTRIBUTE_TAG_INFORMATION Buffer;

                if (Length < sizeof(FILE_ATTRIBUTE_TAG_INFORMATION))
                {
                    Status = STATUS_INFO_LENGTH_MISMATCH;
                    __leave;
                }

                Buffer = (PFILE_ATTRIBUTE_TAG_INFORMATION) SystemBuffer;

/*
                typedef struct _FILE_ATTRIBUTE_TAG_INFORMATION {
                    ULONG FileAttributes;
                    ULONG ReparseTag;
                } FILE_ATTRIBUTE_TAG_INFORMATION, *PFILE_ATTRIBUTE_TAG_INFORMATION;
*/

                Buffer->FileAttributes = Fcb->FileAttributes;

                Buffer->ReparseTag = 0;

                Irp->IoStatus.Information =
                    sizeof(FILE_ATTRIBUTE_TAG_INFORMATION);
                Status = STATUS_SUCCESS;
                __leave;
            }

#endif // (VER_PRODUCTBUILD >= 2195)

        default:
            Status = STATUS_INVALID_INFO_CLASS;
        }
    }
    __finally
    {
        if (FcbResourceAcquired)
        {
            ExReleaseResourceForThreadLite(
                &Fcb->MainResource,
                ExGetCurrentResourceThread()
                );
        }

        if (!AbnormalTermination())
        {
            if (Status == STATUS_PENDING)
            {
                FsdQueueRequest(IrpContext);
            }
            else
            {
                IrpContext->Irp->IoStatus.Status = Status;

                FsdCompleteRequest(
                    IrpContext->Irp,
                    (CCHAR)
                    (NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT)
                    );

                FsdFreeIrpContext(IrpContext);
            }
        }
    }

    return Status;
}

NTSTATUS
FsdSetInformation (
    IN PFSD_IRP_CONTEXT IrpContext
    )
{
    PDEVICE_OBJECT          DeviceObject;
    NTSTATUS                Status = STATUS_UNSUCCESSFUL;
    PFSD_VCB                Vcb;
    PFILE_OBJECT            FileObject;
    PFSD_FCB                Fcb;
    PFSD_CCB                Ccb;
    PIRP                    Irp;
    PIO_STACK_LOCATION      IrpSp;
    FILE_INFORMATION_CLASS  FileInformationClass;
    ULONG                   Length;
    PVOID                   SystemBuffer;
#ifndef FSD_RO
    BOOLEAN                 VcbResourceAcquired = FALSE;
#endif
    BOOLEAN                 FcbMainResourceAcquired = FALSE;
#ifndef FSD_RO
    BOOLEAN                 FcbPagingIoResourceAcquired = FALSE;
#endif

    __try
    {
        ASSERT(IrpContext != NULL);

        ASSERT((IrpContext->Identifier.Type == ICX) &&
               (IrpContext->Identifier.Size == sizeof(FSD_IRP_CONTEXT)));

        DeviceObject = IrpContext->DeviceObject;

        if (DeviceObject == FsdGlobalData.DeviceObject)
        {
            Status = STATUS_INVALID_DEVICE_REQUEST;
            __leave;
        }

        Vcb = (PFSD_VCB) DeviceObject->DeviceExtension;

        ASSERT(Vcb != NULL);

        ASSERT((Vcb->Identifier.Type == VCB) &&
               (Vcb->Identifier.Size == sizeof(FSD_VCB)));

        FileObject = IrpContext->FileObject;

        Fcb = (PFSD_FCB) FileObject->FsContext;

        ASSERT(Fcb != NULL);

        if (Fcb->Identifier.Type == VCB)
        {
            Status = STATUS_INVALID_PARAMETER;
            __leave;
        }

        ASSERT((Fcb->Identifier.Type == FCB) &&
               (Fcb->Identifier.Size == sizeof(FSD_FCB)));

        Ccb = (PFSD_CCB) FileObject->FsContext2;

        ASSERT(Ccb != NULL);

        ASSERT((Ccb->Identifier.Type == CCB) &&
               (Ccb->Identifier.Size == sizeof(FSD_CCB)));

        Irp = IrpContext->Irp;

        IrpSp = IoGetCurrentIrpStackLocation(Irp);

        FileInformationClass = IrpSp->Parameters.SetFile.FileInformationClass;

        Length = IrpSp->Parameters.SetFile.Length;

        SystemBuffer = Irp->AssociatedIrp.SystemBuffer;

#ifndef FSD_RO

        if (FileInformationClass == FileDispositionInformation ||
            FileInformationClass == FileRenameInformation ||
            FileInformationClass == FileLinkInformation)
        {
            if (!ExAcquireResourceExclusiveLite(
                    &Vcb->MainResource,
                    IrpContext->IsSynchronous
                    ))
            {
                Status = STATUS_PENDING;
                __leave;
            }

            VcbResourceAcquired = TRUE;
        }

#endif // !FSD_RO

#ifndef FSD_RO
        if (!FlagOn(Fcb->Flags, FCB_PAGE_FILE))
#endif
        {
            if (!ExAcquireResourceExclusiveLite(
                    &Fcb->MainResource,
                    IrpContext->IsSynchronous
                    ))
            {
                Status = STATUS_PENDING;
                __leave;
            }

            FcbMainResourceAcquired = TRUE;
        }

#ifndef FSD_RO

        if (FileInformationClass == FileDispositionInformation ||
            FileInformationClass == FileRenameInformation ||
            FileInformationClass == FileLinkInformation ||
            FileInformationClass == FileAllocationInformation ||
            FileInformationClass == FileEndOfFileInformation)
        {
            if (!ExAcquireResourceExclusiveLite(
                    &Fcb->PagingIoResource,
                    IrpContext->IsSynchronous
                    ))
            {
                Status = STATUS_PENDING;
                __leave;
            }

            FcbPagingIoResourceAcquired = TRUE;
        }

#endif // !FSD_RO

#ifndef FSD_RO
        if (FlagOn(Vcb->Flags, VCB_READ_ONLY))
#endif
        {
            if (FileInformationClass != FilePositionInformation)
            {
                Status = STATUS_MEDIA_WRITE_PROTECTED;
                __leave;
            }
        }

        switch (FileInformationClass)
        {
        //
        // This is the only set file information request supported on read
        // only file systems
        //
        case FilePositionInformation:
            {
                PFILE_POSITION_INFORMATION Buffer;

                if (Length < sizeof(FILE_POSITION_INFORMATION))
                {
                    Status = STATUS_INVALID_PARAMETER;
                    __leave;
                }

                Buffer = (PFILE_POSITION_INFORMATION) SystemBuffer;

/*
                typedef struct _FILE_POSITION_INFORMATION {
                    LARGE_INTEGER CurrentByteOffset;
                } FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
*/

                if (FlagOn(FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING) &&
                    (Buffer->CurrentByteOffset.LowPart &
                     DeviceObject->AlignmentRequirement)
                   )
                {
                    Status = STATUS_INVALID_PARAMETER;
                    __leave;
                }

                FileObject->CurrentByteOffset = Buffer->CurrentByteOffset;

                Status = STATUS_SUCCESS;
                __leave;
            }

        default:
            Status = STATUS_INVALID_INFO_CLASS;
        }
    }
    __finally
    {

#ifndef FSD_RO

        if (FcbPagingIoResourceAcquired)
        {
            ExReleaseResourceForThreadLite(
                &Fcb->PagingIoResource,
                ExGetCurrentResourceThread()
                );
        }

#endif // !FSD_RO

        if (FcbMainResourceAcquired)
        {
            ExReleaseResourceForThreadLite(
                &Fcb->MainResource,
                ExGetCurrentResourceThread()
                );
        }

#ifndef FSD_RO

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

#endif // !FSD_RO

        if (!AbnormalTermination())
        {
            if (Status == STATUS_PENDING)
            {
                FsdQueueRequest(IrpContext);
            }
            else
            {
                IrpContext->Irp->IoStatus.Status = Status;

                FsdCompleteRequest(
                    IrpContext->Irp,
                    (CCHAR)
                    (NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT)
                    );

                FsdFreeIrpContext(IrpContext);
            }
        }
    }

    return Status;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -