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

📄 dosvdirlib.c

📁 vxworks操作系统的文件系统部分原代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    		 pDirDesc->deDesc.nameLen + pDirDesc->deDesc.extLen,0 );    return retVal;    error:    bzero( (char *)pDstBuf, DOS_DIRENT_STD_LEN );    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() */    /***************************************************************************** dosVDirClustNext - 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 dosVDirClustNext    (    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);    } /* dosVDirClustNext() *//***************************************************************************** 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 = (cookie_t) 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( dosVDirClustNext( 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 = (cookie_t) NULL;		/* temp buffer */    u_int	which;        if( ! always && pVolDesc->chkLevel <= DOS_CHK_ONLY )    	return OK;#if TRUE /* SPR#70968 fix enabled */    /*      * 01o,09nov01,jkf  SPR#70968, chkdsk destroys boot sector      *     * When chkdsk() is in repair mode(DOS_CHK_REPAIR): it can     * destroy the boot sector's first byte (sector 0, offset 0)      * by writing DOS_DEL_MARK(0xe5). The cause of the problem is     * function dosVDirEntryDel() lacks a sanity check for     * pLnPtr->sector being zero.     *     * Workaround:     *      * Add an "if" statement to check if pLnPtr is illegal:      *      * if( ! always && pVolDesc->chkLevel <= DOS_CHK_ONLY )     *     return OK;         *     * /@ SPR#70968: check if pLnPtr is illegal @/     *     * if ( 0 == pLnPtr->sector )      *     return ERROR;      */    if ( 0 == pLnPtr->sector )         {        /* return ERROR if long name start pointer is from 0 sector */        return (ERROR);        }#endif /* SPR#70968 fix enabled */    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 */    

⌨️ 快捷键说明

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