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

📄 dosdiroldlib.c

📁 FAT文件系统原代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* dosDirOldLib.c - MS-DOS old style names dir handler */ /* Copyright 1999-2002 Wind River Systems, Inc. *//*modification history--------------------01j,29apr02,jkf  SPR#72255, upon file creation, set the create, modification,                 and access time fields to match creation rather than using                 the epoch (0).01i,10dec01,jkf  SPR#72039, various fixes from Mr. T. Johnson.01h,21aug01,jkf  SPR#69031, common code for both AE & 5.x.01g,06mar01,jkf  SPR#34704, rootNSec calculation must round up.01f,29feb00,jkf  T3 merge01e,31jul99,jkf  T2 merge, tidiness & spelling.01d,22nov98,vld  all offsets of directory entry changed to be		 counted in absolute offset from parent directory		 start01c,28sep98,vld  gnu extensions dropped from DBG_MSG/ERR_MSG macros01b,02jul98,lrn  doc review01a,18jan98,vld	 written*//*DESCRIPTIONThis library is part of dosFsLib and  is designed to handlethe DOS4.0 standard disk directory structure as well asvxWorks proprietary long names in case sensitive manner.File names in DOS4.0 are composed of a 8 characters name and3 characters extension separated by dot character.They are stored on disk in uppercase mode, and name lookupis case insensitive. New VFAT file name standard alsosupports DOS4.0 directory structure, and if both handlers(this one and dosVDirLib) are installed, VFAT handler take precedence,and will be used for such a volume by default.VxWorks proprietary long names are composed of up to 40 charactersand are fully case sensitive. Also, files with length greater, than4GB can be stored on the volume is formatted with VxWorks proprietarylong names directory structure.Routine dosDirOldLibInit() has to be called once to install thisinto dosFsLib directory handlers list. Once it has been done this directoryhandler will be automatically mounted on each new appropriate volumebeing mounted.SEE ALSO:dosFsLib.*//* includes */#include "vxWorks.h"#include "private/dosFsVerP.h"#include "stat.h"#include "dirent.h"#include "time.h"#include "stdio.h"#include "ctype.h"#include "taskLib.h"#include "stdlib.h"#include "string.h"#include "semLib.h"#include "logLib.h"#include "errnoLib.h"#include "time.h"#include "utime.h"#include "memLib.h"#include "private/dosFsLibP.h"#include "private/dosDirLibP.h"/* defines *//* macros */#undef DBG_PRN_STR#undef DBG_MSG#undef ERR_MSG#undef NDEBUG #ifdef DEBUG#   undef LOCAL#   define LOCAL#   undef ERR_SET_SELF#   define ERR_SET_SELF#   define DBG_PRN_STR( lvl, fmt, pStr, len, arg )		\	{ if( (lvl) <= dosDirOldDebug )		{		\	    char cBuf = ((char *)(pStr))[len];			\	    (pStr)[len] = EOS; 					\	    printErr( (fmt),(pStr),(arg) );			\	    ((char *)(pStr))[len] = cBuf; 	} }#   define DBG_MSG( lvl, fmt, arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8 )	\	{ if( (lvl) <= dosDirOldDebug )					\	    printErr( "%s : %d : " fmt,				\	               __FILE__, __LINE__, arg1,arg2,	\		       arg3,arg4,arg5,arg6,arg7,arg8 ); }#   define ERR_MSG( lvl, fmt, a1,a2,a3,a4,a5,a6 )		\        { logMsg( __FILE__ " : " fmt, (int)(a1), (int)(a2),	\		  (int)(a3), (int)(a4), (int)(a5), (int)(a6) ); }#else	/* NO DEBUG */#   define NDEBUG#   define DBG_PRN_STR( lvl, fmt, pStr, len, arg )	{}#   define DBG_MSG(lvl,fmt,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) 	{}#   define ERR_MSG( lvl, fmt, a1,a2,a3,a4,a5,a6 )		\	{ if( (lvl) <= dosDirOldDebug ) 				\            logMsg( __FILE__ " : " fmt, (int)(a1), (int)(a2),	\		  (int)(a3), (int)(a4), (int)(a5), (int)(a6) ); }#endif /* DEBUG */ #include "assert.h"#ifdef ERR_SET_SELF#   define errnoSet( err ) errnoSetOut( __FILE__, __LINE__, #err, (err) )#endif /* ERR_SET_SELF *//* vxWorks long names specific  *//* typedefs */typedef enum {RD_FIRST, RD_CURRENT, RD_NEXT, FD_ENTRY} RDE_OPTION;				/* function argument */typedef struct DOS_DIROLD_DESC	/* directory handler's part of */				/* volume descriptor */    {    DOS_DIR_PDESCR	genDirDesc;	/* generic descriptor */    } DOS_DIROLD_DESC;typedef DOS_DIROLD_DESC *	DOS_DIROLD_DESC_ID;/* globals */int	dosDirOldDebug = 1;/* locals *//* valid filename characters table ('|' is invalid character) */static const u_char	shortNamesChar[] =                                        /* 0123456789abcdef */                                          "||||||||||||||||"                                          "||||||||||||||||"                                          " !|#$%&'()|||-||"                                          "0123456789||||||"                                          "@ABCDEFGHIJKLMNO"                                          "PQRSTUVWXYZ|||^_"                                          "`ABCDEFGHIJKLMNO"                                          "PQRSTUVWXYZ{|}~|" ,                        longNamesChar[] =                                        /* 0123456789abcdef */                                          "||||||||||||||||"                                          "||||||||||||||||"                                          " !|#$%&'()|+,-.|"                                          "0123456789|;|=||"                                          "@ABCDEFGHIJKLMNO"                                          "PQRSTUVWXYZ[|]^_"                                          "`abcdefghijklmno"                                          "pqrstuvwxyz{|}~|" ;/* forward declarations */#ifdef ERR_SET_SELF/******************************************************************************** errnoSetOut - put error message** This routine is called instead errnoSet during debugging.*/static VOID errnoSetOut(char * pFile, int line, const char * pStr, int errCode )    {    if( errCode != OK  && strcmp( str, "errnoBuf" ) != 0 )        printf( " %s : line %d : %s = %p, task %p\n",                pFile, line, pStr, (void *)errCode,                (void *)taskIdSelf() );    errno = errCode;    }#endif  /* ERR_SET_SELF */ /***************************************************************************** dosDirOldFillFd - fill file descriptor for directory entry.** RETURNS: N/A.*/LOCAL void dosDirOldFillFd    (    DOS_FILE_DESC_ID	pFd,	/* dos file descriptor to fill */    u_char *	pDirEnt		/* directory entry from disk */    )    {    DOS_DIR_PDESCR_ID	pDirDesc = (void *)pFd->pVolDesc->pDirDesc;    DOS_DIR_HDL_ID	pDirHdl = (void *)&(pFd->pFileHdl->dirHdl);    DIRENT_DESCR_ID	pDeDesc;        pDeDesc = &pDirDesc->deDesc;        if( pDirEnt == (u_char *) NULL )	/* root directory */    	{    	DBG_MSG( 600, "root directory\n", 0,0,0,0,0,0,0,0 );    	ROOT_SET( pFd );	/* via <parDirStartCluster> field */    	pFd->curSec = pDirDesc->dirDesc.rootStartSec;    	pFd->nSec = pDirDesc->dirDesc.rootNSec;    	pFd->pos = 0;    	pFd->pFileHdl->attrib = DOS_ATTR_DIRECTORY;    	pFd->pFileHdl->startClust = pDirDesc->rootStartClust;    	    	pDirHdl->sector = NONE;    	pDirHdl->offset = NONE;    	    	pFd->cbioCookie = (cookie_t) NULL;    	pDirHdl->cookie = (cookie_t) NULL;    	    	goto rewind;    	}        /* at the beginning fill directory handle using file descriptor */        pDirHdl->parDirStartCluster = pFd->pFileHdl->startClust;    pDirHdl->sector = pFd->curSec;    pDirHdl->offset = pFd->pos;    pDirHdl->cookie = pFd->cbioCookie;    pFd->cbioCookie = (cookie_t) NULL;    /* disassemble directory entry */        pFd->pos = 0;        pFd->curSec = 0;    pFd->nSec = 0;        pFd->pFileHdl->attrib = *(pDirEnt + pDeDesc->atrribOff);    pFd->pFileHdl->startClust =    		START_CLUST_DECODE( pFd->pVolDesc, pDeDesc, pDirEnt );        pFd->pFileHdl->size = DISK_TO_VX_32(pDirEnt + pDeDesc->sizeOff);        if( pDeDesc->extSizeOff != (u_char) NONE )    	{    	pFd->pFileHdl->size += EXT_SIZE_DECODE( pDeDesc, pDirEnt );    	}        rewind:    DBG_MSG( 600, "pFd = %p "    		  "dir hdl (sec-of-par = %u sector = %u offset = %u)\n"                  "pFileHdl = %p "                  "(startClust = %u size = %lu attr = %p)\n",                  pFd, pDirHdl->parDirStartCluster,                  pDirHdl->sector, pDirHdl->offset,                  pFd->pFileHdl, pFd->pFileHdl->startClust,                  pFd->pFileHdl->size,                  (void *)((int)pFd->pFileHdl->attrib) );    /*     * cause FAT to start from start cluster and     * get start contiguous block     */    bzero( (char *)&pFd->fatHdl, sizeof( pFd->fatHdl ) );    return;    } /* dosDirOldFillFd() *//***************************************************************************** dosDirOldRewindDir - rewind directory pointed by pFd.** This routine sets current sector in pFd to directory start sector* and current position  (offset in sector) to 0.** RETURNS: N/A.*/LOCAL void dosDirOldRewindDir    (    DOS_FILE_DESC_ID	pFd	/* dos file descriptor to fill */    )    {    DOS_DIR_PDESCR_ID	pDirDesc = (void *)pFd->pVolDesc->pDirDesc;        pFd->pos = 0;    pFd->nSec = 0;    pFd->curSec = 0;        /* for FAT32 curSec = rootNSec = 0 */        if( IS_ROOT( pFd ) && pDirDesc->dirDesc.rootNSec != 0 )    	{    	pFd->curSec = pDirDesc->dirDesc.rootStartSec;    	pFd->nSec = pDirDesc->dirDesc.rootNSec;    	return;    	}        /* regular file or FAT32 root */    /*     * cause FAT to start from start cluster and     * get start contiguous block     */    if( pFd->pVolDesc->pFatDesc->seek( pFd, FH_FILE_START, 0 ) == ERROR )    	{    	assert( FALSE );    	}    } /* dosDirOldRewindDir() */   /***************************************************************************** dosDirOldPathParse - parse a full pathname into an array of names.** This routine is similar to pathParse(), except it does not * allocate additional buffers nor changes the path string.** Parses a path in directory tree which has directory names* separated by '/' or '\\'s.  It fills the supplied array of* structures with pointers to directory and file names and * corresponding name length.** All occurrences of '//', '.' and '..'* are right removed from path. All tail dots and spaces are broken from* each name, that is name like "abc. . ." is treated as just "abc".** For instance, "/usr/vw/data/../dir/file" gets parsed into** .CS*                          namePtrArray*                         |---------|*   ---------------------------o    |*   |                     |    3    |*   |                     |---------|*   |   -----------------------o    |*   |   |                 |    2    |*   |   |                 |---------|*   |   |          ------------o    |*   |   |          |      |    3    |*   |   |          |      |---------|*   |   |          |   --------o    |*   |   |          |   |  |    4    |*   |   |          |   |  |---------|*   v   v          v   v  |   NULL  |*   |   |          |   |  |    0    |*   |   |          |   |  |---------|*   v   v          v   v *  |------------------------|*  |usr/vw/data/../dir/file |*  |-------\-----/----------|*          ignored** .CE** RETURNS: number of levels in path.** ERRNO:* S_dosFsLib_ILLEGAL_PATH* S_dosFsLib_ILLEGAL_NAME*/LOCAL int dosDirOldPathParse    (    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;    } /* dosDirOldPathParse() */    /***************************************************************************** dosDirOldTDDecode - 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 dosDirOldTDDecode    (    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 */

⌨️ 快捷键说明

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