?? cdromfslib.c
字號:
/* cdromFsLib.c - ISO 9660 CD-ROM read-only file system library *//* Copyright 1989-1997 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------05a,03jun99,pfl fixed directory and file month entries (SPR# 26756)04r,15nov98,jdi added instructions on modifying BSP to include cdromFS.04e,14jul98,cn added prototype for cdromFsWrite().04d,10jul98,cn updated documentation, changed cdromFS to cdromFsLib (SPR# 21732). Also removed every reference to Rock Ridge extensions support (SPR# 21590). Moved cdromFsInit() to the beginning of the file.04c,08apr98,kbw made minor man page edits04b,30apr97,jdi doc: cleanup.04a,10apr97,dds SPR#7538: add CDROM file system support to vxWorks.03f,17jul96,rst productized for release.03e,25jun96,vld file was compiled with "Tornado". All warnings were fixed up.03c,25jun96,vld new functionality: uppercase names may be reached via case insensitive path string.03b,23jun96,leo the bug in cdromFsFixPos() was fixed up (type of second argument was changed to long).03a,23jun96,leo the bug in cdromFsFindFileInDir() was fixed up (the bug came from ASCI order, wwhere ';' > '.').02a,23jan96,vld the new interpretation of ISO_DIR_REC_EAR_LEN and ISO_PT_REC_EAR_LEN: it is assumed now that the length of EAR is counted in logical blocks. Data always starts from LB bound.01e,23jan96,vld the bug in cdromFsFixPos was fixed up01d,12oct95,rst FCS release, ported to 5.201c,03jul95,rst Beta release, code revew.01b,10apr95,rst alex, vlad total revision of the joined text01a,22feb95,rst initial version*//*DESCRIPTIONThis library defines cdromFsLib, a utility that lets you use standard POSIX I/O calls to read data from a CD-ROM formatted according to the ISO 9660 standard file system.It provides access to CD-ROM file systems using any standardBLOCK_DEV structure (that is, a disk-type driver). The basic initialization sequence is similar to installing a DOS file systemon a SCSI device. 1. Initialize the cdrom file system library(preferably in sysScsiConfig() in sysScsi.c):.CS cdromFsInit ();.CE 2. Locate and create a SCSI physical device:.CS pPhysDev=scsiPhysDevCreate(pSysScsiCtrl,0,0,0,NONE,1,0,0);.CE 3. Create a SCSI block device on the physical device:.CS pBlkDev = (SCSI_BLK_DEV *) scsiBlkDevCreate (pPhysDev, 0, 0);.CE 4. Create a CD-ROM file system on the block device:.CS cdVolDesc = cdromFsDevCreate ("cdrom:", (BLK_DEV *) pBlkDev);.CE Call cdromFsDevCreate() once for each CD-ROM drive attached to your target.After the successful completion of cdromFsDevCreate(), the CD-ROM file system will be available like any DOS file system, and you can access data on the named CD-ROM device using open(), close(), read(), ioctl(), readdir(), and stat(). A write() always returns an error. The cdromFsLib utility supports multiple drives, concurrent access from multiple tasks, and multiple open files.FILE AND DIRECTORY NAMINGThe strict ISO 9660 specification allows only uppercase file names consisting of 8 characters plus a 3 character suffix. To support multipleversions of the same file, the ISO 9660 specification also supports versionnumbers. When specifying a file name in an open() call, you can select thefile version by appending the file name with a semicolon (;) followed by a decimal number indicating the file version. If you omit the version number,cdromFsLib opens the latest version of the file.To accommodate users familiar with MS-DOS, cdromFsLib lets you use lowercase name arguments to access files with names consisting entirely of uppercase characters. Mixed-case file and directory names are accessible only if youspecify their exact case-correct names. For the time being, cdromFsLib further accommodates MS-DOS users by allowing "\e" (backslash) instead of "/" in pathnames. However, the use of the backslash is discouraged because it may not be supported infuture versions of cdromFsLib.Finally, cdromFsLib uses an 8-bit clean implementation of ISO 9660. Thus, cdromFsLib is compatible with CD-ROMs using either Latin or Asian characters in the file names.IOCTL CODES SUPPORTED.iP `FIOGETNAME' 20Returns the file name for a specific file descriptor..iP `FIOLABELGET'Retrieves the volume label. This code can be used to verify that a particular volume has been inserted into the drive..iP `FIOWHERE'Determines the current file position..iP `FIOSEEK'Changes the current file position..iP `FIONREAD'Tells you the number of bytes between the current location and the end of this file..iP `FIOREADDIR'Reads the next directory entry..iP `FIODISKCHANGE'Announces that a disk has been replaced (in case the block driver isnot able to provide this indication)..iP `FIOUNMOUNT'Announces that the a disk has been removed (all currently open file descriptors are invalidated)..iP `FIOFSTATGET'Gets the file status information (directory entry data).MODIFYING A BSP TO USE CDROMFSThe following example describes mounting cdromFS on a SCSI device.Edit your BSP's config.h to make the following changes:.IP 1.Insert the following macro definition: .CS #define INCLUDE_CDROMFS.CE.IP 2.Change FALSE to TRUE in the section under the following comment:.CS /@ change FALSE to TRUE for SCSI interface @/.CE.LPMake the following changes in sysScsi.c(or sysLib.c if your BSP has no sysScsi.c):.IP 1.Add the following declaration to the top of the file: .CS #ifdef INCLUDE_CDROMFS #include "cdromFsLib.h" STATUS cdromFsInit (void); #endif.CE.IP 2.Modify the definition of sysScsiInit() to include the following:.CS #ifdef INCLUDE_CDROMFS cdromFsInit(); #endif.CEThe call to cdromFsInit() initializes cdromFS. This call mustbe made only once and must complete successfully before you cancall any other cdromFsLib routines, such as cdromFsDevCreate().Typically, you make the cdromFSInit() call at system startup.Because cdromFS is used with SCSI CD-ROM devices, it is naturalto call cdromFSInit() from within sysScsiInit()..IP 3.Modify the definition of sysScsiConfig() (if included in your BSP)to include the following: .CS/@ configure a SCSI CDROM at busId 6, LUN = 0 @/#ifdef INCLUDE_CDROMFSif ((pSpd60 = scsiPhysDevCreate (pSysScsiCtrl, 6, 0, 0, NONE, 0, 0, 0)) == (SCSI_PHYS_DEV *) NULL) { SCSI_DEBUG_MSG ("sysScsiConfig: scsiPhysDevCreate failed for CDROM.\n", 0, 0, 0, 0, 0, 0); return (ERROR); }else if ((pSbdCd = scsiBlkDevCreate (pSpd60, 0, 0) ) == NULL) { SCSI_DEBUG_MSG ("sysScsiConfig: scsiBlkDevCreate failed for CDROM.\n", 0, 0, 0, 0, 0, 0); return (ERROR); }/@ * Create an instance of a CD-ROM device in the I/O system. * A block device must already have been created. Internally, * cdromFsDevCreate() calls iosDrvInstall(), which enters the * appropriate driver routines in the I/O driver table. @/if ((cdVolDesc = cdromFsDevCreate ("cdrom:", (BLK_DEV *) pSbdCd )) == NULL) { return (ERROR); }#endif /@ end of #ifdef INCLUDE_CDROMFS @/.CE.IP 4.Before the definition of sysScsiConfig(), declare the followingglobal variables used in the above code fragment:.CS SCSI_PHYS_DEV *pSpd60; BLK_DEV *pSbdCd; CDROM_VOL_DESC_ID cdVolDesc;.CE.LPThe main goal of the above code fragment is to call cdromFsDevCreate().As input, cdromFsDevCreate() expects a pointer to a block device.In the example above, the scsiPhysDevCreate() and scsiBlkDevCreate()calls set up a block device interface for a SCSI CD-ROM device. After the successful completion of cdromFsDevCreate(), the device called "cdrom" is accessible using the standard open(), close(), read(), ioctl(),readdir(), and stat() calls.INCLUDE FILES: cdromFsLib.hCAVEATSThe cdromFsLib utility does not support CD sets containing multiple disks.SEE ALSO: ioLib, ISO 9660 Specification*//* includes */#include <string.h>#include <memLib.h>#include <errnoLib.h>#include <sysLib.h>#include <stdlib.h>#include <stdio.h>#include <logLib.h>#include <errnoLib.h>#include <usrLib.h>#include <iosLib.h>#include <dirent.h>#include <ctype.h>#include "cdromFsLib.h"/* defines */ #ifdef DEBUG#undef LOCAL#define LOCAL int cdromFsDbg = 0; u_char dbgvBuf[2048];#define DBG_MSG(level)\ if((level)<=cdromFsDbg)printf#define DBG_COP_TO_BUF(str, len)\ {\ bzero(dbgvBuf, sizeof(dbgvBuf));\ bcopy((str), dbgvBuf, (len));\ }#else#define DBG_MSG(level) if (0)printf#define DBG_COP_TO_BUF(str, len) (str,len)#endif /* DEBUG */#include <assert.h>#define CDROM_LIB_MAX_PT_SIZE (64 KB) /* maximum path table size supported */#define SLASH '/'#define BACK_SLASH '\\'#define POINT '.'#define SEMICOL ';'/* SEC_BUF struct constant */#define BUF_EMPTY (-1)#define CDROM_COM_BUF_SIZE 3 /* sectors to read via single access *//* * All character variables in the module are defined as u_char (*). * Following macros are defined to prevent compilation warnings */#define bzero(a,b) bzero((char *)(a), (b))#define bcopy(a,b,c) bcopy((char *)(a), (char *)(b), (c))#define bcmp(a,b,c) bcmp((char *)(a), (char *)(b), (c))#define strlen(a) strlen((char *)(a))#define strncpy(a,b,c) strncpy((char *)(a), (char *)(b), (c))#define strcpy(a,b) strcpy((char *)(a), (char *)(b))#define strncmp(a,b,c) strncmp((char *)(a), (char *)(b), (c))#define strcmp(a,b) strcmp((char *)(a), (char *)(b))#define strchr(a,b) strchr((char *)(a), (b))#define strtok_r(a,b,c) ((u_char *)strtok_r((char *)(a), (char *)(b),\ (char **)(c)))#define strspn(a,b) strspn((char *)(a), (char *)(b))/* * Over development all errors are not set to <errno> directly, but * logged on the console with some comments */#ifdef ERR_SET_SELF#define errnoSet(a) errnoSetOut(__LINE__, (u_char *)#a)#endif/* data fields in buffer may not be bounded correctly */#define C_BUF_TO_SHORT(dest, source, start)\ {\ CDROM_SHORT buf;\ bcopy((u_char *)(source)+ (start), (u_char *)&buf, 2);\ (dest) = buf;\ }#define C_BUF_TO_LONG(dest, source, start)\ {\ CDROM_LONG buf;\ bcopy((u_char *)(source)+ (start), (u_char *)&buf, 4);\ (dest) = buf;\ }#define LAST_BITS(val,bitNum) ((~((u_long)(-1)<<(bitNum)))&((u_long)val))#define A_PER_B(a,b) (((a)+(b)-1)/(a))/* to get some fields from path table records */#define PT_REC_SIZE(size, pPT) ((size)=((u_char)(*(pPT)+(*(pPT)&1))+8))#define PT_PARENT_REC(prev, pPT)\ C_BUF_TO_SHORT (prev, pPT, ISO_PT_REC_PARENT_DIR_N)/* * they are use the same data buffer within * <sectBuf> fields, but different copies of * <sectBuf> */#define RESTORE_FD(buf, dest, retErrCode)\ {\ (buf).sectBuf.startSecNum = (dest).sectBuf.startSecNum;\ (dest) = (buf);\ (dest).FCDirRecPtr = cdromFsGetLB((dest).pVDList,\ (dest).FCDirRecLB, &((dest).sectBuf));\ if ((dest).FCDirRecPtr == NULL)\ return retErrCode;\ (dest).FCDirRecPtr += (dest).FCDirRecOffInLB;\ }/* to assign secBuf as empty */#define LET_SECT_BUF_EMPTY(pSecBuf) ((pSecBuf)->startSecNum=BUF_EMPTY) /* typedefs */typedef u_short CDROM_SHORT; /* 2-bytes fields */typedef u_long CDROM_LONG; /* 4-bytes fields *//* globals */STATUS cdromFsInit (void);/* cdrom file system number in driver table */int cdromFsDrvNum = ERROR;/* locals *//* forward declarations */#ifdef ERR_SET_SELFLOCAL VOID errnoSetOut(int line, const u_char * str);#endifLOCAL T_CDROM_FILE_ID cdromFsFDAlloc (CDROM_VOL_DESC_ID pVolDesc);LOCAL void cdromFsFDFree (T_CDROM_FILE_ID pFD);LOCAL STATUS cdromFsSectBufAlloc (CDROM_VOL_DESC_ID pVolDesc, SEC_BUF_ID pSecBuf, int numSectInBuf);LOCAL STATUS cdromFsSectBufAllocBySize (CDROM_VOL_DESC_ID pVolDesc, SEC_BUF_ID pSecBuf, int size);LOCAL void cdromFsSectBufFree (SEC_BUF_ID pSecBuf);LOCAL u_char * cdromFsGetLB (T_CDROMFS_VD_LST_ID pVDLst, u_long LBNum, SEC_BUF_ID secBuf);LOCAL u_char * cdromFsGetLS (CDROM_VOL_DESC_ID pVolDesc, u_long LSNum, SEC_BUF_ID secBuf);LOCAL u_char cdromFsShiftCount (u_long source, u_long dest);LOCAL u_char * cdromFsPTGet (T_CDROMFS_VD_LST_ID pVdLst, SEC_BUF_ID pSecBuf);LOCAL u_long cdromFsNextPTRec (u_char ** ppPT, u_long offset, u_long PTSize);LOCAL STATUS cdromFsVDAddToList (CDROM_VOL_DESC_ID pVolDesc, u_char * pVDData, u_int VDPseudoLBNum, u_char VDSizeToLSSizeShift);LOCAL void cdromFsVolUnmount (CDROM_VOL_DESC_ID pVolDesc);LOCAL STATUS cdromFsVolMount (CDROM_VOL_DESC_ID pVolDesc);LOCAL T_CDROM_FILE_ID cdromFsOpen (CDROM_VOL_DESC_ID pVolDesc, u_char * path, int options);LOCAL STATUS cdromFsClose (T_CDROM_FILE_ID pFD);LOCAL int cdromFsFindDirOnLevel (T_CDROMFS_VD_LST_ID pVDList, u_char * name, u_char * pPT, u_int parDirNum, u_int pathLev, u_char ** ppRecord);LOCAL STATUS cdromFsFindPathInDirHierar(T_CDROMFS_VD_LST_ID pVDList, u_char * path, u_int numPathLevs, T_CDROM_FILE_ID pFD, int options);LOCAL T_CDROM_FILE_ID cdromFsFindPath (CDROM_VOL_DESC_ID pVolDesc, u_char * path, int options);LOCAL STATUS cdromFsFillFDForDir (T_CDROMFS_VD_LST_ID pVDList, T_CDROM_FILE_ID pFD, u_char * pPTRec, u_int dirRecNumInPT, u_int dirRecOffInPT);LOCAL STATUS cdromFsFindFileInDir (T_CDROMFS_VD_LST_ID pVDList, T_CDROM_FILE_ID pFD, u_char * name, u_char * pPTRec, u_int dirRecNumInPT, u_int dirRecOffInPT);LOCAL int cdromFsSplitPath(u_char * path);LOCAL STATUS cdromFsReadyChange (CDROM_VOL_DESC_ID pVDList);LOCAL STATUS cdromFsIoctl (T_CDROM_FILE_ID fd, int function, int arg);LOCAL STATUS cdromFsRead (int desc, u_char * buffer, size_t maxBytes);LOCAL STATUS cdromFsWrite (void);LOCAL STATUS cdromFsSkipDirRec (T_CDROM_FILE_ID fd, u_char flags);LOCAL STATUS cdromFsCountMdu (T_CDROM_FILE_ID fd, int prevabsoff);LOCAL STATUS cdromFsFillStat (T_CDROM_FILE_ID fd,struct stat * arg);LOCAL STATUS cdromFsSkipDirRec (T_CDROM_FILE_ID fd, u_char flags);LOCAL STATUS cdromFsFillPos (T_CDROM_FILE_ID fd,u_char *PrevDirPtr, short i, int len, int NewOffs);LOCAL STATUS cdromFsDirBound (T_CDROM_FILE_ID fd); LOCAL void cdromFsFixPos (T_CDROM_FILE_ID fd, u_long length, u_long absLb);LOCAL void cdromFsFixFsect (T_CDROM_FILE_ID fd);LOCAL void cdromFsSkipGap (T_CDROM_FILE_ID fd , u_long * absLb, long absPos);/******************************************************************************** * cdromFsInit - initialize cdromFsLib*
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -