📄 fatfs.h
字号:
#define VOLF_LOCKED (VOLF_READLOCKED | VOLF_WRITELOCKED)
#define VOLF_FORMATTING 0x00000080 // volume is being (re)formatted
#define VOLF_12BIT_FAT 0x00000100 // 12-bit FAT
#define VOLF_16BIT_FAT 0x00000200 // 16-bit FAT
#define VOLF_32BIT_FAT 0x00000400 // 32-bit FAT
#define VOLF_BACKUP_FAT 0x00000800 // one or more additional backup FATs exist
#define VOLF_MODDISKINFO 0x00001000 // volume DISK_INFO has been modified
#define VOLF_BUFFERED 0x00004000 // volume is buffered
#define VOLF_RETAIN 0x00008000 // volume should be retained across an unmount
#define VOLF_UNCERTAIN 0x00010000 // volume state is uncertain (do not assume unformatted!)
#define VOLF_DIRTY 0x00020000 // volume has dirty buffers pending
#define VOLF_CLOSING 0x00040000 // volume being closed, discard all open handles/dirty buffers
#define VOLF_READONLY DSKF_READONLY // volume is read-only (eg, write-protected)
#define VOLF_SCANNING 0x00100000 // volume is being scanned for inconsistencies
#define VOLF_MODIFIED 0x00200000 // volume has been modified (ie, 1 or more volume writes)
#define VOLF_LOGINIT 0x00400000 // volume has been "logging enabled"
#define VOLF_INITCOMPLETE 0x00800000 // volume has been fully initialized (no need to scan, etc)
#define VOLF_UPDATE_ACCESS 0x01000000 // per-volume version of FATFS_UPDATE_ACCESS
#define VOLF_DIRTY_WARN 0x02000000 // per-volume dirty data warning flag
#define VOLF_TFAT_REDIR_ROOT 0x04000000 // Indicates to redirect the root directory to another hidden director
// for FAT12 or 16, since root dir isn't transacted in those cases
#define VOLF_TFAT_CREATING_ROOT 0x08000000
#define VOLF_SECUREWIPE 0x10000000
#ifdef FAT32
#define VOLF_UNSUPPORTED (VOLF_UNCERTAIN)
#else
#define VOLF_UNSUPPORTED (VOLF_32BIT_FAT | VOLF_UNCERTAIN)
#endif
typedef DWORD UNPACKFN(PVOLUME pvol, DWORD clusIndex, PDWORD pclusData);
typedef DWORD PACKFN(PVOLUME pvol, DWORD clusIndex, DWORD clusData, PDWORD pclusDataPrev);
struct _VOLUME {
HVOL v_hVol;
VOL_DLINK v_dlOpenVolumes;// list of open volumes on dsk
STM_DLINK v_dlOpenStreams;// list of DSTREAMs for this volume
#ifdef PATH_CACHING
CCH_DLINK v_dlCaches; // list of CACHEs for this volume
#endif
PDSK v_pdsk; // DSK the VOLUME is open on
DWORD v_flags; // see VOLF_*
signed char v_volID; // file system volume ID (aka AFS index), INVALID_AFS if none
DWORD v_cCaches; // # cache entries currently attached
DWORD v_cMaxCaches; // Max number of path cache entries
//
// Beginning of portion reset by InitVolume for INVALID volumes
//
BYTE v_bMediaDesc; // media descriptor from BPB
BYTE v_bVerifyCount; // number of read-after-write verifies left to perform
DWORD v_serialID; // volume serial # and label from boot sector
BYTE v_label[OEMNAMESIZE+1];
BYTE v_log2cbSec; // log2(bytes per sector) 9
BYTE v_log2cbBlk; // log2(bytes per block) 9
BYTE v_log2cblkSec; // log2(blocks per sector) 0
BYTE v_log2csecClus; // log2(sectors per cluster) 3
BYTE v_log2cblkClus; // log2(blocks per cluster) 0
DWORD v_secVolBias; // sector bias for volume (ie, reserved sectors)
DWORD v_secBlkBias; // sector bias for block 0 (ie, reserved + hidden sectors)
DWORD v_blkClusBias; // block bias for cluster 0 (ie, # blocks in FAT + root dir)
DWORD v_cbBlk; // bytes per block
DWORD v_cbClus; // bytes per cluster
DWORD v_clusEOF; // cluster EOF threshold
DWORD v_clusMax; // maximum cluster # for volume (starting w/DATA_CLUSTER)
DWORD v_clusAlloc; // last cluster alloc'ed, -1 if none yet
DWORD v_cclusFree; // # of free clusters, -1 if not known yet
LPBYTE v_pFreeClusterList; // number of free clusters for each 128 cluster section
DWORD v_clusterListSize; // size of the cluster list in bytes
DWORD v_csecFAT; // sectors per FAT
DWORD v_secEndFAT; // ending sector # (+1) of active FAT
DWORD v_secEndAllFATs;// ending sector # (+1) of all FATs
DWORD v_csecUsed; // total sectors used in FAT and root
DWORD v_csecTotal; // total sectors on volume
#ifdef FAT32
DWORD v_secFSInfo; // as obtained from BIGFATBPB->BGBPB_FSInfoSec
#endif
UNPACKFN *v_unpack; // FAT unpack function
PACKFN *v_pack; // FAT pack function
//
// End of portion reset by InitVolume for INVALID volumes
//
PDSTREAM v_pstmFAT; // stream used to read/write FAT
PDSTREAM v_pstmRoot; // stream used to read/write root directory
PWSTR v_pwsHostRoot; // pointer to local name of root (NULL if none)
DWORD v_cwsHostRoot; // length (in WCHARs) of local root name
CRITICAL_SECTION v_cs; // critical section for volume
CRITICAL_SECTION v_csStms; // critical section for OpenStreams list
#ifdef PATH_CACHING
CRITICAL_SECTION v_csCaches;// critical section for Caches list
#endif
DWORD v_FATCacheId;
DWORD v_DataCacheId;
DWORD v_flFATFS; // Per Volume FAT Flags
UINT v_nCodePage; // Codepage - Default CP_OEMCP , can be overridden by registry entry CODEPAGE=
//
// Buffer pool fields
//
DWORD v_cbufTotal; // total number of buffers
DWORD v_cbufError; // total buffers with outstanding write errors
PBYTE v_pbBufCarve; // address of carved buffer memory, if any
BUF_DLINK v_dlBufMRU; // MRU list of buffers
DWORD v_cBufThreads; // number of threads buffer pool can handle
HANDLE v_hevBufThreads; // auto-reset event signalled when another thread can be handled
CRITICAL_SECTION v_csBuffers; // buffer pool critical section
#ifdef TFAT
DWORD v_clusFrozenHead; // The head of frozen cluster list
struct
{
DWORD dwSize;
LPBYTE lpBits; // A bit array to hold dirty clusters in FAT;
} v_DirtySectorsInFAT;
// cache some FAT sectors for performance, the buffer is also used for sync fat
LPBYTE v_pFATBuffer;
DWORD v_secFATBufferBias; // sector bias of first FAT0 sector cached
LPBYTE v_ClusBuf; // A buffer for cloning clusters
// Keep a copy of boot sector
LPBYTE v_pBootSec;
BOOL v_fTfat;
LPDWORD v_pFrozenClusterList; // cache used to keep track of frozen clusters
#endif
};
#define NO_CLUSTER 0
#define FREE_CLUSTER NO_CLUSTER
#define FAT_PSEUDO_CLUSTER 0
#define ROOT_PSEUDO_CLUSTER 1
#define DATA_CLUSTER 2 // first legitimate cluster number
#define EOF_CLUSTER ((unsigned)-1)
#define UNKNOWN_CLUSTER EOF_CLUSTER
#define ISROOTDIR(pstm) ((pstm)->s_clusFirst == (pstm)->s_pvol->v_pstmRoot->s_clusFirst)
#define ISPARENTROOTDIR(pstm) ((pstm)->s_sid.sid_clusDir == (pstm)->s_pvol->v_pstmRoot->s_clusFirst)
#define ISEOF(pvol, cl) ((cl) >= (pvol)->v_clusEOF)
#define CLUSTERTOBLOCK(pvol,cl) (((cl) << (pvol)->v_log2cblkClus) + (pvol)->v_blkClusBias)
#define CLUSTERTOSECTOR(pvol,cl) ((((cl)-DATA_CLUSTER) << (pvol)->v_log2csecClus) + (pvol)->v_csecUsed + (pvol)->v_secBlkBias)
#define BLOCKTOCLUSTER(pvol, bl) (((bl) - (pvol)->v_blkClusBias) >> (pvol)->v_log2cblkClus)
#define IS_FAT_SECTOR(pvol, sector) ((sector < ( (pvol)->v_secBlkBias + (pvol)->v_secEndAllFATs )) && (sector >= (pvol)->v_secBlkBias))
#define UNPACK(pvol,index,pdata) ((pvol)->v_unpack((pvol),(index),(pdata)))
#define PACK(pvol,index,data,pold) ((pvol)->v_pack((pvol),(index),(data),(pold)))
// values for lr_id:
#define LOGID_NONE 0
#define LOGID_SCANVOLUME 1 // ScanVolume()
#define LOGID_BUFFERMODIFY 2 // ModifyBuffer()
#define LOGID_BUFFERWRITE 3 // CommitBuffer(PRE)
#define LOGID_BUFFERCOMMIT 4 // CommitBuffer(POST)
#define LOGID_DISKIO 5 // FAT_DeviceIoControl
#define LOGID_CREATEFILE 6 // FAT_CreateFileW
#define LOGID_CLOSEFILE 7 // FAT_CloseFile
#define LOGID_WRITEFILE 8 // FAT_WriteFile
#define LOGID_FLUSHFILEBUFFERS 9 // FAT_FlushFileBuffers
#define LOGID_SETENDOFFILE 10 // FAT_SetEndOfFile
#define LOGID_CREATEDIRECTORY 11 // FAT_CreateDirectoryW
#define LOGID_REMOVEDIRECTORY 12 // FAT_RemoveDirectoryW
#define LOGID_DELETEFILE 13 // FAT_DeleteFileW
#define LOGID_MOVEFILE 14 // FAT_MoveFileW
#define LOGID_TOTAL 15
struct _LOGREC {
WORD lr_size; // total size of LOGREC, including lr_size
BYTE lr_id; // see LOGID_* above
BYTE lr_flags; // reserved for flags (must be zero for now)
DWORD lr_owner; // non-zero thread ID if owned, zero if not
DWORD lr_serialID; // volume serial # from boot sector
DWORD lr_blk; // block # of modification
DWORD lr_off; // offset of modification within block
DWORD lr_cb; // size of modification, in bytes
DWORD lr_crc; // checksum of buffer (on LOGID_BUFFERCOMMIT)
#ifdef DEBUG
CHAR lr_desc[18]; // space for descriptive string
#endif
BYTE lr_abData[]; // original bytes
};
typedef struct _LOGREC LOGREC, *PLOGREC;
/* Open stream structure:
*
* This structure holds the description of an open file or directory. The
* SHANDLE & FHANDLE structures for the same file or directory must point to the
* same DSTREAM structure.
*/
// values for s_flags:
#define STF_INIT 0x0001 // stream has been initialized by DIRENTRY
#define STF_DEMANDPAGED 0x0002 // stream can be demand-paged
#define STF_CREATE_TIME 0x0004 // an explicit create time has been set
#define STF_ACCESS_TIME 0x0008 // an explicit access time has been set
#define STF_WRITE_TIME 0x0010 // an explicit write time has been set
#define STF_VOLUME 0x0020 // this stream is VOLUME-based (ie, not a file)
#define STF_UNMOUNTED 0x0040 // this stream currently unavailable (volume unmounted)
#define STF_BUFCURHELD 0x0080 // pbufCur is currently in use and being held
#define STF_WRITETHRU 0x0100 // somebody has opened the stream in write-through mode
#define STF_VISITED 0x0200 // stream has been visited (see FAT_CloseAllFiles)
#define STF_DIRTY_INFO 0x0400 // stream info out of sync with DIRENTRY
#define STF_DIRTY_DATA 0x0800 // stream data has been modified
#define STF_DIRTY_CLUS 0x1000 // starting cluster in stream info out of sync with DIRENTRY
#define STF_TRANSDATA 0x2000 // transact data for this stream
#define STF_PRIVATE 0x8000 // stream is private (may be a duplicate, but it's for non-shared read-access only)
#define STF_DIRTY (STF_DIRTY_INFO | STF_DIRTY_DATA)
#define MAX_DIRSIZE 0x7FFFFFFF
typedef struct _DSID { // structure for unique data stream IDs (similar to OIDs)
DWORD sid_ordDir; // ordinal in directory of stream's DIRENTRY
DWORD sid_clusDir; // cluster of dir containing stream's DIRENTRY
} DSID;
typedef DSID *PDSID;
#define SETSID(psid,pos,clus) (psid)->sid_ordDir = (pos)/sizeof(DIRENTRY), (psid)->sid_clusDir = (clus)
#if !defined(OIDHIGH) || !defined(OIDLOW)
#define SETSIDFROMOID(psid,oid) (psid)->sid_ordDir = 0, (psid)->sid_clusDir = UNKNOWN_CLUSTER
#else
#define SETSIDFROMOID(psid,oid) (psid)->sid_ordDir = OIDHIGH(oid), (psid)->sid_clusDir = OIDLOW(oid)
#endif
#if !defined(AFSFROMOID) // either AFSFROMOID or OIDAFS must be defined externally...
#define AFSFROMOID(oid) OIDAFS(oid)
#endif
#if !defined(OIDFROMAFS) // either OIDFROMAFS or PACKOID must be defined externally...
#define OIDFROMAFS(iAFS) PACKOID(iAFS,0,0)
#endif
#if !defined(INVALID_OID)
#define INVALID_OID ((CEOID)(INVALID_HANDLE_VALUE))
#endif
#if !defined(PACKOID)
#define OIDFROMSID(pvol,psid) INVALID_OID
#define OIDFROMSTREAM(pstm) INVALID_OID
#else
#define OIDFROMSID(pvol,psid) PACKOID((pvol)->v_volID, (psid)?((PDSID)(psid))->sid_ordDir:0, (psid)?((PDSID)(psid))->sid_clusDir:0)
#define OIDFROMSTREAM(pstm) OIDFROMSID((pstm)->s_pvol, &(pstm)->s_sid)
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -