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

📄 fat.h

📁 winddk src目录下的文件系统驱动源码压缩!
💻 H
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c) 1989-2000 Microsoft Corporation

Module Name:

    Fat.h

Abstract:

    This module defines the on-disk structure of the Fat file system.


--*/

#ifndef _FAT_
#define _FAT_

//
//  The following nomenclature is used to describe the Fat on-disk
//  structure:
//
//      LBN - is the number of a sector relative to the start of the disk.
//
//      VBN - is the number of a sector relative to the start of a file,
//          directory, or allocation.
//
//      LBO - is a byte offset relative to the start of the disk.
//
//      VBO - is a byte offset relative to the start of a file, directory
//          or allocation.
//

typedef LONGLONG LBO;    /* for Fat32, LBO is >32 bits */

typedef LBO *PLBO;

typedef ULONG32 VBO;
typedef VBO *PVBO;


//
//  The boot sector is the first physical sector (LBN == 0) on the volume.
//  Part of the sector contains a BIOS Parameter Block.  The BIOS in the
//  sector is packed (i.e., unaligned) so we'll supply a unpacking macro
//  to translate a packed BIOS into its unpacked equivalent.  The unpacked
//  BIOS structure is already defined in ntioapi.h so we only need to define
//  the packed BIOS.
//

//
//  Define the Packed and Unpacked BIOS Parameter Block
//

typedef struct _PACKED_BIOS_PARAMETER_BLOCK {
    UCHAR  BytesPerSector[2];                       // offset = 0x000  0
    UCHAR  SectorsPerCluster[1];                    // offset = 0x002  2
    UCHAR  ReservedSectors[2];                      // offset = 0x003  3
    UCHAR  Fats[1];                                 // offset = 0x005  5
    UCHAR  RootEntries[2];                          // offset = 0x006  6
    UCHAR  Sectors[2];                              // offset = 0x008  8
    UCHAR  Media[1];                                // offset = 0x00A 10
    UCHAR  SectorsPerFat[2];                        // offset = 0x00B 11
    UCHAR  SectorsPerTrack[2];                      // offset = 0x00D 13
    UCHAR  Heads[2];                                // offset = 0x00F 15
    UCHAR  HiddenSectors[4];                        // offset = 0x011 17
    UCHAR  LargeSectors[4];                         // offset = 0x015 21
} PACKED_BIOS_PARAMETER_BLOCK;                      // sizeof = 0x019 25
typedef PACKED_BIOS_PARAMETER_BLOCK *PPACKED_BIOS_PARAMETER_BLOCK;

typedef struct _PACKED_BIOS_PARAMETER_BLOCK_EX {
    UCHAR  BytesPerSector[2];                       // offset = 0x000  0
    UCHAR  SectorsPerCluster[1];                    // offset = 0x002  2
    UCHAR  ReservedSectors[2];                      // offset = 0x003  3
    UCHAR  Fats[1];                                 // offset = 0x005  5
    UCHAR  RootEntries[2];                          // offset = 0x006  6
    UCHAR  Sectors[2];                              // offset = 0x008  8
    UCHAR  Media[1];                                // offset = 0x00A 10
    UCHAR  SectorsPerFat[2];                        // offset = 0x00B 11
    UCHAR  SectorsPerTrack[2];                      // offset = 0x00D 13
    UCHAR  Heads[2];                                // offset = 0x00F 15
    UCHAR  HiddenSectors[4];                        // offset = 0x011 17
    UCHAR  LargeSectors[4];                         // offset = 0x015 21
    UCHAR  LargeSectorsPerFat[4];                   // offset = 0x019 25
    UCHAR  ExtendedFlags[2];                        // offset = 0x01D 29
    UCHAR  FsVersion[2];                            // offset = 0x01F 31
    UCHAR  RootDirFirstCluster[4];                  // offset = 0x021 33
    UCHAR  FsInfoSector[2];                         // offset = 0x025 37
    UCHAR  BackupBootSector[2];                     // offset = 0x027 39
    UCHAR  Reserved[12];                            // offset = 0x029 41
} PACKED_BIOS_PARAMETER_BLOCK_EX;                   // sizeof = 0x035 53

