📄 fatfs.h
字号:
BYTE fh_flags; // handle status flags (see FHF_*)
BYTE fh_mode; // file access & sharing modes
WORD fh_pad;
DWORD fh_pos; // current file position
HANDLE fh_h; // kernel handle to this FHANDLE
HANDLE fh_hProc; // process that opened the file
};
/* Open search handle structure:
*
* There is one of these for each open FindFirst/FindNext. It holds the
* current position of the find and the pattern being sought. For internal
* (SHF_BYORD or SHF_BYCLUS) searches, sh_h is overloaded as the desired
* DIRENTRY ordinal or cluster.
*
* Also, when an SHANDLE is allocated, sh_awcPattern is not really allocated
* to MAX_PATH WCHARs. It is only allocated to the length stored in sh_cwPattern.
*/
#define INVALID_POS 0xFFFFFFFF
#define INVALID_ATTR 0xFFFFFFFF
// The first three "search by" flags are mutually exclusive searches, hence
// they don't need completely separate bits.
// values for sh_flags:
#define SHF_BYNAME 0x01 // search by name
#define SHF_BYORD 0x02 // search by DIRENTRY ordinal
#define SHF_BYCLUS 0x03 // search by DIRENTRY containing specific cluster
#define SHF_BYMASK 0x03 // mask for the mutually exclusive search types
#define SHF_BYATTR 0x04 #define SHF_WILD 0x08 // allow wildcards
#define SHF_DOTDOT 0x10 // allow search for "." and ".." entries
#define SHF_CREATE 0x20 // turn on auto-generated short name creation
#define SHF_UNMOUNTED FHF_UNMOUNTED
#define SHF_NOT_SHANDLE FHF_FHANDLE
struct _SHANDLE {
SH_DLINK sh_dlOpenHandles;
PDSTREAM sh_pstm; // DSTREAM for the directory
BYTE sh_flags; // search status flags (see SHF_*)
BYTE sh_attr; WORD sh_cwPattern; // # characters in sh_awcPattern (includes room for NULL)
DWORD sh_pos; // last position within directory
HANDLE sh_h; // kernel handle to this SHANDLE
HANDLE sh_hProc; // process that opened the file
#ifdef DEBUG
DWORD sh_cbAlloc; // used to track size of this allocation only
#endif
WCHAR sh_awcPattern[MAX_PATH];// search pattern
};
ERRFALSE(offsetof(FHANDLE,fh_dlOpenHandles) == offsetof(SHANDLE,sh_dlOpenHandles));
ERRFALSE(offsetof(FHANDLE,fh_pstm) == offsetof(SHANDLE,sh_pstm));
ERRFALSE(offsetof(FHANDLE,fh_flags) == offsetof(SHANDLE,sh_flags));
ERRFALSE(offsetof(FHANDLE,fh_h) == offsetof(SHANDLE,sh_h));
ERRFALSE(offsetof(FHANDLE,fh_hProc) == offsetof(SHANDLE,sh_hProc));
/* Define the maximum number of short name (8.3) collisions supported;
* note that if you increase this beyond one more order of magnitude (> 9999),
* then you will have to change itopch() to support larger numbers.
*/
#define MAX_SHORT_NAMES 999
/* Directory search information structure:
*
* This structure can be passed to FindNext to return additional information
* about the directory it just searched. Most of this information is essential
* only if we need to call CreateName. Note that for every DIRINFO structure,
* the caller should have a corresponding SHANDLE structure, because some of the
* information that FindNext records in the DIRINFO is dependent on the SHANDLE
* it was given.
*/
#define DIRINFO_OEM 0x01 // name conforms to 8.3
struct _DIRINFO {
PDIRENTRY di_pde; // pointer to matching DIRENTRY (NULL if none)
DSID di_sid;
DWORD di_clusEntry; // cluster extracted from DIRENTRY
DWORD di_pos; // position of matching (or last) DIRENTRY
DWORD di_posLFN; // position of 1st matching LFN DIRENTRY, if any
int di_cdeNeed; // number of DIRENTRY's needed for LFN (-1 if unknown)
DWORD di_posFree; // position of first free/deleted DIRENTRY to satisfy
int di_cdeFree; // count of free/deleted DIRENTRY(s), 0 if none
DWORD di_posOrphan; // position of orphaned LFN(s) to recover
int di_cdeOrphan; // count of orphaned DIRENTRY(s), 0 if none
int di_cwName; // size of entire name associated with DIRENTRY
PCWSTR di_pwsTail; // pointer to end-most LFN piece, in associated SHANDLE structure
WORD di_cwTail; // size of end-most LFN piece
BYTE di_bNumericTail;// DIRENTRY position (0-6) where numeric tail should start
BYTE di_chksum; // checksum of di_achOEM (valid only if DIRINFO_OEM set)
BYTE di_flags; // see DIRINFO_* above
BYTE di_achOEM[OEMNAMESIZE];
};
typedef struct _DIRINFO DIRINFO, *PDIRINFO;
#define GETDIRENTRYCLUSTER(pvol,pde) ( \
(pvol)->v_clusEOF <= 0xFFFF? \
(pde)->de_clusFirst : \
(pde)->de_clusFirst+(DWORD)((pde)->de_clusFirstHigh<<16)\
)
#define SETDIRENTRYCLUSTER(pvol,pde,clus) { \
(pde)->de_clusFirst = (WORD)(clus); \
if ((pvol)->v_clusEOF > 0xFFFF) \
(pde)->de_clusFirstHigh = (WORD)((clus) >> 16); \
}
#define AccessToMode(dwAccess) ((dwAccess)>>24)
#define FH_MODE_READ AccessToMode(GENERIC_READ) // 0x80
#define FH_MODE_WRITE AccessToMode(GENERIC_WRITE) // 0x40
#define ShareToMode(dwShare) (dwShare)
#define FH_MODE_SHARE_READ ShareToMode(FILE_SHARE_READ) // 0x01
#define FH_MODE_SHARE_WRITE ShareToMode(FILE_SHARE_WRITE) // 0x02
ERRFALSE(FH_MODE_READ!=0);
ERRFALSE(FH_MODE_WRITE!=0);
ERRFALSE((AccessToMode((GENERIC_READ|GENERIC_WRITE)) & (FILE_SHARE_READ|FILE_SHARE_WRITE)) == 0);
// OpenName/CreateName options. These are defined such that ATTR_* flags
// can be combined with them without conflict (but since FH_MODE_* flags already
// conflict with ATTR_*, we have no choice but to shift them into place).
#define NAME_ATTR_MASK 0x000000FF // mask for ATTR_* bits
#define NAME_FILE 0x00000100 // name must be a file
#define NAME_DIR 0x00000200 // name must be a directory
#define NAME_VOLUME 0x00000400 // name may be "VOL:"
#define NAME_NEW 0x00001000 // file must be new
#define NAME_CREATE 0x00002000 // file can be created
#define NAME_TRUNCATE 0x00004000 // file must be truncated
#define NAME_CREATED 0x00008000 // file was actually created
#define NAME_MODE_MASK 0x00FF0000 // mask for FH_MODE_* bits
#define NAME_MODE_SHIFT 16 // shift for FH_MODE_* bits
#define NAME_MODE_READ (FH_MODE_READ << NAME_MODE_SHIFT)
#define NAME_MODE_WRITE (FH_MODE_WRITE << NAME_MODE_SHIFT)
#define NAME_MODE_SHARE_READ (FH_MODE_SHARE_READ << NAME_MODE_SHIFT)
#define NAME_MODE_SHARE_WRITE (FH_MODE_SHARE_WRITE << NAME_MODE_SHIFT)
/* Stucture for SetSizePointer in MISC.C
*/
typedef struct _SIZEPTR {
DWORD c; // count of elements
PVOID p; // pointer to elements
} SIZEPTR;
typedef SIZEPTR *PSIZEPTR;
/* API.C functions
*/
BOOL FAT_Unmount(PVOLUME pvol);
BOOL FAT_NoSupport(void);
BOOL FAT_CloseAllFiles(PVOLUME pvol, HANDLE hProc);
void FAT_Notify(PVOLUME pvol, DWORD dwFlags);
BOOL FATEnter(PVOLUME pvol, BYTE idLog);
void FATEnterQuick(void);
void FATExit(BYTE idLog);
void FATExitQuick(void);
PDSK FSD_Init(PCWSTR pwsDisk);
BOOL FSD_Deinit(PDSK pdsk);
BOOL WINAPI FATMain(HINSTANCE DllInstance, INT Reason, LPVOID Reserved);
/* BUFFER.C functions
*
* Note that HoldBuffer and UnholdBuffer are actually macros, and moreover,
* do not use interlocked inc/dec functions; such calls would be overkill, because
* the only time a buffer's hold count actually transitions from zero -- and the
* only time a buffer's hold count is actually depended upon -- is while csBuffers
* is held, so the integrity of the hold counts should already be assured.
*
* Uses of HoldBuffer and UnholdBuffer outside the normal buffer manipulation
* functions (like those in path.c) are simply applying an *additional* hold to a
* buffer that is already known to be held; without that additional hold, a read to
* a different part of the same stream might otherwise release that buffer's contents,
* allowing it to be reused and thereby invalidating any pointers the caller had
* obtained to the earlier contents of the buffer.
*
* This should help explain the logic in the DEBUG-only assertions embedded in the
* macros below. Also, the hold threshold of 32 is arbitrary; it is simply an attempt
* to validate that hold counts will never exceed the capacity of a BYTE.
*/
#define HoldBuffer(pbuf) ( \
ASSERT(((pbuf)->b_hold != 0 || OWNCRITICALSECTION(&csBuffers)) && (pbuf)->b_hold < 32), \
(pbuf)->b_hold++ \
)
#define UnholdBuffer(pbuf) ( \
ASSERT((pbuf)->b_hold != 0), \
--(pbuf)->b_hold \
)
#define HeldBuffer(pbuf) ( \
ASSERT(OWNCRITICALSECTION(&csBuffers)), \
(pbuf)->b_hold != 0 \
)
#define ASSERTHELDBUFFER(pbuf) ( \
(pbuf)->b_hold != 0 \
)
BOOL BufInit(void);
void BufDeinit(void);
BOOL BufEnter(BOOL fForce);
void BufExit(void);
BOOL AllocBufferPool(PVOLUME pvol);
BOOL FreeBufferPool(PVOLUME pvol);
DWORD ModifyBuffer(PBUF pbuf, PVOID pMod, int cbMod);
void DirtyBuffer(PBUF pbuf);
void DirtyBufferError(PBUF pbuf, PVOID pMod, int cbMod);
DWORD CommitBuffer(PBUF pbuf, BOOL fCS);
void CleanBuffer(PBUF pbuf);
DWORD ChecksumBuffer(PBUF pbuf);
DWORD FindBuffer(PVOLUME pvol, DWORD blk, PDSTREAM pstm, BOOL fNoRead, PBUF *ppbuf);
void AssignStreamBuffer(PDSTREAM pstm, PBUF pbuf, BOOL fCS);
DWORD ReleaseStreamBuffer(PDSTREAM pstm, BOOL fCS);
DWORD ReadStreamBuffer(PDSTREAM pstm, DWORD pos, int lenMod, PVOID *ppvStart, PVOID *ppvEnd);
DWORD ModifyStreamBuffer(PDSTREAM pstm, PVOID pMod, int cbMod);
#define CommitAndReleaseStreamBuffers(pstm) CommitBufferSet(pstm, 1)
#define CommitStreamBuffers(pstm) CommitBufferSet(pstm, 0)
#define CommitVolumeBuffers(pvol) CommitBufferSet((PDSTREAM)(pvol), -1)
#define CommitAllBuffers() CommitBufferSet(NULL, -1)
#define CommitOldBuffers() CommitBufferSet(NULL, -2)
#define WriteAndReleaseStreamBuffers(pstm) CommitAndReleaseStreamBuffers(pstm)
#define WriteStreamBuffers(pstm) CommitStreamBuffers(pstm)
DWORD CommitBufferSet(PDSTREAM pstm, int iCommit);
void InvalidateBufferSet(PVOLUME pvol, BOOL fAll);
BOOL LockBlocks(PDSTREAM pstm, DWORD pos, DWORD len, DWORD *pblk, DWORD *pcblk, BOOL fWrite);
void UnlockBlocks(DWORD blk, DWORD cblk, BOOL fWrite);
/* CACHE.C functions
*/
void PathCacheCreate(PVOLUME pvol, PCWSTR pwsPath, int len, PDSTREAM pstm);
PDSTREAM PathCacheSearch(PVOLUME pvol, PCWSTR *ppwsPath);
BOOL PathCacheInvalidate(PVOLUME pvol, PCWSTR pwsPath);
int PathCacheLength(PCWSTR *ppwsPath, int celRemove);
PCACHE PathCacheFindStream(PVOLUME pvol, PDSTREAM pstm);
PDSTREAM PathCacheDestroy(PVOLUME pvol, PCACHE pcch, BOOL fClose);
void PathCacheDestroyAll(PVOLUME pvol);
/* DISK.C functions
*/
DWORD GetDiskInfo(HANDLE hdsk, PDISK_INFO pdi);
DWORD SetDiskInfo(HANDLE hdsk, PDISK_INFO pdi);
DWORD ReadWriteDisk(PVOLUME pvol, HANDLE hdsk, DWORD cmd, PDISK_INFO pdi, DWORD sector, int cSectors, PVOID pvBuffer);
#ifdef DISK_CACHING
void SetupDiskCache(PVOLUME pvol);
DWORD ReadWriteDisk2(PVOLUME pvol, HANDLE hdsk, DWORD cmd, PDISK_INFO pdi, DWORD sector, int cSectors, PVOID pvBuffer);
#endif
PDSK MountDisk(HANDLE hdsk, PCWSTR pwsDisk, DWORD flVol);
DWORD NamePartitionInfo(PPARTINFO ppi, PWSTR pwsName);
PPI AllocPartitionInfo(PDSK pdsk, DWORD secPartTable, int idxPartTable, PPARTENTRY ppe, DWORD secPartition, PPARTINFO ppiParent, PBYTE pbSector);
void RefreshPartitionInfo(PDSK pdsk);
void FreePartitionInfo(PPI_DLINK pdlPartitions);
BOOL UnmountDisk(PDSK pdsk, BOOL fFrozen);
DWORD UnmountAllDisks(BOOL fFrozen);
/* FAT.C functions
*/
void LockFAT(PVOLUME pvol);
DWORD GetFAT(PVOLUME pvol, DWORD dwOffset, PVOID *ppvEntry, PVOID *ppvEntryEnd);
void UnlockFAT(PVOLUME pvol);
DWORD Unpack12(PVOLUME pvol, DWORD clusIndex, PDWORD pclusData);
DWORD Pack12(PVOLUME pvol, DWORD clusIndex, DWORD clusData, PDWORD pclusOld);
DWORD Unpack16(PVOLUME pvol, DWORD clusIndex, PDWORD pclusData);
DWORD Pack16(PVOLUME pvol, DWORD clusIndex, DWORD clusData, PDWORD pclusOld);
DWORD Unpack32(PVOLUME pvol, DWORD clusIndex, PDWORD pclusData);
DWORD Pack32(PVOLUME pvol, DWORD clusIndex, DWORD clusData, PDWORD pclusOld);
DWORD UnpackRun(PDSTREAM pstm);
DWORD NewCluster(PVOLUME pvol, DWORD clusPrev, PDWORD pclusNew);
/* FILE.C functions
*/
HANDLE FAT_CreateFileW(PVOLUME pvol, HANDLE hProc, LPCWSTR lpFileName, DWORD dwAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreate, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
BOOL FAT_CloseFile(PFHANDLE pfh);
#if NUM_FILE_APIS == 13
BOOL FAT_ReadFilePagein(PFHANDLE pfh, LPVOID buffer, DWORD nBytesToRead, LPDWORD lpNumBytesRead, LPOVERLAPPED lpOverlapped);
#else
BOOL FAT_ReadFileWithSeek(PFHANDLE pfh, LPVOID buffer, DWORD nBytesToRead, LPDWORD lpNumBytesRead, LPOVERLAPPED lpOverlapped, DWORD dwLowOffset, DWORD dwHighOffset);
BOOL FAT_WriteFileWithSeek(PFHANDLE pfh, LPCVOID buffer, DWORD nBytesToWrite, LPDWORD lpNumBytesWritten, LPOVERLAPPED lpOverlapped, DWORD dwLowOffset, DWORD dwHighOffset);
#endif
BOOL FAT_ReadFile(PFHANDLE pfh, LPVOID buffer, DWORD nBytesToRead, LPDWORD lpNumBytesRead, LPOVERLAPPED lpOverlapped);
BOOL FAT_WriteFile(PFHANDLE pfh, LPCVOID buffer, DWORD nBytesToWrite, LPDWORD lpNumBytesWritten, LPOVERLAPPED lpOverlapped);
DWORD FAT_SetFilePointer(PFHANDLE pfh, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod);
DWORD FAT_GetFileSize(PFHANDLE pfh, LPDWORD lpFileSizeHigh);
BOOL FAT_GetFileInformationByHandle(PFHANDLE pfh, LPBY_HANDLE_FILE_INFORMATION lpFileInfo);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -