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

📄 fatstruc.h

📁 winddk src目录下的文件系统驱动源码压缩!
💻 H
📖 第 1 页 / 共 4 页
字号:
    //  file objects.  This count gets decremented in FatCommonCleanup,
    //  while the OpenCount below gets decremented in FatCommonClose.
    //

    CLONG UncleanCount;

    //
    //  A count of the number of file objects that have opened
    //  this file/directory.  For files & directories the FsContext of the
    //  file object points to this record.
    //

    CLONG OpenCount;

    //
    //  A count of how many of "UncleanCount" handles were opened for
    //  non-cached I/O.
    //

    CLONG NonCachedUncleanCount;

    //
    //  The following field is used to locate the dirent for this fcb/dcb.
    //  All directory are opened as mapped files so the only additional
    //  information we need to locate this dirent (beside its parent directory)
    //  is the byte offset for the dirent.  Note that for the root dcb
    //  this field is not used.
    //

    VBO DirentOffsetWithinDirectory;

    //
    //  The following field is filled in when there is an Lfn associated
    //  with this file.  It is the STARTING offset of the Lfn.
    //

    VBO LfnOffsetWithinDirectory;

    //
    //  Thess entries is kept in ssync with the dirent.  It allows a more
    //  accurate verify capability and speeds up FatFastQueryBasicInfo().
    //

    LARGE_INTEGER CreationTime;
    LARGE_INTEGER LastAccessTime;
    LARGE_INTEGER LastWriteTime;

    //
    //  Valid data to disk
    //

    ULONG ValidDataToDisk;

    //
    //  The following field contains the retrieval mapping structure
    //  for the file/directory.  Note that for the Root Dcb this
    //  structure is set at mount time.  Also note that in this
    //  implementation of Fat the Mcb really maps VBOs to LBOs and not
    //  VBNs to LBNs.
    //

    LARGE_MCB Mcb;

    //
    //  The following union is cased off of the node type code for the fcb.
    //  There is a seperate case for the directory versus file fcbs.
    //

    union {

        //
        //  A Directory Control Block (Dcb)
        //

        struct {

            //
            //  A queue of all the fcbs/dcbs that are opened under this
            //  Dcb.
            //

            LIST_ENTRY ParentDcbQueue;

            //
            //  The following field points to the file object used to do I/O to
            //  the directory file for this dcb.  The directory file maps the
            //  sectors for the directory.  This field is initialized by
            //  CreateRootDcb but is left null by CreateDcb.  It isn't
            //  until we try to read/write the directory file that we
            //  create the stream file object for non root dcbs.
            //

            ULONG DirectoryFileOpenCount;
            PFILE_OBJECT DirectoryFile;

            //
            //  If the UnusedDirentVbo is != 0xffffffff, then the dirent at this
            //  offset is guarenteed to unused.  A value of 0xffffffff means
            //  it has yet to be initialized.  Note that a value beyond the
            //  end of allocation means that there an unused dirent, but we
            //  will have to allocate another cluster to use it.
            //
            //  DeletedDirentHint contains lowest possible VBO of a deleted
            //  dirent (assuming as above that it is not 0xffffffff).
            //

            VBO UnusedDirentVbo;
            VBO DeletedDirentHint;

            //
            //  The following two entries links together all the Fcbs
            //  opened under this Dcb sorted in a splay tree by name.
            //
            //  I'd like to go into why we have (and must have) two separate
            //  splay trees within the current fastfat architecture.  I will
            //  provide some insight into what would have to change if we
            //  wanted to have a single UNICODE tree.
            //
            //  What makes FAT unique is that both Oem and Unicode names sit
            //  side by side on disk.  Several unique UNICODE names coming
            //  into fastfat can match a single OEM on-disk name, and there
            //  is really no way to enumerate all the possible UNICODE
            //  source strings that can map to a given OEM name.  This argues
            //  for converting the incomming UNICODE name into OEM, and then
            //  running through an OEM splay tree of the open files.  This
            //  works well when there are only OEM names on disk.
            //
            //  The UNICODE name on disk can be VERY different from the short
            //  name in the DIRENT and not even representable in the OEM code
            //  page.  Even if it were representable in OEM, it is possible
            //  that a case varient of the original UNICODE name would match
            //  a different OEM name, causing us to miss the Fcb in the
            //  prefix lookup phase.  In these cases, we must put UNICODE
            //  name in the splay to guarentee that we find any case varient
            //  of the input UNICODE name.  See the routine description of
            //  FatConstructNamesInFcb() for a detailed analysis of how we
            //  detect this case.
            //
            //  The fundamental limitation we are imposing here is that if
            //  an Fcb exists for an open file, we MUST find it during the
            //  prefix stage.  This is a basic premise of the create path
            //  in fastfat.  In fact if we later find it gravelling through
            //  the disk (but not the splay tree), we will bug check if we
            //  try to add a duplicate entry to the splay tree (not to
            //  mention having two Fcbs).  If we had some mechanism to deal
            //  with cases (and they would be rare) that we don't find the
            //  entry in the splay tree, but the Fcb is actually in there,
            //  then we could go to a single UNICODE splay tree.  While
            //  this uses more pool for the splay tree, and makes string
            //  compares maybe take a bit as longer, it would eliminate the
            //  need for any NLS conversion during the prefix phase, so it
            //  might really be a net win.
            //
            //  The current scheme was optimized for non-extended names
            //  (i.e. US names).  As soon as you start using extended
            //  characters, then it is clearly a win as many code paths
            //  become active that would otherwise not be needed if we
            //  only had a single UNICODE splay tree.
            //
            //  We may think about changing this someday.
            //

            PRTL_SPLAY_LINKS RootOemNode;
            PRTL_SPLAY_LINKS RootUnicodeNode;

            //
            //  The following field keeps track of free dirents, i.e.,
            //  dirents that are either unallocated for deleted.
            //

            RTL_BITMAP FreeDirentBitmap;

            //
            //  Since the FCB specific part of this union is larger, use
            //  the slack here for an initial bitmap buffer.  Currently
            //  there is enough space here for an 8K cluster.
            //

            ULONG FreeDirentBitmapBuffer[1];

        } Dcb;

        //
        //  A File Control Block (Fcb)
        //

        struct {

            //
            //  The following field is used by the filelock module
            //  to maintain current byte range locking information.
            //

            FILE_LOCK FileLock;

            //
            //  The following field is used by the oplock module
            //  to maintain current oplock information.
            //

            OPLOCK Oplock;

            //
            //  This pointer is used to detect writes that eminated in the
            //  cache manager's lazywriter.  It prevents lazy writer threads,
            //  who already have the Fcb shared, from trying to acquire it
            //  exclusive, and thus causing a deadlock.
            //

            PVOID LazyWriteThread;

        } Fcb;

    } Specific;

    //
    //  The following field is used to verify that the Ea's for a file
    //  have not changed between calls to query for Ea's.  It is compared
    //  with a similar field in a Ccb.
    //
    //  IMPORTANT!! **** DO NOT MOVE THIS FIELD ****
    //
    //              The slack space in the union above is computed from
    //              the field offset of the EaModificationCount.
    //

    ULONG EaModificationCount;

    //
    //  The following field is the fully qualified file name for this FCB/DCB
    //  starting from the root of the volume, and last file name in the
    //  fully qualified name.
    //

    FILE_NAME_NODE ShortName;

    //
    //  The following field is only filled in if it is needed with the user's
    //  opened path
    //

    UNICODE_STRING FullFileName;

    USHORT FinalNameLength;

    //
    //  To make life simpler we also keep in the Fcb/Dcb a current copy of
    //  the fat attribute byte for the file/directory.  This field must
    //  also be updated when we create the Fcb, modify the File, or verify
    //  the Fcb
    //

    UCHAR DirentFatFlags;

    //
    //  The case preserved long filename
    //

    UNICODE_STRING ExactCaseLongName;

    //
    //  If the UNICODE Lfn is fully expressible in the system Oem code
    //  page, then we will store it in a prefix table, otherwise we will
    //  store the last UNICODE name in the Fcb.  In both cases the name
    //  has been upcased.
    //
    //  Note that we may need neither of these fields if an LFN was strict
    //  8.3 or differed only in case.  Indeed if there wasn't an LFN, we
    //  don't need them at all.
    //

    union {

        //
        //  This first field is present if FCB_STATE_HAS_OEM_LONG_NAME
        //  is set in the FcbState.
        //

        FILE_NAME_NODE Oem;

        //
        //  This first field is present if FCB_STATE_HAS_UNICODE_LONG_NAME
        //  is set in the FcbState.
        //

        FILE_NAME_NODE Unicode;

    } LongName;

    //
    //  Defragmentation / ReallocateOnWrite synchronization object.  This
    //  is filled in by FatMoveFile() and affects the read and write paths.
    //

    PKEVENT MoveFileEvent;

} FCB, *PFCB;

#ifndef BUILDING_FSKDEXT
//
//  DCB clashes with a type defined outside the filesystems,  in headers
//  pulled in by FSKD.  We don't need this typedef for fskd anyway....
//
typedef FCB DCB;
typedef DCB *PDCB;
#endif


//
//  Here are the Fcb state fields.
//

#define FCB_STATE_DELETE_ON_CLOSE        (0x00000001)
#define FCB_STATE_TRUNCATE_ON_CLOSE      (0x00000002)
#define FCB_STATE_PAGING_FILE            (0x00000004)
#define FCB_STATE_FORCE_MISS_IN_PROGRESS (0x00000008)
#define FCB_STATE_FLUSH_FAT              (0x00000010)
#define FCB_STATE_TEMPORARY              (0x00000020)
#define FCB_STATE_SYSTEM_FILE            (0x00000080)
#define FCB_STATE_NAMES_IN_SPLAY_TREE    (0x00000100)
#define FCB_STATE_HAS_OEM_LONG_NAME      (0x00000200)
#define FCB_STATE_HAS_UNICODE_LONG_NAME  (0x00000400)
#define FCB_STATE_DELAY_CLOSE            (0x00000800)

//
//  Copies of the dirent's FAT_DIRENT_NT_BYTE_* flags for
//  preserving case of the short name of a file
//

#define FCB_STATE_8_LOWER_CASE           (0x00001000)
#define FCB_STATE_3_LOWER_CASE           (0x00002000)

//
//  This is the slack allocation in the Dcb part of the UNION above
//

#define DCB_UNION_SLACK_SPACE ((ULONG)                       \
    (FIELD_OFFSET(DCB, EaModificationCount) -                \
     FIELD_OFFSET(DCB, Specific.Dcb.FreeDirentBitmapBuffer)) \
)

//
//  This is the special (64bit) allocation size that indicates the
//  real size must be retrieved from disk.  Define it here so we
//  avoid excessive magic numbering around the driver.
//

#define FCB_LOOKUP_ALLOCATIONSIZE_HINT   ((LONGLONG) -1)


//
//  The Ccb record is allocated for every file object.  Note that this
//  record is exactly 0x34 long on x86 so that it will fit into a 0x40
//  piece of pool.  Please carefully consider modifications.
//
//  Define the Flags field.
//

#define CCB_FLAG_MATCH_ALL               (0x0001)
#define CCB_FLAG_SKIP_SHORT_NAME_COMPARE (0x0002)

//
//  This tells us whether we allocated buffers to hold search templates.
//

#define CCB_FLAG_FREE_OEM_BEST_FIT       (0x0004)
#define CCB_FLAG_FREE_UNICODE            (0x0008)

//
//  These flags prevents cleanup from updating the modify time, etc.
//

#define CCB_FLAG_USER_SET_LAST_WRITE     (0x0010)
#define CCB_FLAG_USER_SET_LAST_ACCESS    (0x0020)
#define CCB_FLAG_USER_SET_CREATION       (0x0040)

//
//  This bit says the file object associated with this Ccb was opened for
//  read only access.
//

#define CCB_FLAG_READ_ONLY               (0x0080)

//
//  These flags, are used is DASD handles in read and write.
//

#define CCB_FLAG_DASD_FLUSH_DONE         (0x0100)
#define CCB_FLAG_DASD_PURGE_DONE         (0x0200)

//
//  This flag keeps track of a handle that was opened for
//  DELETE_ON_CLOSE.
//

#define CCB_FLAG_DELETE_ON_CLOSE         (0x0400)

//
//  This flag keeps track of which side of the name pair on the file
//  associated with the handle was opened
//

#define CCB_FLAG_OPENED_BY_SHORTNAME     (0x0800)

//
//  This flag indicates that the query template has not been upcased
// (i.e., query should be case-insensitive)
//

⌨️ 快捷键说明

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