shithub: libdvdcss

Download patch

ref: aa2a222868f993d893b1448461292e95940f3aca
parent: 50899042baa76832eeead4ab35fe0d49c4dd0b85
author: Steven M. Schultz <[email protected]>
date: Thu Dec 19 10:29:53 EST 2002

* ./src/bsdi_ioctl.c, ./src/bsdi_dvd.h: updated the bsdi libdvd with
    Steven M. Schultz's latest changes.


--- a/src/bsdi_dvd.h
+++ b/src/bsdi_dvd.h
@@ -1,3 +1,7 @@
+/*
+ * $Id: bsdi_dvd.h,v 1.3 2002/12/19 15:29:53 sam Exp $
+*/
+
 #ifndef	_DVD_H_
 #define	_DVD_H_
 
@@ -224,6 +228,7 @@
 #define CDROMEJECT		0x5309 /* Ejects the cdrom media */
 #define CDROMCLOSETRAY          0x5319 /* Reverse of CDROMEJECT */
 #define CDROM_DRIVE_STATUS      0x5326 /* Get tray position, etc. */
+#define CDROM_DISC_STATUS	0x5327 /* Get disc type, etc. */
 #define CDROMREADMODE2		0x530c /* Read CDROM mode 2 data (2336 Bytes) */
 #define CDROMREADMODE1		0x530d /* Read CDROM mode 1 data (2048 Bytes) */
 #define CDROMREADRAW            0x5314 /* read data in raw mode (2352 bytes) */
@@ -244,6 +249,9 @@
 #define CDROM_LBA 0x01 		/* logical block: first frame is #0 */
 #define CDROM_MSF 0x02 		/* minute-second-frame: binary. not bcd here!*/
 
+/* bit to tell whether track is data or audio (cdrom_tocentry.cdte_ctrl) */
+#define CDROM_DATA_TRACK        0x04
+
 /* The leadout track is always 0xAA, regardless of # of tracks on disc */
 #define CDROM_LEADOUT           0xAA
 
@@ -254,6 +262,17 @@
 #define CDS_DRIVE_NOT_READY     3
 #define CDS_DISC_OK             4
 
+/*
+ * Return values for CDROM_DISC_STATUS ioctl.
+ * Can also return CDS_NO_INFO and CDS_NO_DISC from above
+*/
+#define	CDS_AUDIO		100
+#define	CDS_DATA_1		101
+#define	CDS_DATA_2		102
+#define	CDS_XA_2_1		103
+#define	CDS_XA_2_2		104
+#define	CDS_MIXED		105
+
 /* For compile compatibility only - we don't support changers */
 #define CDSL_NONE               ((int) (~0U>>1)-1)
 #define CDSL_CURRENT            ((int) (~0U>>1))
@@ -312,4 +331,14 @@
 	__u8	block_length_med;
 	__u8	block_length_lo;
 };
+
+typedef	struct
+{
+	int	data;
+	int	audio;
+	int	cdi;
+	int	xa;
+	int	error;
+} tracktype;
+
 #endif /* _DVD_H_ */
--- a/src/bsdi_ioctl.c
+++ b/src/bsdi_ioctl.c
@@ -49,8 +49,9 @@
 static int scsi_cmd(int, cgc_t *);
 static int cdrom_ioctl(int, u_long, void *);
 static int cdrom_tray_move(int, int);
+static void cdrom_count_tracks(int, tracktype *);
 static int dvd_ioctl(int, u_long, void *);
-static	int	debug;
+static	int	debug = 0;
 
 void dvd_cdrom_debug(int flag)
 	{
@@ -72,9 +73,11 @@
 		case	CDROMREADTOCENTRY:
 		case	CDROMEJECT:
 		case	CDROMREADRAW:
+		case	CDROMREADMODE1:
 		case	CDROMREADMODE2:
 		case	CDROMCLOSETRAY:
 		case	CDROM_DRIVE_STATUS:
+		case	CDROM_DISC_STATUS:
 			return(cdrom_ioctl(fd, cmd, arg));
 		default:
 			return(ioctl(fd, cmd, arg));
@@ -401,7 +404,7 @@
 
 static int scsi_cmd(int fd, cgc_t *cgc)
 	{
-	int	scsistatus, cdblen;
+	int	i, scsistatus, cdblen;
 	unsigned char	*cp;
 	struct	scsi_user_cdb suc;
 
@@ -427,12 +430,14 @@
 	if	(scsistatus && debug)
 		{
 		cp = suc.suc_sus.sus_sense;
-		fprintf(stderr,"scsistatus = %x cmd = %x\n",
-			scsistatus, cgc->cdb[0]);
-		fprintf(stderr, "sense %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
-			cp[0], cp[1], cp[2], cp[3], cp[4], cp[5],
-			cp[6], cp[7], cp[8], cp[9], cp[10], cp[11],
-			cp[12], cp[13], cp[14], cp[15]);
+		fprintf(stderr,"scsistatus = %x cdb =",
+			scsistatus);
+		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");
 		}
 	if	(cgc->sus)
 		bcopy(&suc.suc_sus, cgc->sus, sizeof (struct scsi_user_sense));
@@ -456,7 +461,7 @@
 				errno = ret;
 			return(ret ? -1 : 0);
 		case	DVD_AUTH:
-			ret = dvd_do_auth (fd, (dvd_authinfo *)arg);
+			ret = dvd_do_auth(fd, (dvd_authinfo *)arg);
 			if	(ret)
 				errno = ret;
 			return(ret ? -1 : 0);
@@ -596,11 +601,35 @@
  * This sucks but emulates the expected behaviour.  Instead of the return
  * value being the actual status a success/fail indicator should have been
  * returned and the 3rd arg to the ioctl should have been an 'int *' to update
- * with the actual status.
+ * with the actual status.   Both the drive and disc status ioctl calls are
+ * similarily braindamaged.
 */
 		case	CDROM_DRIVE_STATUS:
+			return(CDS_NO_INFO);	/* XXX */
+		case	CDROM_DISC_STATUS:
+			{
+			tracktype tracks;
+			int	cnt;
+
+			cdrom_count_tracks(fd, &tracks);
+			if	(tracks.error)
+				return(tracks.error);
+			if	(tracks.audio > 0)
+				{
+				cnt = tracks.data + tracks.cdi + tracks.xa;
+				if	(cnt == 0)
+					return(CDS_AUDIO);
+				else
+					return(CDS_MIXED);
+				}
+			if	(tracks.cdi)
+				return(CDS_XA_2_2);
+			if	(tracks.xa)
+				return(CDS_XA_2_1);
+			if	(tracks.data)
+				return(CDS_DATA_1);
 			return(CDS_NO_INFO);
-			break;
+			}
 		}
 	errno = ret;
 	return(ret ? -1 : 0);
@@ -657,6 +686,49 @@
 			cgc->cdb[9] = 0x10;
 		}
 	return(scsi_cmd(fd, cgc));
+	}
+
+static void cdrom_count_tracks(int fd, tracktype *tracks)
+	{
+	struct	cdrom_tochdr header;
+	struct	cdrom_tocentry entry;
+	int	ret, i;
+
+	bzero(tracks, sizeof (*tracks));
+	ret = cdrom_ioctl(fd, CDROMREADTOCHDR, &header);
+/*
+ * This whole business is a crock anyhow so we don't bother distinguishing
+ * between no media, drive not ready, etc and on any error just say we have
+ * no info.
+*/
+	if	(ret)
+		{
+		tracks->error = CDS_NO_INFO;
+		return;
+		}
+
+	entry.cdte_format = CDROM_MSF;
+	for	(i = header.cdth_trk0; i <= header.cdth_trk1; i++)
+		{
+		entry.cdte_track = i;
+		if	(cdrom_ioctl(fd, CDROMREADTOCENTRY, &entry))
+			{
+			tracks->error = CDS_NO_INFO;
+			return;
+			}
+		if	(entry.cdte_ctrl & CDROM_DATA_TRACK)
+			{
+			if	(entry.cdte_format == 0x10)
+				tracks->cdi++;
+			else if	(entry.cdte_format == 0x20)
+				tracks->xa++;
+			else
+				tracks->data++;
+			}
+		else
+			tracks->audio++;
+		}
+	return;
 	}
 
 static int cdrom_tray_move(int fd, int flag)