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

📄 dosvdirlib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 5 页
字号:
    return NO_SHORT;    } /* dosVDirNameEncodeShort() */    /***************************************************************************** dosVDirNameEncode - encode name to disk format.** This routine encodes incoming file name into Windows-95 long names* format. During encoding the* name is verified to be composed of valid characters.* * The source name is* split into several directory entries, that has valid format,* unless alias checksum.* Also src name is attempted to be encoded in short manner.** RETURNS: directory entries per long name include alias or (-1) if name is*  illegal.* * ERRNO:* S_dosFsLib_ILLEGAL_NAME*/LOCAL int dosVDirNameEncode    (     DOS_DIR_PDESCR_ID	pDirDesc,    PATH_ARRAY_ID	pNamePtr,	/* name buffer */    u_char *	pDstName,	/* buffer for name in disk format */    SHORT_ENCODE *	pShortEncodeStrat /* short name encodding */    					 /* strategy/result */	    )    {    u_char *	pSrc = pNamePtr->pName;	/* source name dynamic ptr */    u_char *	pDst;		/* ptr to encoded destination entry */    u_char	numEnt;		/* entries per long name */    u_char	entNum, chNum;	/* loop counters */        if( pNamePtr->nameLen > DOS_VFAT_NAME_LEN )    	goto error;        /* number of entries per long name */        numEnt = ( pNamePtr->nameLen + CHAR_PER_VENTRY  - 1 ) /    	     CHAR_PER_VENTRY;        /* try to encode src name as short */        bzero( (char *)pDstName, DOS_DIRENT_STD_LEN );    if( ( dosVDirNameEncodeShort( pDirDesc, pNamePtr,    			          pDstName ) == STRICT_SHORT ) )    	    	{    	if( *pShortEncodeStrat == STRICT_SHORT )	    {	    return 1;     	    }        *pShortEncodeStrat = STRICT_SHORT;	}    else    	{    	*pShortEncodeStrat = NOT_STRICT_SHORT;    	}    	        bcopy( (char *)pDstName, (char *)pDstName + numEnt * DOS_DIRENT_STD_LEN,           DOS_DIRENT_STD_LEN );    bzero( (char *)pDstName, numEnt * DOS_DIRENT_STD_LEN );    			        /* start encoding from bottom (first) entry */        pDst = pDstName + (numEnt - 1) * DOS_DIRENT_STD_LEN;    for( entNum = 1;    	 entNum <= numEnt;    	 entNum ++, pDst -=  DOS_DIRENT_STD_LEN )    	{    	*pDst = entNum;	/* encode entry number */    	*(pDst + pDirDesc->deDesc.atrribOff) = DOS_ATTR_VFAT;    				/* VFAT long name representation */    	    	/* encode characters */    	    	for( chNum = 0;    	     chNum < CHAR_PER_VENTRY &&    	     pSrc < pNamePtr->pName + pNamePtr->nameLen;    	     pSrc ++, chNum ++ )    	    {    	    if( dosVDirCharEncode( pSrc, pDst + chOffsets[ chNum ],    	    			   longNamesChar ) == ERROR )    	    	{    	    	goto error;    	    	}    	    }    	        /* fill extra characters in last entry with 0xff */    	    	for( chNum ++; chNum < CHAR_PER_VENTRY; chNum ++ )    	    {    	    assert( pSrc >= pNamePtr->pName + pNamePtr->nameLen );    	        	    *(pDst + chOffsets[ chNum ]) = 0xff;    	    *(pDst + chOffsets[ chNum ] + 1) = 0xff;    	    }    	}        /* mark last entry */        pDst += DOS_DIRENT_STD_LEN;    *pDst |= DOS_VLAST_ENTRY;            return numEnt + 1;error:    errnoSet( S_dosFsLib_ILLEGAL_NAME );    return (-1);    } /* dosVDirNameEncode() */    /***************************************************************************** dosVDirClastNext - get next or add and init cluster to directory.** RETURNS: OK or ERROR if end of directory is reached or* no more cluster could be allocated or disk is full.*/LOCAL STATUS dosVDirClastNext    (    DOS_FILE_DESC_ID	pFd,    u_int	alloc	/* 0 or DH_ALLOC */    )    {    block_t	sec;	/* work count */        /* get next/allocate cluster */        alloc = ( alloc == 0 )? FAT_NOT_ALLOC : FAT_ALLOC_ONE;    if( pFd->pVolDesc->pFatDesc->getNext( pFd, alloc ) == ERROR )    	return ERROR;        assert( pFd->pFileHdl->startClust != 0 );        if( alloc == FAT_NOT_ALLOC )    	return OK;        /* init cluster */    for( sec = pFd->curSec; sec < pFd->curSec + pFd->nSec;         sec ++ )    	{    	if( cbioIoctl(pFd->pVolDesc->pCbio,			CBIO_CACHE_NEWBLK, (void *)sec ) == ERROR )    	    {    	    return ERROR;    	    }    	}            return OK;    } /* dosVDirClastNext() *//***************************************************************************** dosVDirDirentGet - get bundle directory entry from disk.** This routine reads bundle directory entry from disk. * On this level each entry containing part of long name is accepted* independent of others.** <which> argument defines which entry to get.* This routine can be* used for readdir (<which> = RD_FIRST/RD_CURRENT/RD_NEXT),* in that case <pFd> describes the* directory is being read, or for getting directory entry* corresponding to <pFd> (<which> = FD_ENTRY).** RETURNS: OK or ERROR if directory chain end reached or*  disk access error.*/LOCAL STATUS dosVDirDirentGet    (    DOS_FILE_DESC_ID	pFd,	/* dos file descriptor to fill */    u_char *	pDirEnt,    RDE_OPTION	 which		/* which entry to get */    )    {    DOS_DIR_PDESCR_ID	pDirDesc = (void *)pFd->pVolDesc->pDirDesc;    DOS_DIR_HDL_ID	pDirHdl = (void *)&(pFd->pFileHdl->dirHdl);    int			dirEntSize = pDirDesc->deDesc.dirEntSize;    DOS_FILE_DESC	workFd;        /* prepare to operation */        if( which == FD_ENTRY ) /* get directory entry of file */    	{    	DBG_MSG( 600, "pFd = %p, FD_ENTRY\n", pFd ,0,0,0,0,0,0,0);    	/*    	 * it is being read directory entry of the file/dir,    	 * pointed by file descriptor.    	 * Prepare working fd.    	 */    	workFd = *pFd;    	workFd.curSec = pDirHdl->sector;    	workFd.pos = pDirHdl->offset;    	workFd.cbioCookie = pDirHdl->cookie;    	    	goto getEntry;    	}        /* readdir */        if(  which == RD_CURRENT )	/* read current dir entry */    	{    	assert( pFd->nSec != 0 );    	assert( pFd->curSec != 0 );    	    	goto getEntry;    	}        if( which == RD_FIRST )	/* read start dir entry */    	{    	DBG_MSG( 600, "pFd = %p, RD_FIRST\n", pFd ,0,0,0,0,0,0,0);    	dosVDirRewindDir( pFd );	/* rewind directory */    	}    else if( which == RD_NEXT )	/* read next dir entry */    	{    	DBG_MSG( 600, "pFd = %p, RD_NEXT\n", pFd ,0,0,0,0,0,0,0);    	assert( pFd->curSec != 0 );    	    	/* correct position */    	    	pFd->pos += dirEntSize;    	    	/* check for sector bounds */    	    	if( OFFSET_IN_SEC( pFd->pVolDesc, pFd->pos ) == 0 )    	    {    	    pFd->curSec++;    	    pFd->nSec--;    	    }    	}    else	/* impossible flag */    	{    	assert( which != which );    	}     	    /* may be contiguous block finished - get next contiguous block */    	        if( pFd->nSec == 0 )    	{    	if( pFd->pVolDesc->pFatDesc->getNext(    	    			pFd, FAT_NOT_ALLOC ) == ERROR )    	    {    	    return ERROR;    	    }    	pFd->cbioCookie = NULL;	/* we jumped to other sector */    	}        workFd = *pFd;    getEntry:    /* read directory entry */        if( cbioBytesRW(workFd.pVolDesc->pCbio, workFd.curSec,    		    OFFSET_IN_SEC( workFd.pVolDesc, workFd.pos ),		    (addr_t)pDirEnt, dirEntSize, CBIO_READ,    		    &workFd.cbioCookie ) == ERROR )    	{    	return ERROR;    	}    DBG_PRN_STR( 600, "entry: %s\n", pDirEnt,    		 pDirDesc->deDesc.nameLen + pDirDesc->deDesc.extLen,0 );    		     return OK;    } /* dosVDirDirentGet() *//***************************************************************************** dosVDirDeStore - store some contiguous fields of directory entry.** This routine stores <nBytes> pointed by <pData> starting* from offset <offset> in directory entry is currently* pointed by <pFd> or next to this one, depending on* the <which> argument.* * <which> can be one of PUT_CURRENT or PUT_NEXT bitwise or-ed with* DH_ALLOC, if new directory entry is being created.** RETURNS: OK or ERROR if write error occurred.*/LOCAL STATUS dosVDirDeStore    (    DOS_FILE_DESC_ID	pFd,	/* directory descriptor */    off_t	offset,	/* offset in directory entry */    size_t	nBytes,	/* num of bytes to write */    void *	pData,	/* ptr to data buffer */    u_int	which	/* (PUT_CURRENT or PUT_NEXT) ored with */    			/* DH_ALLOC */    )    {    DOS_VOLUME_DESC_ID	pVolDesc = pFd->pVolDesc;        if( (which & PUT_NEXT) != 0 )    	{    	pFd->pos += DOS_DIRENT_STD_LEN;    	if( OFFSET_IN_SEC( pFd->pVolDesc, pFd->pos ) == 0 )    	    {    	    pFd->curSec ++;    	    pFd->nSec --;    	    }    	}        if( pFd->nSec == 0 )	/* current cluster group exhausted */    	{    	if( dosVDirClastNext( pFd, (which & DH_ALLOC) ) == ERROR )    	    return ERROR;    	}        /* store data */        if( cbioBytesRW( pVolDesc->pCbio, pFd->curSec,                     OFFSET_IN_SEC( pVolDesc, pFd->pos ) + offset,    		pData, nBytes, CBIO_WRITE, &pFd->cbioCookie ) == ERROR )    	{    	return ERROR;    	}        return OK;    } /* dosVDirDeStore() *//***************************************************************************** dosVDirEntryDel - mark long name as deleted.* * This routine marks <nEnt> traditional directory entries as deleted.* Entries are started from position is pointed by <pLnPtr>.** RETURNS: OK or ERROR if disk access failed.*/LOCAL STATUS dosVDirEntryDel    (    DOS_VOLUME_DESC_ID	pVolDesc,/* dos volume descriptor */    DIRENT_PTR_ID	pLnPtr,	/* long name start ptr */    u_int		nEnt,	/* number of entries to mark as deleted */    				/* 0 - to accept the number from disk */    BOOL		always	/* delete independent of is check disk */    				/* in progress or not */    )    {    DOS_DIR_PDESCR_ID	pDirDesc;    DOS_FILE_DESC	workFd = {0};	/* temporary file descriptor */    DOS_FILE_HDL	workFileHdl; /* temporary file handle */    u_char	dirent[ DOS_DIRENT_STD_LEN ]; /* directory entry buffer */    cookie_t	cookie = NULL;		/* temp buffer */    u_int	which;        if( ! always && pVolDesc->chkLevel <= DOS_CHK_ONLY )    	return OK;        pDirDesc = (void *)pVolDesc->pDirDesc;    bzero( (char *)&workFileHdl, sizeof( workFileHdl ) );    workFd.pVolDesc = pVolDesc;    workFd.pFileHdl = &workFileHdl;    workFd.curSec = pLnPtr->sector;    workFd.pos = pLnPtr->offset;    workFileHdl.startClust = NONE;	/* don't care */        if( workFd.curSec < pVolDesc->dataStartSec )    	{	/* old root */    	workFd.nSec = pVolDesc->dataStartSec - workFd.curSec;    	}    else if( pVolDesc->pFatDesc->seek(    				&workFd, workFd.curSec, 0 ) == ERROR )        {        assert( FALSE );        return ERROR;        }        /* get number of entries per long name */        if( nEnt == 0 )    	{        if( cbioBytesRW(pVolDesc->pCbio, workFd.curSec,		OFFSET_IN_SEC( pVolDesc, workFd.pos ),    		(addr_t)dirent, DOS_DIRENT_STD_LEN, 		CBIO_READ, &cookie ) == ERROR )    	    {    	    return ERROR;    	    }    	    	assert( dirent[ pDirDesc->deDesc.atrribOff ] == DOS_ATTR_VFAT );    	    	nEnt = ( *dirent & VFAT_ENTNUM_MASK ) + 1 /* include alias */;    	}        /* mark all directory entries */        *dirent = DOS_DEL_MARK;    for( which = PUT_CURRENT; nEnt > 0; nEnt --, which = PUT_NEXT )    	{    	if( dosVDirDeStore( &workFd, 0, 1, &dirent, which ) == ERROR )    	    {    	    return ERROR;    	    }    	}        return OK;    } /* dosVDirEntryDel() */    /***************************************************************************** dosVDirFullEntGet - get VFAT full directory entry from disk.** This routine reads entry out of directory pointed by <pFd>. * It puts into buffer <pEntry> full long name and alias.* Invalid entries (with inconsistent checksum and so on)* are usually passed, but deleted if check disk is in progress.** <which> argument defines which entry to get and may be* RD_FIRST, RD_CURRENT and RD_NEXT.** RETURNS: OK or ERROR if directory chain end reached.*/LOCAL STATUS dosVDirFullEntGet    (    DOS_FILE_DESC_ID	pFd,	/* dos file descriptor to fill */    u_char *		pEntry,    RDE_OPTION	 	which,	/* which entry to get */    DIRENT_PTR_ID	pLnPtr,	/* to fill with long name start ptr */    u_int *		nEntries /* entries counter in directory */    )    {    DOS_DIR_PDESCR_ID	pDirDesc = (void *)pFd->pVolDesc->pDirDesc;    STATUS	status = ERROR;    u_char *	pDst = pEntry;	/* current destination position */    int	entNum = NONE;		/* expected sequence number of */    				/* current entry per long name */    int	numEnt = 0;		/* number of entries per long name */    u_char	chkSum = 0;	/* alias checksum */    u_char	atrribOff = pDirDesc->deDesc.atrribOff;

⌨️ 快捷键说明

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