📄 doschklib.c
字号:
else { fd.pFileHdl->startClust = dirStartClust; fd.pFileHdl->attrib = DOS_ATTR_DIRECTORY; } /* rewind directory */ pDir->dd_cookie = 0; while( pFd->pVolDesc->pDirDesc->readDir( &fd, pDir, pFd ) == OK ) { switch( keyType ) { case FIND_BY_CLUST: if( pFd->pFileHdl->startClust == startClust ) return OK; break; case FIND_BY_NAME: if( strcmp( (char *)key, pDir->dd_dirent.d_name ) == 0 ) return OK; break; default: assert( FALSE ); } } assert( FALSE ); return ERROR; } /* dosChkEntryFind() */ /********************************************************************************* dosChkBuildPath - reconstruct file path.** This routine reconstructs full path of the file is described* by <pFd> and puts it to <pChkDesc->chkPath> buffer.** RETURNS: OK or ERROR if disk access error.*/LOCAL STATUS dosChkBuildPath ( DOS_FILE_DESC_ID pSrcFd ) { DIR * pDir = &pSrcFd->pVolDesc->pChkDesc->chkDir; DOS_FILE_DESC fd; DOS_FILE_HDL flHdl; u_char * pPath; u_char * chkPath = pSrcFd->pVolDesc->pChkDesc->chkPath; u_short nameLen; pPath = chkPath + sizeof( pSrcFd->pVolDesc->pChkDesc->chkPath ) - 1; bzero( (char *)chkPath, sizeof( pSrcFd->pVolDesc->pChkDesc->chkPath ) ); if( (pSrcFd->pFileHdl->attrib & DOS_ATTR_DIRECTORY) != 0 ) { pPath --; *pPath = SLASH; } fd = *pSrcFd; flHdl = *pSrcFd->pFileHdl; fd.pFileHdl = &flHdl; FOREVER { if( dosChkEntryFind( &fd, flHdl.dirHdl.parDirStartCluster, (void *)flHdl.startClust, FIND_BY_CLUST ) == ERROR ) { return ERROR; } /* insert name to path */ nameLen = strlen( pDir->dd_dirent.d_name ); if( nameLen > pPath - chkPath ) { do { pPath = memchr( pPath + 1, SLASH, strlen( (char *)pPath ) ); } while( pPath - chkPath < 4 ); pPath -= 4; *pPath = DOT, *(pPath + 1) = DOT, *(pPath + 2) = DOT; *(pPath + 3) = SLASH; break; } pPath -= strlen( pDir->dd_dirent.d_name ); bcopy( pDir->dd_dirent.d_name, (char *)pPath, strlen( pDir->dd_dirent.d_name ) ); if( IS_ROOT( &fd ) ) break; pPath --; *pPath = SLASH; /* find cluster containing parent directory */ if( flHdl.dirHdl.parDirStartCluster == 0 ) { /* current parent directory is root */ flHdl.dirHdl.parDirStartCluster = (UINT32)NONE; } else if( dosChkChainStartGet( &fd, flHdl.dirHdl.parDirStartCluster, (uint32_t *)&flHdl.dirHdl.parDirStartCluster, (uint32_t *)&flHdl.startClust ) == ERROR ) { assert( FALSE ); } } memmove( chkPath, pPath, strlen( (char *)pPath ) + 1 ); return OK; } /* dosChkBuildPath() */ /********************************************************************************* dosChkMsg - print message.**/LOCAL void dosChkMsg ( DOS_FILE_DESC_ID pFd, char * msgFormat, MSG_PATH msgPath, /* whether to build file path or use current path */ int arg1, int arg2, int arg3, int arg4, char * extraMsg ) { char * path = NULL; if( msgPath == CURRENT_PATH ) path = pFd->pVolDesc->pChkDesc->chkCurPath; else if( dosChkBuildPath( pFd ) == OK ) path = (char *)pFd->pVolDesc->pChkDesc->chkPath; else return; printf( "\r" ); printf( msgFormat, path, arg1, arg2, arg3, arg4 ); if( extraMsg != NULL && *extraMsg != EOS ) printf("%s", extraMsg ); printf( "\n" ); return; } /* dosChkMsg() */ /********************************************************************************* dosChkEntryDel - delete entry and unmark chain , if required.** This routine deletes entry is described by pFd, unmarks* associated FAT chain, if <unmark> is TRUE and outputs* message in accordance with <mess> format string.** RETURNS: CHK_OK, or CHK_ERROR if disk I/O error.*/LOCAL CHK_STATUS dosChkEntryDel ( DOS_FILE_DESC_ID pFd, BOOL unmark, u_char * mess, MSG_PATH msgPath, int msgArg1, int msgArg2, int msgArg3, int msgArg4 ) { /* put message */ dosChkMsg( pFd, (char *)mess, msgPath, msgArg1, msgArg2, msgArg3, msgArg4, CHK_DEL_MSG ); pFd->pVolDesc->pChkDesc->nErrors ++; if( pFd->pVolDesc->chkLevel > CHK_ONLY ) { if( pFd->pVolDesc->pDirDesc->updateEntry( pFd, DH_DELETE, 0 ) == ERROR ) { return CHK_ERROR; } } /* unmark chain */ if( unmark ) dosChkChainUnmark( pFd ); /* mark file descriptor as deleted */ pFd->pFileHdl->deleted = 1; return CHK_OK; } /* dosChkEntryDel() */ /********************************************************************************* dosChkStartCrossProc - process entries are cross linked on start cluster.** This routine deletes entry, that was created earlier.** RETURNS: CHK_OK or CHK_RESTART, if directory has been deleted.*/LOCAL CHK_STATUS dosChkStartCrossProc ( DOS_FILE_DESC_ID pFd ) { DOS_FILE_DESC localFd; DOS_FILE_HDL localFlHdl; UINT32 entryClust; /* entry location cluster */ UINT32 startClust; /* file/dir start cluster */ struct stat fStat; /* used to get creation time */ time_t creatTime; /* creation time of one of the files */ BOOL unmark = TRUE; /* whether to unmark chain */ MSG_PATH msgPath = GET_PATH; /* whether to build file path */ /* or to use current path */ assert( pFd != NULL && pFd->pVolDesc->magic == DOS_FS_MAGIC ); bzero( (char *)&localFd, sizeof( localFd ) ); bzero( (char *)&localFlHdl, sizeof( localFlHdl ) ); localFd.busy = 1; localFd.pFileHdl = &localFlHdl; localFd.pVolDesc = pFd->pVolDesc; /* find peer entry */ dosChkChainStartGet( pFd, pFd->pFileHdl->startClust, (uint32_t *)&entryClust, (uint32_t *)&startClust ); if( dosChkEntryFind( &localFd, entryClust, (void *)startClust, FIND_BY_CLUST ) == ERROR ) { return CHK_ERROR; } assert( pFd->pFileHdl->startClust == localFlHdl.startClust ); /* delete older entry, but never delete ROOT */ pFd->pVolDesc->pDirDesc->dateGet( pFd, &fStat ); creatTime = fStat.st_ctime; pFd->pVolDesc->pDirDesc->dateGet( &localFd, &fStat ); /* let <localFd> describes file to be deleted */ if( IS_ROOT( &localFd ) || creatTime >= fStat.st_ctime ) { dosChkMsg( &localFd, CHK_CROSS_L_START_MSG, GET_PATH, 0,0,0,0, CHK_REMAIN_MSG ); localFd = *pFd; localFlHdl = *pFd->pFileHdl; localFd.pFileHdl = &localFlHdl; /* the chain already checked. Do not unmark and recheck */ unmark = FALSE; msgPath = CURRENT_PATH; pFd->pFileHdl->deleted = 1; } else { dosChkMsg( pFd, CHK_CROSS_L_START_MSG, CURRENT_PATH, 0,0,0,0, CHK_REMAIN_MSG ); } /* delete the file */ return dosChkEntryDel( &localFd, unmark, (u_char *)CHK_CROSS_L_START_MSG, msgPath, 0,0,0,0 ); } /* dosChkStartCrossProc() */ /********************************************************************************* dosChkDirStruct - check internal directory structure.** This routine checks, that directory has valid . and ..* entries at top of it.** RETURNS: CHK_OK, CHK_RESTART, if the directory has been deleted or* CHK_ERROR if another error occurred.*/LOCAL CHK_STATUS dosChkDirStruct ( DOS_FILE_DESC_ID pDirFd, DOS_FILE_DESC_ID pLocalFd ) { u_char dots; DIR * pDir = &pDirFd->pVolDesc->pChkDesc->chkDir; /* root directory does not contain . and .. entries */ if( IS_ROOT( pDirFd ) ) return CHK_OK; for( dots = 1; dots <= 2; dots ++ ) { if( pDirFd->pVolDesc->pDirDesc->readDir( pDirFd, pDir, pLocalFd ) != OK ) { break; } if( *(pDir->dd_dirent.d_name) != '.' || *(pDir->dd_dirent.d_name + dots - 1) != '.' || *(pDir->dd_dirent.d_name + dots) != EOS ) { break; } if( dots == 1 && /* . */ pDirFd->pFileHdl->startClust != pLocalFd->pFileHdl->startClust ) { break; } else if( dots == 2 && /* .. */ pDirFd->pFileHdl->startClust != pLocalFd->pFileHdl->dirHdl.parDirStartCluster ) { break; } } if( dots <= 2 ) { return dosChkEntryDel( pDirFd, TRUE, (u_char *)CHK_BAD_DIR_MSG, CURRENT_PATH, 0,0,0,0 ); } return CHK_OK; } /* dosChkDirStruct() */ /********************************************************************************* dosFsChkTree - DOS FS sanity check utility.** RETURNS: OK or ERROR if device is not a valid DOS device,* corrections can not be written to disk* or disk read error.** ERRNO:* S_dosFsLib_INVALID_PARAMETER*/CHK_STATUS dosFsChkTree ( DOS_FILE_DESC_ID pFd ) { CHK_DSK_DESC_ID pChkDesc = pFd->pVolDesc->pChkDesc; DOS_FILE_DESC localFd; DOS_FILE_HDL localFlHdl; UINT32 work1; u_long ddCookie; char * pCurPathPos = NULL; assert( pFd != NULL && pFd->pVolDesc->magic == DOS_FS_MAGIC ); bzero( (char *)&localFd, sizeof( localFd ) ); bzero( (char *)&localFlHdl, sizeof( localFlHdl ) ); localFd.busy = 1; localFd.pFileHdl = &localFlHdl; localFd.pVolDesc = pFd->pVolDesc; /* separately check ROOT directory chain */ if( IS_ROOT( pFd ) ) { if( pFd->pFileHdl->startClust != 0 && dosChkChainVerify( pFd ) != CHK_OK ) { return CHK_ERROR; } } pCurPathPos = pChkDesc->chkCurPath + strlen( pChkDesc->chkCurPath ); *pCurPathPos = SLASH; pCurPathPos ++; /* rewind directory */ pChkDesc->chkDir.dd_cookie = 0; /* check . and .. */ work1 = dosChkDirStruct( pFd, &localFd ); if( work1 != CHK_OK ) { pChkDesc->nErrors ++; return work1; } /* pass directory */ for( ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -