Esempio n. 1
0
/*!  
  Return the starting LSN for track number
  i_track in cdio.  Tracks numbers start at 1.
  The "leadout" track is specified either by
  using i_track LEADOUT_TRACK or the total tracks+1.
  CDIO_INVALID_LBA is returned on error.
*/
lsn_t
cdio_get_track_lsn(const CdIo_t *p_cdio, track_t i_track)
{
  if (p_cdio == NULL) return CDIO_INVALID_LSN;

  if (p_cdio->op.get_track_lba) {
    return cdio_lba_to_lsn(p_cdio->op.get_track_lba (p_cdio->env, i_track));
  } else {
    msf_t msf;
    if (cdio_get_track_msf(p_cdio, i_track, &msf))
      return cdio_msf_to_lsn(&msf);
    return CDIO_INVALID_LSN;
  }
}
Esempio n. 2
0
/*!  
  Return the starting LSN for track number
  track_num in cdio.  Tracks numbers start at 1.
  The "leadout" track is specified either by
  using track_num LEADOUT_TRACK or the total tracks+1.
  CDIO_INVALID_LBA is returned on error.
*/
lsn_t
cdio_get_track_lsn(const CdIo *cdio, track_t track_num)
{
  if (cdio == NULL) return CDIO_INVALID_LBA;

  if (cdio->op.get_track_lba) {
    return cdio_lba_to_lsn(cdio->op.get_track_lba (cdio->env, track_num));
  } else {
    msf_t msf;
    if (cdio_get_track_msf(cdio, track_num, &msf))
      return cdio_msf_to_lsn(&msf);
    return CDIO_INVALID_LSN;
  }
}
Esempio n. 3
0
/*!
  Convert a MSF into the corresponding LSN.
  CDIO_INVALID_LSN is returned if there is an error.
*/
lba_t
cdio_msf_to_lsn (const msf_t *msf)
{
  return cdio_lba_to_lsn(cdio_msf_to_lba (msf));
}
Esempio n. 4
0
/*!
  Convert an LBA into the corresponding MSF.
*/
void
cdio_lba_to_msf (lba_t lba, msf_t *msf)
{
  cdio_assert (msf != 0);
  cdio_lsn_to_msf(cdio_lba_to_lsn(lba), msf);
}
Esempio n. 5
0
/*!  
  Return the starting LSN for the pregap for track number
  i_track in cdio.  Track numbers start at 1.
  CDIO_INVALID_LSN is returned on error.
*/
lsn_t
cdio_get_track_pregap_lsn(const CdIo_t *p_cdio, track_t i_track)
{
  return cdio_lba_to_lsn(cdio_get_track_pregap_lba(p_cdio, i_track));
}
Esempio n. 6
0
/*! 
  Read and cache the CD's Track Table of Contents and track info.
  Return true if successful or false if an error.
*/
bool
read_toc_win32ioctl (_img_private_t *p_env) 
{
  CDROM_TOC    cdrom_toc;
  DWORD        dw_bytes_returned;
  unsigned int i, j;
  bool         b_fulltoc_first;  /* Do we do fulltoc or DeviceIoControl 
				    first? */
  if ( ! p_env ) return false;

  /* 
     The MMC5 spec says:
       For media other than CD, information may be fabricated in order
                                            ^^^ ^^
       to emulate a CD structure for the specific media.

     There is no requirement though that it *has* to and some DVD
     drives like one by Thompson for XBOX don't support a
     IOCTL_CDROM_READ_TOC for DVD's. So if we have a DVD we should not
     prefer getting the TOC via MMC.

     But on the other hand in GNU/Linux it is reported that using the
     TOC via MMC gives better information such as for CD DATA Form 2 (used
     in SVCDs). So if we *don't* have a DVD I think we want to try MMC
     first. 

     Is this complicated enough? I could be wrong...

   */
  b_fulltoc_first = (CDIO_DISC_MODE_NO_INFO == dvd_discmode_win32ioctl(p_env));

  if ( b_fulltoc_first && read_fulltoc_win32mmc(p_env) ) return true;

  /* SCSI-MMC READ_TOC (FULTOC) read failed or we don't want to try it
     initiaily.  Try reading TOC via DeviceIoControl... */

  if( DeviceIoControl( p_env->h_device_handle,
		       IOCTL_CDROM_READ_TOC,
		       NULL, 0, &cdrom_toc, sizeof(CDROM_TOC),
		       &dw_bytes_returned, NULL ) == 0 ) {
    char *psz_msg = NULL;
    long int i_err = GetLastError();
    cdio_log_level_t loglevel = b_fulltoc_first 
      ? CDIO_LOG_WARN : CDIO_LOG_DEBUG;

    FORMAT_ERROR(i_err, psz_msg);
    if (psz_msg) {
      cdio_log(loglevel, "could not read TOC (%ld): %s", i_err, psz_msg);
      LocalFree(psz_msg);
    } else 
      cdio_log(loglevel, "could not read TOC (%ld)", i_err);

    if ( !b_fulltoc_first && read_fulltoc_win32mmc(p_env) ) return true;
    return false;
  }
  
  p_env->gen.i_first_track = cdrom_toc.FirstTrack;
  p_env->gen.i_tracks  = cdrom_toc.LastTrack - cdrom_toc.FirstTrack + 1;

  j = p_env->gen.i_first_track;
  for( i = 0 ; i <= p_env->gen.i_tracks ; i++, j++ ) {
    p_env->tocent[ i ].start_lsn = 
      cdio_lba_to_lsn(
		      cdio_msf3_to_lba( cdrom_toc.TrackData[i].Address[1],
					cdrom_toc.TrackData[i].Address[2],
					cdrom_toc.TrackData[i].Address[3] )
		      );
    p_env->tocent[i].Control   = cdrom_toc.TrackData[i].Control;
    p_env->tocent[i].Format    = cdrom_toc.TrackData[i].Adr;

    p_env->gen.track_flags[j].preemphasis = 
      p_env->tocent[i].Control & 0x1 
      ? CDIO_TRACK_FLAG_TRUE : CDIO_TRACK_FLAG_FALSE;

    p_env->gen.track_flags[j].copy_permit = 
      p_env->tocent[i].Control & 0x2 
      ? CDIO_TRACK_FLAG_TRUE : CDIO_TRACK_FLAG_FALSE;
    
    p_env->gen.track_flags[j].channels = 
      p_env->tocent[i].Control & 0x8 ? 4 : 2;
    

    cdio_debug("p_sectors: %i, %lu", i, 
	       (unsigned long int) (p_env->tocent[i].start_lsn));
  }
  p_env->gen.toc_init = true;
  return true;
}
Esempio n. 7
0
/*!  
  Read and cache the CD's Track Table of Contents and track info.
  via a SCSI MMC READ_TOC (FULTOC).  Return true if successful or
  false if an error.
*/
static bool
read_fulltoc_win32mmc (_img_private_t *p_env) 
{
  mmc_cdb_t  cdb = {{0, }};
  CDROM_TOC_FULL  cdrom_toc_full;
  int             i_status, i, j;
  int             i_track_format = 0;
  int             i_seen_flag;

  /* Operation code */
  CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_TOC);

  cdb.field[1] = 0x00;

  /* Format */
  cdb.field[2] = CDIO_MMC_READTOC_FMT_FULTOC;

  memset(&cdrom_toc_full, 0, sizeof(cdrom_toc_full));

  /* Setup to read header, to get length of data */
  CDIO_MMC_SET_READ_LENGTH16(cdb.field, sizeof(cdrom_toc_full));

  i_status = run_mmc_cmd_win32ioctl (p_env, 1000*60*3,
				     mmc_get_cmd_len(cdb.field[0]), 
				     &cdb, SCSI_MMC_DATA_READ, 
				     sizeof(cdrom_toc_full), &cdrom_toc_full);

  if ( 0 != i_status ) {
    cdio_debug ("SCSI MMC READ_TOC failed\n");  
    return false;
  } 
    
  i_seen_flag=0;
  for( i = 0 ; i <= CDIO_CD_MAX_TRACKS+3; i++ ) {
    
    if ( 0xA0 == cdrom_toc_full.TrackData[i].POINT ) { 
      /* First track number */
      p_env->gen.i_first_track = cdrom_toc_full.TrackData[i].PMIN;
      i_track_format = cdrom_toc_full.TrackData[i].PSEC;
      i_seen_flag|=0x01;
    }
    
    if ( 0xA1 == cdrom_toc_full.TrackData[i].POINT ) { 
      /* Last track number */
      p_env->gen.i_tracks = 
	cdrom_toc_full.TrackData[i].PMIN - p_env->gen.i_first_track + 1;
      i_seen_flag|=0x02;
    }

    j = cdrom_toc_full.TrackData[i].POINT;
    if ( 0xA2 ==  j ) { 
      /* Start position of the lead out */
      p_env->tocent[ p_env->gen.i_tracks ].start_lsn = 
	cdio_lba_to_lsn(
			cdio_msf3_to_lba(
					 cdrom_toc_full.TrackData[i].PMIN,
					 cdrom_toc_full.TrackData[i].PSEC,
					 cdrom_toc_full.TrackData[i].PFRAME 
					 )
			);
      p_env->tocent[ p_env->gen.i_tracks ].Control 
	= cdrom_toc_full.TrackData[i].Control;
      p_env->tocent[ p_env->gen.i_tracks ].Format  = i_track_format;
      i_seen_flag|=0x04;
    }
    
    if (cdrom_toc_full.TrackData[i].POINT > 0 
	&& cdrom_toc_full.TrackData[i].POINT <= p_env->gen.i_tracks) {
      p_env->tocent[j-1].start_lsn = 
	cdio_lba_to_lsn(
			cdio_msf3_to_lba(
					 cdrom_toc_full.TrackData[i].PMIN,
					 cdrom_toc_full.TrackData[i].PSEC,
					 cdrom_toc_full.TrackData[i].PFRAME 
					 )
			);
      p_env->tocent[j-1].Control = 
	cdrom_toc_full.TrackData[i].Control;
      p_env->tocent[j-1].Format  = i_track_format;
      
      set_track_flags(&(p_env->gen.track_flags[j]), 
		      p_env->tocent[j-1].Control);
    
      cdio_debug("p_sectors: %i, %lu", i, 
		 (unsigned long int) (p_env->tocent[i].start_lsn));
      
      if (cdrom_toc_full.TrackData[i].POINT == p_env->gen.i_tracks)
	i_seen_flag|=0x08;
    }
    
    if ( 0x0F == i_seen_flag ) break;
  }
  if ( 0x0F == i_seen_flag ) {
    p_env->gen.toc_init = true; 
    return true;
  }
  return false;
}