📄 cdromfslib.c
字号:
* This routine initializes cdromFsLib. It must be called exactly* once before calling any other routine in cdromFsLib. ** ERRNO: S_cdromFsLib_ALREADY_INIT** RETURNS: OK or ERROR, if cdromFsLib has already been initialized.** SEE ALSO: cdromFsDevCreate(), iosLib.h*/STATUS cdromFsInit (void) { if (cdromFsDrvNum != ERROR) { return cdromFsDrvNum; } /* install cdromFs into driver table */ cdromFsDrvNum = iosDrvInstall ( (FUNCPTR) NULL, /* pointer to driver create function */ (FUNCPTR) NULL, /* pointer to driver delete function */ (FUNCPTR) cdromFsOpen, /* pointer to driver open function */ (FUNCPTR) cdromFsClose, /* pointer to driver close function */ (FUNCPTR) cdromFsRead, /* pointer to driver read function */ (FUNCPTR) cdromFsWrite, /* pointer to driver write function */ (FUNCPTR) cdromFsIoctl /* pointer to driver ioctl function */ ); if (cdromFsDrvNum == ERROR) { printf("cdromFsLib: iosDrvInstall failed\n"); printErrno(errnoGet()); } else {#ifdef DEBUG printf("cdromFsLib: Initialized\n");#endif } return cdromFsDrvNum; } /* cdromFsInit() */#ifdef ERR_SET_SELF/********************************************************************************* errnoSetOut - put error message** This routine is called instead of errnoSet() during module creation.** RETURNS: N/A*/LOCAL VOID errnoSetOut(int line, const u_char * str) { printf("ERROR: line %d %s\n", line, str); }#endif /* ERR_SET_SELF *//********************************************************************************* cdromFsFDAlloc - allocate file descriptor structure** This routine allocates a file descriptor structure and initializes some * of its base members, such as 'magic' and 'sectBuf'. Later, you can use * this file descriptor structure when opening a file. However, be aware that * the file descriptor allocated here is not yet connected to the volume's file * descriptor list. To free the file descriptor structure allocated here, * use cdromFsFDFree().* * RETURNS: ptr to FD or NULL.*/LOCAL T_CDROM_FILE_ID cdromFsFDAlloc ( CDROM_VOL_DESC_ID pVolDesc /* processed volume */ ) { T_CDROM_FILE_ID pFD = malloc(sizeof(T_CDROM_FILE)); if (pFD == NULL) return NULL; bzero (pFD, sizeof (T_CDROM_FILE)); /* allocate sector reading buffer (by default size) */ if (cdromFsSectBufAlloc (pVolDesc, & (pFD->sectBuf), 0) == ERROR) { free (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.** RETURN: N/A.*/LOCAL void cdromFsFDFree ( T_CDROM_FILE_ID pFD ) { pFD->magic = 0; cdromFsSectBufFree (&(pFD->sectBuf)); if (pFD->FRecords != NULL) free (pFD->FRecords); if (pFD->inList) lstDelete (&(pFD->pVDList->pVolDesc->FDList), (NODE *)pFD); pFD->inList = 0; free (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;*/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->numSects >= numSectInBuf && pSecBuf->numSects <= numSectInBuf + 1) return OK; free(pSecBuf->sectData); pSecBuf->magic = 0; } /* newly init control structure */ LET_SECT_BUF_EMPTY (pSecBuf); pSecBuf->numSects = numSectInBuf; /* allocation */ pSecBuf->sectData = malloc(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); assert (pSecBuf != NULL); return (cdromFsSectBufAlloc (pVolDesc , pSecBuf, A_PER_B(pVolDesc->sectSize, size) + 1)); }#ifdef DEBUG/********************************************************************************* cdromFsSectBufAllocByLB - allocate by number of LB buffer for reading volume.** After using, buffer must be deallocated by means of cdromFsSectBufFree().* This routine calls cdromFsSectBufAllocBySize() with* size equals to total <numLB> logical blocks size.* If <numLB> == 0, allocated buffer is of 1 sectors size.** RETURNS: OK or ERROR;*/LOCAL STATUS cdromFsSectBufAllocByLB ( T_CDROMFS_VD_LST_ID pVDList, SEC_BUF_ID pSecBuf, /* buffer control structure */ /* to which buffer is connected */ int numLB /* minimum LS in buffer */ ) { assert (pVDList != NULL); assert (pVDList->pVolDesc != NULL); assert (pSecBuf != NULL); return (cdromFsSectBufAllocBySize (pVDList->pVolDesc , pSecBuf, numLB * pVDList->LBSize)); }#endif /*DEBUG*//********************************************************************************* cdromFsSectBufFree - deallocate volume sector buffer.** RETURN: N/A*/LOCAL void cdromFsSectBufFree ( SEC_BUF_ID pSecBuf /* buffer control structure */ ) { assert (pSecBuf != NULL); if (pSecBuf->magic == SEC_BUF_MAG && pSecBuf->sectData != NULL) 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.** ERRNO: S_cdromFsLib_DEVICE_REMOVED, if cdrom disk has not been ejected;* or any, may be set by block device driver read function.** RETURNS: ptr on LS within buffer or NULL if error accessing device.*/LOCAL u_char * cdromFsGetLS ( CDROM_VOL_DESC_ID pVolDesc, u_long LSNum, /* logical sector to get */ 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); assert (LSNum < pVolDesc->pBlkDev->bd_nBlocks / pVolDesc->LSToPhSSizeMult); DBG_MSG (400)("access for sector %lu\n", 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->startSecNum == BUF_EMPTY || 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 volume sector */ numLSRead = min (pBlkDev->bd_nBlocks / pVolDesc->LSToPhSSizeMult - LSNum, pSecBuf->numSects); if (pBlkDev->bd_blkRd (pBlkDev, LSNum * pVolDesc->LSToPhSSizeMult, numLSRead * pVolDesc->LSToPhSSizeMult, pSecBuf->sectData) == ERROR) { LET_SECT_BUF_EMPTY (pSecBuf); DBG_MSG(0)(" CDROM ERROR: error reading volume sect %lu - %lu\a\n", LSNum, pSecBuf->numSects); return (NULL); } /* successfully read */ pSecBuf->startSecNum = LSNum; } 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 */ SEC_BUF_ID pSecBuf /* sector data control structure, */ /* to put data to */ ) { u_int secNum; /* LS, contane LB */ u_char * pData; /* ptr to LB within read data buffer */ CDROM_VOL_DESC_ID pVolDesc; assert (pVDList != NULL); assert (LBNum > 15); pVolDesc = pVDList->pVolDesc; assert (pVolDesc != NULL); if (pSecBuf == NULL) /* to use common buffer */ pSecBuf = &(pVDList->pVolDesc->sectBuf); assert (pSecBuf->sectData != NULL); DBG_MSG(300)("access for LB %lu\n", LBNum); secNum = LBNum >> pVDList->LBToLSShift; /* LS, contane LB */ pData = cdromFsGetLS (pVolDesc, secNum, pSecBuf); if (pData == NULL) return NULL; DBG_MSG(400)("offset in buf: %lu(last bits = %lu)\n", pVDList->LBSize * LAST_BITS(LBNum, pVDList->LBToLSShift), LAST_BITS(LBNum, pVDList->LBToLSShift)); return (pData + pVDList->LBSize * LAST_BITS (LBNum, pVDList->LBToLSShift)); }/********************************************************************************* 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 */ ) { assert (pVdLst != NULL); if (pSecBuf == NULL) /* use volume dir hierarchy PT buffer */ pSecBuf = &(pVdLst->PTBuf); /* if buffer already has been allocated, following call do nothing */ if (cdromFsSectBufAllocBySize (pVdLst->pVolDesc, pSecBuf, pVdLst->PTSize) == ERROR) return NULL; /* if PT already in buffer, following call do nothing */ return (cdromFsGetLB(pVdLst, pVdLst->PTStartLB, pSecBuf)); }/********************************************************************************* 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 (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -