📄 fatfs.h
字号:
#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)
BYTE v_log2cbBlk; // log2(bytes per block)
BYTE v_log2cblkSec; // log2(blocks per sector)
BYTE v_log2csecClus; // log2(sectors per cluster)
BYTE v_log2cblkClus; // log2(blocks per cluster)
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
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;
/* Data run:
*
* This structure is used to describe a contiguous run of data on the disk.
* Note that the start and end fields are stream-relative, whereas all the
* block and cluster fields are volume-relative.
*
* NOTE that although r_blk and r_clusThis convey similar information, we
* can't eliminate either of them. That's because the FAT (and possibly ROOT)
* streams are not cluster-mapped, so the only fields that get used in those
* cases are the first three (r_start, r_end and r_blk).
*/
typedef struct _RUN {
DWORD r_start; // starting byte position of run
DWORD r_end; // ending byte of run + 1
DWORD r_blk; // first block of run
DWORD r_clusThis; // first cluster of this run
DWORD r_clusNext; // next cluster after this run
DWORD r_clusPrev; // cluster preceding this run (0 if none)
} RUN, *PRUN;
/* 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_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
struct _DSTREAM {
STM_DLINK s_dlOpenStreams; // linkage for v_dlOpenStreams
FH_DLINK s_dlOpenHandles; // list of FHANDLE's or SHANDLE's
PVOLUME s_pvol; // VOLUME the DSTREAM is open on
long s_refs; // usage count for the stream
WORD s_flags; // stream status flags (see STF_*)
WORD s_cwPath; // # characters in path to this stream (excluding NULL)
RUN s_run; // run info from current/last operation
PBUF s_pbufCur; // pointer to stream's current buffer, if any
DWORD s_offbufCur; // stream offset associated with current buffer
DWORD s_size; // length of the stream
FILELOCKSTATE s_filelockstate; // data required to manage sub-file locks on file
CRITICAL_SECTION s_cs; // critical section for this stream
#ifdef TFAT
PDSTREAM s_pstmParent; // parent stream: TFAT only
#endif
//
// Beginning of portion that actually relates to non-STF_VOLUME streams only!
// (actually, s_cwPath belongs down here as well, but since it's a WORD, it fits
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -