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

📄 fastio.c

📁 This is a ReiserFs file system driver for Windows NT/2000/XP/Vista.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * COPYRIGHT:        GNU GENERAL PUBLIC LICENSE VERSION 2
 * PROJECT:          ReiserFs file system driver for Windows NT/2000/XP/Vista.
 * FILE:             fastio.c
 * PURPOSE:          
 * PROGRAMMER:       Mark Piper, Matt Wu, Bo Brant閚.
 * HOMEPAGE:         
 * UPDATE HISTORY: 
 */

/* INCLUDES *****************************************************************/

#include "rfsd.h"

/* GLOBALS ***************************************************************/

extern PRFSD_GLOBAL RfsdGlobal;

/* DEFINITIONS *************************************************************/

#ifdef ALLOC_PRAGMA
#if DBG
#pragma alloc_text(PAGE, RfsdFastIoRead)
#pragma alloc_text(PAGE, RfsdFastIoWrite)
#endif
#pragma alloc_text(PAGE, RfsdFastIoCheckIfPossible)
#pragma alloc_text(PAGE, RfsdFastIoQueryBasicInfo)
#pragma alloc_text(PAGE, RfsdFastIoQueryStandardInfo)
#pragma alloc_text(PAGE, RfsdFastIoQueryNetworkOpenInfo)
#pragma alloc_text(PAGE, RfsdFastIoLock)
#pragma alloc_text(PAGE, RfsdFastIoUnlockSingle)
#pragma alloc_text(PAGE, RfsdFastIoUnlockAll)
#pragma alloc_text(PAGE, RfsdFastIoUnlockAll)
#endif

BOOLEAN
RfsdFastIoCheckIfPossible (
              IN PFILE_OBJECT         FileObject,
              IN PLARGE_INTEGER       FileOffset,
              IN ULONG                Length,
              IN BOOLEAN              Wait,
              IN ULONG                LockKey,
              IN BOOLEAN              CheckForReadOperation,
              OUT PIO_STATUS_BLOCK    IoStatus,
              IN PDEVICE_OBJECT       DeviceObject
              )
{
    BOOLEAN          bPossible = FastIoIsNotPossible;
    PRFSD_FCB        Fcb;
    LARGE_INTEGER    lLength;
    
    lLength.QuadPart = Length;
    
    __try {

        __try {

            if (DeviceObject == RfsdGlobal->DeviceObject) {
                __leave;
            }
            
            Fcb = (PRFSD_FCB) FileObject->FsContext;
            
            ASSERT(Fcb != NULL);
            
            if (Fcb->Identifier.Type == RFSDVCB) {
                __leave;
            }
            
            ASSERT((Fcb->Identifier.Type == RFSDFCB) &&
                (Fcb->Identifier.Size == sizeof(RFSD_FCB)));
            
            if (IsDirectory(Fcb)) {
                __leave;
            }
            
            FsRtlEnterFileSystem();
            
            if (CheckForReadOperation) {

                bPossible = FsRtlFastCheckLockForRead(
                    &Fcb->FileLockAnchor,
                    FileOffset,
                    &lLength,
                    LockKey,
                    FileObject,
                    PsGetCurrentProcess());

            } else {

                if (IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY) ||
                    IsFlagOn(Fcb->Vcb->Flags, VCB_WRITE_PROTECTED)) {
                    bPossible = FastIoIsNotPossible;
                } else {
                    bPossible = FsRtlFastCheckLockForWrite(
                        &Fcb->FileLockAnchor,
                        FileOffset,
                        &lLength,
                        LockKey,
                        FileObject,
                        PsGetCurrentProcess());
                }
            }

            RfsdPrint((DBG_INFO, "RfsdFastIIOCheckPossible: %s %s %s\n",
                RfsdGetCurrentProcessName(),
                "FASTIO_CHECK_IF_POSSIBLE",
                Fcb->AnsiFileName.Buffer
                ));

            RfsdPrint((DBG_INFO, 
                "RfsdFastIIOCheckPossible: Offset: %I64xg Length: %xh Key: %u %s %s\n",
                FileOffset->QuadPart,
                Length,
                LockKey,
                (CheckForReadOperation ? "CheckForReadOperation:" :
                                         "CheckForWriteOperation:"),
                (bPossible ? "Succeeded" : "Failed")));
        } __except (EXCEPTION_EXECUTE_HANDLER) {
            bPossible = FastIoIsNotPossible;
        }

    } __finally {

        FsRtlExitFileSystem();
    }
    
    return bPossible;
}


#if DBG
BOOLEAN
RfsdFastIoRead (IN PFILE_OBJECT         FileObject,
           IN PLARGE_INTEGER       FileOffset,
           IN ULONG                Length,
           IN BOOLEAN              Wait,
           IN ULONG                LockKey,
           OUT PVOID               Buffer,
           OUT PIO_STATUS_BLOCK    IoStatus,
           IN PDEVICE_OBJECT       DeviceObject)
{
    BOOLEAN     Status;
    PRFSD_FCB    Fcb;
    
    Fcb = (PRFSD_FCB) FileObject->FsContext;
    
    ASSERT(Fcb != NULL);
    
    ASSERT((Fcb->Identifier.Type == RFSDFCB) &&
        (Fcb->Identifier.Size == sizeof(RFSD_FCB)));

    RfsdPrint((DBG_INFO, "RfsdFastIoRead: %s %s %s\n",
        RfsdGetCurrentProcessName(),
        "FASTIO_READ",
        Fcb->AnsiFileName.Buffer     ));

    RfsdPrint((DBG_INFO, "RfsdFastIoRead: Offset: %I64xh Length: %xh Key: %u\n",
        FileOffset->QuadPart,
        Length,
        LockKey       ));

    Status = FsRtlCopyRead (
        FileObject, FileOffset, Length, Wait,
        LockKey, Buffer, IoStatus, DeviceObject);
    
    return Status;
}

BOOLEAN
RfsdFastIoWrite (
           IN PFILE_OBJECT         FileObject,
           IN PLARGE_INTEGER       FileOffset,
           IN ULONG                Length,
           IN BOOLEAN              Wait,
           IN ULONG                LockKey,
           OUT PVOID               Buffer,
           OUT PIO_STATUS_BLOCK    IoStatus,
           IN PDEVICE_OBJECT       DeviceObject)
{
    BOOLEAN      bRet;
    PRFSD_FCB    Fcb;
    
    Fcb = (PRFSD_FCB) FileObject->FsContext;
    
    ASSERT(Fcb != NULL);
    
    ASSERT((Fcb->Identifier.Type == RFSDFCB) &&
        (Fcb->Identifier.Size == sizeof(RFSD_FCB)));

    RfsdPrint((DBG_INFO,
        "RfsdFastIoWrite: %s %s %s\n",
        RfsdGetCurrentProcessName(),
        "FASTIO_WRITE",
        Fcb->AnsiFileName.Buffer     ));

    RfsdPrint((DBG_INFO,
        "RfsdFastIoWrite: Offset: %I64xh Length: %xh Key: %xh\n",
        FileOffset->QuadPart,
        Length,
        LockKey       ));

    if (IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY)) {
        DbgBreak();
        return FALSE;
    }

    bRet = FsRtlCopyWrite (
        FileObject, FileOffset, Length, Wait,
        LockKey, Buffer, IoStatus, DeviceObject);
    
    return bRet;
}

#endif /* DBG */


BOOLEAN
RfsdFastIoQueryBasicInfo (IN PFILE_OBJECT             FileObject,
              IN BOOLEAN                  Wait,
              OUT PFILE_BASIC_INFORMATION Buffer,
              OUT PIO_STATUS_BLOCK        IoStatus,
              IN PDEVICE_OBJECT           DeviceObject)
{
    BOOLEAN     Status = FALSE;
    PRFSD_FCB   Fcb;
    BOOLEAN     FcbMainResourceAcquired = FALSE;
    
    __try {

        __try {

            if (DeviceObject == RfsdGlobal->DeviceObject) {
                IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
                Status = TRUE;
                __leave;
            }
            
            Fcb = (PRFSD_FCB) FileObject->FsContext;
            
            ASSERT(Fcb != NULL);
            
            if (Fcb->Identifier.Type == RFSDVCB) {
                IoStatus->Status = STATUS_INVALID_PARAMETER;
                Status = TRUE;
                __leave;
            }
            
            ASSERT((Fcb->Identifier.Type == RFSDFCB) &&
                (Fcb->Identifier.Size == sizeof(RFSD_FCB)));

            RfsdPrint((DBG_INFO, 
                "RfsdFastIoQueryBasicInfo: %s %s %s\n",
                RfsdGetCurrentProcessName(),
                "FASTIO_QUERY_BASIC_INFO",
                Fcb->AnsiFileName.Buffer
                ));

            FsRtlEnterFileSystem();
            
            if (!ExAcquireResourceSharedLite(
                &Fcb->MainResource,
                Wait)) {
                Status = FALSE;
                __leave;
            }
            
            FcbMainResourceAcquired = TRUE;
            
            RtlZeroMemory(Buffer, sizeof(FILE_BASIC_INFORMATION));
            
            /*
            typedef struct _FILE_BASIC_INFORMATION {
            LARGE_INTEGER   CreationTime;
            LARGE_INTEGER   LastAccessTime;
            LARGE_INTEGER   LastWriteTime;
            LARGE_INTEGER   ChangeTime;
            ULONG           FileAttributes;
            } FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
            */

            Buffer->CreationTime = RfsdSysTime(Fcb->Inode->i_ctime);
            Buffer->LastAccessTime = RfsdSysTime(Fcb->Inode->i_atime);
            Buffer->LastWriteTime = RfsdSysTime(Fcb->Inode->i_mtime);
            Buffer->ChangeTime = RfsdSysTime(Fcb->Inode->i_mtime);
            
            
            Buffer->FileAttributes = Fcb->RfsdMcb->FileAttr;
            
            IoStatus->Information = sizeof(FILE_BASIC_INFORMATION);
            
            IoStatus->Status = STATUS_SUCCESS;
            
            Status =  TRUE;
        } __except (EXCEPTION_EXECUTE_HANDLER) {

            IoStatus->Status = GetExceptionCode();
            Status = TRUE;
        }

    } __finally {

        if (FcbMainResourceAcquired)
        {
            ExReleaseResourceForThreadLite(
                &Fcb->MainResource,
                ExGetCurrentResourceThread()
                );
        }
        
        FsRtlExitFileSystem();
    }
    
    
    if (Status == FALSE) {

        RfsdPrint((DBG_ERROR, 
            "RfsdFastIoQueryBasicInfo: %s %s *** Status: FALSE ***\n",
            RfsdGetCurrentProcessName(),
            "FASTIO_QUERY_BASIC_INFO"
            ));
    } else if (IoStatus->Status != STATUS_SUCCESS) {

        RfsdPrint((DBG_ERROR, 
            "RfsdFastIoQueryBasicInfo: %s %s *** Status: %s (%#x) ***\n",
            RfsdFastIoQueryBasicInfo,
            "FASTIO_QUERY_BASIC_INFO",
            RfsdNtStatusToString(IoStatus->Status),
            IoStatus->Status
            ));
    }
    
    return Status;
}

BOOLEAN
RfsdFastIoQueryStandardInfo (
                IN PFILE_OBJECT                 FileObject,
                IN BOOLEAN                      Wait,
                OUT PFILE_STANDARD_INFORMATION  Buffer,
                OUT PIO_STATUS_BLOCK            IoStatus,
                IN PDEVICE_OBJECT               DeviceObject
                )
{
    
    BOOLEAN     Status = FALSE;
    PRFSD_VCB   Vcb;
    PRFSD_FCB   Fcb;
    BOOLEAN     FcbMainResourceAcquired = FALSE;

    LONGLONG    FileSize;
    LONGLONG    AllocationSize;

    __try {

        __try {

            if (DeviceObject == RfsdGlobal->DeviceObject) {

                IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
                Status = TRUE;
                __leave;
            }
            
            Fcb = (PRFSD_FCB) FileObject->FsContext;
            
            ASSERT(Fcb != NULL);
            
            if (Fcb->Identifier.Type == RFSDVCB)  {
                IoStatus->Status = STATUS_INVALID_PARAMETER;
                Status = TRUE;
                __leave;
            }
            
            ASSERT((Fcb->Identifier.Type == RFSDFCB) &&
                (Fcb->Identifier.Size == sizeof(RFSD_FCB)));

            RfsdPrint((DBG_INFO,
                "RfsdFastIoQueryStandardInfo: %s %s %s\n",
                RfsdGetCurrentProcessName(),
                "FASTIO_QUERY_STANDARD_INFO",
                Fcb->AnsiFileName.Buffer ));

            Vcb = Fcb->Vcb;

            FsRtlEnterFileSystem();
            
            if (!ExAcquireResourceSharedLite(
                &Fcb->MainResource,
                Wait        )) {
                Status = FALSE;
                __leave;
            }
            
            FcbMainResourceAcquired = TRUE;
            
            RtlZeroMemory(Buffer, sizeof(FILE_STANDARD_INFORMATION));
            
            /*
            typedef struct _FILE_STANDARD_INFORMATION {
            LARGE_INTEGER   AllocationSize;
            LARGE_INTEGER   EndOfFile;
            ULONG           NumberOfLinks;
            BOOLEAN         DeletePending;
            BOOLEAN         Directory;
            } FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
            */

            FileSize  = (LONGLONG) Fcb->Inode->i_size;

#if DISABLED
            if (S_ISREG(Fcb->Inode->i_mode))
                FileSize |= ((LONGLONG)(Fcb->Inode->i_size_high) << 32);
#endif

            AllocationSize = CEILING_ALIGNED(FileSize, (ULONGLONG)Vcb->BlockSize);		// TODO: This is incorrect for file tails...

            Buffer->AllocationSize.QuadPart = AllocationSize;
            Buffer->EndOfFile.QuadPart = FileSize;
            Buffer->NumberOfLinks = Fcb->Inode->i_links_count;
            
            if (IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY)) {
                Buffer->DeletePending = FALSE;
            } else {
                Buffer->DeletePending = IsFlagOn(Fcb->Flags, FCB_DELETE_PENDING);
            }
            
            if (FlagOn(Fcb->RfsdMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY)) {
                Buffer->Directory = TRUE;
            } else {
                Buffer->Directory = FALSE;
            }
            
            IoStatus->Information = sizeof(FILE_STANDARD_INFORMATION);
            
            IoStatus->Status = STATUS_SUCCESS;
            
            Status =  TRUE;

        } __except (EXCEPTION_EXECUTE_HANDLER) {

            IoStatus->Status = GetExceptionCode();
            Status = TRUE;
        }

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

#if DBG
    if (Status == FALSE) {
        RfsdPrint((DBG_INFO,
            "RfsdFastIoQueryStandardInfo: %s %s *** Status: FALSE ***\n",
            RfsdGetCurrentProcessName(),
            "FASTIO_QUERY_STANDARD_INFO"            ));
    } else if (IoStatus->Status != STATUS_SUCCESS) {
        RfsdPrint((DBG_INFO,
            "RfsdFastIoQueryStandardInfo: %s %s *** Status: %s (%#x) ***\n",
            RfsdGetCurrentProcessName(),
            "FASTIO_QUERY_STANDARD_INFO",
            RfsdNtStatusToString(IoStatus->Status),
            IoStatus->Status            ));
    }
#endif
    
    return Status;
}

BOOLEAN
RfsdFastIoLock (
           IN PFILE_OBJECT         FileObject,
           IN PLARGE_INTEGER       FileOffset,
           IN PLARGE_INTEGER       Length,
           IN PEPROCESS            Process,
           IN ULONG                Key,
           IN BOOLEAN              FailImmediately,
           IN BOOLEAN              ExclusiveLock,
           OUT PIO_STATUS_BLOCK    IoStatus,
           IN PDEVICE_OBJECT       DeviceObject
           )
{
    BOOLEAN     Status = FALSE;
    PRFSD_FCB   Fcb;
    
    __try {

⌨️ 快捷键说明

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