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

📄 cdromfslib.c

📁 VxWorks操作系统内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* allocate sector reading buffer (by default size) */    if (cdromFsSectBufAlloc (pVolDesc, & (pFD->sectBuf), 0) == ERROR)	{	KHEAP_FREE ((char *)pFD);	return (NULL);	}    pFD->inList = 0;		/* FD not included to volume FD list yet */    pFD->magic = FD_MAG;    return (pFD);    }/***************************************************************************** cdromFsFDFree - deallocate a file descriptor structure** This routine deallocates all allocated memory associated with the specified* file descriptor structure.** RETURNS: N/A.*/LOCAL void cdromFsFDFree    (    T_CDROM_FILE_ID	pFD    )    {    pFD->magic = 0;    cdromFsSectBufFree (&(pFD->sectBuf));#ifdef	CDROMFS_MODE_AUTO_COMBINE_VOLUME_DESCRIPTORS    if (pFD->pMultDir != 0)	   /* Moved here from cdromFsClose() */	KHEAP_FREE (pFD->pMultDir);#endif	/* CDROMFS_MODE_AUTO_COMBINE_VOLUME_DESCRIPTORS */    if (pFD->FRecords != NULL)	KHEAP_FREE (pFD->FRecords);    if (pFD->inList)	lstDelete (&(pFD->pVDList->pVolDesc->FDList), (NODE *)pFD);    pFD->inList = 0;    KHEAP_FREE ((char *)pFD);    }/***************************************************************************** cdromFsSectBufAlloc - allocate a buffer for reading volume sectors** This routine is designed to allocate a buffer for reading volume data* by Logical Sectors.  If the <numSectInBuf> parameter is a value greater* than zero, the buffer size is assumed to be equal to <numSectInBuf>* times the sector size.  If you specify a <numSectInBuf> of 0, the buffer* size is CDROM_COM_BUF_SIZE.** The buffer may already have been connected with given control structure.* If one is large enough, but not two, it is just left intact, if not, -* free it.** After use, buffer must be deallocated by means of cdromFsSectBufFree ().** RETURNS: OK or ERROR;** ERRNO: S_memLib_NOT_ENOUGH_MEMORY*/LOCAL STATUS cdromFsSectBufAlloc    (    CDROM_VOL_DESC_ID	pVolDesc,    SEC_BUF_ID	pSecBuf,	/* buffer control structure */				/* to which buffer is connected */    int numSectInBuf		/* LS in buffer */    )    {    assert (pVolDesc != NULL);    assert (pSecBuf != NULL);    numSectInBuf = (numSectInBuf == 0)?	 CDROM_COM_BUF_SIZE: numSectInBuf;    /*     * may be, any buffer has already been connected with given     * control structure. Check its size.     */    if (pSecBuf->magic == SEC_BUF_MAG && pSecBuf->sectData != NULL)	{	if (pSecBuf->maxSects >= numSectInBuf &&	    pSecBuf->maxSects <= numSectInBuf + 1)	    return OK;	pSecBuf->magic = 0;	KHEAP_FREE (pSecBuf->sectData);	}    /* newly init control structure */    LET_SECT_BUF_EMPTY (pSecBuf);    pSecBuf->maxSects	= numSectInBuf;    /* allocation */    pSecBuf->sectData = KHEAP_ALLOC (numSectInBuf * pVolDesc->sectSize);    if (pSecBuf->sectData == NULL)	return ERROR;    pSecBuf->magic = SEC_BUF_MAG;    return (OK);    }/***************************************************************************** cdromFsSectBufAllocBySize - allocate buffer for reading volume.** After use, buffer must be deallocated by means of cdromFsSectBufFree ().* This routine calls cdromFsSectBufAlloc() with sufficient* number of sectors covers <size>.* If <size> == 0, allocated buffer is  1 sector size.** RETURNS: OK or ERROR;*/LOCAL STATUS cdromFsSectBufAllocBySize    (    CDROM_VOL_DESC_ID	pVolDesc,    SEC_BUF_ID	pSecBuf,	/* buffer control structure */				/* to which buffer is connected */    int size			/* minimum buffer size in bytes */    )    {    assert (pVolDesc != NULL);	/* SPR#34659 failed */    assert (pSecBuf != NULL);    return (cdromFsSectBufAlloc (pVolDesc , pSecBuf,				 A_PER_B (pVolDesc->sectSize, size) + 1));    }/***************************************************************************** cdromFsSectBufFree - deallocate volume sector buffer.** RETURNS: N/A*/LOCAL void cdromFsSectBufFree    (    SEC_BUF_ID	pSecBuf		/* buffer control structure */    )    {    assert (pSecBuf != NULL);    if (pSecBuf->magic == SEC_BUF_MAG && pSecBuf->sectData != NULL)	KHEAP_FREE (pSecBuf->sectData);    /* buffer structure is unusable now */    pSecBuf->sectData = NULL;    pSecBuf->magic = 0;    }/***************************************************************************** cdromFsGetLS - read logical sector from volume.** This routine tries to find requested LS in <pSecBuf> and, if failed,* reads sector from device. Number of read sectors equal to buffer size.** RETURNS: ptr on LS within buffer or NULL if error accessing device.** ERRNO: S_cdromFsLib_DEVICE_REMOVED, if CD disk has not been ejected;* or any, may be set by block device driver read function.*/LOCAL u_char * cdromFsGetLS    (    CDROM_VOL_DESC_ID	pVolDesc,    u_long		LSNum,		/* logical sector to get */    u_long		maxLSs,		/* maximum LS to read */    SEC_BUF_ID		pSecBuf		/* sector data control structure, */					/* to put data to */    )    {    assert (pVolDesc != NULL);    assert (pSecBuf->sectData != NULL);    assert (pSecBuf->magic == SEC_BUF_MAG);				/* SPR#75766 Next assert() failed. */    assert (LSNum < pVolDesc->pBlkDev->bd_nBlocks / pVolDesc->LSToPhSSizeMult);    if (maxLSs == 0)	maxLSs = 1;    DBG_MSG(400)("%d. access for sector %lu\n", __LINE__, LSNum);    /* check for disk has not been ejected */    if (pVolDesc->pBlkDev->bd_readyChanged)	{	cdromFsVolUnmount (pVolDesc);	errnoSet (S_cdromFsLib_DEVICE_REMOVED);	return (NULL);	}    /* may be sector already in buffer ('if' for negative condition) */    if (pSecBuf->numSects == 0 ||	LSNum < pSecBuf->startSecNum ||	LSNum >= pSecBuf->startSecNum + pSecBuf->numSects)	{	/* sector not in the buffer, read it from disk */	BLK_DEV * pBlkDev = pVolDesc->pBlkDev;	u_long	  numLSRead;	assert (pBlkDev != NULL);	/*	 * num read sects must not exceed last CD volume sector	 * This is needed to avoid reading off the end of a volume.	 */	numLSRead = min (pBlkDev->bd_nBlocks / pVolDesc->LSToPhSSizeMult -			 LSNum, pSecBuf->maxSects);	/*	 * num read sects must not exceed last allowed read ahead sector	 * This is needed to avoid reading off the end of a file section.	 * On a CD-R those blocks might not be recorded at all.	 */	numLSRead = min (numLSRead, maxLSs);	/* Do the read */	if (pBlkDev->bd_blkRd (pBlkDev, LSNum * pVolDesc->LSToPhSSizeMult,			       numLSRead * pVolDesc->LSToPhSSizeMult,			       pSecBuf->sectData) == ERROR)	    {	    LET_SECT_BUF_EMPTY (pSecBuf);	    DBG_MSG(0)("%d. CDROM ERROR: error reading volume sect"		       " %lu - %lu\a\n",		       __LINE__, LSNum, pSecBuf->numSects);	    return (NULL);	    }	/* successfully read */	pSecBuf->startSecNum = LSNum;	pSecBuf->numSects = numLSRead;	}    return (pSecBuf->sectData +	     (LSNum - pSecBuf->startSecNum) * pVolDesc->sectSize);    }/***************************************************************************** cdromFsGetLB - get logical block** This routine tries to find requested LB in <pSecBuf> and, if it fails,* reads sector, containing the LB from device.* <pSecBuf> is used as sector buffer. If <pSecBuf> is NULL, global* volume buffer is used.** RETURNS: ptr on LB within buffer or NULL if error with set errno* to appropriate value.*/LOCAL u_char * cdromFsGetLB    (    T_CDROMFS_VD_LST_ID pVDList,    u_long	LBNum,			/* logical block to get */    u_long	maxLBs,			/* maximum LB to read */    SEC_BUF_ID	pSecBuf			/* sector data control structure, */					/* to put data to */    )    {    u_int	secNum;		/* LS, contane LB */    u_int	maxLSs;		/* maximum LS to read */    u_char *	pData;		/* ptr to LB within read data buffer */    CDROM_VOL_DESC_ID	pVolDesc;    assert (pVDList != NULL);    assert (LBNum > 15);	/* SPR#80424 failed */    pVolDesc = pVDList->pVolDesc;    assert (pVolDesc != NULL);    if (pSecBuf == NULL)	/* to use common buffer */	pSecBuf = &(pVDList->pVolDesc->sectBuf);    assert (pSecBuf->sectData != NULL);    DBG_MSG(300)("%d. access for LB %lu\n", __LINE__, LBNum);    secNum = LBNum >> pVDList->LBToLSShift;		/* LS, contain LB  */    maxLSs =  maxLBs >> pVDList->LBToLSShift;    pData = cdromFsGetLS (pVolDesc, secNum, maxLSs, pSecBuf);    if (pData == NULL)	return NULL;    DBG_MSG(400)("%d. offset in buf: %lu(last bits = %lu)\n",		 __LINE__,		 pVDList->LBSize * LAST_BITS (LBNum, pVDList->LBToLSShift),		 LAST_BITS (LBNum, pVDList->LBToLSShift));    return (pData + pVDList->LBSize *		     LAST_BITS (LBNum, pVDList->LBToLSShift));    }/***************************************************************************** cdromFsDIRGet - get directory from the current root folder** This routine tries to find requested directory for an specifically FD.* The routine call the function cdromFsGetLB with Directory RecLB** RETURNS: ptr on LB from directory buffer or NULL if any error occurred.*/LOCAL u_char * cdromFsDIRGet    (	T_CDROM_FILE_ID pFD	/* FD to fill, containing parent */    )    {    u_long	headSizeLB;	/* Size of directory in LBs */    u_long	headLBIndex;	/* (Destination) LB in dir preceding head */    u_long	headLBNum;	/* (Destination) LB containing dir record */    u_long	headRemLB;	/* (Destination) Remaining LB in the directory */    u_char *	pHeadLb;	/* (Destination) Point to LB of dir record */#ifdef	CDROMFS_MODE_AUTO_COMBINE_VOLUME_DESCRIPTORS    u_char *	pNextLb;	/* (Source) Point to LB of same directory */				/* in another volume descriptor */    u_int	headDirEnt;	/* (Destination) # of dir records in pHead dir */    u_int	nextDirEnt;	/* (Source) # of dir records in pNext dir */    u_int	nrMulVD;	/* Loop index */#endif	/* CDROMFS_MODE_AUTO_COMBINE_VOLUME_DESCRIPTORS */    assert (pFD != NULL);    /* Get the logical block that contains the directory record */    headLBIndex = pFD->FCDirRecAbsOff / pFD->pVDList->LBSize;    headLBNum = pFD->FCDirFirstRecLB + headLBIndex;    headSizeLB	= ROUND_UP (pFD->FSize, pFD->pVDList->LBSize) / pFD->pVDList->LBSize;    headRemLB = headSizeLB - headLBIndex;    pHeadLb = cdromFsGetLB (pFD->pVDList, headLBNum, headRemLB, &(pFD->sectBuf));#ifdef	CDROMFS_MODE_AUTO_COMBINE_VOLUME_DESCRIPTORS    if (pFD->nrMultDir !=0 && pFD->pMultDir[0] !=0)	{	for (nrMulVD = 0; nrMulVD < pFD->nrMultDir; nrMulVD++)	    {	    headDirEnt = cdromFsFindDirEntered (pHeadLb, pFD->pVDList->LBSize);	    /* Get the logical block that contains the alternate record */	    pNextLb = cdromFsGetLB (pFD->pVDList, pFD->pMultDir[nrMulVD], 1, 0);	    nextDirEnt = cdromFsFindDirEntered (pNextLb, pFD->pVDList->LBSize);	    if (nextDirEnt > 2)		{		cdromFsAddRecsToFD (pNextLb, 2, pHeadLb, headDirEnt,				    nextDirEnt-2,				    (pFD->sectBuf.numSects -				     (headLBNum - pFD->sectBuf.startSecNum)) *				    pFD->pVDList->pVolDesc->sectSize);		}	    }	}#endif	/* CDROMFS_MODE_AUTO_COMBINE_VOLUME_DESCRIPTORS */    return (pHeadLb);    }/***************************************************************************** cdromFsPTGet - retrieve Path Table for given VD from volume.** By default, if pSecBuf == NULL, volume dir hierarchy PT buffer* is used for storing path table. It is allocated only once and* is deallocated over volume unmounting.** Only if pSecBuf != NULL required space for PT automaticly allocated in it.** RETURNS: ptr to PT or NULL if any error occurred.*/LOCAL u_char * cdromFsPTGet    (    T_CDROMFS_VD_LST_ID pVdLst,    SEC_BUF_ID	pSecBuf		/* may be NULL. Ptr to buffer control */				/* structure to read PT to */    )    {    u_char *	pPT;		/* Return value */    u_long	PTSizeLB;	/* Number of LB in path table */    assert (pVdLst != NULL);    if (pSecBuf == NULL)	/* use volume dir hierarchy PT buffer */	pSecBuf = &(pVdLst->PTBuf);    /*     * if the buffer already has been allocated, the following call does     * nothing     */    /*     * SPR#34659 Problem pVdList->pVolDesc can be set to NULL by     * cdromFsVolUnmount() concurrent with cdromFsOpen().  This is fixed     * by cdromFsVolLock() added to cdromFsOpen().     */    if (cdromFsSectBufAllocBySize (pVdLst->pVolDesc, pSecBuf,				   pVdLst->PTSize) == ERROR)	return NULL;    /* Compute size of PT in blocks */

⌨️ 快捷键说明

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