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

📄 _cdio_bsdi.c

📁 linux下的MPEG1
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    $Id: _cdio_bsdi.c,v 1.3 2005/01/01 02:43:57 rockyb Exp $    Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>    Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*//* This file contains BSDI-specific code and implements low-level    control of the CD drive.*/#ifdef HAVE_CONFIG_H# include "config.h"#endifstatic const char _rcsid[] = "$Id: _cdio_bsdi.c,v 1.3 2005/01/01 02:43:57 rockyb Exp $";#include <cdio/logging.h>#include <cdio/sector.h>#include <cdio/util.h>#include "cdio_assert.h"#include "cdio_private.h"#define DEFAULT_CDIO_DEVICE "/dev/rsr0c"#include <string.h>#ifdef HAVE_BSDI_CDROM#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <unistd.h>#include <fcntl.h>/*#define USE_ETC_FSTAB*/#ifdef USE_ETC_FSTAB#include <fstab.h>#endif#include <dvd.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/ioctl.h>#include </sys/dev/scsi/scsi.h>#include </sys/dev/scsi/scsi_ioctl.h>#include "cdtext_private.h"typedef  enum {  _AM_NONE,  _AM_IOCTL,} access_mode_t;typedef struct {  /* Things common to all drivers like this.      This must be first. */  generic_img_private_t gen;   access_mode_t access_mode;  /* Some of the more OS specific things. */  /* Track information */  struct cdrom_tochdr    tochdr;  struct cdrom_tocentry  tocent[CDIO_CD_MAX_TRACKS+1]; } _img_private_t;/* Define the Cdrom Generic Command structure */typedef struct  cgc{  scsi_mmc_cdb_t cdb;  u_char  *buf;  int     buflen;  int     rw;  unsigned int timeout;  scsi_user_sense_t *sus;} cgc_t;/*    This code adapted from Steven M. Schultz's libdvd*/static int run_scsi_cmd_bsdi(const void *p_user_data, unsigned int i_timeout_ms,		  unsigned int i_cdb, const scsi_mmc_cdb_t *p_cdb, 		  scsi_mmc_direction_t e_direction, 		  unsigned int i_buf, /*in/out*/ void *p_buf ){  const _img_private_t *p_env = p_user_data;  int     i_status, i_asc;  struct  scsi_user_cdb suc;  struct  scsi_sense   *sp;   again:  suc.suc_flags = SCSI_MMC_DATA_READ == e_direction ?     SUC_READ : SUC_WRITE;  suc.suc_cdblen = i_cdb;  memcpy(suc.suc_cdb, p_cdb, i_cdb);  suc.suc_data = p_buf;  suc.suc_datalen = i_buf;  suc.suc_timeout = msecs2secs(i_timeout_ms);  if      (ioctl(p_env->gen.fd, SCSIRAWCDB, &suc) == -1)    return(errno);  i_status = suc.suc_sus.sus_status;#if 0    /*   * If the device returns a scsi sense error and debugging is enabled print   * some hopefully useful information on stderr.   */  if      (i_status && debug)    {      unsigned char   *cp;      int i;      cp = suc.suc_sus.sus_sense;      fprintf(stderr,"i_status = %x cdb =",	      i_status);      for     (i = 0; i < cdblen; i++)	fprintf(stderr, " %x", cgc->cdb[i]);      fprintf(stderr, "\nsense =");      for     (i = 0; i < 16; i++)	fprintf(stderr, " %x", cp[i]);      fprintf(stderr, "\n");    }#endif  /*   * HACK!  Some drives return a silly "medium changed" on the first   * command AND a non-zero i_status which gets turned into a fatal   * (EIO) error even though the operation was a success.  Retrying   * the operation clears the media changed status and gets the   * answer.  */  sp = (struct scsi_sense *)&suc.suc_sus.sus_sense;  i_asc = XSENSE_ASC(sp);  if      (i_status == STS_CHECKCOND && i_asc == 0x28)    goto again;#if 0  if      (cgc->sus)    memcpy(cgc->sus, &suc.suc_sus, sizeof (struct scsi_user_sense));#endif  return(i_status);}/* 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 boolcdio_is_cdrom(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_EXCL|O_NONBLOCK), 0);  /* Should we want to test the condition in more detail:     ENOENT is the error for /dev/xxxxx does not exist;     ENODEV means there's no drive present. */  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, "cd9660") == 0) ) {    is_cd = true;  }  return(is_cd);}/*!  Initialize CD device. */static bool_cdio_init (_img_private_t *p_env){  if (p_env->gen.init) {    cdio_warn ("init called more than once");    return false;  }    p_env->gen.fd = open (p_env->gen.source_name, O_RDONLY, 0);  if (p_env->gen.fd < 0)    {      cdio_warn ("open (%s): %s", p_env->gen.source_name, strerror (errno));      return false;    }  p_env->gen.init = true;  p_env->gen.toc_init = false;  return true;}/* Read audio sectors*/static int_read_audio_sectors_bsdi (void *user_data, void *data, lsn_t lsn,			  unsigned int nblocks){  char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };  struct cdrom_msf *msf = (struct cdrom_msf *) &buf;  msf_t _msf;  _img_private_t *p_env = 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);  if (p_env->gen.ioctls_debugged == 75)    cdio_debug ("only displaying every 75th ioctl from now on");  if (p_env->gen.ioctls_debugged == 30 * 75)    cdio_debug ("only displaying every 30*75th ioctl from now on");    if (p_env->gen.ioctls_debugged < 75       || (p_env->gen.ioctls_debugged < (30 * 75)  	  && p_env->gen.ioctls_debugged % 75 == 0)      || p_env->gen.ioctls_debugged % (30 * 75) == 0)    cdio_debug ("reading %2.2d:%2.2d:%2.2d",	       msf->cdmsf_min0, msf->cdmsf_sec0, msf->cdmsf_frame0);    p_env->gen.ioctls_debugged++;   switch (p_env->access_mode) {    case _AM_NONE:      cdio_warn ("no way to read audio");      return 1;      break;          case _AM_IOCTL: {      unsigned int i;      for (i=0; i < nblocks; i++) {	if (ioctl (p_env->gen.fd, CDROMREADRAW, &buf) == -1)  {	  perror ("ioctl()");	  return 1;	  /* exit (EXIT_FAILURE); */	}	memcpy (((char *)data) + (CDIO_CD_FRAMESIZE_RAW * i), buf, 		CDIO_CD_FRAMESIZE_RAW);      }      break;    }  }  return 0;}/*!   Reads a single mode1 sector from cd device into data starting   from lsn. Returns 0 if no error.  */static int_read_mode1_sector_bsdi (void *user_data, void *data, lsn_t lsn, 			 bool b_form2){#if FIXED  char buf[M2RAW_SECTOR_SIZE] = { 0, };  do something here. #else  return cdio_generic_read_form1_sector(user_data, 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_bsdi (void *user_data, void *data, lsn_t lsn, 			  bool b_form2, unsigned int nblocks){  _img_private_t *p_env = 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_bsdi (p_env, 					    ((char *)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_bsdi (void *user_data, void *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 = 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);  if (p_env->gen.ioctls_debugged == 75)    cdio_debug ("only displaying every 75th ioctl from now on");  if (p_env->gen.ioctls_debugged == 30 * 75)    cdio_debug ("only displaying every 30*75th ioctl from now on");    if (p_env->gen.ioctls_debugged < 75       || (p_env->gen.ioctls_debugged < (30 * 75)  	  && p_env->gen.ioctls_debugged % 75 == 0)      || p_env->gen.ioctls_debugged % (30 * 75) == 0)    cdio_debug ("reading %2.2d:%2.2d:%2.2d",	       msf->cdmsf_min0, msf->cdmsf_sec0, msf->cdmsf_frame0);    p_env->gen.ioctls_debugged++;   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;    }  if (b_form2)    memcpy (data, buf, M2RAW_SECTOR_SIZE);  else    memcpy (((char *)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_bsdi (void *user_data, void *data, lsn_t lsn, 			  bool b_form2, unsigned int nblocks){  _img_private_t *p_env = 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 = _read_mode2_sector_bsdi(p_env, 					 ((char *)data) + 					 (i_blocksize * i),					 lsn + i, b_form2);    if (retval) return retval;  }  return 0;}/*!   Return the size of the CD in logical block address (LBA) units. */static uint32_t _stat_size_bsdi (void *user_data){  _img_private_t *p_env = user_data;  struct cdrom_tocentry tocent;  uint32_t size;  tocent.cdte_track = CDIO_CDROM_LEADOUT_TRACK;  tocent.cdte_format = CDROM_LBA;  if (ioctl (p_env->gen.fd, CDROMREADTOCENTRY, &tocent) == -1)    {      perror ("ioctl(CDROMREADTOCENTRY)");      exit (EXIT_FAILURE);    }  size = tocent.cdte_addr.lba;  return size;}

⌨️ 快捷键说明

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