📄 fat.h
字号:
// ULONG
// FatBytesPerCluster (
// IN PBIOS_PARAMETER_BLOCK Bios
// );
//
// ULONG
// FatBytesPerFat (
// IN PBIOS_PARAMETER_BLOCK Bios
// );
//
// ULONG
// FatReservedBytes (
// IN PBIOS_PARAMETER_BLOCK Bios
// );
//
#define FatBytesPerCluster(B) ((ULONG)((B)->BytesPerSector * (B)->SectorsPerCluster))
#define FatBytesPerFat(B) (IsBpbFat32(B)? \
((ULONG)((B)->BytesPerSector * (B)->LargeSectorsPerFat)) : \
((ULONG)((B)->BytesPerSector * (B)->SectorsPerFat)))
#define FatReservedBytes(B) ((ULONG)((B)->BytesPerSector * (B)->ReservedSectors))
//
// This macro returns the size of the root directory dirent area in bytes
// For Fat32, the root directory is variable in length. This macro returns
// 0 because it is also used to determine the location of cluster 2.
//
// ULONG
// FatRootDirectorySize (
// IN PBIOS_PARAMETER_BLOCK Bios
// );
//
#define FatRootDirectorySize(B) ((ULONG)((B)->RootEntries * sizeof(DIRENT)))
//
// This macro returns the first Lbo (zero based) of the root directory on
// the device. This area is after the reserved and fats.
//
// For Fat32, the root directory is moveable. This macro returns the LBO
// for cluster 2 because it is used to determine the location of cluster 2.
// FatRootDirectoryLbo32() returns the actual LBO of the beginning of the
// actual root directory.
//
// LBO
// FatRootDirectoryLbo (
// IN PBIOS_PARAMETER_BLOCK Bios
// );
//
#define FatRootDirectoryLbo(B) (FatReservedBytes(B) + ((B)->Fats * FatBytesPerFat(B)))
#define FatRootDirectoryLbo32(B) (FatFileAreaLbo(B)+((B)->RootDirFirstCluster-2)*FatBytesPerCluster(B))
//
// This macro returns the first Lbo (zero based) of the file area on the
// the device. This area is after the reserved, fats, and root directory.
//
// LBO
// FatFirstFileAreaLbo (
// IN PBIOS_PARAMTER_BLOCK Bios
// );
//
#define FatFileAreaLbo(B) (FatRootDirectoryLbo(B) + FatRootDirectorySize(B))
//
// This macro returns the number of clusters on the disk. This value is
// computed by taking the total sectors on the disk subtracting up to the
// first file area sector and then dividing by the sectors per cluster count.
// Note that I don't use any of the above macros since far too much
// superfluous sector/byte conversion would take place.
//
// ULONG
// FatNumberOfClusters (
// IN PBIOS_PARAMETER_BLOCK Bios
// );
//
//
// for prior to MS-DOS Version 3.2
//
// After DOS 4.0, at least one of these, Sectors or LargeSectors, will be zero.
// but DOS version 3.2 case, both of these value might contains some value,
// because, before 3.2, we don't have Large Sector entry, some disk might have
// unexpected value in the field, we will use LargeSectors if Sectors eqaul to zero.
//
#define FatNumberOfClusters(B) ( \
\
IsBpbFat32(B) ? \
\
((((B)->Sectors ? (B)->Sectors : (B)->LargeSectors) \
\
- ((B)->ReservedSectors + \
(B)->Fats * (B)->LargeSectorsPerFat )) \
\
/ \
\
(B)->SectorsPerCluster) \
: \
((((B)->Sectors ? (B)->Sectors : (B)->LargeSectors) \
\
- ((B)->ReservedSectors + \
(B)->Fats * (B)->SectorsPerFat + \
(B)->RootEntries * sizeof(DIRENT) / (B)->BytesPerSector ) ) \
\
/ \
\
(B)->SectorsPerCluster) \
)
//
// This macro returns the fat table bit size (i.e., 12 or 16 bits)
//
// ULONG
// FatIndexBitSize (
// IN PBIOS_PARAMETER_BLOCK Bios
// );
//
#define FatIndexBitSize(B) \
((UCHAR)(IsBpbFat32(B) ? 32 : (FatNumberOfClusters(B) < 4087 ? 12 : 16)))
//
// This macro raises STATUS_FILE_CORRUPT and marks the Fcb bad if an
// index value is not within the proper range.
// Note that the first two index values are invalid (0, 1), so we must
// add two from the top end to make sure the everything is within range
//
// VOID
// FatVerifyIndexIsValid (
// IN PIRP_CONTEXT IrpContext,
// IN PVCB Vcb,
// IN ULONG Index
// );
//
#define FatVerifyIndexIsValid(IC,V,I) { \
if (((I) < 2) || ((I) > ((V)->AllocationSupport.NumberOfClusters + 1))) { \
FatRaiseStatus(IC,STATUS_FILE_CORRUPT_ERROR); \
} \
}
//
// These two macros are used to translate between Logical Byte Offsets,
// and fat entry indexes. Note the use of variables stored in the Vcb.
// These two macros are used at a higher level than the other macros
// above.
//
// Note, these indexes are true cluster numbers.
//
// LBO
// GetLboFromFatIndex (
// IN FAT_ENTRY Fat_Index,
// IN PVCB Vcb
// );
//
// FAT_ENTRY
// GetFatIndexFromLbo (
// IN LBO Lbo,
// IN PVCB Vcb
// );
//
#define FatGetLboFromIndex(VCB,FAT_INDEX) ( \
( (LBO) \
(VCB)->AllocationSupport.FileAreaLbo + \
(((LBO)((FAT_INDEX) - 2)) << (VCB)->AllocationSupport.LogOfBytesPerCluster) \
) \
)
#define FatGetIndexFromLbo(VCB,LBO) ( \
(ULONG) ( \
(((LBO) - (VCB)->AllocationSupport.FileAreaLbo) >> \
(VCB)->AllocationSupport.LogOfBytesPerCluster) + 2 \
) \
)
//
// The following macro does the shifting and such to lookup an entry
//
// VOID
// FatLookup12BitEntry(
// IN PVOID Fat,
// IN FAT_ENTRY Index,
// OUT PFAT_ENTRY Entry
// );
//
#define FatLookup12BitEntry(FAT,INDEX,ENTRY) { \
\
CopyUchar2((PUCHAR)(ENTRY), (PUCHAR)(FAT) + (INDEX) * 3 / 2); \
\
*ENTRY = (FAT_ENTRY)(0xfff & (((INDEX) & 1) ? (*(ENTRY) >> 4) : \
*(ENTRY))); \
}
//
// The following macro does the tmp shifting and such to store an entry
//
// VOID
// FatSet12BitEntry(
// IN PVOID Fat,
// IN FAT_ENTRY Index,
// IN FAT_ENTRY Entry
// );
//
#define FatSet12BitEntry(FAT,INDEX,ENTRY) { \
\
FAT_ENTRY TmpFatEntry; \
\
CopyUchar2((PUCHAR)&TmpFatEntry, (PUCHAR)(FAT) + (INDEX) * 3 / 2); \
\
TmpFatEntry = (FAT_ENTRY) \
(((INDEX) & 1) ? ((ENTRY) << 4) | (TmpFatEntry & 0xf) \
: (ENTRY) | (TmpFatEntry & 0xf000)); \
\
*((UNALIGNED UCHAR2 *)((PUCHAR)(FAT) + (INDEX) * 3 / 2)) = *((UNALIGNED UCHAR2 *)(&TmpFatEntry)); \
}
//
// The following macro compares two FAT_TIME_STAMPs
//
#define FatAreTimesEqual(TIME1,TIME2) ( \
RtlEqualMemory((TIME1),(TIME2), sizeof(FAT_TIME_STAMP)) \
)
#define EA_FILE_SIGNATURE (0x4445) // "ED"
#define EA_SET_SIGNATURE (0x4145) // "EA"
//
// If the volume contains any ea data then there is one EA file called
// "EA DATA. SF" located in the root directory as Hidden, System and
// ReadOnly.
//
typedef struct _EA_FILE_HEADER {
USHORT Signature; // offset = 0
USHORT FormatType; // offset = 2
USHORT LogType; // offset = 4
USHORT Cluster1; // offset = 6
USHORT NewCValue1; // offset = 8
USHORT Cluster2; // offset = 10
USHORT NewCValue2; // offset = 12
USHORT Cluster3; // offset = 14
USHORT NewCValue3; // offset = 16
USHORT Handle; // offset = 18
USHORT NewHOffset; // offset = 20
UCHAR Reserved[10]; // offset = 22
USHORT EaBaseTable[240]; // offset = 32
} EA_FILE_HEADER; // sizeof = 512
typedef EA_FILE_HEADER *PEA_FILE_HEADER;
typedef USHORT EA_OFF_TABLE[128];
typedef EA_OFF_TABLE *PEA_OFF_TABLE;
//
// Every file with an extended attribute contains in its dirent an index
// into the EaMapTable. The map table contains an offset within the ea
// file (cluster aligned) of the ea data for the file. The individual
// ea data for each file is prefaced with an Ea Data Header.
//
typedef struct _EA_SET_HEADER {
USHORT Signature; // offset = 0
USHORT OwnEaHandle; // offset = 2
ULONG32 NeedEaCount; // offset = 4
UCHAR OwnerFileName[14]; // offset = 8
UCHAR Reserved[4]; // offset = 22
UCHAR cbList[4]; // offset = 26
UCHAR PackedEas[1]; // offset = 30
} EA_SET_HEADER; // sizeof = 30
typedef EA_SET_HEADER *PEA_SET_HEADER;
#define SIZE_OF_EA_SET_HEADER 30
#define MAXIMUM_EA_SIZE 0x0000ffff
#define GetcbList(EASET) (((EASET)->cbList[0] << 0) + \
((EASET)->cbList[1] << 8) + \
((EASET)->cbList[2] << 16) + \
((EASET)->cbList[3] << 24))
#define SetcbList(EASET,CB) { \
(EASET)->cbList[0] = (CB >> 0) & 0x0ff; \
(EASET)->cbList[1] = (CB >> 8) & 0x0ff; \
(EASET)->cbList[2] = (CB >> 16) & 0x0ff; \
(EASET)->cbList[3] = (CB >> 24) & 0x0ff; \
}
//
// Every individual ea in an ea set is declared the following packed ea
//
typedef struct _PACKED_EA {
UCHAR Flags;
UCHAR EaNameLength;
UCHAR EaValueLength[2];
CHAR EaName[1];
} PACKED_EA;
typedef PACKED_EA *PPACKED_EA;
//
// The following two macros are used to get and set the ea value length
// field of a packed ea
//
// VOID
// GetEaValueLength (
// IN PPACKED_EA Ea,
// OUT PUSHORT ValueLength
// );
//
// VOID
// SetEaValueLength (
// IN PPACKED_EA Ea,
// IN USHORT ValueLength
// );
//
#define GetEaValueLength(EA,LEN) { \
*(LEN) = 0; \
CopyUchar2( (LEN), (EA)->EaValueLength ); \
}
#define SetEaValueLength(EA,LEN) { \
CopyUchar2( &((EA)->EaValueLength), (LEN) ); \
}
//
// The following macro is used to get the size of a packed ea
//
// VOID
// SizeOfPackedEa (
// IN PPACKED_EA Ea,
// OUT PUSHORT EaSize
// );
//
#define SizeOfPackedEa(EA,SIZE) { \
ULONG _NL,_DL; _NL = 0; _DL = 0; \
CopyUchar1(&_NL, &(EA)->EaNameLength); \
GetEaValueLength(EA, &_DL); \
*(SIZE) = 1 + 1 + 2 + _NL + 1 + _DL; \
}
#define EA_NEED_EA_FLAG 0x80
#define MIN_EA_HANDLE 1
#define MAX_EA_HANDLE 30719
#define UNUSED_EA_HANDLE 0xffff
#define EA_CBLIST_OFFSET 0x1a
#define MAX_EA_BASE_INDEX 240
#define MAX_EA_OFFSET_INDEX 128
#endif // _FAT_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -