📄 dosfslib.c
字号:
DOS_HDLR_DESC dosFatHdlrsList[ DOS_MAX_HDLRS ] = {{0}};DOS_HDLR_DESC dosDirHdlrsList[ DOS_MAX_HDLRS ] = {{0}};STATUS (*dosFsChkRtn)( DOS_FILE_DESC_ID pFd ) = NULL; /* check disk routine */STATUS (*dosFsVolFormatRtn)( void * dev, int opt, FUNCPTR pPromptFunc ) = NULL; /* volume format routine *//* locals */STATUS fat16VolMount( DOS_VOLUME_DESC_ID pVolDesc );LOCAL STATUS dosFsRead( FAST DOS_FILE_DESC_ID pFd, char * pBuf, int maxBytes );LOCAL STATUS dosFsIoctl ( FAST DOS_FILE_DESC_ID pFd, int function, int arg );LOCAL DOS_FILE_DESC_ID dosFsOpen ( FAST DOS_VOLUME_DESC * pVolDesc, char * path, int flags, int mode );LOCAL STATUS dosFsDelete (DOS_VOLUME_DESC_ID pVolDesc, char * path);LOCAL STATUS dosFsClose ( DOS_FILE_DESC_ID pFd );LOCAL DOS_VOLUME_DESC_ID dosFsVolDescGet( void * devName, u_char ** ppTail );#ifdef ERR_SET_SELF/******************************************************************************** errnoSetOut - put error message** This routine is called instead of errnoSet during debugging.*/static VOID errnoSetOut(char * file, int line, const char * str, int errCode ) { if( errCode != OK && strcmp( str, "errnoBuf" ) != 0 ) printf( " %s : line %d : %s = %p, task %p\n", file, line, str, (void *)errCode, (void *)taskIdSelf() ); errno = errCode; }#endif /* ERR_SET_SELF *//********************************************************************************* dosFsIsValHuge - check if value is grater, than 4GB (max 32 bit).** RETURNS: TRUE if is grater, else return FALSE.*/LOCAL BOOL dosFsIsValHuge ( fsize_t val ) { return DOS_IS_VAL_HUGE( val ); } /* dosFsIsValHuge() *//********************************************************************************* dosFsVolDescGet - convert device name to volume descriptor ptr.* * This routine validates <devNameOrPVolDesc> as a DOS volume* descriptor ptr. If failed, it supposed to be a path on a* DOS device. This routine uses standard* iosLib function iosDevFind() to get pointer onto* the device descriptor. If device is eligible,* <ppTail> is filled with pointer* to the first character, following* portion the device name.** RETURNS: ptr to DOS_VOLUME_DESC or NULL, if it is not a DOSFS device.** ERRNO:* S_dosFsLib_INVALID_PARAMETER*/LOCAL DOS_VOLUME_DESC_ID dosFsVolDescGet ( void * devNameOrPVolDesc, /* device name or ptr to */ /* volume descriptor */ u_char ** ppTail /* return ptr onto name following device name */ ) { DOS_VOLUME_DESC_ID pVolDesc; /* pointer to volume descriptor */ char * devName = (devNameOrPVolDesc == NULL)? "" : devNameOrPVolDesc; u_char * nameTail; if( ppTail == NULL ) ppTail = &nameTail; *ppTail = NULL; pVolDesc = devNameOrPVolDesc; /* suppose the argument to be a volume descriptor ptr */ if( (pVolDesc != NULL ) && pVolDesc->magic == DOS_FS_MAGIC ) return pVolDesc; /* extract volume descriptor ptr from device name */ pVolDesc = (void *)iosDevFind( devName, (char **)ppTail ); if( (pVolDesc != NULL ) && pVolDesc->magic == DOS_FS_MAGIC ) return pVolDesc; errnoSet( S_dosFsLib_INVALID_PARAMETER ); return NULL; } /* dosFsVolDescGet() *//********************************************************************************* dosFsFSemTake - take file semaphore.** RETURNS: STATUS as result of semTake.*/LOCAL STATUS dosFsFSemTake ( DOS_FILE_DESC_ID pFd, int timeout ) { STATUS retStat; assert( pFd - pFd->pVolDesc->pFdList < pFd->pVolDesc->maxFiles ); assert( pFd->pFileHdl - pFd->pVolDesc->pFhdlList < pFd->pVolDesc->maxFiles ); retStat = semTake( pFd->pVolDesc->pFsemList + (pFd->pFileHdl - pFd->pVolDesc->pFhdlList), timeout); assert( retStat == OK ); return retStat; } /* dosFsFSemTake() */ /********************************************************************************* dosFsFSemGive - release file semaphore.** RETURNS: STATUS as result of semGive.*/LOCAL STATUS dosFsFSemGive ( DOS_FILE_DESC_ID pFd ) { STATUS retStat; assert( pFd - pFd->pVolDesc->pFdList < pFd->pVolDesc->maxFiles ); assert( pFd->pFileHdl - pFd->pVolDesc->pFhdlList < pFd->pVolDesc->maxFiles ); retStat = semGive( pFd->pVolDesc->pFsemList + (pFd->pFileHdl - pFd->pVolDesc->pFhdlList) ); assert( retStat == OK ); return retStat; } /* dosFsFSemGive() */ /********************************************************************************* dosFsVolUnmount - unmount a dosFs volume** This routine is called when I/O operations on a volume are to be* discontinued. This is the preferred action prior to changing a* removable disk.** All buffered data for the volume is written to the device* (if possible, with no error returned if data cannot be written),* any open file descriptors are marked as obsolete,* and the volume is marked as not currently mounted.** When a subsequent open() operation is initiated on the device,* new volume will be mounted automatically.** Once file descriptors have been marked as obsolete, any attempt to* use them for file operations will return an error. (An obsolete file* descriptor may be freed by using close(). The call to close() will* return an error, but the descriptor will in fact be freed).** This routine may also be invoked by calling ioctl() with the* FIOUNMOUNT function code.** This routine must not be called from interrupt level.** RETURNS: OK, or ERROR if the volume was not mounted.** NOMANUAL*/STATUS dosFsVolUnmount ( void * devNameOrPVolDesc /* device name or ptr to */ /* volume descriptor */ ) { DOS_VOLUME_DESC_ID pVolDesc; /* pointer to volume descriptor */ int i; /* get volume descriptor */ pVolDesc = dosFsVolDescGet( devNameOrPVolDesc, NULL ); if( pVolDesc == NULL ) return ERROR; if( ! pVolDesc->mounted ) return ERROR; /* acquire semaphore */ if( semTake( & pVolDesc->devSem, WAIT_FOREVER ) == ERROR ) return ERROR; /* mark all opened file descriptors as obsolete */ for( i = 0; i < pVolDesc->maxFiles; i ++ ) { if( pVolDesc->pFdList[ i ].busy ) pVolDesc->pFdList[ i ].pFileHdl->obsolet = 1; } pVolDesc->nBusyFd = 0; /* flush buffers */ cbioIoctl( pVolDesc->pCbio, CBIO_CACHE_FLUSH, (void*)(-1) ); cbioIoctl( pVolDesc->pCbio, CBIO_CACHE_INVAL, 0 ); pVolDesc->mounted = FALSE; /* volume unmounted */ semGive( & pVolDesc->devSem ); return OK; } /* dosFsVolUnmount() */ /********************************************************************************* dosFsChkDsk - make volume integrity checking.** This library does not makes integrity check process itself, but* instead uses routine provided by dosChkLib. * This routine prepares parameters and invokes checking routine* via preinitialized function pointer. If dosChkLib does not configured* into vxWorks, this routine returns ERROR.** Ownership on device should be taken by an upper level routine.** RETURNS: STATUS as returned by volume checking routine or* ERROR, if such routine does not installed.** ERRNO:* S_dosFsLib_UNSUPPORTED.*/STATUS dosFsChkDsk ( FAST DOS_FILE_DESC_ID pFd, /* file descriptor of root dir */ u_int params /* check level and verbosity */ ) { DOS_VOLUME_DESC_ID pVolDesc = pFd->pVolDesc; STATUS retVal = ERROR; if( dosFsChkRtn == NULL ) { errnoSet( S_dosFsLib_UNSUPPORTED ); ERR_MSG(1,"Check disk utility not installed\n", 0,0,0,0,0,0 ); return ERROR; } /* prepare check disk parameters */ if( (params & 0xff) == 0 ) params |= DOS_CHK_ONLY; /* prevent attempts to write on read only volume */ if( cbioModeGet(pVolDesc->pCbio) == O_RDONLY ) params = (params & ~0xff) | DOS_CHK_ONLY; pVolDesc->chkLevel = min( params & 0xff, DOS_CHK_REPAIR ); pVolDesc->chkVerbLevel = ( (params & 0xff00) == DOS_CHK_VERB_0 )? 0 : params >> 8; /* run disk check */ retVal = dosFsChkRtn( pFd ); /* synchronize cache and cause device to remount */ cbioIoctl( pVolDesc->pCbio, CBIO_CACHE_INVAL, (void *)(-1) ); pVolDesc->chkLevel = 0; pVolDesc->chkVerbLevel = 0; /* reset dcache driver to recount boot block checksum */ if( TRUE == cbioRdyChgdGet (pVolDesc->pCbio) ) { retVal = ERROR; /* volume was changed during check disk */ } else { cbioIoctl( pVolDesc->pCbio, CBIO_RESET, NULL ); } return retVal; } /* dosFsChkDsk() *//********************************************************************************* dosFsBadBootMsg - print error message while boot sector parsing.** RETURNS: N/A.*/LOCAL void dosFsBadBootMsg ( u_int dbgLevel, /* message level */ u_int offset, /* offset of invalid field */ u_int val, /* invalid value */ char * extraMsg, /* extra message */ u_int line /* line number of error detecting code */ ) {#ifdef DEBUG printErr( "%s : %u. Malformed boot sector. Offset %u, value %u. %s\n", __FILE__, __LINE__, offset, val, ( (extraMsg == NULL)? " " : extraMsg ) );#else /* not DEBUG */ ERR_MSG( dbgLevel, "Malformed boot sector. Offset %u, value %u. %s\n", offset, val, ( (extraMsg == NULL)? " " : extraMsg ), 0,0,0 ); #endif /* DEBUG */ } /********************************************************************************* dosFsBootSecGet - extract boot sector parameters.** This routine reads boot sector from the disk and extracts* current volume parameters from of it.** This routine also performs sanity check of those volume parameters,* that are mutually dependent or alternative.* * If read or damaged boot sector is encountered, this routine* searches for backup copy of boot sector and accepts volume* volume configuration from this copy.,** RETURNS: OK or ERROR if disk read error or inconsistent* boot sector data or failure to obtain cbio parameters.** ERRNO:* S_dosFsLib_UNKNOWN_VOLUME_FORMAT*/LOCAL STATUS dosFsBootSecGet ( DOS_VOLUME_DESC_ID pVolDesc /* pointer to volume descriptor */ ) { CBIO_PARAMS cbioParams; u_int work; u_char bootSec[ DOS_BOOT_BUF_SIZE ] = { 0 }; /* buffer to read thoughtful */ /* part of boot sector */ u_char pass = 0; u_char tmpType [ DOS_BOOT_FSTYPE_LEN + 1] = { 0 }; /* read boot sector */ pVolDesc->bootSecNum = DOS_BOOT_SEC_NUM;boot_get: /* reset device in order to synchronize boot sector checksum */ if( cbioIoctl(pVolDesc->pCbio, CBIO_RESET, 0 ) == ERROR ) { return ERROR; } /* Get CBIO device parameters */ if (ERROR == cbioParamsGet (pVolDesc->pCbio, &cbioParams)) { return (ERROR); } /* read boot sector data and boot sector bottom pattern */ work = min( cbioParams.cbio_bytesPerBlk, DOS_BOOT_BUF_SIZE ); if( ( cbioBytesRW(pVolDesc->pCbio, pVolDesc->bootSecNum, 0 /* off */, (addr_t)bootSec, work, CBIO_READ, NULL ) == ERROR ) || cbioBytesRW(pVolDesc->pCbio, pVolDesc->bootSecNum, cbioParams.cbio_bytesPerBlk - 2 /* off */, (addr_t)&work, 2, CBIO_READ, NULL ) == ERROR ) { ERR_MSG( 1, "ERROR read boot sector\n", 0,0,0,0,0,0 ); if( TRUE == cbioRdyChgdGet (pVolDesc->pCbio) ) return ERROR; goto error; } /* check jump code */ if( bootSec[ DOS_BOOT_JMP ] != 0xe9 && bootSec[ DOS_BOOT_JMP ] != 0xeb ) { dosFsBadBootMsg( 1, DOS_BOOT_JMP, (u_int)bootSec[ DOS_BOOT_JMP ], NULL , __LINE__); goto error; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -