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

📄 _cdio_linux.c

📁 linux下的MPEG1
💻 C
📖 第 1 页 / 共 3 页
字号:
/*!  Eject media in CD drive.   Return 0 if success and 1 for failure, and 2 if no routine. */static int eject_media_linux (void *p_user_data) {  _img_private_t *p_env = p_user_data;  int ret=2;  int status;  int fd;  if ((fd = open (p_env->gen.source_name, O_RDONLY|O_NONBLOCK)) > -1) {    if((status = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT)) > 0) {      switch(status) {      case CDS_TRAY_OPEN:	if((ret = ioctl(fd, CDROMCLOSETRAY)) != 0) {	  cdio_warn ("ioctl CDROMCLOSETRAY failed: %s\n", strerror(errno));  	  ret = 1;	}	break;      case CDS_DISC_OK:	if((ret = ioctl(fd, CDROMEJECT)) != 0) {	  int eject_error = errno;	  /* Try ejecting the MMC way... */	  ret = scsi_mmc_eject_media(p_env->gen.cdio);	  if (0 != ret) {	    cdio_warn("ioctl CDROMEJECT failed: %s\n", 		      strerror(eject_error));	    ret = 1;	  }	}	/* force kernel to reread partition table when new disc inserted */	ret = ioctl(p_env->gen.fd, BLKRRPART);	break;      default:	cdio_warn ("Unknown CD-ROM (%d)\n", status);	ret = 1;      }    } else {      cdio_warn ("CDROM_DRIVE_STATUS failed: %s\n", strerror(errno));      ret=1;    }    close(fd);  } else    ret = 2;  close(p_env->gen.fd);  p_env->gen.fd = -1;  return ret;}/*!   Get disc type associated with the cd object.*/static discmode_tget_discmode_linux (void *p_user_data){  _img_private_t *p_env = p_user_data;  int32_t i_discmode;  /* See if this is a DVD. */  cdio_dvd_struct_t dvd;  /* DVD READ STRUCT for layer 0. */  dvd.physical.type = CDIO_DVD_STRUCT_PHYSICAL;  dvd.physical.layer_num = 0;  if (0 == ioctl (p_env->gen.fd, DVD_READ_STRUCT, &dvd)) {    switch(dvd.physical.layer[0].book_type) {    case CDIO_DVD_BOOK_DVD_ROM:  return CDIO_DISC_MODE_DVD_ROM;    case CDIO_DVD_BOOK_DVD_RAM:  return CDIO_DISC_MODE_DVD_RAM;    case CDIO_DVD_BOOK_DVD_R:    return CDIO_DISC_MODE_DVD_R;    case CDIO_DVD_BOOK_DVD_RW:   return CDIO_DISC_MODE_DVD_RW;    case CDIO_DVD_BOOK_DVD_PR:   return CDIO_DISC_MODE_DVD_PR;    case CDIO_DVD_BOOK_DVD_PRW:  return CDIO_DISC_MODE_DVD_PRW;    default:                     return CDIO_DISC_MODE_DVD_OTHER;    }  }  i_discmode = ioctl (p_env->gen.fd, CDROM_DISC_STATUS);    if (i_discmode < 0) return CDIO_DISC_MODE_ERROR;  /* FIXME Need to add getting DVD types. */  switch(i_discmode) {  case CDS_AUDIO:    return CDIO_DISC_MODE_CD_DA;  case CDS_DATA_1:  case CDS_DATA_2:    return CDIO_DISC_MODE_CD_DATA;  case CDS_MIXED:    return CDIO_DISC_MODE_CD_MIXED;  case CDS_XA_2_1:  case CDS_XA_2_2:    return CDIO_DISC_MODE_CD_XA;  case CDS_NO_INFO:    return CDIO_DISC_MODE_NO_INFO;  default:    return CDIO_DISC_MODE_ERROR;  }}/* Check a drive to see if it is a CD-ROM    Return 1 if a CD-ROM. 0 if it exists but isn't a CD-ROM drive   and -1 if no device exists .*/static boolis_cdrom_linux(const char *drive, char *mnttype){  bool is_cd=false;  int cdfd;  struct cdrom_tochdr    tochdr;    /* If it doesn't exist, return -1 */  if ( !cdio_is_device_quiet_generic(drive) ) {    return(false);  }    /* If it does exist, verify that it's an available CD-ROM */  cdfd = open(drive, (O_RDONLY|O_NONBLOCK), 0);  if ( cdfd >= 0 ) {    if ( ioctl(cdfd, CDROMREADTOCHDR, &tochdr) != -1 ) {      is_cd = true;    }    close(cdfd);    }  /* Even if we can't read it, it might be mounted */  else if ( mnttype && (strcmp(mnttype, "iso9660") == 0) ) {    is_cd = true;  }  return(is_cd);}/* MMC driver to read audio sectors.    Can read only up to 25 blocks.*/static int_read_audio_sectors_linux (void *p_user_data, void *buf, lsn_t lsn, 			   unsigned int nblocks){  _img_private_t *p_env = p_user_data;  return scsi_mmc_read_sectors( p_env->gen.cdio, buf, lsn, 				CDIO_MMC_READ_TYPE_CDDA, nblocks);}/* Packet driver to read mode2 sectors.    Can read only up to 25 blocks.*/static int_read_mode2_sectors_mmc (_img_private_t *p_env, void *p_buf, lba_t lba, 			 unsigned int nblocks, bool b_read_10){  scsi_mmc_cdb_t cdb = {{0, }};  CDIO_MMC_SET_READ_LBA(cdb.field, lba);  if (b_read_10) {    int retval;        CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_10);    CDIO_MMC_SET_READ_LENGTH16(cdb.field, nblocks);    if ((retval = scsi_mmc_set_blocksize (p_env->gen.cdio, M2RAW_SECTOR_SIZE)))      return retval;        if ((retval = run_scsi_cmd_linux (p_env, 0, 				      scsi_mmc_get_cmd_len(cdb.field[0]),				      &cdb, 				      SCSI_MMC_DATA_READ,				      M2RAW_SECTOR_SIZE * nblocks, 				      p_buf)))      {	scsi_mmc_set_blocksize (p_env->gen.cdio, CDIO_CD_FRAMESIZE);	return retval;      }        if ((retval = scsi_mmc_set_blocksize (p_env->gen.cdio, CDIO_CD_FRAMESIZE)))      return retval;  } else    cdb.field[1] = 0; /* sector size mode2 */    cdb.field[9] = 0x58; /* 2336 mode2 */    CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_CD);    CDIO_MMC_SET_READ_LENGTH24(cdb.field, nblocks);    return run_scsi_cmd_linux (p_env, 0, 			       scsi_mmc_get_cmd_len(cdb.field[0]), &cdb, 			       SCSI_MMC_DATA_READ,			       M2RAW_SECTOR_SIZE * nblocks, p_buf);    return 0;}static int_read_mode2_sectors (_img_private_t *p_env, void *p_buf, lba_t lba, 		     unsigned int nblocks, bool b_read_10){  unsigned int l = 0;  int retval = 0;  while (nblocks > 0)    {      const unsigned nblocks2 = (nblocks > 25) ? 25 : nblocks;      void *p_buf2 = ((char *)p_buf ) + (l * M2RAW_SECTOR_SIZE);            retval |= _read_mode2_sectors_mmc (p_env, p_buf2, lba + l, 					 nblocks2, b_read_10);      if (retval)	break;      nblocks -= nblocks2;      l += nblocks2;    }  return retval;}/*!   Reads a single mode1 sector from cd device into data starting   from lsn. Returns 0 if no error.  */static int_read_mode1_sector_linux (void *p_user_data, void *p_data, lsn_t lsn, 			 bool b_form2){#if FIXED  char buf[M2RAW_SECTOR_SIZE] = { 0, };  struct cdrom_msf *p_msf = (struct cdrom_msf *) &buf;  msf_t _msf;  _img_private_t *p_env = p_user_data;  cdio_lba_to_msf (cdio_lsn_to_lba(lsn), &_msf);  msf->cdmsf_min0 = cdio_from_bcd8(_msf.m);  msf->cdmsf_sec0 = cdio_from_bcd8(_msf.s);  msf->cdmsf_frame0 = cdio_from_bcd8(_msf.f); retry:  switch (p_env->access_mode)    {    case _AM_NONE:      cdio_warn ("no way to read mode1");      return 1;      break;          case _AM_IOCTL:      if (ioctl (p_env->gen.fd, CDROMREADMODE1, &buf) == -1)	{	  perror ("ioctl()");	  return 1;	  /* exit (EXIT_FAILURE); */	}      break;          case _AM_READ_CD:    case _AM_READ_10:      if (_read_mode2_sectors (p_env->gen.fd, buf, lsn, 1, 				      (p_env->access_mode == _AM_READ_10)))	{	  perror ("ioctl()");	  if (p_env->access_mode == _AM_READ_CD)	    {	      cdio_info ("READ_CD failed; switching to READ_10 mode...");	      p_env->access_mode = _AM_READ_10;	      goto retry;	    }	  else	    {	      cdio_info ("READ_10 failed; switching to ioctl(CDROMREADMODE2) mode...");	      p_env->access_mode = _AM_IOCTL;	      goto retry;	    }	  return 1;	}      break;    }  memcpy (data, buf + CDIO_CD_SYNC_SIZE + CDIO_CD_HEADER_SIZE, 	  b_form2 ? M2RAW_SECTOR_SIZE: CDIO_CD_FRAMESIZE);  #else  return cdio_generic_read_form1_sector(p_user_data, p_data, lsn);#endif  return 0;}/*!   Reads nblocks of mode2 sectors from cd device into data starting   from lsn.   Returns 0 if no error.  */static int_read_mode1_sectors_linux (void *p_user_data, void *p_data, lsn_t lsn, 			  bool b_form2, unsigned int nblocks){  _img_private_t *p_env = p_user_data;  unsigned int i;  int retval;  unsigned int blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE;  for (i = 0; i < nblocks; i++) {    if ( (retval = _read_mode1_sector_linux (p_env,					    ((char *)p_data) + (blocksize*i),					    lsn + i, b_form2)) )      return retval;  }  return 0;}/*!   Reads a single mode2 sector from cd device into data starting   from lsn. Returns 0 if no error.  */static int_read_mode2_sector_linux (void *p_user_data, void *p_data, lsn_t lsn, 			  bool b_form2){  char buf[M2RAW_SECTOR_SIZE] = { 0, };  struct cdrom_msf *msf = (struct cdrom_msf *) &buf;  msf_t _msf;  _img_private_t *p_env = p_user_data;  cdio_lba_to_msf (cdio_lsn_to_lba(lsn), &_msf);  msf->cdmsf_min0 = cdio_from_bcd8(_msf.m);  msf->cdmsf_sec0 = cdio_from_bcd8(_msf.s);  msf->cdmsf_frame0 = cdio_from_bcd8(_msf.f); retry:  switch (p_env->access_mode)    {    case _AM_NONE:      cdio_warn ("no way to read mode2");      return 1;      break;          case _AM_IOCTL:      if (ioctl (p_env->gen.fd, CDROMREADMODE2, &buf) == -1)	{	  perror ("ioctl()");	  return 1;	  /* exit (EXIT_FAILURE); */	}      break;          case _AM_READ_CD:    case _AM_READ_10:      if (_read_mode2_sectors (p_env, buf, lsn, 1, 			       (p_env->access_mode == _AM_READ_10)))	{	  perror ("ioctl()");	  if (p_env->access_mode == _AM_READ_CD)	    {	      cdio_info ("READ_CD failed; switching to READ_10 mode...");	      p_env->access_mode = _AM_READ_10;	      goto retry;	    }	  else	    {	      cdio_info ("READ_10 failed; switching to ioctl(CDROMREADMODE2) mode...");	      p_env->access_mode = _AM_IOCTL;	      goto retry;	    }	  return 1;	}      break;    }  if (b_form2)    memcpy (p_data, buf, M2RAW_SECTOR_SIZE);  else    memcpy (((char *)p_data), buf + CDIO_CD_SUBHEADER_SIZE, CDIO_CD_FRAMESIZE);    return 0;}/*!   Reads nblocks of mode2 sectors from cd device into data starting   from lsn.   Returns 0 if no error.  */static int_read_mode2_sectors_linux (void *p_user_data, void *data, lsn_t lsn, 			  bool b_form2, unsigned int nblocks){  _img_private_t *p_env = p_user_data;  unsigned int i;  unsigned int i_blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE;  /* For each frame, pick out the data part we need */  for (i = 0; i < nblocks; i++) {    int retval;    if ( (retval = _read_mode2_sector_linux (p_env, 					    ((char *)data) + (i_blocksize*i),					    lsn + i, b_form2)) )      return retval;  }

⌨️ 快捷键说明

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