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

📄 cdromfslib.c

📁 VxWorks操作系统内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    PTSizeLB = ROUND_UP (pVdLst->PTSize, pVdLst->LBSize) / pVdLst->LBSize;    /* if PT already in buffer, following call do nothing */    pPT = cdromFsGetLB (pVdLst, pVdLst->PTStartLB, PTSizeLB, pSecBuf);    return (pPT);    }/***************************************************************************** cdromFsNextPTRec - pass to a next PT record.** As result, *ppPT points to the next PT record.** RETURNS: offset of record from PT start or 0 if last record encounted*/LOCAL u_long cdromFsNextPTRec    (    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)++)	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>.* If <source> <= <dest>, the result is positive and <dest> == <source>* << the result.** If <source> > <dest>, the result is negative and <dest> == <source>* >> - the result.** 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.** 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.** ERRNO: S_cdromFsLib_ONE_OF_VALUES_NOT_POWER_OF_2.*/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 ((dest << i) == source)		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.** ERRNO: S_cdromFsLib_SUCH_PATH_TABLE_SIZE_NOT_SUPPORTED,* S_cdromFsLib_MAX_DIR_HIERARCHY_LEVEL_OVERFLOW,* S_memLib_NOT_ENOUGH_MEMORY*/LOCAL STATUS cdromFsVDAddToList    (    CDROM_VOL_DESC_ID	pVolDesc,    const u_char *	pVDData,	/* data, has been got from disk */#ifdef	CDROMFS_MULTI_SESSION_SUPPORT    u_long	SesiPseudoLBNum,	/* LB number at which session starts */					/* if let (LB size = VD size) */#endif	/* CDROMFS_MULTI_SESSION_SUPPORT */    u_long	VDPseudoLBNum,		/* LB number, contains given VD, */					/* if let (LB size = VD size) */    u_short	uniCodeLev,		/* See T_CDROMFS_VD_LST.uniCodeLev */    u_char	VDSizeToLSSizeShift	/* relation between VD size */					/* and LS size */    )    {    T_CDROMFS_VD_LST_ID pVDList;    assert (pVolDesc != NULL);    assert (pVDData != NULL);    pVDList = KHEAP_ALLOC (sizeof (T_CDROMFS_VD_LST));    if (pVDList == NULL)	return (ERROR);    bzero ((u_char *) pVDList, sizeof (T_CDROMFS_VD_LST));    pVDList->uniCodeLev = uniCodeLev;    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);    C_BUF_TO_LONG (pVDList->PTSizeOnCD, pVDData, ISO_VD_PT_SIZE);    if (pVDList->PTSizeOnCD > CDROM_LIB_MAX_PT_SIZE)	{	errnoSet (S_cdromFsLib_SUCH_PATH_TABLE_SIZE_NOT_SUPPORTED);	KHEAP_FREE ((char *)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);    /*     * ISO-9660 6.2.2 Logical Block     * sizeof(Logical Block) <= sizeof(Logical Sector).     * sizeof(Logical Block) is always a power of 2.     *     * cdromFsLib implementation     * sizeof(Logical Block) = pVDList->LBSize.     * sizeof(Logical Sector) = sizeof(Logical Block) << pVDList->LSToLSShift.     */    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->VDPseudoLBNum	= VDPseudoLBNum;    /*     * 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 for ISO 9660 or 120 for Joliet.     * 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)	{	KHEAP_FREE ((char *)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)("%d. %4d\t%20s\tparent # %3d, D_ID_LEN %2d	 level %d\n",		     __LINE__, prevRecNum + 1, dbgvBuf, (int)prev, (int)*pPT,		     level + 2);#endif	/* DEBUG */	/* 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)	{	KHEAP_FREE ((char *)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.** RETURNS: N/A** ERRNO: S_cdromFsLib_SEMGIVE_ERROR*/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 (semTake (pVolDesc->mDevSem, WAIT_FOREVER) == ERROR)	return;    /*     * mark all opened	files as unaccessible     *     *	SPR#70072  This must be done before the below     *	lstFree (&(pVolDesc->VDList)); so that cdromFsFDFree() does not     *	corrupt memory by removing the FD from that list after the list     *	has already been freed.     */    for (pFDList = (T_CDROM_FILE_ID)lstFirst (&(pVolDesc->FDList));	 pFDList != NULL;	 pFDList = (T_CDROM_FILE_ID)lstNext ((NODE *)pFDList))	{	pFDList->inList = 0;	   /* SPR#70072 */	}    /* 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 in VD, that volume unmounted */    pVolDesc->unmounted = 1;#ifdef	CDROMFS_MULTI_SESSION_SUPPORT    /* for Multisession, set Session to default */    pVolDesc->SesiToRead = DEFAULT_SESSION;#endif	/* CDROMFS_MULTI_SESSION_SUPPORT */    if (semGive (pVolDesc->mDevSem) == ERROR)	errnoSet (S_cdromFsLib_SEMGIVE_ERROR);    assert (lstCount (&(pVolDesc->VDList)) == 0);    }/***************************************************************************** cdromFsVolMount - mount cdrom volume.** This routine reads the volume descriptors and creates VD lists.* This routine checks which CD-Rom mode is set and adds only this VD's* to the list which mode is set. (mode can be Joliet, ISO9660 or AUTO mode)** RETURNS: OK or ERROR** ERRNO: S_cdromFsLib_UNKNOWN_FILE_SYSTEM, S_cdromFsLib_SEMGIVE_ERROR, or* any errno may be set by supplementary functions, for example* S_memLib_NOT_ENOUGH_MEMORY from malloc().*/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	  */#ifdef	CDROMFS_MULTI_SESSION_SUPPORT    u_long		sesStartLB;    /* Session start LB */#endif	/* CDROMFS_MULTI_SESSION_SUPPORT */    u_char		VDLast = 0;    u_char		primVDMounted; /* primary VD mounted flag */    u_char		UCSLevel;      /* which UCS-2 Level is used */    u_char *		pVDData;    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;#ifdef	CDROMFS_MULTI_SESSION_SUPPORT    sesStartLB =#endif	/* CDROMFS_MULTI_SESSION_SUPPORT */

⌨️ 快捷键说明

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