⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fatfs.h

📁 FAT文件系统源代码
💻 H
📖 第 1 页 / 共 5 页
字号:

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)
    StreamRunList    s_runList;             // 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
//  better up above)
//
    DSID        s_sid;               // unique stream ID
    DSID        s_sidParent;         // unique stream ID for parent
    DWORD       s_offDir;            // offset in block of stream's DIRENTRY
    DWORD       s_blkDir;            // block of dir containing stream's DIRENTRY
    DWORD       s_clusFirst;         // first cluster in stream
    FILETIME    s_ftCreate;          // creation time from DIRENTRY
    FILETIME    s_ftAccess;          // last access time from DIRENTRY
    FILETIME    s_ftWrite;           // last write time from DIRENTRY
    BYTE        s_attr;              // file attribute byte
    BYTE        s_achOEM[OEMNAMESIZE+1];
};


/*  Open file handle structure:
 *
 *  There is one these for each open file handle on the volume. It holds the
 *  current file position, the file access mode, etc.
 */

// values for fh_flags:
#define FHF_FAILUI      0x01    // Used to determine if we need to put up a UI window on failure
#define FHF_LOCKED      0x10    // volume-level lock granted
#define FHF_VOLUME      0x20    // volume-level access only (ie, CreateFile("VOL:"))
#define FHF_UNMOUNTED   0x40    // this handle currently unavailable (volume has been unmounted)
#define FHF_FHANDLE     0x80    // this bit NOT set for SHANDLEs

struct _FHANDLE {
    FH_DLINK    fh_dlOpenHandles;
    PDSTREAM    fh_pstm;        // DSTREAM for the file
    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
};

#ifndef UNDER_CE
#define offsetof(x,y) 0
#endif

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_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(PVOLUME pvol, 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.
 *
 *  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 < 32), \
                                    InterlockedIncrement (&((pbuf)->b_hold)) \
                                )
#define UnholdBuffer(pbuf)      ( \
                                    ASSERT((pbuf)->b_hold != 0), \
                                    InterlockedDecrement (&((pbuf)->b_hold)) \
                                )
#define HeldBuffer(pbuf)        ( \
                                    (pbuf)->b_hold != 0 \
                                )
#define ASSERTHELDBUFFER(pbuf)  ( \
                                    (pbuf)->b_hold != 0 \
                                )

BOOL    BufInit(PVOLUME pvol);
void    BufDeinit(PVOLUME pvol);
BOOL    BufEnter(PVOLUME pvol, BOOL fForce);
void    BufExit(PVOLUME pvol);

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   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);
DWORD   InvalidateSteamBuffer(PDSTREAM pstm);
void    InvalidateBufferSet(PVOLUME pvol, BOOL fAll);
BOOL    LockBlocks(PDSTREAM pstm, DWORD pos, DWORD len, DWORD *pblk, DWORD *pcblk, BOOL fWrite);
void    UnlockBlocks(PDSTREAM pstm, 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);
BOOL     PathCacheStreamInvalidate(PVOLUME pvol, PDSTREAM pstm);
int      PathCacheLength(PCWSTR *ppwsPath, int celRemove);
PCACHE   PathCacheFindStream(PVOLUME pvol, PDSTREAM pstm);
PDSTREAM PathCacheDestroy(PVOLUME pvol, PCACHE pcch, BOOL fClose);
void     PathCacheDestroyAll(PVOLUME pvol);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -