[轉]Windows文件系統的雜談

 
2011-08-19 11:37

author: jonathan

本文檔的CopyRight歸jonathan所有,可自由轉載,轉載時請保持文檔的完整性。
/*---------------------------------------------------------------------------------------------------------------------*/

1 雜談

1.1 FCB/SCB的COMMON結構定義
// fat
#define NTC_UNDEFINED                    ((NODE_TYPE_CODE)0x0000)

#define FAT_NTC_DATA_HEADER              ((NODE_TYPE_CODE)0x0500)
#define FAT_NTC_VCB                      ((NODE_TYPE_CODE)0x0501)
#define FAT_NTC_FCB                      ((NODE_TYPE_CODE)0x0502)
#define FAT_NTC_DCB                      ((NODE_TYPE_CODE)0x0503)
#define FAT_NTC_ROOT_DCB                 ((NODE_TYPE_CODE)0x0504)
#define FAT_NTC_CCB                      ((NODE_TYPE_CODE)0x0507)
#define FAT_NTC_IRP_CONTEXT              ((NODE_TYPE_CODE)0x0508)

// ntfs
#define NTC_UNDEFINED                    ((NODE_TYPE_CODE)0x0000)

#define NTFS_NTC_DATA_HEADER             ((NODE_TYPE_CODE)0x0700)
#define NTFS_NTC_VCB                     ((NODE_TYPE_CODE)0x0701)
#define NTFS_NTC_FCB                     ((NODE_TYPE_CODE)0x0702)
#define NTFS_NTC_SCB_INDEX               ((NODE_TYPE_CODE)0x0703)
#define NTFS_NTC_SCB_ROOT_INDEX          ((NODE_TYPE_CODE)0x0704)
#define NTFS_NTC_SCB_DATA                ((NODE_TYPE_CODE)0x0705)
#define NTFS_NTC_SCB_MFT                 ((NODE_TYPE_CODE)0x0706)
#define NTFS_NTC_SCB_NONPAGED            ((NODE_TYPE_CODE)0x0707)
#define NTFS_NTC_CCB_INDEX               ((NODE_TYPE_CODE)0x0708)
#define NTFS_NTC_CCB_DATA                ((NODE_TYPE_CODE)0x0709)
#define NTFS_NTC_IRP_CONTEXT             ((NODE_TYPE_CODE)0x070A)
#define NTFS_NTC_LCB                     ((NODE_TYPE_CODE)0x070B)
#define NTFS_NTC_PREFIX_ENTRY            ((NODE_TYPE_CODE)0x070C)
#define NTFS_NTC_QUOTA_CONTROL           ((NODE_TYPE_CODE)0x070D)

//cdfs
#define NTC_UNDEFINED                   ((NODE_TYPE_CODE)0x0000)

#define CDFS_NTC_DATA_HEADER            ((NODE_TYPE_CODE)0x0301)
#define CDFS_NTC_VCB                    ((NODE_TYPE_CODE)0x0302)
#define CDFS_NTC_FCB_PATH_TABLE         ((NODE_TYPE_CODE)0x0303)
#define CDFS_NTC_FCB_INDEX              ((NODE_TYPE_CODE)0x0304)
#define CDFS_NTC_FCB_DATA               ((NODE_TYPE_CODE)0x0305)
#define CDFS_NTC_FCB_NONPAGED           ((NODE_TYPE_CODE)0x0306)
#define CDFS_NTC_CCB                    ((NODE_TYPE_CODE)0x0307)
#define CDFS_NTC_IRP_CONTEXT            ((NODE_TYPE_CODE)0x0308)
#define CDFS_NTC_IRP_CONTEXT_LITE       ((NODE_TYPE_CODE)0x0309)

typedef struct _FSRTL_COMMON_FCB_HEADER {
CSHORT NodeTypeCode;
CSHORT NodeByteSize;
UCHAR Flags;
UCHAR IsFastIoPossible;
UCHAR Flags2;
UCHAR Reserved : 4;
UCHAR Version : 4;
PERESOURCE Resource;
PERESOURCE PagingIoResource;
LARGE_INTEGER AllocationSize;
LARGE_INTEGER FileSize;
LARGE_INTEGER ValidDataLength;
} FSRTL_COMMON_FCB_HEADER;
typedef FSRTL_COMMON_FCB_HEADER *PFSRTL_COMMON_FCB_HEADER;

Flags2 & FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS

typedef struct _FSRTL_ADVANCED_FCB_HEADER {
FSRTL_COMMON_FCB_HEADER;
PFAST_MUTEX FastMutex;
LIST_ENTRY FilterContexts;
EX_PUSH_LOCK PushLock;
PVOID* FileContextSupportPointer;
} FSRTL_ADVANCED_FCB_HEADER;
typedef FSRTL_ADVANCED_FCB_HEADER *PFSRTL_ADVANCED_FCB_HEADER;

typedef struct _FSRTL_PER_STREAM_CONTEXT {
LIST_ENTRY Links;
PVOID OwnerId;
PVOID InstanceId;
PFREE_FUNCTION FreeCallback;
} FSRTL_PER_STREAM_CONTEXT, *PFSRTL_PER_STREAM_CONTEXT;

OwnerId和InstanceId都需要有意義的值:
OwnerId = 可以是驅動對象的地址等
InstanceId = 可以使流上下文地址 (FsRtlGetPerStreamContextPointer)

1.2 Cleanup和Close的區別

在FCB或者SCB中都有如下兩個變量:

    CLONG CleanupCount; 打開未關閉文件句柄。   
    CLONG CloseCount; 打開未關閉文件對象。

在SCB中還有一變量:

    //
    // A count of the number of file objects opened on this stream
    // which represent user non-cached handles. We use this count to
    // determine when to flush and purge the data section in only
    // non-cached handles remain on the file.
    //
    CLONG NonCachedCleanupCount;

1.3 資源同步問題

在文件過濾驅動中,如要訪問ExAcquireResourceExclusive等資源時,爲了防止一般內核的APC調度,需調用如下接口:

FsRtlEnterFileSystem(KeEnterCriticalRegion)
FsRtlExitFileSystem(KeExitCriticalRegion)

關於設置TopLevelIrp也是很重要的,在訪問ExAcquireResourceExclusive等資源時,也需要考慮該接口調用:

if ( IoGetTopLevelIrp() == NULL ) {

        IoSetTopLevelIrp( Irp );

        return TRUE;

    } else {

        return FALSE;
    }

設置IoSetTopLevelIrp目的:當前調用的irp是否是原始的線程操作irp還是由於線程的其他操作從而又產生的新的irp操作。

1.4 文件對象狀態跟蹤

跟蹤一個文件操作的狀態,一般使用FCB。而FCB的生命週期,又是以CREATE開始,以CLOSE結束。
但是文件系統內部也會通過IoCreateStreamFileObject(會調用IRP_MJ_CLEANUP) 和 IoCreateStreamFileObjectLite(會調用IRP_MJ_CLEANUP或者IRP_MJ_CLOSE)等創建文件對象,但是這些文件對象卻不會調用Create,爲跟蹤狀態帶來困難。

因此,必須在IRP_MJ_READ、IRP_MJ_WRITE、IRP_MJ_SET_INFORMATION和IRP_MJ_GET_INFORMATION中動態創建。

1.5 文件加密中注意要清緩存

1.5.1 文件加密關注重點是緩存問題

1.5.2 清緩存有兩個時機:create和cleanup

1.5.3 清緩存方式

1.5.4 雙緩存與雙FCB,個人認爲本質是相同,不過是管理緩存的方法和機制作了改變,結果可能雙FCB有更加穩定和高移植性

1.6 同步機制

spin_lock, event, resource, mutex, time, semaphore, thread, process, file等各種對象

1.7 IRP_MJ_FILE_SYSTEM_CONTROL

    此接口調用的device是設備,但是這個設備參數哪裏來的呢?

    其實就是IrpSp->Parameters.MountVolume.Vpb->RealDevice中的設備。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章