⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dosvdirlib.c

📁 vxworks操作系统的文件系统部分原代码
💻 C
📖 第 1 页 / 共 5 页
字号:
** RETURNS: number of levels in path.** ERRNO:* S_dosFsLib_ILLEGAL_PATH* S_dosFsLib_ILLEGAL_NAME*/LOCAL int dosVDirPathParse    (    DOS_VOLUME_DESC_ID	pVolDesc,    u_char *		path,    PATH_ARRAY_ID	pnamePtrArray    )    {    FAST u_int		numPathLevels;    FAST u_char *	pName;    FAST u_char *	pRegChar; /* last not DOT and not SPACE char */        pnamePtrArray[0].pName = NULL;    /* go throw path string from left to right */        pName = path;    numPathLevels = 0;    while( *pName != EOS )	/* there is 'break' in loop also */    	{    	/* pass slashes */    	    	if( *pName == SLASH || *pName == BACK_SLASH )    	    {    	    pName++;    	    continue;    	    }    	    	/* process special names ( "." ".." ) */    	    	if( *pName == DOT )    	   {    	   /* "/./" - ignore "current directory" */    	   if( *(pName + 1) == EOS || *(pName + 1) == SLASH ||    	       *(pName + 1) == BACK_SLASH )    	   	{    	   	pName ++;    	   	continue;    	   	}    	       	   /* "/../" - goto one level back */    	       	   if( (*(pName + 1) == DOT) &&    	       ( *(pName + 2) == EOS || *(pName + 2) == SLASH ||    	         *(pName + 2) == BACK_SLASH ) )    	   	{    	   	if( numPathLevels > 0 )    	   	    numPathLevels --;    	   	pName +=2;    	   	continue;    	   	}    	   } /* if( *pName == DOT ) */    	       	/* regular name: insert it into array */    	    	if( numPathLevels >= DOS_MAX_DIR_LEVELS )    	    break;	/* max level overloaded */    	    	pnamePtrArray[numPathLevels].pName = pName;    	pnamePtrArray[numPathLevels + 1].pName = NULL;    	pRegChar = NULL;    	while( *pName != SLASH && *pName != BACK_SLASH &&    	       *pName != EOS )    	    {    	    if( *pName != DOT || *pName == SPACE )    	    	pRegChar = pName;    	    pName++;    	    }    	    	/* name can not contain only dots */    	    	if( pRegChar == NULL )    	    {    	    errnoSet( S_dosFsLib_ILLEGAL_NAME );    	    return ERROR;    	    }    	    	pnamePtrArray[numPathLevels].nameLen =    		pRegChar + 1 - pnamePtrArray[numPathLevels].pName;    	    	numPathLevels++;    	} /* while( *pName != EOS ) */        /* check result */        if( *pName != EOS )	/* path termination has not been reached */    	{    	errnoSet( S_dosFsLib_ILLEGAL_PATH );    	return ERROR;    	}#ifdef DEBUG    DBG_MSG( 600, "path: %s, result: \n", path ,0,0,0,0,0,0,0);    pName = (void *)pnamePtrArray;    for( ; pnamePtrArray->pName != NULL; pnamePtrArray++ )    	{    	int i = pnamePtrArray - (PATH_ARRAY_ID)pName + 1;    	DBG_PRN_STR( 600, "%s : %d", pnamePtrArray->pName,    			pnamePtrArray->nameLen, i );    	}    DBG_PRN_STR(600, "\b\b \n", "", 0, 0);#endif /* DEBUG */    return numPathLevels;    } /* dosVDirPathParse() */    /***************************************************************************** dosVDirChkSum - count checksum for long name alias.** RETURNS: N/A.*/LOCAL u_char dosVDirChkSum    (    u_char *	alias    )    {    u_int	i;    u_char	chkSum;        for( chkSum = 0, i = 0; i < DOS_STDNAME_LEN + DOS_STDEXT_LEN; i++ )    	{    	chkSum = ( ( ( chkSum &    1 ) << 7 ) |    	    	   ( ( chkSum & 0xfe ) >> 1 )    	    	 ) +  alias[ i ];    	}    return chkSum;    } /* dosVDirChkSum() */    /***************************************************************************** dosVDirTDDecode - decode time-date field from disk format.** This routine decodes required date-time field in the directory* entry into time_t format.* * Parameter which defines which time field to decode. It* can be one of:* DH_TIME_CREAT, DH_TIME_MODIFY, DH_TIME_ACCESS.** RETURNS: time in time_t format.**/LOCAL time_t dosVDirTDDecode    (    DOS_DIR_PDESCR_ID	pDirDesc,    u_char *	pDirent,	/* directory entry buffer */    u_int	which	/* what field to decode: one of */    			/* DH_TIME_CREAT, DH_TIME_MODIFY or DH_TIME_ACCESS */    )    {    struct tm	tm = {0};	/* broken down time buffer */    UINT16	dtBuf;		/* 16-bit buffer */    u_char	tOff = 0, dOff = 0;	/* field offset */        switch( which )        {        case DH_TIME_CREAT:            tOff = pDirDesc->deDesc.creatTimeOff;            dOff = pDirDesc->deDesc.creatDateOff;            break;        case DH_TIME_MODIFY:            tOff = pDirDesc->deDesc.modifTimeOff;            dOff = pDirDesc->deDesc.modifDateOff;            break;        case DH_TIME_ACCESS:            tOff = pDirDesc->deDesc.accessTimeOff;            dOff = pDirDesc->deDesc.accessDateOff;            break;        default:            assert( FALSE );        }        if( dOff != (u_char)NONE )    	{    	dtBuf = DISK_TO_VX_16( pDirent + dOff );    	    	tm.tm_mday    = dtBuf & 0x1f;    		/* ANSI months are zero-based */	    	tm.tm_mon     = ((dtBuf >> 5) & 0x0f) - 1;    		/* DOS starts at 1980, ANSI starts at 1900 */	    	tm.tm_year    = ((dtBuf >> 9) & 0x7f) + 1980 - 1900;    	}    if( tOff != (u_char)NONE )    	{    	dtBuf = DISK_TO_VX_16( pDirent + tOff );    	    	tm.tm_sec     = (dtBuf & 0x1f) << 1;    	tm.tm_min     = (dtBuf >> 5) & 0x3f;    	tm.tm_hour    = (dtBuf >> 11) & 0x1f;    	}        /* encode into time_t format */        return mktime( &tm );    } /* dosVDirTDDecode() *//***************************************************************************** dosVDirTDEncode - encode time-date to disk format.** This routine takes time value is provided in <curTime> argument* and encodes it into directory entry format.* * Parameter <timesMask> defines which time fields to fill. Following* values can be bitwise or-ed:* DH_TIME_CREAT, DH_TIME_MODIFY, DH_TIME_ACCESS.** RETURNS: N/A.*/LOCAL void dosVDirTDEncode    (    DOS_DIR_PDESCR_ID	pDirDesc,    u_char *	pDirEnt,    u_int	timesMask,    time_t	curTime	/* time to encode */    )    {    struct tm   tm;	/* buffer for split time-date */    u_char	timeB[2], dateB[2];	/* buffers for encoding */        localtime_r( &curTime, &tm );    /* encode time */        VX_TO_DISK_16( ( tm.tm_sec >> 1 ) |    		  ( tm.tm_min << 5 ) |    		  ( tm.tm_hour << 11 ), timeB );        /*     * encode date;     * in <pDate> year is related to 1980, but in tm, - to 1900     */    tm.tm_year =  ( tm.tm_year < 80 )? 80 : tm.tm_year;    VX_TO_DISK_16( tm.tm_mday | ( ( tm.tm_mon + 1 ) << 5 ) |    		  ( ( tm.tm_year - 80 ) <<  9 ), dateB );        /* put time-date into directory entry buffer */        if( timesMask & DH_TIME_CREAT &&        pDirDesc->deDesc.creatDateOff != (u_char)NONE  )    	{    	pDirEnt[ pDirDesc->deDesc.creatTimeOff ] = timeB[0];    	pDirEnt[ pDirDesc->deDesc.creatTimeOff + 1 ] = timeB[1];    	pDirEnt[ pDirDesc->deDesc.creatDateOff ] = dateB[0];    	pDirEnt[ pDirDesc->deDesc.creatDateOff + 1 ] = dateB[1];    	}    if( timesMask & DH_TIME_MODIFY &&        pDirDesc->deDesc.modifDateOff != (u_char)NONE  )    	{    	pDirEnt[ pDirDesc->deDesc.modifTimeOff ] = timeB[0];    	pDirEnt[ pDirDesc->deDesc.modifTimeOff + 1 ] = timeB[1];    	pDirEnt[ pDirDesc->deDesc.modifDateOff ] = dateB[0];    	pDirEnt[ pDirDesc->deDesc.modifDateOff + 1 ] = dateB[1];    	}    if( timesMask & DH_TIME_ACCESS &&        pDirDesc->deDesc.accessDateOff != (u_char)NONE  )    	{    	if( pDirDesc->deDesc.accessTimeOff != (u_char)NONE )    	    {    	    pDirEnt[ pDirDesc->deDesc.accessTimeOff ] = timeB[0];    	    pDirEnt[ pDirDesc->deDesc.accessTimeOff + 1 ] = timeB[1];    	    }    	pDirEnt[ pDirDesc->deDesc.accessDateOff ] = dateB[0];    	pDirEnt[ pDirDesc->deDesc.accessDateOff + 1 ] = dateB[1];    	}    } /* dosVDirTDEncode() */    /***************************************************************************** dosVDirCharEncode - validate and encode character.** RETURNS: OK or ERROR.*/LOCAL STATUS dosVDirCharEncode    (    u_char *	pSrc,    u_char *	pDst,    const u_char *	codeTbl	/* characters table */    				/* ( shortNamesChar or longNamesChar ) */    )    {    /* allow all high characters */    	    if( *pSrc & 0x80 )    	{    	*pDst = *pSrc;    	}    else if( codeTbl[ *pSrc ] != INVALID_CHAR )    	{    	*pDst = codeTbl[ *pSrc ];    	}    else    	{    	return ERROR;    	}        return OK;    } /* dosVDirCharEncode() */    /***************************************************************************** dosVDirNameEncodeShort - encode name in short style.** This routine encodes incoming file name into 8+3 uppercase format.* During encoding the* name is verified to be composed of valid characters.** RETURNS: STRICT_SHORT, if name is valid short and uppercase,*  NOT_STRICT_SHORT, if name is short, but not uppercase,*  NO_SHORT, if name can not be encoded as short.* */LOCAL SHORT_ENCODE dosVDirNameEncodeShort    (     DOS_DIR_PDESCR_ID	pDirDesc,    PATH_ARRAY_ID	pNamePtr,	/* name buffer */    u_char *	pDstName	/* buffer for name in disk format */    )    {    u_char *	pSrc;		/* source name dynamic ptr */    u_char *	pDstBuf;	/* for debug output only */    int		i,j;		/* work */    SHORT_ENCODE	retVal = STRICT_SHORT;    /* extension length (0 - no extension) */    u_char	extLen = pDirDesc->deDesc.extLen;        pDstBuf = pDstName;        bfill( (char *)pDstName,    	   pDirDesc->deDesc.nameLen + pDirDesc->deDesc.extLen, SPACE );        /* encode name and check it by the way */        DBG_MSG( 600, "",0,0,0,0,0,0,0,0 );    DBG_PRN_STR( 600, "%s\n", pNamePtr->pName, pNamePtr->nameLen, 0 );    for( i = 0, pSrc = pNamePtr->pName;    	 i < min( pDirDesc->deDesc.nameLen,    	 	  pNamePtr->nameLen );    	 i++, pDstName++, pSrc++  )    	{    	/* check for extension */    	    	if( extLen != 0 && *pSrc == DOT )     	    break;    	    	if( dosVDirCharEncode( pSrc, pDstName, shortNamesChar ) == ERROR )    	    goto error;    	    	if( *pDstName != *pSrc )    	    retVal = NOT_STRICT_SHORT;    	}    /* check state */        if( i == pNamePtr->nameLen )    	goto retOK;	/* name finished */        if( *pSrc != DOT )	/* name too long */        goto error;        pSrc++;	/* pass DOT */    pDstName += pDirDesc->deDesc.nameLen - i;    i++;        /* encode extension */        for( j = 0; j < extLen && i < pNamePtr->nameLen;    	 i++, j++, pDstName++, pSrc++  )    	{    	if( dosVDirCharEncode( pSrc, pDstName, shortNamesChar ) == ERROR )    	    goto error;    	if( *pDstName != *pSrc )    	    retVal = NOT_STRICT_SHORT;    	}        /* check status */        if( i < pNamePtr->nameLen )	/* extension too long */    	goto error;retOK:    /*      * A space in a short file name is indeed technically allowed, but     * in order to be compatible with M$ Scandisk and Norton Disk Doctor      * we mangle 8.3 names if they contain a space.  This will prevent      * ScanDisk and Norton Disk Doctor from reporting a (false) orphaned      * LFN entry on the alias, and offering to correct it.  Both will     * correct it by marking the LFN invalid (fragmenting the disk...)     * and simply using the short file name, which destroys the case     * sensitive part of the filename.     * Basically, this code is added to appease the windoze tools      * that complain about our file system, since that supposedly      * looks bad....but windo$e should NOT need to mangle a short     * filename with a space....but Windows 95 OSR2 does just that..     * Note only with "3D MAZES.SCR" style.       * Not with "NAME    .   " filenames.     */    /* check backwards through name, wont be more than 11 chars (0-10) */    i = pNamePtr->nameLen - 1;    while (i > 1) /* ignore 0 and 1 chars, name won't begin with space.*/        {	/* ignore "name   " type filenames */	if (*(pNamePtr->pName + i) != SPACE)		    break;        /* found non-space char, break */ 	i--; 	}    if (i != 1) /* don't care if "2   " style name */	{	while (i > 0) /* now look for a space */	    {	    if (*(pNamePtr->pName + i) == SPACE)		        {		goto error; /* windoze likes it a longname */		}	    i--;    	    }  	}        DBG_PRN_STR( 600, "result: %s\n", pDstBuf, 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -