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

📄 cdromfslib.c

📁 the vxworks system kernel souce packeg.there may be something you need .
💻 C
📖 第 1 页 / 共 5 页
字号:
    u_char **	ppPT,		/* address of ptr to current record */    				/* within buffer, containing PT */    u_long	offset,		/* offset of current record from PT start */    u_long	PTSize		/* path table size (stored in volume */    				/* descriptor */    )    {    short	size;	/* current PT record size */    /* skip current PT record */    PT_REC_SIZE(size, *ppPT);    offset += size;    *ppPT += size;    /*      * set of zero bytes may follow PT record, if that is last record in LB.     * First non zero byte starts next record     */    for (; offset < PTSize; offset ++, *ppPT += 1)	if (**ppPT != 0)	    break;    return (offset);    }/********************************************************************************* cdromFsShiftCount - count shift for transfer <source> to <dest>.** This routine takes two values, that are power of two and counts* the difference of powers, which is, for instance, the number of* bits to shift <source> in order to get <dest>.* Because <dest> may be less, than <source>, (-1) may not be* used as error indication return code, so an impossible value of* 100 is taken for this purpose.** ERRNO: S_cdromFsLib_ONE_OF_VALUES_NOT_POWER_OF_2.** RETURNS: number of bits to shift <source>, in order to get <dest>* or a value of (100) if it is impossible to calculate shift count.*/LOCAL u_char cdromFsShiftCount    (    u_long	source,    u_long	dest    )    {    u_char	i;    if (source <= dest)	{	for (i = 0; i < sizeof (u_long) * 8; i++)	    if ((source << i) == dest)		return i;	}    else	/* source > dest */	{	for (i = 1; i < sizeof (u_long) * 8; i++)	    if ((source >> i) == dest)		return (-i);	}        errnoSet (S_cdromFsLib_ONE_OF_VALUES_NOT_POWER_OF_2);    return (100);    }/********************************************************************************* cdromFsVDAddToList - add VD to VD list.** Allocate VD list structure, fill in its fields (from <pVDData> buffer)* and add to VD list.** RETURNS: OK or ERROR if any failed.*/LOCAL STATUS cdromFsVDAddToList    (    CDROM_VOL_DESC_ID	pVolDesc,    u_char *	pVDData,		/* data, has been got from disk */    u_int	VDPseudoLBNum,		/* LB number, contains given VD, */    					/* if let (LB size = VD size) */    u_char	VDSizeToLSSizeShift	/* relation between VD size */    					/* and LS size */    )    {    T_CDROMFS_VD_LST_ID	pVDList;    assert (pVolDesc != NULL);    assert (pVDData != NULL);    pVDList = malloc (sizeof (T_CDROMFS_VD_LST));    if (pVDList == NULL)	return (ERROR);	    bzero((u_char *) pVDList, sizeof (T_CDROMFS_VD_LST));        pVDList->pVolDesc = pVolDesc;        C_BUF_TO_LONG (pVDList->volSize, pVDData, ISO_VD_VOL_SPACE_SIZE);        /* since PT is stored in memory, max PT size is restricted */    C_BUF_TO_LONG (pVDList->PTSize, pVDData, ISO_VD_PT_SIZE);    if (pVDList->PTSize > CDROM_LIB_MAX_PT_SIZE)        {        errnoSet (S_cdromFsLib_SUCH_PATH_TABLE_SIZE_NOT_SUPPORTED);        free (pVDList);    	return (ERROR);    	}        C_BUF_TO_LONG (pVDList->PTStartLB, pVDData, ISO_VD_PT_OCCUR);    C_BUF_TO_LONG (pVDList->rootDirSize, pVDData,		   ISO_VD_ROOT_DIR_REC + ISO_DIR_REC_DATA_LEN);    C_BUF_TO_LONG (pVDList->rootDirStartLB, pVDData,		   ISO_VD_ROOT_DIR_REC + ISO_DIR_REC_EXTENT_LOCATION);    C_BUF_TO_SHORT (pVDList->volSetSize, pVDData, ISO_VD_VOL_SET_SIZE);    C_BUF_TO_SHORT (pVDList->volSeqNum, pVDData, ISO_VD_VOL_SEQUENCE_N);    C_BUF_TO_SHORT (pVDList->LBSize, pVDData, ISO_VD_LB_SIZE);    pVDList->LBToLSShift = cdromFsShiftCount (pVDList->LBSize,					      pVolDesc->sectSize);        pVDList->type	= ((T_ISO_VD_HEAD_ID)pVDData)->type;    pVDList->fileStructVersion	= *(pVDData + ISO_VD_FILE_STRUCT_VER);    pVDList->VDInSector	= VDPseudoLBNum >> VDSizeToLSSizeShift;    pVDList->VDOffInSect	= LAST_BITS (VDPseudoLBNum,					     VDSizeToLSSizeShift) *				  ISO_VD_SIZE;    /*      * read PT to buffer and init dirLevBorders...[].     * In accordance with ISO9660 all directories records in     * PT are sorted by hierarchy levels and are numbered from 1.     * (only root has number 1 and lays on level 1).     * Number of levels restricted to 8.     * dirLevBordersOff[ n ] contains offset of first PT record on level     * (n+2) (root excluded and array encounted from 0) from PT start.     * dirLevLastRecNum[ n ] contains number of last PT record on level     * (n+2).     * Base of algorithm:     * Storing number of last PT rec on hierarchy level <n> in     * <prevLevLastRecNum>, will skip level <n+1>, on which all     * directories have parent only within n; first directory     * which parent dir number exceeds <prevLevLastRecNum>     * starts level n+2.     */    {    u_char * pPT;    u_int	 offset,		/* absolute offset from PT start */	         level,	        	/* hierarchy level (minus 2) */          	 prevLevLastRecNum,	/* number of last PT rec on */        				/* previous hierarchy level */        	 prevRecNum ;		/* previous PT record number */        pPT = cdromFsPTGet (pVDList, NULL);    if (pPT == NULL)	{	free (pVDList);	return (ERROR);	}        /*      * pass over root dir entry, dir hierarchy level 1;     * root dir record is first PT record and its number is 1     */        offset = cdromFsNextPTRec (&pPT, 0, pVDList->PTSize);        level = 0;	/* not put to array data for root directory */    prevRecNum = 1;	/*  root number in PT */    prevLevLastRecNum = 1;    bzero ((u_char *)(pVDList->dirLevBordersOff),	   sizeof(pVDList->dirLevBordersOff));    bzero ((u_char *)(pVDList->dirLevLastRecNum),	   sizeof(pVDList->dirLevLastRecNum));        /*      * over this loop all dir hierarchy levels' bounds in PT     * will be found.     */        pVDList->dirLevBordersOff[0] = offset;    for(; offset < pVDList->PTSize && level < CDROM_MAX_DIR_LEV - 1;)	{	u_int prev;	/* parent dir number for current record */		PT_PARENT_REC (prev, pPT);#ifdef	DEBUG	/* debugging */		DBG_COP_TO_BUF(pPT + ISO_PT_REC_DI, *pPT);	DBG_MSG(200)("%4d\t%20s\tparent # %3d, D_ID_LEN %2d  level %d\n",		     prevRecNum + 1, dbgvBuf, (int)prev, (int)*pPT,		     level + 2);#endif		/* if directory level overed */    	    	if(prev > prevLevLastRecNum)	    {	    /* close level */	    	    pVDList->dirLevLastRecNum[level] = prevRecNum;	    	    level++;	    if (level > CDROM_MAX_DIR_LEV - 1)		break;	    	    /* current level first record offset within PT */	    	    pVDList->dirLevBordersOff[level] = offset;	    prevLevLastRecNum = prevRecNum;	    }		prevRecNum ++;		offset = cdromFsNextPTRec (&pPT, offset, pVDList->PTSize);	}        /* close last level */        pVDList->dirLevLastRecNum[level] = prevRecNum;        /*      * may be loop breaking only because CDROM_MAX_DIR_LEV overloading     * before fully PT exhausting, that is an error     */        if (offset < pVDList->PTSize)	{	free (pVDList);	errnoSet (S_cdromFsLib_MAX_DIR_HIERARCHY_LEVEL_OVERFLOW);	return (ERROR);	}        pVDList->numDirLevs = level + 1;       /* <level> starts from 0 */    pVDList->numPTRecs = prevRecNum;    }  /* hierarchy bounds init */        /* VD have been built. Add it to VD list */        pVDList->magic = VD_LIST_MAG;        lstAdd  (&(pVolDesc->VDList), (NODE *)pVDList);    return (OK);    }/********************************************************************************* cdromFsVolUnmount - mark in all device depends data, that volume unmounted.* * All volume descriptors are deallocated.* FDList not deallocated, but only marked as "file unaccessible.** RETURN: N/A*/LOCAL void cdromFsVolUnmount    (    CDROM_VOL_DESC_ID	pVolDesc  /* cdrom volume decriptor id */    )    {    T_CDROM_FILE_ID	pFDList;    T_CDROMFS_VD_LST_ID	pVDList;    assert (pVolDesc != NULL);    assert (pVolDesc->mDevSem != NULL);    if (pVolDesc->unmounted)    	return;    	    if (semTake(pVolDesc->mDevSem, WAIT_FOREVER) == ERROR)	return;	    /* free VD list with PT buffers */    for (pVDList = (T_CDROMFS_VD_LST_ID)lstFirst(&(pVolDesc->VDList));	 pVDList != NULL;	 pVDList = (T_CDROMFS_VD_LST_ID)lstNext((NODE *)pVDList))	{	cdromFsSectBufFree(&(pVDList->PTBuf));	}	    lstFree (&(pVolDesc->VDList));    /* mark all opened  files as unaccessible */        for (pFDList = (T_CDROM_FILE_ID)lstFirst(&(pVolDesc->FDList));	 pFDList != NULL;	 pFDList = (T_CDROM_FILE_ID)lstNext((NODE *)pFDList))	{	pFDList->volUnmount = 1;	}        /* mark in VD, that volume unmounted */    pVolDesc->unmounted = 1;    if (semGive(pVolDesc->mDevSem) == ERROR)	errnoSet (S_cdromFsLib_SEMGIVE_ERROR);    }/********************************************************************************* cdromFsVolMount - mount cdrom volume.** This routine reads volume descriptors and creates VD list.** ERRNO: S_cdromFsLib_UNNOWN_FILE_SYSTEM or any errno may be set by* supplementary functions (such as malloc).** RETURNS: OK or ERROR*/LOCAL STATUS cdromFsVolMount    (    CDROM_VOL_DESC_ID	pVolDesc  /* cdrom volume decriptor id */    )    {    T_CDROMFS_VD_LST	VDList;        /* volume descriptor list  */    u_long      	LBRead;        /* logical blk to read     */    u_char	        VDLast = 0;    u_char              primVDMounted; /* primary VD mounted flag */    assert (pVolDesc != NULL);    assert (pVolDesc->mDevSem != NULL);    /* private semaphore */    if (semTake (pVolDesc->mDevSem, WAIT_FOREVER) == ERROR)	return ERROR;    /* before mount new volume, it have to unmount previous */    if (! pVolDesc->unmounted)	cdromFsVolUnmount (pVolDesc);    pVolDesc->pBlkDev->bd_readyChanged = FALSE;    /*      * before VD was read let LB size equal to VD size, since     * each VD defines its own LB size. Because VD size and LS size are     * powers of 2, one may be get from second by means of shift.     */    VDList.LBSize = ISO_VD_SIZE;    VDList.LBToLSShift = cdromFsShiftCount (ISO_VD_SIZE, pVolDesc->sectSize);    VDList.pVolDesc = pVolDesc;        /* data in buffer remain from unmounted volume, so invalid */    LET_SECT_BUF_EMPTY (&(VDList.pVolDesc->sectBuf));        /* no one primary VD was found yet */    primVDMounted = 0;    /* by ISO, first volume descriptor always lays in ISO_PVD_BASE_LS */    for (LBRead = ISO_PVD_BASE_LS << VDList.LBToLSShift; ! VDLast ; LBRead ++)	{	u_char *	pVDData;	/* read VD from disk */	pVDData = cdromFsGetLB (&VDList, LBRead, NULL);		if (pVDData == NULL)	    {	    cdromFsVolUnmount (pVolDesc);	    semGive (pVolDesc->mDevSem);	    return ERROR;	    }		/* check standard ISO volume ID */	if (strncmp(((T_ISO_VD_HEAD_ID)pVDData)->stdID, ISO_STD_ID ,		    ISO_STD_ID_SIZE))	    {	    /* not ISO volume ID */	   	    /*	     * may be any unknown VD in set, but not first, that must be	     * ISO primary VD only (at least in current version)	     */	    if (primVDMounted)	/* primary have been found already */		continue;	    else		{		cdromFsVolUnmount (pVolDesc);	        semGive (pVolDesc->mDevSem);		logMsg ("Warning: unknown CR-ROM format detected, ignored.\n",			0,0,0,0,0,0);		errnoSet (S_cdromFsLib_UNNOWN_FILE_SYSTEM);		return ERROR;		}	    } /* check VD ID */	/* 	 * only VD set termination, primary and supplementary VD are 	 * interesting; and not process secondary copies of primary VD	 */	if (((T_ISO_VD_HEAD_ID)pVDData)->type == ISO_VD_SETTERM)	    VDLast = 1;	else if ((((T_ISO_VD_HEAD_ID)pVDData)->type == ISO_VD_PRIMARY &&		  ! primVDMounted) ||		 ((T_ISO_VD_HEAD_ID)pVDData)->type == ISO_VD_SUPPLEM)	    {	    /* first VD on volume must be primary (look ISO 9660) */	    	    if (((T_ISO_VD_HEAD_ID)pVDData)->type == ISO_VD_SUPPLEM &&		! primVDMounted)		{		cdromFsVolUnmount (pVolDesc);	        semGive (pVolDesc->mDevSem);		logMsg ("Warning: unknown CR-ROM format detected, ignored.\n",			0,0,0,0,0,0);		errnoSet (S_cdromFsLib_UNNOWN_FILE_SYSTEM);		return ERROR;		}			    if (cdromFsVDAddToList (pVolDesc, pVDData, LBRead,				    VDList.LBToLSShift) == ERROR)	        {	        cdromFsVolUnmount (pVolDesc);	        semGive (pVolDesc->mDevSem);	        return ERROR;	        }	        	    /* if primary VD found in VD set */	    	    if (((T_ISO_VD_HEAD_ID)pVDData)->type == ISO_VD_PRIMARY)	        primVDMounted = 1;		    } /* else if */	} /* for */        /* each volume contains at least one, primary volume descriptor. */        if (lstFirst(&(pVolDesc->VDList)) == NULL)

⌨️ 快捷键说明

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