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

📄 interface.c

📁 刻录光盘的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* @(#)interface.c	1.3 00/01/25 Copyright 1998,1999 Heiko Eissfeldt */#ifndef lintstatic char     sccsid[] ="@(#)interface.c	1.3 00/01/25 Copyright 1998,1999 Heiko Eissfeldt";#endif/*** * CopyPolicy: GNU Public License 2 applies * Copyright (C) 1994-1997 Heiko Eissfeldt heiko@colossus.escape.de * * Interface module for cdrom drive access * * Two interfaces are possible. * * 1. using 'cooked' ioctls() (Linux only) *    : available for atapi, sbpcd and cdu31a drives only. * * 2. using the generic scsi device (for details see SCSI Prog. HOWTO). *    NOTE: a bug/misfeature in the kernel requires blocking signal *          SIGINT during SCSI command handling. Once this flaw has *          been removed, the sigprocmask SIG_BLOCK and SIG_UNBLOCK calls *          should removed, thus saving context switches. * * For testing purposes I have added a third simulation interface. * * Version 0.8: used experiences of Jochen Karrer. *              SparcLinux port fixes *              AlphaLinux port fixes * */#if 0#define SIM_CD#endif#include "config.h"#include <stdio.h>#include <standard.h>#include <stdlib.h>#include <unixstd.h>#include <strdefs.h>#include <errno.h>#include <signal.h>#include <fcntl.h>#include <assert.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <statdefs.h>#include "mycdrom.h"#include "lowlevel.h"/* some include file locations have changed with newer kernels */#if defined (__linux__)# if LINUX_VERSION_CODE > 0x10300 + 97#  if LINUX_VERSION_CODE < 0x200ff#   include <linux/sbpcd.h>#   include <linux/ucdrom.h>#  endif#  if !defined(CDROM_SELECT_SPEED)#   include <linux/ucdrom.h>#  endif# endif#endif#include <scg/scsitransp.h>#include "mytype.h"#include "byteorder.h"#include "interface.h"#include "cdda2wav.h"#include "semshm.h"#include "setuid.h"#include "ringbuff.h"#include "toc.h"#include "global.h"#include "ioctl.h"#include "scsi_cmds.h"#include <utypes.h>#include <cdrecord.h>unsigned interface;int trackindex_disp = 0;TOC g_toc [MAXTRK]; /* 100 */unsigned char MCN[14];  /* including a zero string terminator */void     (*EnableCdda) __PR((SCSI *, int Switch));unsigned (*ReadToc) __PR(( SCSI *scgp, TOC *ptoc ));void	 (*ReadTocText) __PR(( SCSI *scgp ));unsigned (*ReadLastAudio) __PR(( SCSI *scgp, unsigned tracks ));void     (*ReadCdRom) __PR((SCSI *scgp, UINT4 *p, unsigned lSector, unsigned SectorBurstVal ));void     (*ReadCdRomData) __PR((SCSI *scgp, unsigned char *p, unsigned lSector, unsigned SectorBurstVal ));subq_chnl *(*ReadSubQ) __PR(( SCSI *scgp, unsigned char sq_format, unsigned char track ));void     (*SelectSpeed) __PR(( SCSI *scgp, unsigned speed ));int	(*Play_at) __PR(( SCSI *scgp, unsigned int from_sector, unsigned int sectors));int	(*StopPlay) __PR(( SCSI *scgp));void	(*trash_cache) __PR((UINT4 *p, unsigned lSector, unsigned SectorBurstVal));typedef struct string_len {  char *str;  unsigned int sl;} mystring;static mystring drv_is_not_mmc[] = {	{"SONY    CD-ROM CDU625    1.0",28},	{NULL,0}	/* must be last entry */};static mystring drv_has_mmc_cdda[] = {	{NULL,0}	/* must be last entry */};static int	Is_a_Toshiba3401;int Toshiba3401 __PR((void));int Toshiba3401 ( ) {  return Is_a_Toshiba3401;}/* hook */static void Dummy __PR(( void ));static void Dummy ( ){}static SCSI    *scgp;SCSI * get_scsi_p __PR((void));SCSI * get_scsi_p( ){    return scgp;}#if !defined(SIM_CD)static void trash_cache_SCSI __PR((UINT4 *p, unsigned lSector, unsigned SectorBurstVal));static void trash_cache_SCSI(p, lSector, SectorBurstVal)	UINT4 *p;	unsigned lSector;	unsigned SectorBurstVal;{      /* trash the cache */      ReadCdRom(get_scsi_p(), p, find_an_off_sector(lSector, SectorBurstVal), min(global.nsectors,6));}static void Check_interface_for_device __PR((struct stat *statstruct, char *pdev_name));static int OpenCdRom __PR((char *pdev_name));static void SetupSCSI __PR((void));static void SetupSCSI( ){    unsigned char *p;    if (interface != GENERIC_SCSI) {	/* unfortunately we have the wrong interface and are	 * not able to change on the fly */	fprintf(stderr, "The generic SCSI interface and devices are required\n");	exit(1);    }    /* do a test unit ready to 'init' the device. */    TestForMedium(scgp);    /* check for the correct type of unit. */    p = Inquiry(scgp);#undef TYPE_ROM#define TYPE_ROM 5#undef TYPE_WORM#define TYPE_WORM  4    if (p == NULL) {	fprintf(stderr, "Inquiry command failed. Aborting...\n");	exit(1);    }    if ((*p != TYPE_ROM && *p != TYPE_WORM)) {	fprintf(stderr, "this is neither a scsi cdrom nor a worm device\n");	exit(1);    }    /* generic Sony type defaults */    density = 0x0;    accepts_fua_bit = -1;    accepts_fua_bit = -1;    EnableCdda = (void (*) __PR((SCSI *, int)))Dummy;    ReadCdRom = ReadCdda12;    ReadCdRomData = (void (*) __PR((SCSI *, unsigned char *, unsigned, unsigned ))) ReadStandard;    ReadLastAudio = ReadFirstSessionTOCSony;    SelectSpeed = SpeedSelectSCSISony;    Play_at = Play_atSCSI;    StopPlay = StopPlaySCSI;    trash_cache = trash_cache_SCSI;    ReadTocText = ReadTocTextSCSIMMC;    /* check for brands and adjust special peculiaritites */    /* If your drive is not treated correctly, you can adjust some things       here:       *in_leendian: should be to 1, if the CDROM drive or CD-Writer		  delivers the samples in the native byteorder of the audio cd		  (LSB first).		  HP CD-Writers need it set to 0.       NOTE: If you get correct wav files when using sox with the '-x' option,             the endianess is wrong. You can use the -C option to specify	     the value of (*in_lendian).     */    {      int mmc_code;      allow_atapi(scgp, 1);      if (*p == TYPE_ROM) {        mmc_code = heiko_mmc(scgp);      } else {        mmc_code = 0;      }      /* Exceptions for drives that report incorrect MMC capability */      if (mmc_code != 0) {	/* these drives are NOT capable of MMC commands */        mystring *pp = drv_is_not_mmc;	while (pp->str != NULL) {	  if (!strncmp(pp->str, (char *)p+8,pp->sl)) {	    mmc_code = 0;	    break;	  }	  pp++;        }      }      {	/* these drives flag themselves as non-MMC, but offer CDDA reading	   only with a MMC method. */        mystring *pp = drv_has_mmc_cdda;	while (pp->str != NULL) {	  if (!strncmp(pp->str, (char *)p+8,pp->sl)) {	    mmc_code = 1;	    break;	  }	  pp++;        }      }      switch (mmc_code) {       case 2:      /* SCSI-3 cdrom drive with accurate audio stream */         if ( (*in_lendian) == -1 )	   (*in_lendian) = 1;         global.overlap = 0;         ReadCdRom = ReadCddaMMC12;         ReadLastAudio = ReadFirstSessionTOCMMC;         global.speed = 0xffff;         SelectSpeed = SpeedSelectSCSIMMC;    	 ReadTocText = ReadTocTextSCSIMMC;       break;       case 1:      /* SCSI-3 cdrom drive with no accurate audio stream */         if ( (*in_lendian) == -1 )	   (*in_lendian) = 1;         global.overlap = 1;         ReadCdRom = ReadCddaMMC12;         ReadLastAudio = ReadFirstSessionTOCMMC;         global.speed = 0xffff;         SelectSpeed = SpeedSelectSCSIMMC;         break;       case -1: /* "MMC drive does not support cdda reading, sorry\n." */	/* fall through */       case 0:      /* non SCSI-3 cdrom drive */         ReadLastAudio = NULL;    if (!memcmp(p+8,"TOSHIBA", 7) ||        !memcmp(p+8,"IBM", 3) ||        !memcmp(p+8,"DEC", 3)) {	density = 0x82;	EnableCdda = EnableCddaModeSelect; 	ReadCdRom = ReadStandard;        SelectSpeed = SpeedSelectSCSIToshiba;        if (!memcmp(p+16, "CD-ROM XM-3401",14)) {	   Is_a_Toshiba3401 = 1;	}	if ( (*in_lendian) == -1 )		(*in_lendian) = 1;    } else if (!memcmp(p+8,"IMS",3) ||               !memcmp(p+8,"KODAK",5) ||               !memcmp(p+8,"RICOH",5) ||               !memcmp(p+8,"HP",2) ||               !memcmp(p+8,"PHILIPS",7) ||               !memcmp(p+8,"PLASMON",7) ||               !memcmp(p+8,"GRUNDIG CDR100IPW",17) ||               !memcmp(p+8,"MITSUMI CD-R ",13)) {	EnableCdda = EnableCddaModeSelect;	ReadCdRom = ReadStandard;        SelectSpeed = SpeedSelectSCSIPhilipsCDD2600;	/* treat all of these as bigendian */	if ( (*in_lendian) == -1 )		(*in_lendian) = 0;	/* no overlap reading for cd-writers */	global.overlap = 0;    } else if (!memcmp(p+8,"NRC",3)) {        SelectSpeed = NULL;    } else if (!memcmp(p+8,"YAMAHA",6)) {	EnableCdda = EnableCddaModeSelect;        SelectSpeed = SpeedSelectSCSIYamaha;	/* no overlap reading for cd-writers */	global.overlap = 0;	if ( (*in_lendian) == -1 )		(*in_lendian) = 1;    } else if (!memcmp(p+8,"PLEXTOR",7)) {	if ( (*in_lendian) == -1 )		(*in_lendian) = 1;	global.overlap = 0;        ReadLastAudio = ReadFirstSessionTOCSony;    	ReadTocText = ReadTocTextSCSIMMC;    } else if (!memcmp(p+8,"SONY",4)) {	if ( (*in_lendian) == -1 )		(*in_lendian) = 1;        if (!memcmp(p+16, "CD-ROM CDU55E",13)) {	   ReadCdRom = ReadCddaMMC12;	}        ReadLastAudio = ReadFirstSessionTOCSony;    	ReadTocText = ReadTocTextSCSIMMC;    } else if (!memcmp(p+8,"NEC",3)) {	ReadCdRom = ReadCdda10;        ReadTocText = NULL;        SelectSpeed = SpeedSelectSCSINEC;	if ( (*in_lendian) == -1 )		(*in_lendian) = 1;        if (!memcmp(p+29,"5022.0r",3)) /* I assume all versions of the 502 require this? */               global.overlap = 0;           /* no overlap reading for NEC CD-ROM 502 */    } else if (!memcmp(p+8,"MATSHITA",8)) {	ReadCdRom = ReadCdda12Matsushita;	if ( (*in_lendian) == -1 )		(*in_lendian) = 1;    }    } /* switch (get_mmc) */    }    ReadToc = ReadTocSCSI;    ReadSubQ = ReadSubQSCSI;    /* look if caddy is loaded */    if (interface == GENERIC_SCSI) while (!wait_unit_ready(scgp, 60)) {	fprintf(stderr,"load cdrom please and press enter");	getchar();    }}/********************** General setup *******************************//* As the name implies, interfaces and devices are checked.  We also   adjust nsectors, overlap, and interface for the first time here.   Any unnecessary privileges (setuid, setgid) are also dropped here.*/static void Check_interface_for_device( statstruct, pdev_name)	struct stat *statstruct;	char *pdev_name;{#if !defined (STAT_MACROS_BROKEN) || (STAT_MACROS_BROKEN != 1)    if (!S_ISCHR(statstruct->st_mode) &&	!S_ISBLK(statstruct->st_mode)) {      fprintf(stderr, "%s is not a device\n",pdev_name);      exit(1);    }#endif#if defined (HAVE_ST_RDEV) && (HAVE_ST_RDEV == 1)    switch ((int) (statstruct->st_rdev >> 8L)) {#if defined (__linux__)    case SCSI_GENERIC_MAJOR:	/* generic */#else    default:			/* ??? what is the proper value here */#endif#if !defined (STAT_MACROS_BROKEN) || (STAT_MACROS_BROKEN != 1)#if defined (__linux__)       if (!S_ISCHR(statstruct->st_mode)) {	 fprintf(stderr, "%s is not a char device\n",pdev_name);	 exit(1);       }       if (interface != GENERIC_SCSI) {	 fprintf(stderr, "wrong interface (cooked_ioctl) for this device (%s)\nset to generic_scsi\n", pdev_name);	 interface = GENERIC_SCSI;       }#endif#endif       break;#if defined (__linux__) || defined (__FreeBSD__)#if defined (__linux__)    case SCSI_CDROM_MAJOR:     /* scsi cd */    default:			/* for example ATAPI cds */#else#if defined (__FreeBSD__)    case 117:	if (!S_ISCHR(statstruct->st_mode)) {	    fprintf(stderr, "%s is not a char device\n",pdev_name);	    exit(1);	}	if (interface != COOKED_IOCTL) {	    fprintf(stderr, "cdrom device (%s) is not of type generic SCSI. "		    "Setting interface to cooked_ioctl.\n", pdev_name);	    interface = COOKED_IOCTL;	}	break;    case 19:     /* first atapi cd */#endif

⌨️ 快捷键说明

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