📄 fat.h
字号:
/*++
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 + -