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

📄 fatfs.h

📁 从大量的wince源代码中剥离出的fat文件系统源代码.移植性非常高. 里面带有source i.rar
💻 H
📖 第 1 页 / 共 5 页
字号:
    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 + -