typedef PACKED_BIOS_PARAMETER_BLOCK_EX *PPACKED_BIOS_PARAMETER_BLOCK_EX;

//
//  The IsBpbFat32 macro is defined to work with both packed and unpacked
//  BPB structures.  Since we are only checking for zero, the byte order
//  does not matter.
//

#define IsBpbFat32(bpb) (*(USHORT *)(&(bpb)->SectorsPerFat) == 0)

typedef struct BIOS_PARAMETER_BLOCK {
    USHORT BytesPerSector;
    UCHAR  SectorsPerCluster;
    USHORT ReservedSectors;
    UCHAR  Fats;
    USHORT RootEntries;
    USHORT Sectors;
    UCHAR  Media;
    USHORT SectorsPerFat;
    USHORT SectorsPerTrack;
    USHORT Heads;
    ULONG32  HiddenSectors;
    ULONG32  LargeSectors;
    ULONG32  LargeSectorsPerFat;
    union {
        USHORT ExtendedFlags;
        struct {
            ULONG ActiveFat:4;
            ULONG Reserved0:3;
            ULONG MirrorDisabled:1;
            ULONG Reserved1:8;
        };
    };
    USHORT FsVersion;
    ULONG32 RootDirFirstCluster;
    USHORT FsInfoSector;
    USHORT BackupBootSector;
} BIOS_PARAMETER_BLOCK, *PBIOS_PARAMETER_BLOCK;

//
//  This macro takes a Packed BIOS and fills in its Unpacked equivalent
//

#define FatUnpackBios(Bios,Pbios) {                                         \
    CopyUchar2(&(Bios)->BytesPerSector,    &(Pbios)->BytesPerSector[0]   ); \
    CopyUchar1(&(Bios)->SectorsPerCluster, &(Pbios)->SectorsPerCluster[0]); \
    CopyUchar2(&(Bios)->ReservedSectors,   &(Pbios)->ReservedSectors[0]  ); \
    CopyUchar1(&(Bios)->Fats,              &(Pbios)->Fats[0]             ); \
    CopyUchar2(&(Bios)->RootEntries,       &(Pbios)->RootEntries[0]      ); \
    CopyUchar2(&(Bios)->Sectors,           &(Pbios)->Sectors[0]          ); \
    CopyUchar1(&(Bios)->Media,             &(Pbios)->Media[0]            ); \
    CopyUchar2(&(Bios)->SectorsPerFat,     &(Pbios)->SectorsPerFat[0]    ); \
    CopyUchar2(&(Bios)->SectorsPerTrack,   &(Pbios)->SectorsPerTrack[0]  ); \
    CopyUchar2(&(Bios)->Heads,             &(Pbios)->Heads[0]            ); \
    CopyUchar4(&(Bios)->HiddenSectors,     &(Pbios)->HiddenSectors[0]    ); \
    CopyUchar4(&(Bios)->LargeSectors,      &(Pbios)->LargeSectors[0]     ); \
    CopyUchar4(&(Bios)->LargeSectorsPerFat,&((PPACKED_BIOS_PARAMETER_BLOCK_EX)Pbios)->LargeSectorsPerFat[0]  ); \
    CopyUchar2(&(Bios)->ExtendedFlags,     &((PPACKED_BIOS_PARAMETER_BLOCK_EX)Pbios)->ExtendedFlags[0]       ); \
    CopyUchar2(&(Bios)->FsVersion,         &((PPACKED_BIOS_PARAMETER_BLOCK_EX)Pbios)->FsVersion[0]           ); \
    CopyUchar4(&(Bios)->RootDirFirstCluster,                                \
                                           &((PPACKED_BIOS_PARAMETER_BLOCK_EX)Pbios)->RootDirFirstCluster[0] ); \
    CopyUchar2(&(Bios)->FsInfoSector,      &((PPACKED_BIOS_PARAMETER_BLOCK_EX)Pbios)->FsInfoSector[0]        ); \
    CopyUchar2(&(Bios)->BackupBootSector,  &((PPACKED_BIOS_PARAMETER_BLOCK_EX)Pbios)->BackupBootSector[0]    ); \
}

//
//  Define the boot sector
//

typedef struct _PACKED_BOOT_SECTOR {
    UCHAR Jump[3];                                  // offset = 0x000   0
    UCHAR Oem[8];                                   // offset = 0x003   3
    PACKED_BIOS_PARAMETER_BLOCK PackedBpb;          // offset = 0x00B  11
    UCHAR PhysicalDriveNumber;                      // offset = 0x024  36
    UCHAR CurrentHead;                              // offset = 0x025  37
    UCHAR Signature;                                // offset = 0x026  38
    UCHAR Id[4];                                    // offset = 0x027  39
    UCHAR VolumeLabel[11];                          // offset = 0x02B  43
    UCHAR SystemId[8];                              // offset = 0x036  54
} PACKED_BOOT_SECTOR;                               // sizeof = 0x03E  62

typedef PACKED_BOOT_SECTOR *PPACKED_BOOT_SECTOR;

typedef struct _PACKED_BOOT_SECTOR_EX {
    UCHAR Jump[3];                                  // offset = 0x000   0
    UCHAR Oem[8];                                   // offset = 0x003   3
    PACKED_BIOS_PARAMETER_BLOCK_EX PackedBpb;       // offset = 0x00B  11
    UCHAR PhysicalDriveNumber;                      // offset = 0x040  64
    UCHAR CurrentHead;                              // offset = 0x041  65
    UCHAR Signature;                                // offset = 0x042  66
    UCHAR Id[4];                                    // offset = 0x043  67
    UCHAR VolumeLabel[11];                          // offset = 0x047  71
    UCHAR SystemId[8];                              // offset = 0x058  88
} PACKED_BOOT_SECTOR_EX;                            // sizeof = 0x060  96

typedef PACKED_BOOT_SECTOR_EX *PPACKED_BOOT_SECTOR_EX;

//
//  Define the FAT32 FsInfo sector.
//

typedef struct _FSINFO_SECTOR {
    ULONG SectorBeginSignature;                     // offset = 0x000   0
    UCHAR ExtraBootCode[480];                       // offset = 0x004   4
    ULONG FsInfoSignature;                          // offset = 0x1e4 484
    ULONG FreeClusterCount;                         // offset = 0x1e8 488
    ULONG NextFreeCluster;                          // offset = 0x1ec 492
    UCHAR Reserved[12];                             // offset = 0x1f0 496
    ULONG SectorEndSignature;                       // offset = 0x1fc 508
} FSINFO_SECTOR, *PFSINFO_SECTOR;

#define FSINFO_SECTOR_BEGIN_SIGNATURE   0x41615252
#define FSINFO_SECTOR_END_SIGNATURE     0xAA550000

#define FSINFO_SIGNATURE                0x61417272

//
//  We use the CurrentHead field for our dirty partition info.
//

#define FAT_BOOT_SECTOR_DIRTY            0x01
#define FAT_BOOT_SECTOR_TEST_SURFACE     0x02

//
//  Define a Fat Entry type.
//
//  This type is used when representing a fat table entry.  It also used
//  to be used when dealing with a fat table index and a count of entries,
//  but the ensuing type casting nightmare sealed this fate.  These other
//  two types are represented as ULONGs.
//

typedef ULONG32 FAT_ENTRY;

#define FAT32_ENTRY_MASK 0x0FFFFFFFUL

//
//  We use these special index values to set the dirty info for
//  DOS/Win9x compatibility.
//

#define FAT_CLEAN_VOLUME        (~FAT32_ENTRY_MASK | 0)
#define FAT_DIRTY_VOLUME        (~FAT32_ENTRY_MASK | 1)

#define FAT_DIRTY_BIT_INDEX     1

//
//  Physically, the entry is fully set if clean, and the high
//  bit knocked out if it is dirty (i.e., it is really a clean
//  bit).  This means it is different per-FAT size.
//

#define FAT_CLEAN_ENTRY         (~0)

#define FAT12_DIRTY_ENTRY       0x7ff
#define FAT16_DIRTY_ENTRY       0x7fff
#define FAT32_DIRTY_ENTRY       0x7fffffff

//
//  The following constants the are the valid Fat index values.
//

