📄 dosdiroldlib.c
字号:
options, &freeEnt ) == OK ) return OK; } else { errnoSet( S_dosFsLib_FILE_NOT_FOUND ); } /* error; release dir handle */ return ERROR; } /* dosDirOldPathLkup() *//***************************************************************************** dosDirOldDateGet - fill in date-time fields in stat structure.** RETURNS: OK or ERROR if disk access error.**/LOCAL STATUS dosDirOldDateGet ( DOS_FILE_DESC_ID pFd, struct stat * pStat ) { DOS_DIR_PDESCR_ID pDirDesc = (void *)pFd->pVolDesc->pDirDesc; u_char dirent[ DOS_VX_DIRENT_LEN ]; /* directory entry buffer */ /* root directory has not its own entry */ if( IS_ROOT( pFd ) ) { pStat->st_mtime = pDirDesc->rootModifTime; return OK; } /* get directory entry */ if( dosDirOldDirentGet( pFd, dirent, FD_ENTRY ) == ERROR ) return ERROR; pStat->st_ctime = dosDirOldTDDecode( pDirDesc, dirent, DH_TIME_CREAT ); pStat->st_mtime = dosDirOldTDDecode( pDirDesc, dirent, DH_TIME_MODIFY ); pStat->st_atime = dosDirOldTDDecode( pDirDesc, dirent, DH_TIME_ACCESS ); return OK; } /* dosDirOldDateGet() */ /********************************************************************************* dosDirOldVolLabel - set/get dos volume label.** This routine gets/changes the volume label entry in the root directory of a* dosFs volume.** Only one volume label entry may exist per volume and in root directory only.* When request to change volume label arrives and there is already a volume* label, the name is simply* replaced. If there is currently no label, a new volume label entry is* created.** RETURNS: OK, or ERROR if volume is not available.** ERRNO:* S_dosFsLib_INVALID_PARAMETER* S_dosFsLib_NO_LABEL* S_dosFsLib_ROOT_DIR_FULL*/LOCAL STATUS dosDirOldVolLabel ( DOS_VOLUME_DESC_ID pVolDesc, u_char * label, u_int request /* FIOLABELSET, FIOLABELGET */ ) { DOS_DIR_PDESCR_ID pDirDesc = (void *)pVolDesc->pDirDesc; DOS_FILE_DESC fd; /* work file descriptor */ DOS_FILE_HDL fHdl; /* work file handle */ u_int numEnt; /* number of passed entries */ u_short labOffInBoot; /* volume label offset in boot sector */ char * noName = "NO LABEL"; STATUS status = ERROR; /* search status */ u_char dirent[ DOS_VX_DIRENT_LEN ]; /* directory entry buffer */ if( ! ( request == FIOLABELSET || request == FIOLABELGET ) ) { errnoSet( S_dosFsLib_INVALID_PARAMETER ); return ERROR; } labOffInBoot = ( pVolDesc->fatType == FAT32 )? DOS32_BOOT_VOL_LABEL: DOS_BOOT_VOL_LABEL; if( label == NULL ) { if( request == FIOLABELSET ) label = (u_char *)noName; /* use default name */ else { errnoSet( S_dosFsLib_INVALID_PARAMETER ); return ERROR; } } /* init file descriptor */ fd.pVolDesc = pVolDesc; fd.pFileHdl = &fHdl; dosDirOldFillFd( &fd, ROOT_DIRENT ); /* search for volume label */ for( numEnt = 0, (status = dosDirOldDirentGet( &fd, dirent, RD_FIRST )); (status != ERROR) && *dirent != LAST_DIRENT; numEnt ++, status = dosDirOldDirentGet( &fd, dirent, RD_NEXT ) ) { if( *(dirent + pDirDesc->deDesc.atrribOff) & DOS_ATTR_VOL_LABEL ) break; } /* get label */ if( request == FIOLABELGET ) { if( status == ERROR || *dirent == LAST_DIRENT ) { /* * no volume label found in root dir * extract label out of boot sector */ bcopy( pVolDesc->bootVolLab, (char *)dirent, DOS_VOL_LABEL_LEN ); } bcopy( (char *)dirent, (char *)label, DOS_VOL_LABEL_LEN ); numEnt = DOS_VOL_LABEL_LEN; while( numEnt > 0 && label[ numEnt-1 ] == SPACE ) label[ --numEnt ] = EOS; return OK; } /* change/create label */ /* * if no label found and no free entry in root, * add and init one more cluster. */ if( status == ERROR ) /* label not found and no free entry */ { if( numEnt >= pDirDesc->rootMaxEntries ) /* root dir is full */ { errnoSet( S_dosFsLib_ROOT_DIR_FULL ); return ERROR; } else if( dosDirOldClustAdd( &fd ) == ERROR ) return ERROR; } /* encode name */ bzero( (char *)dirent, sizeof( dirent ) ); bfill( (char *)dirent, pDirDesc->deDesc.nameLen + pDirDesc->deDesc.extLen, SPACE ); bcopy( (char *)label, (char *)dirent, min( DOS_VOL_LABEL_LEN, strlen( (char *)label ) ) ); dirent[ pDirDesc->deDesc.atrribOff] = DOS_ATTR_VOL_LABEL; /* --- store label --- */ /* store in root directory */ status = cbioBytesRW( pVolDesc->pCbio, fd.curSec, OFFSET_IN_SEC( pVolDesc, fd.pos ), (addr_t)dirent, pDirDesc->deDesc.dirEntSize, CBIO_WRITE, &fHdl.dirHdl.cookie ); #ifdef CNANGE_BOOT /* XXX - avoid changing boot block to avoid false disk removal event */ /* store in boot sector */ bcopy( (char *)dirent, pVolDesc->bootVolLab, DOS_VOL_LABEL_LEN ); status |= cbioBytesRW( pVolDesc->pCbio, DOS_BOOT_SEC_NUM, labOffInBoot, (addr_t)dirent, DOS_VOL_LABEL_LEN, CBIO_WRITE, NULL );#endif /* CNANGE_BOOT */ return status; } /* dosDirOldVolLabel() */ /********************************************************************************* dosDirOldNameChk - validate file name.** This routine validates incoming file name to be composed* of valid characters.** RETURNS: OK if name is OK or ERROR.*/LOCAL STATUS dosDirOldNameChk ( DOS_VOLUME_DESC_ID pVolDesc, u_char * name ) { DOS_DIR_PDESCR_ID pDirDesc = (void *)pVolDesc->pDirDesc; PATH_ARRAY namePtr; u_char dirent[ DOS_VX_DIRENT_LEN ] = {0}; /* directory entry buffer */ namePtr.pName = name; namePtr.nameLen = strlen((char *)name); return dosDirOldNameEncode( pDirDesc, &namePtr, dirent ); } /* dosDirOldNameChk() *//********************************************************************************* dosDirOldShow - display handler specific volume configuration data.** RETURNS: N/A.*/LOCAL void dosDirOldShow ( DOS_VOLUME_DESC_ID pVolDesc ) { DOS_DIR_PDESCR_ID pDirDesc = (void *)pVolDesc->pDirDesc; if( ! pVolDesc->mounted ) return; printf(" - names style: %s\n", ( (pDirDesc->nameStyle == STDDOS)? "8.3 STD DOS" : "VxLong" ) ); if( pDirDesc->dirDesc.rootStartSec != 0 ) /* FAT12/FAT16 */ { printf(" - root dir start sector: %u\n", pDirDesc->dirDesc.rootStartSec ); printf(" - # of sectors per root: %u\n", pDirDesc->dirDesc.rootNSec ); printf(" - max # of entries in root: %u\n", pDirDesc->rootMaxEntries ); } else /* FAT32 */ { printf(" - root dir start cluster: %u\n", pDirDesc->rootStartClust ); } return; } /* dosDirOldShow() *//********************************************************************************* dosDirOldVolUnmount - stub.** RETURNS: N/A.*/LOCAL void dosDirOldVolUnmount ( DOS_VOLUME_DESC_ID pVolDesc ) { return; } /* dosDirOldVolUnmount() *//********************************************************************************* dosDirOldVolMount - init all data required to access the volume.** This routine fills all local and shared structures fields, that* depend on a directory structure format. All data is updated* from boot sector of the volume is being mounted and from* volume descriptor argument.** RETURNS: OK or ERROR if the volume has inappropriate format.** ERRNO:* S_dosFsLib_UNSUPPORTED* S_dosFsLib_UNKNOWN_VOLUME_FORMAT*/LOCAL STATUS dosDirOldVolMount ( DOS_VOLUME_DESC_ID pVolDesc, void * arg ) { DOS_DIR_PDESCR_ID pDirDesc = NULL; DIRENT_DESCR_ID pDeDesc = NULL; cookie_t cookie = 0; char bootSec[DOS_BOOT_BUF_SIZE]; assert( (pVolDesc != NULL) && pVolDesc->magic == DOS_FS_MAGIC ); /* check for vxWorks long names */ if( cbioBytesRW( pVolDesc->pCbio, pVolDesc->bootSecNum, 0, bootSec, min( sizeof( bootSec ), pVolDesc->bytesPerSec ), CBIO_READ, &cookie ) == ERROR ) { return ERROR; } /* * if previous volume had alternative directory structure, * unmount previous directory handler and * allocate directory handler descriptor */ if( pVolDesc->pDirDesc == NULL || pVolDesc->pDirDesc->volUnmount != dosDirOldVolUnmount ) { /* unmount previous directory handler */ if( pVolDesc->pDirDesc != NULL && pVolDesc->pDirDesc->volUnmount != NULL ) { pVolDesc->pDirDesc->volUnmount( pVolDesc ); } /* allocate directory handler descriptor */ pVolDesc->pDirDesc = KHEAP_REALLOC((char *) pVolDesc->pDirDesc, sizeof( DOS_DIR_PDESCR ) ); if( pVolDesc->pDirDesc == NULL ) return ERROR; } pDirDesc = (void *)pVolDesc->pDirDesc; pDeDesc = &pDirDesc->deDesc; bzero( (char *)pDirDesc, sizeof( DOS_DIR_PDESCR ) ); if( bcmp( bootSec + DOS_BOOT_SYS_ID, DOS_VX_LONG_NAMES_SYS_ID, strlen( DOS_VX_LONG_NAMES_SYS_ID ) ) == 0 ) { /* use vxWorks long names */ ERR_MSG( 10, "VxLong names\n", 0,0,0,0,0,0 ); pDirDesc->nameStyle = VXLONG; pDeDesc->dirEntSize = DOS_VX_DIRENT_LEN; pDeDesc->nameLen = DOS_VX_NAME_LEN; pDeDesc->extLen = DOS_VX_EXT_LEN; pDeDesc->atrribOff = DOS_VX_ATTRIB_OFF; pDeDesc->creatTimeOff = DOS_VX_CREAT_TIME_OFF; pDeDesc->creatDateOff = DOS_VX_CREAT_DATE_OFF; pDeDesc->modifTimeOff = DOS_VX_MODIF_TIME_OFF; pDeDesc->modifDateOff = DOS_VX_MODIF_DATE_OFF; pDeDesc->accessTimeOff = DOS_VX_LAST_ACCESS_TIME_OFF; pDeDesc->accessDateOff = DOS_VX_LAST_ACCESS_DATE_OFF; pDeDesc->startClustOff = DOS_VX_START_CLUST_OFF; pDeDesc->extStartClustOff = DOS_VX_EXT_START_CLUST_OFF; pDeDesc->sizeOff = DOS_VX_FILE_SIZE_OFF; pDeDesc->extSizeOff = DOS_VX_EXT_FILE_SIZE_OFF; pDeDesc->extSizeLen = DOS_VX_EXT_FILE_SIZE_LEN; } else { /* use DOS traditional 8.3 name */ ERR_MSG( 10, "DOS 8.3 names\n", 0,0,0,0,0,0 ); pDirDesc->nameStyle = STDDOS; pDeDesc->dirEntSize = DOS_DIRENT_STD_LEN; pDeDesc->nameLen = DOS_STDNAME_LEN; pDeDesc->extLen = DOS_STDEXT_LEN; pDeDesc->atrribOff = DOS_ATTRIB_OFF; pDeDesc->creatTimeOff = DOS_MODIF_TIME_OFF; pDeDesc->creatDateOff = DOS_MODIF_DATE_OFF; pDeDesc->modifTimeOff = DOS_MODIF_TIME_OFF; pDeDesc->modifDateOff = DOS_MODIF_DATE_OFF; pDeDesc->accessTimeOff = NONE; pDeDesc->accessDateOff = NONE; pDeDesc->startClustOff = DOS_START_CLUST_OFF; pDeDesc->extStartClustOff = DOS_EXT_START_CLUST_OFF; pDeDesc->sizeOff = DOS_FILE_SIZE_OFF; pDeDesc->extSizeOff = DOS_EXT_FILE_SIZE_OFF; pDeDesc->extSizeLen = DOS_EXT_FILE_SIZE_LEN; } /* check correspondence of cluster and directory entry size */ if( pDeDesc->dirEntSize > ( pVolDesc->secPerClust << pVolDesc->secSizeShift ) ) { ERR_MSG( 0, "cluster size %d bytes is too small, min = %d\n", pVolDesc->secPerClust << pVolDesc->secSizeShift, pDeDesc->dirEntSize, 0,0,0,0 ); errnoSet( S_dosFsLib_UNKNOWN_VOLUME_FORMAT ); return ERROR; } /* * init root directory parameters in accordance with * volume FAT version */ if( pVolDesc->fatType == FAT32 ) /* FAT32 */ { /* * init root directory descriptor. * Get root directory start cluster number */ pDirDesc->rootStartClust = DISK_TO_VX_32( bootSec + DOS32_BOOT_ROOT_START_CLUST ); if( pDirDesc->rootStartClust < 2 ) { ERR_MSG( 1, "Malformed volume format (FAT32: rootStartClust " " = %u)\n", pDirDesc->rootStartClust, 0,0,0,0,0 ); errnoSet( S_dosFsLib_UNKNOWN_VOLUME_FORMAT ); return ERROR; } pDirDesc->dirDesc.rootStartSec = 0; pDirDesc->dirDesc.rootNSec = 0; pDirDesc->rootMaxEntries = (u_int)(-1); /* not restricted */ } else /* FAT12/FAT16 */ { /* * init root directory descriptor. * Get number of entries-per-root directory */ pDirDesc->rootMaxEntries = DISK_TO_VX_16( bootSec + DOS_BOOT_MAX_ROOT_ENTS); if( pDirDesc->rootMaxEntries == 0 ) { ERR_MSG( 1, "Malformed volume format (FAT12/16: " "rootMaxEntries = 0)\n", 0,0,0,0,0,0 ); errnoSet( S_dosFsLib_UNKNOWN_VOLUME_FORMAT ); return ERROR; } pDirDesc->rootStartClust = 0; /* don't change this 0 ! */ /* it is important while */ /* creating subdir in root */ /* SPR#34704 This operation must round up. */ pDirDesc->dirDesc.rootNSec = (((pDirDesc->rootMaxEntries * pDeDesc->dirEntSize) + (pVolDesc->bytesPerSec - 1)) / pVolDesc->bytesPerSec); /* root directory resides ahead regular data area */ pDirDesc->dirDesc.rootStartSec = pVolDesc->dataStartSec; pVolDesc->dataStartSec += pDirDesc->dirDesc.rootNSec; } /* init root directory last modification time */ pDirDesc->rootModifTime = time( NULL ); /* fill functions pointers */ pDirDesc->dirDesc.pathLkup = dosDirOldPathLkup; pDirDesc->dirDesc.readDir = dosDirOldReaddir; pDirDesc->dirDesc.updateEntry = dosDirOldUpdateEntry; pDirDesc->dirDesc.dateGet = dosDirOldDateGet; pDirDesc->dirDesc.volLabel = dosDirOldVolLabel; pDirDesc->dirDesc.nameChk = dosDirOldNameChk; pDirDesc->dirDesc.volUnmount = dosDirOldVolUnmount; pDirDesc->dirDesc.show = dosDirOldShow; return OK; } /* dosDirOldVolMount() *//********************************************************************************* dosDirOldLibInit - install <8.3> and VxLong names handler into dosFsLib** RETURNS: OK or ERROR if handler installation failed.** NOMANUAL*/STATUS dosDirOldLibInit ( void ) { DOS_HDLR_DESC hdlr; hdlr.id = DOS_DIROLD_HDLR_ID; hdlr.mountRtn = dosDirOldVolMount; hdlr.arg = NULL; return dosFsHdlrInstall( dosDirHdlrsList, &hdlr ); } /* dosDirOldLibInit() *//* End of File */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -