📄 doschklib.c
字号:
DOS_FILE_DESC_ID pFd, /* pointer to file descriptor */ uint32_t startClust, /* start cluster of chain */ uint32_t entNum, /* valid entry number */ uint32_t entCont /* entry contents */ ) { DOS_VOLUME_DESC_ID pVolDesc = pFd->pVolDesc; DOS_FAT_DESC_ID pFatDesc = pVolDesc->pFatDesc; uint32_t fileSize; uint32_t clustSize; uint32_t entValue; /* sense of entry contents */ uint32_t nextEntCont; /* next entry content, if current entry contents valid cluster number */ uint32_t prevEnt; /* */ uint32_t numClusts; /* size of chain in clusters */ uint32_t eofClust; char * errMsg; errMsg = NULL; eofClust = 0; numClusts = 1; /* start cluster */ if ( (pFd->pFileHdl->attrib & DOS_ATTR_DIRECTORY) == 0 ) { clustSize = pVolDesc->secPerClust * pVolDesc->bytesPerSec; fileSize = (pFd->pFileHdl->size + clustSize - 1) / clustSize; } else /* this is a directory */ fileSize = 0xffffffff; nextEntCont = entCont; entCont = entNum; entNum = startClust; entValue = DOS_FAT_ALLOC; do { /* Proceed with next entry */ prevEnt = entNum; /* previous entry */ entNum = entCont; /* entry to check */ entCont = nextEntCont; /* contents of the entry to check */ if (fileSize == numClusts) { /* file size is reached */ errMsg = CHK_LONG_CHAIN_MSG; eofClust = prevEnt; break; } /* Check for cross link and mark entry */ if (dosChkEntryMarkSet (pFd, entNum, startClust) != OK) { /* cross-link */ if (dosChkEntryMark (pFd, MARK_GET, entNum, 0) == LOST_CHAIN_MARK) dosChkEntryMark (pFd, MARK_SET, entNum, startClust); else { errMsg = CHK_CROSS_LINK_MSG; eofClust = prevEnt; } break; } numClusts += 1; /* increase number of clusters in chain */ } /* while entry content is next entry number */ while (( entValue = pFatDesc->clustValueGet ( pFd, pFatDesc->activeCopyNum, entCont, &nextEntCont) ) == DOS_FAT_ALLOC); switch (entValue) { case DOS_FAT_BAD: errMsg = CHK_BAD_CHAIN_MSG; /* ??? */ eofClust = prevEnt; numClusts -= 1; break; case DOS_FAT_AVAIL: case DOS_FAT_INVAL: case DOS_FAT_RESERV: errMsg = CHK_BAD_CHAIN_MSG; /* ??? */ eofClust = entNum; break; case DOS_FAT_ALLOC: case DOS_FAT_EOF: default: break; } if (errMsg != NULL) { dosChkMsg (pFd, errMsg, CURRENT_PATH, 0, 0, 0, 0, NULL); pVolDesc->pChkDesc->nErrors++; } if ( (eofClust != 0) && (pVolDesc->chkLevel >= DOS_CHK_REPAIR) ) { pFatDesc->clustValueSet (pFd, pFatDesc->activeCopyNum, eofClust, DOS_FAT_EOF, 0); } if ( ((pFd->pFileHdl->attrib & DOS_ATTR_DIRECTORY) == 0) && (fileSize > numClusts) ) dosChkEntryDel (pFd, TRUE, (u_char *)CHK_SHORT_CHAIN_MSG, CURRENT_PATH, 0, 0, 0, 0); return numClusts; } /* dosChkChainMark *//********************************************************************************* dosChkChainVerify - verify a cluster chain** RETURNS: special status representing the state of this chain*/LOCAL CHK_STATUS dosChkChainVerify ( DOS_FILE_DESC_ID pFd /* pointer to file descriptor */ ) { DOS_VOLUME_DESC_ID pVolDesc = pFd->pVolDesc; DOS_FAT_DESC_ID pFatDesc = pVolDesc->pFatDesc; DOS_FILE_HDL_ID pFileHdl = pFd->pFileHdl; uint32_t parDirStartClust; uint32_t startClust; uint32_t nextEnt; uint32_t nextEntCont = 0; uint32_t entValue; /* sense of entry contents */ parDirStartClust = pFd->pFileHdl->dirHdl.parDirStartCluster; startClust = pFileHdl->startClust; /* Check start cluster pointer */ entValue = pFatDesc->clustValueGet (pFd, pFatDesc->activeCopyNum, startClust, &nextEnt); if (entValue != DOS_FAT_ALLOC) { if ( (entValue == DOS_FAT_AVAIL) && /* start cluster is 0 */ ((pFileHdl->attrib & DOS_ATTR_DIRECTORY) == 0) && /* a file */ (pFileHdl->size == 0) ) /* size is 0 */ return CHK_OK; return dosChkEntryDel (pFd, FALSE, (u_char *)CHK_BAD_START_MSG, CURRENT_PATH, 0, 0, 0, 0); } /* Check start cluster contents */ entValue = pFatDesc->clustValueGet (pFd, pFatDesc->activeCopyNum, nextEnt, &nextEntCont); if ( (entValue & (DOS_FAT_ALLOC | DOS_FAT_EOF)) == 0 ) { if (entValue == DOS_FAT_BAD) return dosChkEntryDel (pFd, FALSE, (u_char *)CHK_BAD_START_MSG, CURRENT_PATH, 0, 0, 0, 0); /* ??? */ else { /* ??? */ dosChkMsg (pFd, CHK_BAD_START_MSG, CURRENT_PATH, 0, 0, 0, 0, NULL); pVolDesc->pChkDesc->nErrors++; if (pVolDesc->chkLevel >= DOS_CHK_REPAIR) { pFatDesc->clustValueSet (pFd, pFatDesc->activeCopyNum, startClust, DOS_FAT_EOF, 0); } } } if (entValue != DOS_FAT_ALLOC) { /* File consists of 1 start cluster only */ if ( ((pFileHdl->attrib & DOS_ATTR_DIRECTORY) == 0) && (pFileHdl->size > pVolDesc->secPerClust * pVolDesc->bytesPerSec) ) return dosChkEntryDel (pFd, FALSE, (u_char *)CHK_SHORT_CHAIN_MSG, CURRENT_PATH, 0, 0, 0, 0); } /* Mark start cluster as file's chain start */ if (dosChkEntryMarkSet (pFd, startClust, parDirStartClust | START_CLUST_MASK) != OK) { if ( (dosChkEntryMark (pFd, MARK_GET, startClust, 0) & START_CLUST_MASK) == 0) return dosChkEntryDel (pFd, FALSE, (u_char *)CHK_CROSS_LINK_MSG, CURRENT_PATH, 0, 0, 0, 0); /* ??? */ dosChkStartCrossProc (pFd); if (pFileHdl->deleted) return CHK_OK; dosChkEntryMark (pFd, MARK_SET, startClust, parDirStartClust | START_CLUST_MASK); } if (entValue == DOS_FAT_ALLOC) if (dosChkChainMark (pFd, startClust, nextEnt, nextEntCont) == (uint32_t)CHK_ERROR) return CHK_ERROR; return CHK_OK; } /* dosChkChainVerify *//********************************************************************************* dosChkChainStartGet - find where is beginning of a chain** RETURNS: OK*/LOCAL STATUS dosChkChainStartGet ( DOS_FILE_DESC_ID pFd, /* pointer to file descriptor */ uint32_t entNum, /* FAT entry number */ uint32_t * pParDirStartClust, /* where to return start cluster number of parent directory */ uint32_t * pStartClust /* where to return start cluster number of chain */ ) { uint32_t mark; mark = dosChkEntryMark (pFd, MARK_GET, entNum, 0); if ((mark & START_CLUST_MASK) == 0) /* not start cluster */ { /* go to start cluster */ entNum = mark; mark = dosChkEntryMark (pFd, MARK_GET, entNum, 0); } *pStartClust = entNum; *pParDirStartClust = mark & (~START_CLUST_MASK); return OK; } /* dosChkChainStartGet *//********************************************************************************* dosChkChainUnmark - Un-mark an entire chain** RETURNS:*/LOCAL void dosChkChainUnmark ( DOS_FILE_DESC_ID pFd /* pointer to file descriptor */ ) { DOS_FAT_DESC_ID pFatDesc = pFd->pVolDesc->pFatDesc; uint32_t entNum; uint32_t nextEnt; entNum = pFd->pFileHdl->startClust; while ( (pFatDesc->clustValueGet (pFd, pFatDesc->activeCopyNum, entNum, &nextEnt) == DOS_FAT_ALLOC) && (dosChkEntryMark (pFd, MARK_GET, entNum, 0) != 0) ) { dosChkEntryMark (pFd, MARK_SET, entNum, 0); entNum = nextEnt; } } /* dosChkChainUnmark *//********************************************************************************* dosChkLostFind - find lost chains in the FAT** RETURNS:OK or ERROR if any of the chains contained an illegal value*/LOCAL STATUS dosChkLostFind ( DOS_FILE_DESC_ID pFd /* pointer to file descriptor */ ) { DOS_VOLUME_DESC_ID pVolDesc = pFd->pVolDesc; DOS_FAT_DESC_ID pFatDesc = pVolDesc->pFatDesc; CHK_DSK_DESC_ID pChkDesc = pVolDesc->pChkDesc; uint32_t entNum; uint32_t entCont; uint32_t nextEntCont; uint32_t entValue; uint32_t retVal = OK; uint32_t lostClusts = 0; cookie_t bufCookie = (cookie_t) NULL, fatCookie = (cookie_t) NULL; for (entNum = DOS_MIN_CLUST; entNum < pFd->pVolDesc->nFatEnts; entNum++) { if (dosChkEntryMark (pFd, IS_BUSY, entNum, 0) == 0) { /* Get content of the entry */ bufCookie = pFd->fatHdl.cbioCookie; pFd->fatHdl.cbioCookie = fatCookie; pFatDesc->clustValueGet (pFd, pFatDesc->activeCopyNum, entNum, &entCont); /* Value the entry content */ entValue = pFatDesc->clustValueGet (pFd, pFatDesc->activeCopyNum, entCont, &nextEntCont); fatCookie = pFd->fatHdl.cbioCookie; pFd->fatHdl.cbioCookie = bufCookie; switch (entValue) { case DOS_FAT_ALLOC: case DOS_FAT_EOF: case DOS_FAT_INVAL: case DOS_FAT_RESERV: pChkDesc->chkNLostChains++;/* Count number of lost chains */ pChkDesc->nErrors++; /* Count number of errors */ retVal = ERROR; dosChkEntryMark (pFd, MARK_SET, entNum, LOST_CHAIN_MARK); if (entValue == DOS_FAT_ALLOC) lostClusts += dosChkChainMark (pFd, entNum, entCont, nextEntCont); else lostClusts += 1; break; case DOS_FAT_BAD: pChkDesc->chkNBadClusts++; break; case DOS_FAT_AVAIL: pChkDesc->chkNFreeClusts++; break; } /* switch */ } } /* for */ pChkDesc->chkTotalBytesInLostChains = lostClusts * pVolDesc->secPerClust * pVolDesc->bytesPerSec;; return retVal; } /* dosChkLostFind *//********************************************************************************* dosChkLostFree - free all lost chains in the FAT** RETURNS: OK.*/LOCAL STATUS dosChkLostFree ( DOS_FILE_DESC_ID pFd /* pointer to file descriptor */ ) { DOS_VOLUME_DESC_ID pVolDesc = pFd->pVolDesc; DOS_FAT_DESC_ID pFatDesc = pVolDesc->pFatDesc; uint32_t entNum; uint32_t nextEnt; uint32_t nextEntCont; uint32_t entVal; uint32_t i; if (pVolDesc->chkLevel < DOS_CHK_REPAIR) return OK; for (i = DOS_MIN_CLUST; i < pFd->pVolDesc->nFatEnts; i++) { entNum = i; if (dosChkEntryMark (pFd, MARK_GET, entNum, 0) == LOST_CHAIN_MARK) { /* Follow lost chain and free clusters */ pFatDesc->clustValueGet (pFd, pFatDesc->activeCopyNum, entNum, &nextEnt); /* While entry content is next cluster number */ while ( (entVal = pFatDesc->clustValueGet ( pFd, pFatDesc->activeCopyNum, nextEnt, &nextEntCont)) == DOS_FAT_ALLOC ) { pFatDesc->clustValueSet (pFd, pFatDesc->activeCopyNum, entNum, DOS_FAT_AVAIL, 0); entNum = nextEnt; nextEnt = nextEntCont; } /* For end of file */ pFatDesc->clustValueSet (pFd, pFatDesc->activeCopyNum, entNum, DOS_FAT_AVAIL, 0); } } /* for */ return OK; } /* dosChkLostFree *//* End of File */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -