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

📄 iso9660.c

📁 本程序为ST公司开发的源代码
💻 C
字号:
/*****************************************************************************//*                                                                           *//* <C> STMicroelectronics - copyright information                            *//*                                                                           *//*                                                                           *//* COMMENT }DOCUMENTATION                                                    *//* File Name     :: iso9660.c                                                *//* Creation Date :: September 2005                                           *//* Author        :: Ondrej Trubac                                            *//* Version       :: $Revision: 1.25 $                                        *//* Last change   :: $Date: 2007/06/01 14:09:54 $ by $Author: trubac $ *//* Description   :: ISO9660 detection/handling                               *//* }                                                                         *//*****************************************************************************//*************************************************** * * COPYRIGHT (C) ST Microelectronics  2005 *            All Rights Reserved * ******************************************************************************* *  \brief        Player * *  \par          Change History: * * - BB060626     Fixed ISO9660 parsing (directory record larger than sector) * - BB060929a    Improved no TOC and Copyprotected CD support * **************************************************** * * STM CVS Log: * * $Log: ISO9660.c,v $ * Revision 1.25  2007/06/01 14:09:54  trubac * Update HEAD by changes from B_3_1_P3 (1.20.2.3) * * Revision 1.24  2007/05/02 12:31:41  belardi * Removed unused variable * * Revision 1.23  2007/03/28 17:09:42  trubac * workaround for variable length character encoding (Asian standards) * * Revision 1.22  2007/03/13 13:05:22  trubac * boot record ignored when ISO9660 detected * * Revision 1.20  2006/11/17 16:36:14  dellorto * added copy of PVD address for hostif read TOC message * * Revision 1.19  2006/10/17 09:59:27  trubac * ISO_Detect cosmetic rearangement + copy protected CD support * * Revision 1.18  2006/09/18 09:55:22  belardi * Corrected CVS keyword usage * * Revision 1.17  2006/09/18 09:24:02  belardi * Added Log CVS keyword into file header * * ******************************************************************************/#include <stdio.h>#include <stdlib.h>// #include <conio.h> used for PC when _getch needed#include <string.h>#include "gendef.h"#include "accordoptypes.h"      //"aptypes.h"#include "apdevsys.h"#include "iso9660.h"#include "cddevice.h"#include "bytestream.h"#include "debug.h"#include "utf8.h"#include "xfile.h"#include "filesys.h"#include "capture.h"#include "controller.h"#include "hostif_high.h"#if (ISO_DEBUG != 0)#define ISOPRINTF(...)  dprintf(__VA_ARGS__)#else//#define ISOPRINTF(x)#define ISOPRINTF(...)  do{}while(0)#endif#define SECTOR_SIZE   2048GRESULT ISO_GetDirItem(SCAN_STRUCT *scans, DIR_ITEM *item, uint8 *buf){  FS_DESCRIPTOR *fsd;  uint8 *tbuf;  uint16 position;  int i;  uint32 offset;  uint8 p;  GRESULT res;  t_conv_param pp;  t_lba slba;  int tmp1,j;  uint8 *cp;  uint16 wc;//static GRESULT debug_error;  fsd = scans->fs_descriptor;  if (!scans->DirRecordOffset)  {    slba = 150 + fsd->PartitionLBA + scans->DirRecordLba;    ISOPRINTF("ISO_GetDirItem1 LBA: %d\n", slba);    PREPARE_IOREAD(FS_XFER_command_event, DEV_CD_ID, slba, slba, 0, SECTOR_SIZE, buf, SECTOR_SIZE,                   IO_READ_IMMEDIATE);    if (0 > (res = IO_Read(IO_READ_IMMEDIATE)))    {      //debug_error = res+1;      return res;    }    scans->DirRecordLength = BYTEREAD32(buf, 14);    p = *buf;    scans->DirRecordOffset = p + buf[p];    scans->OffsetSectors = 0;    // check of directory LBA, should match with directory extent position    slba = BYTEREAD32(buf,6);    if(slba!=scans->DirRecordLba)    {//        debug_error = E_FS_INTEGRITY_ERROR;        return E_FS_INTEGRITY_ERROR;  }    if(buf[25]&2)    {        if(buf[32]>2)        {  //          debug_error = E_UNEXPECTED;            return E_UNEXPECTED;        }    }    else    {//        debug_error = E_UNKNOWN_FS_TYPE;        return E_UNKNOWN_FS_TYPE;    }    }    if( (!(scans->DirRecordOffset%SECTOR_SIZE))&&(scans->DirRecordOffset!=SECTOR_SIZE*scans->OffsetSectors))  {      scans->OffsetSectors++;      slba = 150 + fsd->PartitionLBA + scans->OffsetSectors + scans->DirRecordLba;      ISOPRINTF("ISO_GetDirItem3 LBA: %d\n", slba);      PREPARE_IOREAD(FS_XFER_command_event, DEV_CD_ID, slba, slba, 0, SECTOR_SIZE, buf, SECTOR_SIZE,                   IO_READ_IMMEDIATE);      if (0 > (res = IO_Read(IO_READ_IMMEDIATE)))      {          //debug_error = res+2;          return res;      }        }      skip_nulls:  if (scans->DirRecordOffset >= scans->DirRecordLength)    return S_NOT_FOUND;  position = scans->DirRecordOffset % SECTOR_SIZE;  //zero_check:  p = buf[position];  if (!p)  {    scans->OffsetSectors++;    scans->DirRecordOffset = SECTOR_SIZE * scans->OffsetSectors;    slba = 150 + fsd->PartitionLBA + scans->OffsetSectors + scans->DirRecordLba;    ISOPRINTF("ISO_GetDirItem2 LBA: %d\n", slba);    PREPARE_IOREAD(FS_XFER_command_event, DEV_CD_ID, slba, slba, 0, SECTOR_SIZE, buf, SECTOR_SIZE,                   IO_READ_IMMEDIATE);    if (0 > (res = IO_Read(IO_READ_IMMEDIATE)))    {        //debug_error = res+3;      return res;    }    goto skip_nulls;  }  tbuf = &buf[position];  offset = scans->DirRecordOffset;  scans->DirRecordOffset += p;   if ((position + p) > SECTOR_SIZE)  /* BB060929a */  {    return E_WRONG_FORMAT;  }  if (tbuf[25] & 2)  {    item->dir.DirRecordLba = BYTEREAD32(tbuf, 6);    item->dir.ParentOffset = offset;    if (!scans->byte0)    {      memcpy(item->dir.Name, tbuf + 33, tbuf[32]);      item->dir.NameLength = tbuf[32];    }    else    {      pp.be = 1;      pp.trunc = 0;      pp.limit = 255;        item->dir.NameLength = WideStringToUTF8(tbuf + 33, item->dir.Name, tbuf[32] >> 1, &pp);      if(item->dir.NameLength<0)      {          return E_WRONG_FORMAT;    }    }    return S_DIR_FOUND;  }  // else this is file  item->file.DirRecordLba = scans->DirRecordLba;  item->file.DirRecordOffset = offset;  item->file.ExtentLba = BYTEREAD32(tbuf, 6);  item->file.FileSize = BYTEREAD32(tbuf, 14);  p = tbuf[32];         // length of identifier  if ((position + p) > SECTOR_SIZE)  /* BB060929a */  {    return E_WRONG_FORMAT;  }  tmp1 = j = 0;    // check ';' and UCS-2   for (i = p - 1; i >= 0; i--)  {    if (!tbuf[33 + i])        tmp1 = 1;    if ((!j)&&(tbuf[33 + i] == 0x3B))    {      j = i;      break;    }  }    if(j && scans->byte0)  {      if(tmp1)   // check if name is UCS-2 encoded           j--;  }        i = j;  if (i <= 1)  {    i = p;     // real name length    //return E_WRONG_FORMAT;  }  if (tbuf[33 + i - 1] == 0x2E)  {    return S_FILE_SKIP;  }  p = i;  if (scans->byte0)  {    pp.be = 1;    pp.trunc = 0;    pp.limit = 250;    if(tmp1)    {        item->file.NameLength = WideFileNameToUTF8(tbuf + 33, item->file.Name, i >> 1, &pp);        if(item->file.NameLength<0)        {            return E_WRONG_FORMAT;    }  }    else    {    // characters are not UCS-2, but kind of multibyte encoding, like GB2312,GBK,...        cp = item->file.Name;        i = 0;        tmp1 = 0;        do        {            wc = 0;            if(tbuf[33+i]>=128)            {                wc = tbuf[33+i] << 8;                i++;            }            wc += tbuf[33+i];            i++;            tmp1 += wc2utf8(wc,&cp);  // convert character to UTF-8 sequence                    }while(i<p);                item->file.NameLength = tmp1;               }  }  else  {    item->file.NameLength = i;    memcpy(item->file.Name, tbuf + 33, i);  }  return S_FILE_FOUND;}/*************************************************************************/GRESULT ISO_Detect(DUID cdid, int partition, FS_DESCRIPTOR *fsd){  CD_DeviceDescriptor *cddesc;  int err;  int32 res;  uint8 cbuf[256];  uint32 volumeDescriptorLba;  PRIVATE_DATA_ISO9660 *isod;  if (SYS_DeviceType(cdid) != DEV_CD_ID)  {    return E_INVALID_DEVICE_TYPE;  }  hostif_pvd_address = 0xFFFFFFFF;  cddesc = (CD_DeviceDescriptor *) SYS_DeviceDescriptor(cdid);  if (NULL == (void *) cddesc)  {    return E_INVALID_DEVICE_DESCRIPTOR;  }  fsd->attributes = 0;  isod = &fsd->PD.ISO_pd;  res = CD_LastSessionLBA();  if (res < 0)    return E_NO_FS_CARRIER;  /* BB060929a */  isod->IsoVolumeLba = res + 16 - TOC_OFFSET_SECTOR;  // Unless noted otherwise every lba is considered to be without 2 seconds offset  // for requesting from CD, value lba+150 must be used  // now check if ISO9660 Primary Volume Descriptor and Joliet descriptor is present  volumeDescriptorLba = isod->IsoVolumeLba;  // reset device flags according detection method#if 0  if (flags & ISO_DETECT_PRIMARY_DESCRIPTOR_ONLY)  {    SYS_ClearDeviceAttribute(cdid, DEV_ATTR_ISO_PRIMARY_VOL_DESCRIPTOR);  }  else  {    if (flags & ISO_DETECT_SUPPLEM_DESCRIPTOR_ONLY)      SYS_ClearDeviceAttribute(cdid, DEV_ATTR_ISO_SUPPLEM_VOL_DESCRIPTOR);    else      SYS_ClearDeviceAttribute(cdid, DEV_ATTR_ISO9660_FILESYSTEM);  }#else  SYS_ClearDeviceAttribute(cdid, DEV_ATTR_ISO9660_FILESYSTEM);#endif  //cbuf = (uint8*)malloc(256);  isod->PrimaryDescriptorLba = 0;  isod->SupplementaryDescriptorLba = 0;  isod->IsoDescriptorLba = 0;  fsd->LargeBlockSize = SECTOR_SIZE;  fsd->Partition = partition;  fsd->PartitionLBA = SYS_PartitionLBA(cdid, partition, SECTOR_SIZE);  fsd->FSType = FS_ISO9660_TYPE;  fsd->did = cdid;  do  {    ISOPRINTF("ISO_Detect LBA: %d\n", 150 + fsd->PartitionLBA + volumeDescriptorLba);    PREPARE_IOREAD(FS_XFER_command_event,                   DEV_CD_ID,                   150 + fsd->PartitionLBA + volumeDescriptorLba,                   150 + fsd->PartitionLBA + volumeDescriptorLba,                   0, SECTOR_SIZE, cbuf, 256, IO_READ_IMMEDIATE);    err = IO_Read(IO_READ_IMMEDIATE);    if (err < 0)    {      return err;    }    if (cbuf[0] == 0)    {      //free(cbuf);      //return S_FALSE;   can cause problem when boot record found    }    if (cbuf[0] == 1)     // PRIMARY VOLUME DESCRIPTOR    {      if (!strncmp("CD001", (char *) cbuf + 1, 5))      {      	SYS_SetDeviceAttribute(cdid,DEV_ATTR_ISO9660_FILESYSTEM|DEV_ATTR_ISO_PRIMARY_VOL_DESCRIPTOR);        isod->PrimaryDescriptorLba = volumeDescriptorLba;   #if 0      // optional selection of volume descriptors        if(flags&ISO_DETECT_PRIMARY_DESCRIPTOR_ONLY)        {           isod->IsoDescriptorLba = volumeDescriptorLba;            fsd->attributes &=(MAX_UINT_VALUE-ISO9660_SUPPLEM_VOL_DESCRIPTOR_FLAG);           break;                                                  }  #endif        volumeDescriptorLba++;        continue;      }    }    if (cbuf[0] == 2)     // SUPPLEMENTARY VOLUME DESCRIPTOR    {      if (!strncmp("CD001", (char *) cbuf + 1, 5))      {        SYS_SetDeviceAttribute(cdid,           DEV_ATTR_ISO9660_FILESYSTEM|DEV_ATTR_ISO_SUPPLEM_VOL_DESCRIPTOR);        isod->SupplementaryDescriptorLba = volumeDescriptorLba;   #if 0 // optional descriptor selection        if(flags&ISO_DETECT_SUPPLEM_DESCRIPTOR_ONLY)        {           isod->IsoDescriptorLba = volumeDescriptorLba;            fsd->attributes |= ISO9660_SUPPLEM_VOL_DESCRIPTOR_FLAG;           break;                                                  }  #endif        volumeDescriptorLba++;        continue;      }    }    volumeDescriptorLba++;  }  while ((volumeDescriptorLba < (isod->IsoVolumeLba + 10)) && (cbuf[0] != 255));   // VOLUMEDESCRIPTORSETTERMINATOR)    // -see-iso9660-8.1.1  if(!isod->IsoDescriptorLba)    {        /*   this option is not included        if(flags&(ISO_DETECT_PRIMARY_DESCRIPTOR_ONLY|ISO_DETECT_SUPPLEM_DESCRIPTOR_ONLY))         {            return S_FALSE;        }    	*/            if(isod->SupplementaryDescriptorLba)        {            isod->IsoDescriptorLba=isod->SupplementaryDescriptorLba;            fsd->attributes |= ISO9660_SUPPLEM_VOL_DESCRIPTOR_FLAG;        }        else        {            if(isod->PrimaryDescriptorLba)            {                   isod->IsoDescriptorLba=isod->PrimaryDescriptorLba;                fsd->attributes &= (MAX_UINT_VALUE-ISO9660_SUPPLEM_VOL_DESCRIPTOR_FLAG);            }            else                return S_FALSE;        }    }        hostif_pvd_address = isod->IsoDescriptorLba + 150;// Now ISO descriptor lba is set        err=ISO_GetDiscInfo(fsd,cbuf);    if(err<0)	    return err;       return S_TRUE;}/*************************************************************************/GRESULT ISO_GetDiscInfo(FS_DESCRIPTOR *cdd, uint8 *buf){  int position;  uint8 *ptr;  unsigned int lbaDiskSize;  unsigned int sectorSize;    GRESULT err;  t_conv_param p;//    err=IO_Read(cdd->did,cdd->PartitionLBA+cdd->PD.ISO_pd.IsoDescriptorLba,0,2048,buf,256,CD_FAIL_ON_READ_TIMEOUT);    PREPARE_IOREAD(FS_XFER_command_event,DEV_CD_ID,150+cdd->PartitionLBA+cdd->PD.ISO_pd.IsoDescriptorLba,150+cdd->PartitionLBA+cdd->PD.ISO_pd.IsoDescriptorLba,0,2048,buf,256,IO_READ_IMMEDIATE);  			err=IO_Read(IO_READ_IMMEDIATE);    if(err<0)	{	    return err;	}      position = VOLUMENAME_POS;  ptr = cdd->VolumeName;  /* prepare data for joliet cd type */  if (cdd->attributes & ISO9660_SUPPLEM_VOL_DESCRIPTOR_FLAG)  // test if Joliet  {    p.be = 1;    p.trunc = 0;    p.limit = 32;    cdd->VolumeNameLength = WideStringToUTF8(buf + position, ptr, 16, &p);  }  else  {    cdd->VolumeNameLength = 11;    memcpy(ptr, buf + position, 11);  }  /* extract lba cd disk size */  lbaDiskSize = BYTEREAD24(buf, VOLUMESPACESIZE_POS);  /* extract sector size */  sectorSize = BYTEREAD16(buf, LOGICALBLOCKSIZE_POS);  cdd->PD.ISO_pd.DiscSize = ((unsigned long) lbaDiskSize) * ((unsigned long) sectorSize);  cdd->PD.ISO_pd.PathTableLba = BYTEREAD24(buf, PATHTABLELBA_POS);  cdd->PD.ISO_pd.PathTableLength = BYTEREAD24(buf, PATHTABLESIZE_POS);  cdd->PD.ISO_pd.RootRecordLba = BYTEREAD24(buf, ROOTDIRLBA_POS);  DEBUG_LOG("PathTable LBA : %d\n", cdd->PD.ISO_pd.PathTableLba)  DEBUG_LOG("PathTable length : %d\n", cdd->PD.ISO_pd.PathTableLength)  DEBUG_LOG("RootRecordLba : %d\n", cdd->PD.ISO_pd.RootRecordLba)  return S_OK;}/*************************************************************************//*****************************************************************/#if 0 // [RB] commented out to reduce ROM spaceuint8 ISO_ExtensionCheck(FILE_STRUCT *file, char *ex){  return 1;}#endif

⌨️ 快捷键说明

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