📄 dosfsfat.c
字号:
assert ( copyNum < pVolDesc->nFats); assert ( (cluster >= DOS_MIN_CLUST) && (cluster < pFatDesc->nFatEnts) ); assert ( copyNum != pVolDesc->pFatDesc->activeCopyNum || ( (value == pFatDesc->dos_fat_avail) || ((value >= DOS_MIN_CLUST) && (value < pFatDesc->nFatEnts)) || (value == pFatDesc->dos_fat_eof) ) ); cookie = pFd->fatHdl.cbioCookie; /* Offset of the entry in the FAT in bytes */ fatOff = cluster + (cluster >> 1); /* index = cluster * 1.5 */ /* Number of sector containing the entry */ secNum = pFatDesc->fatStartSec + copyNum * pVolDesc->secPerFat + (fatOff >> pVolDesc->secSizeShift); /* Mirror last modified FAT sector if entry is situated in other sector */ if (pFd->pFileHdl->fatSector != secNum && copyNum == pVolDesc->pFatDesc->activeCopyNum) { fat16MirrorSect (pFd); pFd->pFileHdl->fatSector = secNum; } /* Offset of the entry in the sector */ secOff = fatOff & (pVolDesc->bytesPerSec - 1); /* Number of bytes to write */ nBytes = pVolDesc->bytesPerSec - secOff; if (nBytes > 2) nBytes = 2; /* Read previous entry value */ if (cbioBytesRW (pCbio, secNum, secOff,(addr_t) valBuf, nBytes, CBIO_READ, &cookie) != OK) return ERROR; /* read error */ if (nBytes == 1) if (cbioBytesRW (pCbio, secNum + 1, 0,(addr_t) (&valBuf[1]), 1, CBIO_READ, &pFd->fatHdl.cbioCookie) != OK) return ERROR; /* read error */ if (cluster & 0x1) /* if cluster number is ODD */ { valBuf [0] &= 0x0f; /* clear high order 4 bits */ valBuf [0] |= (value << 4); /* put in low bits of value */ valBuf [1] = (value >> 4); /* next byte is high bits */ } else /* if cluster number is EVEN */ { valBuf [0] = value; /* this byte gets low bits */ valBuf [1] &= 0xf0; /* clear low bits next byte */ valBuf [1] |= (value >> 8) & 0x0f; /* put in high bits */ } /* Write entry to disk */ if (cbioBytesRW (pCbio, secNum, secOff,(addr_t)valBuf, nBytes, CBIO_WRITE, &cookie) != OK) return ERROR; if (nBytes == 1) if (cbioBytesRW (pCbio, secNum + 1, 0, (addr_t)(&valBuf [1]), 1, CBIO_WRITE, &pFd->fatHdl.cbioCookie) != OK) return ERROR; return OK; } /* fat12EntWrite *//******************************************************************************** * fat16EntRead - read FAT entry from disk* * This routine reads the file allocation table (FAT) entry from a dosFs* volume.** This routine only reads from the first copy of the FAT on disk, even if* other copies exist.* * RETURNS: Contents of the entry, or FAT_CBIO_ERR if error accessing disk.*/LOCAL uint32_t fat16EntRead ( FAST DOS_FILE_DESC_ID pFd, /* pointer to file descriptor */ FAST uint32_t copyNum,/* fat copy number */ FAST uint32_t entry /* entry number */ ) { FAST DOS_VOLUME_DESC_ID pVolDesc = pFd->pVolDesc; /* pointer to volume descriptor */ FAST CBIO_DEV_ID pCbio = pVolDesc->pCbio; /* pointer to CBIO device */ FAST MS_FAT_DESC_ID pFatDesc = (void *) pVolDesc->pFatDesc; /* pointer to FAT descriptor */ FAST block_t secNum; /* sector number to read/write */ FAST off_t secOff; /* offset in the sector */ uint8_t valBuf [2]; /* buffer for value in the entry */ assert ( copyNum < pVolDesc->nFats); assert ( (entry >= DOS_MIN_CLUST) && (entry < pFatDesc->nFatEnts) ); /* Offset of the entry in the FAT in bytes */ entry <<= 1; /* Number of sector containing the entry */ secNum = pFatDesc->fatStartSec + copyNum * pVolDesc->secPerFat + (entry >> pVolDesc->secSizeShift); /* Offset of the entry in the sector */ secOff = entry & (pVolDesc->bytesPerSec - 1); /* Read entry from disk */ if (cbioBytesRW (pCbio, secNum, secOff, (addr_t)valBuf, 2, CBIO_READ, &pFd->fatHdl.cbioCookie) != OK) { pFd->fatHdl.errCode = FAT_CBIO_ERR; return FAT_CBIO_ERR; /* read error */ } return (valBuf [0] | (valBuf [1] << 8)); /* copy word, swapping bytes */ } /* fat16EntRead *//******************************************************************************** * fat16EntWrite - write FAT entry to disk* * This routine writes the file allocation table (FAT) entry to a dosFs* volume.** This routine only writes to the first copy of the FAT on disk, even if* other copies exist.* * RETURNS: OK, or ERROR if error accessing disk.*/LOCAL STATUS fat16EntWrite ( FAST DOS_FILE_DESC_ID pFd, /* pointer to file descriptor */ FAST uint32_t copyNum,/* fat copy number */ FAST uint32_t entry, /* entry number */ FAST uint32_t value /* value to write */ ) { FAST DOS_VOLUME_DESC_ID pVolDesc = pFd->pVolDesc; /* pointer to volume descriptor */ FAST CBIO_DEV_ID pCbio = pVolDesc->pCbio; /* pointer to CBIO device */ FAST MS_FAT_DESC_ID pFatDesc = (void *) pVolDesc->pFatDesc; /* pointer to FAT descriptor */ FAST block_t secNum; /* sector number to read/write */ FAST off_t secOff; /* offset in the sector */ uint8_t valBuf [2]; /* buffer for value in the entry */ assert ( copyNum < pVolDesc->nFats); assert ( (entry >= DOS_MIN_CLUST) && (entry < pFatDesc->nFatEnts) ); assert ( copyNum != pVolDesc->pFatDesc->activeCopyNum || ( (value == pFatDesc->dos_fat_avail) || ((value >= DOS_MIN_CLUST) && (value < pFatDesc->nFatEnts)) || (value == pFatDesc->dos_fat_eof) ) ); /* Offset of the entry in the FAT in bytes */ entry <<= 1; /* Number of sector containing the entry */ secNum = pFatDesc->fatStartSec + copyNum * pVolDesc->secPerFat + (entry >> pVolDesc->secSizeShift); /* Mirror last modified FAT sector if entry is situated in other sector */ if (pFd->pFileHdl->fatSector != secNum && copyNum == pVolDesc->pFatDesc->activeCopyNum) { fat16MirrorSect (pFd); pFd->pFileHdl->fatSector = secNum; } /* Offset of the entry in the sector */ secOff = entry & (pVolDesc->bytesPerSec - 1); valBuf [0] = value & 0xff; /* this byte gets low bits */ valBuf [1] = (value >> 8) & 0xff; /* next byte gets high bits */ /* Write entry to disk */ return cbioBytesRW (pCbio, secNum, secOff, (addr_t)valBuf, 2, CBIO_WRITE, &pFd->fatHdl.cbioCookie); } /* fat16EntWrite *//******************************************************************************** * fat32EntRead - read FAT entry from disk* * This routine reads the file allocation table (FAT) entry from a dosFs* volume.** This routine only reads from the first copy of the FAT on disk, even if* other copies exist.* * RETURNS: Contents of the entry, or FAT_CBIO_ERR if error accessing disk.*/LOCAL uint32_t fat32EntRead ( FAST DOS_FILE_DESC_ID pFd, /* pointer to file descriptor */ FAST uint32_t copyNum,/* fat copy number */ FAST uint32_t entry /* entry number */ ) { FAST DOS_VOLUME_DESC_ID pVolDesc = pFd->pVolDesc; /* pointer to volume descriptor */ FAST CBIO_DEV_ID pCbio = pVolDesc->pCbio; /* pointer to CBIO device */ FAST MS_FAT_DESC_ID pFatDesc = (void *) pVolDesc->pFatDesc; /* pointer to FAT descriptor */ FAST block_t secNum; /* sector number to read/write */ FAST off_t secOff; /* offset in the sector */ uint8_t valBuf [4]; uint8_t highByteMask = 0x0f; /* do not mask high bits when non active copy is being written */ if (copyNum != pVolDesc->pFatDesc->activeCopyNum) highByteMask = 0xff; /* buffer for value in the entry */ assert ( copyNum < pVolDesc->nFats); assert ( (entry >= DOS_MIN_CLUST) && (entry < pFatDesc->nFatEnts) ); /* Offset of the entry in the FAT in bytes */ entry <<= 2; /* Number of sector containing the entry */ secNum = pFatDesc->fatStartSec + copyNum * pVolDesc->secPerFat + (entry >> pVolDesc->secSizeShift); /* Offset of the entry in the sector */ secOff = entry & (pVolDesc->bytesPerSec - 1); /* Read entry from disk */ if (cbioBytesRW (pCbio, secNum, secOff, (addr_t)valBuf, 4, CBIO_READ, &pFd->fatHdl.cbioCookie) != OK) { pFd->fatHdl.errCode = FAT_CBIO_ERR; return FAT_CBIO_ERR; /* read error */ } return (valBuf [0] | (valBuf [1] << 8) | (valBuf [2] << 16) | ((valBuf [3] & highByteMask) << 24));/* mask highest 4 bits */ } /* fat32EntRead *//******************************************************************************** * fat32EntWrite - write FAT entry to disk* * This routine writes the file allocation table (FAT) entry to a dosFs* volume.** This routine only writes to the first copy of the FAT on disk, even if* other copies exist.* * RETURNS: OK, or ERROR if error accessing disk.*/LOCAL STATUS fat32EntWrite ( FAST DOS_FILE_DESC_ID pFd, /* pointer to file descriptor */ FAST uint32_t copyNum,/* fat copy number */ FAST uint32_t entry, /* entry number */ FAST uint32_t value /* value to write */ ) { FAST DOS_VOLUME_DESC_ID pVolDesc = pFd->pVolDesc; /* pointer to volume descriptor */ FAST CBIO_DEV_ID pCbio = pVolDesc->pCbio; /* pointer to CBIO device */ FAST MS_FAT_DESC_ID pFatDesc = (void *) pVolDesc->pFatDesc; /* pointer to FAT descriptor */ FAST block_t secNum; /* sector number to read/write */ FAST off_t secOff; /* offset in the sector */ uint8_t valBuf [4]; /* buffer for value in the entry */ uint8_t highByteMask = 0x0f; /* do not mask high bits when non active copy is being written */ if (copyNum != pVolDesc->pFatDesc->activeCopyNum) highByteMask = 0xff; assert ( copyNum < pVolDesc->nFats); assert ( (entry >= DOS_MIN_CLUST) && (entry < pFatDesc->nFatEnts) ); assert ( highByteMask == 0xff || ( (value == pFatDesc->dos_fat_avail) || ((value >= DOS_MIN_CLUST) && (value < pFatDesc->nFatEnts)) || (value == pFatDesc->dos_fat_eof) ) ); /* Offset of the entry in the FAT in bytes */ entry <<= 2; /* Number of sector containing the entry */ secNum = pFatDesc->fatStartSec + copyNum * pVolDesc->secPerFat + (entry >> pVolDesc->secSizeShift); /* Mirror last modified FAT sector if entry is situated in other sector */ if (pFd->pFileHdl->fatSector != secNum && highByteMask != 0xff ) { fat16MirrorSect (pFd); pFd->pFileHdl->fatSector = secNum; } /* Offset of the entry in the sector */ secOff = entry & (pVolDesc->bytesPerSec - 1); valBuf [0] = value & 0xff; /* */ valBuf [1] = (value >> 8) & 0xff; /* */ valBuf [2] = (value >> 16) & 0xff; /* */ valBuf [3] = (value >> 24) & highByteMask; /* */ /* Write entry to disk */ return cbioBytesRW (pCbio, secNum, secOff, (addr_t)valBuf, 4, CBIO_WRITE, &pFd->fatHdl.cbioCookie); } /* fat32EntWrite *//********************************************************************************* fat16ContigGet - get next section of contiguous clusters in file chain* * This routine reads FAT entries starting from the passed cluster number, and * returns number of contiguous clusters in the file chain starting from the * passed one up to number of clusters requested.** If starting cluster number is out of legal cluster number range, a 0 is * returned, except of the following 2 cases:** 1) If start cluster number is 0 .** 2) If start cluster number is end of file .** This routine checks the File Allocation Table (FAT) to determine the* length, in clusters, of a contiguous section of a file. The starting* cluster to check is passed as an input parameter. The number of* contiguous clusters beginning with that cluster (including the starting* cluster itself) is returned. The minimum returned value is 1.** RETURNS: Number of contiguous clusters in chain starting from the passed one,* or 0 if starting cluster number is illegal or disk access error.*/LOCAL STATUS fat16ContigGet ( FAST DOS_FILE_DESC_ID pFd, /* pointer to file descriptor */ FAST uint32_t numClusts /* num. of clusters to follow */ ) { FAST DOS_FILE_HDL_ID pFileHdl = pFd->pFileHdl; /* pointer to file handle */ FAST DOS_FAT_HDL_ID pFatHdl = &(pFd->fatHdl); /* pointer to FAT handle */ FAST DOS_VOLUME_DESC_ID pVolDesc = pFd->pVolDesc; /* pointer to volume descriptor */ FAST MS_FAT_DESC_ID pFatDesc = (void *) pVolDesc->pFatDesc; /* pointer to FAT handler descriptor */ FAST uint32_t startClust; /* starting cluster number */ FAST uint32_t nextClust; /* next cluster number */ FAST uint32_t cluster; /* cluster number */ FAST uint32_t maxClust; /* maximum cluster number */ startClust = nextClust = pFatHdl->nextClust; cluster = pFatHdl->lastClust; if ((startClust < DOS_MIN_CLUST) || (startClust >= pFatDesc->nFatEnts)) { if ((startClust == 0) && (cluster == 0)) /* file just open */ startClust = pFileHdl->startClust; if (startClust > pFatDesc->dos_fat_bad) /* end of file chain */ { startClust = ENTRY_READ (pFd, pFatDesc->dosFatDesc.activeCopyNum, cluster); } if ((startClust < DOS_MIN_CLUST) || (startClust >= pFatDesc->nFatEnts)) { assert ((startClust == 0) || (startClust > pFatDesc->dos_fat_bad)); pFatHdl->nextClust = startClust; return ERROR; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -