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

📄 dosvdirlib.c

📁 vxworks操作系统的文件系统部分原代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    	}    	    /* check result */        if( status == ERROR )    	{    	goto ret;    	}    status = ERROR;        /* *pDiskName == LAST_DIRENT */        if( IS_ROOT( pFd ) &&    	nEntries + nEntInName > pDirDesc->rootMaxEntries )        {    	goto ret;    	}        /* will create new entry on this place, if required */        if( pFreeEnt->sector == 0 )    	{    	pFreeEnt->deNum = nEntries;    	pFreeEnt->sector = pFd->curSec;    	pFreeEnt->offset = pFd->pos;    	}ret:    if( status != ERROR ) /* file found; fill file descriptor */    	{    	dosVDirFillFd( pFd, pDiskName + aliasOff, &lnPtr );    	}    *pFreeEntLen = freeChankLen; /* Return numbers of free ents */        semGive( pDirDesc->bufSem );    return status;     } /* dosVDirLkupInDir() */    /***************************************************************************** dosVDirAliasCreate - create alias for long file name.** This routine takes 1 first byte of file name and expands it* with ~ and 6 decimal digits of sequence number of alias's* entry in directory. Then it takes three characters of long name* following last dot symbol and puts them to alias extension.** RETURNS: N/A.*/LOCAL void dosVDirAliasCreate    (    DOS_DIR_PDESCR_ID	pDirDesc,    PATH_ARRAY_ID	pNamePtr,    u_char *	pAlias,	/* dst alias */    u_int	entNum	/* empty entry in directory */    )    {    u_char *	pSrc;	/* loop pointer to src name */    u_char *	pDst;	/* loop pointer to dst alias */    char	entNumBuf[ DOS_STDNAME_LEN + DOS_STDEXT_LEN + 1 ];        entNum =  1000000 - entNum % 1000000;        bfill( (char *)pAlias, DOS_STDNAME_LEN + DOS_STDEXT_LEN, SPACE );        pSrc = pNamePtr->pName;    pDst = pAlias;        /* pass top dots in name */        for( ; *pSrc == DOT; pSrc ++ );    assert( *pSrc != EOS );    for( ; *pSrc != DOT  &&           pSrc != pNamePtr->pName + pNamePtr->nameLen &&           pDst != pAlias + DOS_STDNAME_LEN;    	 pSrc++, pDst++ )    	{    	if( dosVDirCharEncode( pSrc, pDst, shortNamesChar ) == ERROR )    	    break;    	}    	     /* encode directory entry number */        sprintf( entNumBuf, "%c%u", TILDA, entNum );    entNum = strlen( entNumBuf );        if( pDst > pAlias + DOS_STDNAME_LEN - entNum )    	pDst = pAlias + DOS_STDNAME_LEN - entNum;        bcopy( entNumBuf, (char *)pDst, entNum );        /* === extension === */        pDst = pAlias + DOS_STDNAME_LEN;        /* find last DOT */        for( pSrc = pNamePtr->pName + pNamePtr->nameLen - 1;         pSrc != pNamePtr->pName && *pSrc != DOT; pSrc -- );        /* encode 3 extension characters */        if( pSrc == pNamePtr->pName )    	return;	/* no extension */        /* *pSrc == DOT */        for( pSrc++;    	 pDst != pAlias + DOS_STDNAME_LEN + DOS_STDEXT_LEN &&    	 pSrc != pNamePtr->pName + pNamePtr->nameLen;    	 pSrc++, pDst++ )    	{    	if( dosVDirCharEncode( pSrc, pDst, shortNamesChar ) == ERROR )    	    {    	    *pDst = SPACE;    	    break;    	    }    	}    DBG_PRN_STR( 700, "result: %s\n", pAlias,     		 pDirDesc->deDesc.nameLen + pDirDesc->deDesc.extLen,0 );    } /* dosVDirAliasCreate() */#ifdef	__unused__/***************************************************************************** dosVDirFullDeUpdate - update fields in long name directory entries.** This routine deletes full long name entry or updates.** RETURNS: OK or ERROR if disk write error occurred.*/LOCAL STATUS dosVDirFullDeUpdate    (    DOS_FILE_DESC_ID	pFd,	/* directory descriptor */    u_int	operation	/* DH_DELETE */    )    {    DOS_VOLUME_DESC_ID	pVolDesc = pFd->pVolDesc;    DOS_FILE_DESC	workFd = {0};	/* temporary file descriptor */    DOS_FILE_HDL	workFileHdl; /* temporary file handle */    UINT32	value = 0; /* start cluster number in disk format */    STATUS	st = ERROR;    u_char	nEnt;	/* entries per long name */    u_char	fieldOff = 0, fieldLen = 0;        if( operation == DH_DELETE )    	{    	fieldOff = 0;    	fieldLen = 1;    	*(u_char *)&value = DOS_DEL_MARK;    	}    else    	{    	assert( FALSE );    	}    /* init file descriptor */        bzero( (char *)&workFileHdl, sizeof( workFileHdl ) );    workFd.pVolDesc = pVolDesc;    workFd.pFileHdl = &workFileHdl;    workFd.pFileHdl->startClust =     			pFd->pFileHdl->dirHdl.parDirStartCluster;        /* get number of entries per long name */        if( pFd->pFileHdl->dirHdl.lnSector == 0 )    	{	/* short name only */    	nEnt = 0;    	workFd.curSec = pFd->pFileHdl->dirHdl.sector;    	workFd.pos = pFd->pFileHdl->dirHdl.offset;    	}    else	/* long name */    	{    	workFd.curSec = pFd->pFileHdl->dirHdl.lnSector;    	workFd.pos = pFd->pFileHdl->dirHdl.lnOffset;    	        if( cbioBytesRW(    		pVolDesc->pCbio, workFd.curSec,		OFFSET_IN_SET( pVolDesc, workFd.pos ),    		&nEnt, 1, CBIO_READ, NULL ) == ERROR )    	    {    	    return ERROR;    	    }        if( (nEnt & DOS_VLAST_ENTRY) == 0 )    	    {    	    ERR_MSG(10, "Long name terminating flag missing\n", 0,0,0,0 );    	    return ERROR;    	    }    	}            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;        }        /* update all directory entries */        for( nEnt = (nEnt & VFAT_ENTNUM_MASK),         (st = dosVDirDeStore( &workFd, fieldOff, fieldLen, &value,         		       PUT_CURRENT ));         st != ERROR && nEnt > 0; nEnt -- )    	{    	st = dosVDirDeStore( &workFd, fieldOff, fieldLen, &value,         		     PUT_NEXT );         }    return st;    } /* dosVDirFullDeUpdate() */#endif /* __unused__ *//***************************************************************************** dosVDirUpdateEntry - set new directory entry contents.** This routine pulls file size, attributes and so on out of* file descriptor and stores it in the correspondence directory* entry.* * This function is also used for entry deletion. In this* case <flags> have to be set to DH_DELETE.** Time value provided in <curTime> can be encoded into appropriate* fields within directory entry structure in accordance with* <flags> argument. <flags> can be or-ed of* DH_TIME_CREAT, DH_TIME_MODIFY or DH_TIME_ACCESS.* If <curTime> is 0, current system time is used.** RETURNS: OK or ERROR if name is invalid or disk access error occurred.**/LOCAL STATUS dosVDirUpdateEntry    (    DOS_FILE_DESC_ID	pFd,    u_int		flags,    time_t		curTime		/* time to encode */    )    {    DOS_DIR_PDESCR_ID	pDirDesc = (void *)pFd->pVolDesc->pDirDesc;    u_char	dirent[ DOS_DIRENT_STD_LEN ]; /* directory entry buffer */        curTime = ( curTime == 0 )? time( NULL ) : curTime;        /* root directory has not its own entry */        if( IS_ROOT( pFd ) )    	{    	if( (flags & DH_TIME_MODIFY) != 0 )    	    pDirDesc->rootModifTime = curTime;    	else    	    assert( (flags & DH_TIME_MODIFY) != 0 );    	    	return OK;    	}        if( flags & DH_DELETE )	/* delete entry */    	{    	DIRENT_PTR	dePtr;    	u_int	nEnt = 0;    	    	if( pFd->pFileHdl->dirHdl.lnSector == 0 )    	    {	/* short name only */    	    dePtr.sector = pFd->pFileHdl->dirHdl.sector;    	    dePtr.offset = pFd->pFileHdl->dirHdl.offset;    	    nEnt = 1;    	    }    	else	/* long name */    	    {    	    dePtr.sector = pFd->pFileHdl->dirHdl.lnSector;    	    dePtr.offset = pFd->pFileHdl->dirHdl.lnOffset;    	    }    	        	return dosVDirEntryDel( pFd->pVolDesc, &dePtr, nEnt, TRUE );    	}        /* get directory entry */        if( dosVDirDirentGet( pFd, dirent, FD_ENTRY ) == ERROR )    	return ERROR;        /*     * encode other fields, but also start cluster, because entire     * directory entry will be stored     */    START_CLUST_ENCODE( &pDirDesc->deDesc,    		        pFd->pFileHdl->startClust,  dirent );    dirent[ pDirDesc->deDesc.atrribOff ] = pFd->pFileHdl->attrib;    VX_TO_DISK_32( pFd->pFileHdl->size,    		   dirent + pDirDesc->deDesc.sizeOff );    if( pDirDesc->deDesc.extSizeOff != (u_char) NONE )    	{    	EXT_SIZE_ENCODE( &pDirDesc->deDesc, dirent, pFd->pFileHdl->size );    	}        dosVDirTDEncode( pDirDesc, dirent, flags, curTime );        /* store directory entry */    return cbioBytesRW( pFd->pVolDesc->pCbio, pFd->pFileHdl->dirHdl.sector,    		OFFSET_IN_SEC( pFd->pVolDesc, pFd->pFileHdl->dirHdl.offset ),		(addr_t)dirent, pDirDesc->deDesc.dirEntSize, CBIO_WRITE,    		&pFd->pFileHdl->dirHdl.cookie );    } /* dosVDirUpdateEntry *//***************************************************************************** dosVDirFileCreateInDir - create new entry in directory.** This routine creates new directory entry in place of* deleted entry. If no deleted entry large enough found in directory,* additional entry created at the directory tail.** <pFreeEnt> must contain a pointer into an appropriate deleted entry in* the directory or into free space in bottom of the directory.* If <pFreeEnt->sector> eq. to 0 indicates,* that no free entries found in directory and* <pFd> reached directory end. In this case one more cluster is* added to directory chain and new file is created in it.** RETURNS: OK or ERROR if new entry can not be created.** ERRNO:* S_dosFsLib_DIR_READ_ONLY* S_dosFsLib_INVALID_PARAMETER* S_dosFsLib_ROOT_DIR_FULL* */LOCAL STATUS dosVDirFileCreateInDir    (    DOS_FILE_DESC_ID	pFd,	/* directory descriptor */    PATH_ARRAY_ID	pNamePtr,    u_int		options,	/* creat flags */    DIRENT_PTR_ID	pFreeEnt,	/* empty entry in directory */    int			freeEntLen	/* Number of contig empty entries in directory */    )    {    DOS_DIR_PDESCR_ID	pDirDesc = (void *)pFd->pVolDesc->pDirDesc;    DOS_DIR_HDL_ID	pDirHdl = (void *)&(pFd->pFileHdl->dirHdl);    cookie_t	cookie;		/* temp buffer */    u_char *	dirent = pDirDesc->nameBuf; /* directory entry buffer */    u_char *	alias;		/* long name alias */    u_int	whichEntry;    u_int	allocFlag;    int numEnt;	/* directory entries per full VFAT entry */    int i;    SHORT_ENCODE	shortNameEncode = STRICT_SHORT;    				/* encodding of short name strategy */    STATUS	retStat = ERROR;    u_char	chkSum = 0;	/* alias checksum */    u_char	parentIsRoot = 0;	/* creation in root */        /* check permissions */        if( pFd->pFileHdl->attrib & DOS_ATTR_RDONLY )    	{    	errnoSet( S_dosFsLib_DIR_READ_ONLY );    	return ERROR;    	}    	    /* only file and directory can be created */        if( !( S_ISREG( options ) || S_ISDIR( options ) ) )    	{    	errnoSet( S_dosFsLib_INVALID_PARAMETER );    	return ERROR;    	}        if( IS_ROOT( pFd ) )    	parentIsRoot = 1;        /* protect buffers */        if( semTake( pDirDesc->bufSem, WAIT_FOREVER ) == ERROR )    	return ERROR;        /* check/encode file name */        numEnt = dosVDirNameEncode( pDirDesc, pNamePtr, dirent,    				&shortNameEncode );    if( numEnt == ERROR )    	goto ret;        /* set alias pointer */        alias = dirent + ( numEnt - 1 ) * DOS_DIRENT_STD_LEN;        /*     * if name can not be directly encoded as short,     * create special alias.      */        if ( *alias ==  EOS )     	{    	assert( alias != dirent );    	dosVDirAliasCreate(    			pDirDesc, pNamePtr, alias, pFreeEnt->deNum + numEnt );    	}    /* encode time fields */        dosVDirTDEncode( pDirDesc, alias,    		     DH_TIME_CREAT | DH_TIME_MODIFY | DH_TIME_ACCESS,    		     time( NULL ) );        /* alias checksum */        chkSum = dosVDirChkSum( alias );        /* use empty entry, that was found during path lkup */        if( pFreeEnt->sector != 0 )    	{    	/* point file descriptor onto the deleted entry position */    	    	if( IS_ROOT( pFd ) && pDirDesc->rootMaxEntries < (u_int)(-1) )    	    {    	    pFd->nSec += pFd->curSec - pFreeEnt->sector;    	    pFd->curSec = pFreeEnt->sector;    	    }    	else if( pF

⌨️ 快捷键说明

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