#define FAT_CLUSTER_AVAILABLE            (FAT_ENTRY)0x00000000
#define FAT_CLUSTER_RESERVED             (FAT_ENTRY)0x0ffffff0
#define FAT_CLUSTER_BAD                  (FAT_ENTRY)0x0ffffff7
#define FAT_CLUSTER_LAST                 (FAT_ENTRY)0x0fffffff

//
//  Fat files have the following time/date structures.  Note that the
//  following structure is a 32 bits long but USHORT aligned.
//

typedef struct _FAT_TIME {

    USHORT DoubleSeconds : 5;
    USHORT Minute        : 6;
    USHORT Hour          : 5;

} FAT_TIME;
typedef FAT_TIME *PFAT_TIME;

typedef struct _FAT_DATE {

    USHORT Day           : 5;
    USHORT Month         : 4;
    USHORT Year          : 7; // Relative to 1980

} FAT_DATE;
typedef FAT_DATE *PFAT_DATE;

typedef struct _FAT_TIME_STAMP {

    FAT_TIME Time;
    FAT_DATE Date;

} FAT_TIME_STAMP;
typedef FAT_TIME_STAMP *PFAT_TIME_STAMP;

//
//  Fat files have 8 character file names and 3 character extensions
//

typedef UCHAR FAT8DOT3[11];
typedef FAT8DOT3 *PFAT8DOT3;


//
//  The directory entry record exists for every file/directory on the
//  disk except for the root directory.
//

typedef struct _PACKED_DIRENT {
    FAT8DOT3       FileName;                         //  offset =  0
    UCHAR          Attributes;                       //  offset = 11
    UCHAR          NtByte;                           //  offset = 12
    UCHAR          CreationMSec;                     //  offset = 13
    FAT_TIME_STAMP CreationTime;                     //  offset = 14
    FAT_DATE       LastAccessDate;                   //  offset = 18
    union {
        USHORT     ExtendedAttributes;               //  offset = 20
        USHORT     FirstClusterOfFileHi;             //  offset = 20
    };
    FAT_TIME_STAMP LastWriteTime;                    //  offset = 22
    USHORT         FirstClusterOfFile;               //  offset = 26
    ULONG32        FileSize;                         //  offset = 28
} PACKED_DIRENT;                                     //  sizeof = 32
typedef PACKED_DIRENT *PPACKED_DIRENT;

//
//  A packed dirent is already quadword aligned so simply declare a dirent as a
//  packed dirent
//

typedef PACKED_DIRENT DIRENT;
typedef DIRENT *PDIRENT;

//
//  The first byte of a dirent describes the dirent.  There is also a routine
//  to help in deciding how to interpret the dirent.
//

#define FAT_DIRENT_NEVER_USED            0x00
#define FAT_DIRENT_REALLY_0E5            0x05
#define FAT_DIRENT_DIRECTORY_ALIAS       0x2e
#define FAT_DIRENT_DELETED               0xe5

//
//  Define the NtByte bits.
//

#define FAT_DIRENT_NT_BYTE_8_LOWER_CASE  0x08
#define FAT_DIRENT_NT_BYTE_3_LOWER_CASE  0x10

//
//  Define the various dirent attributes
//

#define FAT_DIRENT_ATTR_READ_ONLY        0x01
#define FAT_DIRENT_ATTR_HIDDEN           0x02
#define FAT_DIRENT_ATTR_SYSTEM           0x04
#define FAT_DIRENT_ATTR_VOLUME_ID        0x08
#define FAT_DIRENT_ATTR_DIRECTORY        0x10
#define FAT_DIRENT_ATTR_ARCHIVE          0x20
#define FAT_DIRENT_ATTR_DEVICE           0x40
#define FAT_DIRENT_ATTR_LFN              (FAT_DIRENT_ATTR_READ_ONLY | \
                                          FAT_DIRENT_ATTR_HIDDEN |    \
                                          FAT_DIRENT_ATTR_SYSTEM |    \
                                          FAT_DIRENT_ATTR_VOLUME_ID)


//
//  These macros convert a number of fields in the Bpb to bytes from sectors
//

⌨️ 快捷键说明

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