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

📄 dosvdirlib.c

📁 FAT文件系统原代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* dosVDirLib.c - MS-DOS VFAT-style Long File names dir handler */ /* Copyright 1999-2002 Wind River Systems, Inc. *//*modification history--------------------01p,10dec01,jkf  SPR#72039, various fixes from Mr. T. Johnson.01o,09nov01,jkf  SPR#70968, chkdsk destroys boot sector01n,21aug01,jkf  SPR#69031, common code for both AE & 5.x.01m,06mar01,jkf  SPR#34704, rootNSec calculation must round up.01n,01aug00,dat  SPR 31480, directory cluster corruption fix (neeraj)01l,07mar00,jkf  Corrected pentium specific compiler warning "using %eax                  instead of %ax due to l" (source of P6 reg stall?)01k,29feb00,jkf  T3 changes, cleanup. 01j,31aug99,jkf  changes for new CBIO API.01i,31jul99,jkf  moved the fix for SPR#28276 from dosVDirFileCreateInDir()                  to dosVDirNameEncodeShort because it was only mangling the                  name in 01g and not creating an alias for it, no SPR.01h,31jul99,jkf  default debug global to zero, no SPR.01g,31jul99,jkf  Fixed dosVDirFileCreateInDir to mangle 8.3 names containing                  char-space-char, per MS compatability.  MS Scandisk and 		 Norton Disk Doctor stops reporting a false orphaned LFN 		 which they repair by removing it.  SPR#2827601f,31jul99,jkf  T2 merge, tidiness & spelling.01e,07dec98,lrn  minor Show output cosmetics01d,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  review doc01a,18jan98,vld  written,*//*DESCRIPTIONThis library is part of dosFsLib and is designed to handle theVFAT "long filename" standard disk directory structure.VFAT is the file name format initially introduced with OS/2 operatingsystem, and subsequently adopted by Microsoft in Windows 95 and NToperating systems for FAT-based file systems.With this format, every file has a Long Name which occupies a number ofdirectory entries, and a short file name which adheres to the vintageMS-DOS file naming conventions. The later are called aliases.This handler performs its lookup only by file long names, not by aliases,in other words, the aliases, are provided only for data interchange withMicrosoft implementations of FAT, and are ignored otherwise.Aliases, that are created for long file names are Windows95/98 compatible,that means, they are readable from Windows applications, but they arenot produced from the corresponding long file name.In this implementation the alias is made of numbers to ensure thatevery alias is unique in its directory without having to scan the entiredirectory.  This ensure determinism.Therefore if a volume written with this handler is every transported toan old MS-DOS system or comparable implementation of dosFs,which only accepts vintage 8.3 file names, the names of files will notbe readily associated with their original names, and thus practicallyunusable. The goal was to ensure determinism and file safety.Uppercase 8.3 filename that follow strict 8.3 rules such as "UPPERFIL.TXT" will not be stored in a long filename.  Lowercase 8.3 Filenames such as "Upperfil.txt" will have a readablealias created of "UPPERFIL.TXT"   Lowercase 8.3 Filenames such as "File   " will have an alias created of "FILE    ".Filenames with a sequence of char, space, char strings. Such as "3D Pipes.scr" will also have a munged alias created akin to "3~999997".The routine dosVDirInit() routine has to be called once to install this handler into dosFsLib. Once that has been done this directoryhandler will be automatically mounted for each new DOS volume being mounted and containing VFAT or early DOS directory structure.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 */#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) <= dosVDirDebug )		{		\	    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) <= dosVDirDebug )					\	    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) <= dosVDirDebug ) 				\            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 */#define VFAT_MAX_ENT	( (DOS_VFAT_NAME_LEN + CHAR_PER_VENTRY - 1) \			  / CHAR_PER_VENTRY )					/* max directory entries required */					/* to store VFAT long name */#define MAX_VFAT_FULL_DIRENT	( DOS_DIRENT_STD_LEN * (VFAT_MAX_ENT + 1) )					/* max space of long name + alias */					/* may occupy on disk */#define CHAR_PER_VENTRY		13	/* num of characters of long name */					/* encoded within directory entry */#define VFAT_ENTNUM_MASK	0x1f	/* mask of "entry number within */					/* long name" field */ #define DOS_VFAT_CHKSUM_OFF	13#define DOS_ATTR_VFAT		0x0f	/* value of attribute field for */					/* directory entries, that encodes */					/* VFAT long name *//* special characters */#define DOS_VLAST_ENTRY	0x40	/* last entry in long name representation *//* special function argument value */#define DH_ALLOC	(1<<7)	/* add cluster to directory chain */#define PUT_CURRENT	(1<<0)	/* store currently pointed directory entry */#define	PUT_NEXT	(1<<1)	/* store next directory entry *//* macros *//* typedefs */typedef enum {RD_FIRST, RD_CURRENT, RD_NEXT, FD_ENTRY} RDE_OPTION;				/* function argument */typedef enum {STRICT_SHORT, NOT_STRICT_SHORT, NO_SHORT} SHORT_ENCODE;				/* function argument */typedef struct DOS_VDIR_DESCR	/* directory handler's part of */				/* volume descriptor */    {    DOS_DIR_PDESCR	genDirDesc;	/* generic descriptor */    } DOS_VDIR_DESCR;typedef DOS_VDIR_DESCR *	DOS_VDIR_DESCR_ID;/* globals */unsigned int	dosVDirDebug = 0;/* locals *//* positions of filename characters encoding within VFAT directory entry */LOCAL const u_char	chOffsets[] = { 1, 3, 5, 7, 9,					14, 16, 18, 20, 22, 24, 						28, 30 };/* 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{|}~|" ;#ifdef ERR_SET_SELF/******************************************************************************** errnoSetOut - put error message** This routine is called instead 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 *//***************************************************************************** dosVDirFillFd - fill file descriptor for directory entry.** RETURNS: N/A.*/LOCAL void dosVDirFillFd    (    DOS_FILE_DESC_ID	pFd,	/* dos file descriptor to fill */    u_char *	pDirEnt,	/* directory entry from disk */    DIRENT_PTR_ID	pLnPtr	/* start of long name */    )    {    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 == 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;    	pDirHdl->lnSector = 0;    	pDirHdl->lnOffset = 0;    	    	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;        /* long name ptr */        if( pLnPtr != NULL )    	{    	pDirHdl->lnSector = pLnPtr->sector;    	pDirHdl->lnOffset = pLnPtr->offset;    	}    else	/* just a short name */    	{    	pDirHdl->lnSector = 0;    	pDirHdl->lnOffset = 0;    	}    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 );    	}    DBG_MSG( 100, "StartCluster = %u = %p, size = %lu\n",    		pFd->pFileHdl->startClust, (void *)pFd->pFileHdl->startClust,    		(u_long)pFd->pFileHdl->size & 0xffffffff ,0,0,0,0,0);        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;    } /* dosVDirFillFd() *//***************************************************************************** dosVDirRewindDir - 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 dosVDirRewindDir    (    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 );    	}    } /* dosVDirRewindDir() */   /***************************************************************************** dosVDirPathParse - parse a full pathname into an array of names.** This routine is similar to pathParse(), but on the contrary 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 * correspondence 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

⌨️ 快捷键说明

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