mirror of
https://github.com/mpv-player/mpv
synced 2024-10-06 14:54:02 +02:00
importing libdvdcss 1.2.2 files
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@7028 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
131935f8ad
commit
211d6637bc
315
libmpdvdkit2/bsdi_dvd.h
Normal file
315
libmpdvdkit2/bsdi_dvd.h
Normal file
@ -0,0 +1,315 @@
|
||||
#ifndef _DVD_H_
|
||||
#define _DVD_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <machine/endian.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
int dvd_cdrom_ioctl(int, unsigned long, void *);
|
||||
int cdrom_blocksize(int, int);
|
||||
void dvd_cdrom_debug(int);
|
||||
__END_DECLS
|
||||
|
||||
#define ioctl(a,b,c) dvd_cdrom_ioctl((a),(b),(c))
|
||||
|
||||
typedef unsigned char __u8;
|
||||
typedef unsigned short __u16;
|
||||
typedef unsigned int __u32;
|
||||
|
||||
#define DVD_READ_STRUCT 0x5390 /* Read structure */
|
||||
#define DVD_WRITE_STRUCT 0x5391 /* Write structure */
|
||||
#define DVD_AUTH 0x5392 /* Authentication */
|
||||
|
||||
#define DVD_STRUCT_PHYSICAL 0x00
|
||||
#define DVD_STRUCT_COPYRIGHT 0x01
|
||||
#define DVD_STRUCT_DISCKEY 0x02
|
||||
#define DVD_STRUCT_BCA 0x03
|
||||
#define DVD_STRUCT_MANUFACT 0x04
|
||||
|
||||
struct dvd_layer {
|
||||
__u8 book_version : 4;
|
||||
__u8 book_type : 4;
|
||||
__u8 min_rate : 4;
|
||||
__u8 disc_size : 4;
|
||||
__u8 layer_type : 4;
|
||||
__u8 track_path : 1;
|
||||
__u8 nlayers : 2;
|
||||
__u8 track_density : 4;
|
||||
__u8 linear_density : 4;
|
||||
__u8 bca : 1;
|
||||
__u32 start_sector;
|
||||
__u32 end_sector;
|
||||
__u32 end_sector_l0;
|
||||
};
|
||||
|
||||
struct dvd_physical {
|
||||
__u8 type;
|
||||
__u8 layer_num;
|
||||
struct dvd_layer layer[4];
|
||||
};
|
||||
|
||||
struct dvd_copyright {
|
||||
__u8 type;
|
||||
|
||||
__u8 layer_num;
|
||||
__u8 cpst;
|
||||
__u8 rmi;
|
||||
};
|
||||
|
||||
struct dvd_disckey {
|
||||
__u8 type;
|
||||
|
||||
unsigned agid : 2;
|
||||
__u8 value[2048];
|
||||
};
|
||||
|
||||
struct dvd_bca {
|
||||
__u8 type;
|
||||
|
||||
int len;
|
||||
__u8 value[188];
|
||||
};
|
||||
|
||||
struct dvd_manufact {
|
||||
__u8 type;
|
||||
|
||||
__u8 layer_num;
|
||||
int len;
|
||||
__u8 value[2048];
|
||||
};
|
||||
|
||||
typedef union {
|
||||
__u8 type;
|
||||
|
||||
struct dvd_physical physical;
|
||||
struct dvd_copyright copyright;
|
||||
struct dvd_disckey disckey;
|
||||
struct dvd_bca bca;
|
||||
struct dvd_manufact manufact;
|
||||
} dvd_struct;
|
||||
|
||||
/*
|
||||
* DVD authentication ioctl
|
||||
*/
|
||||
|
||||
/* Authentication states */
|
||||
#define DVD_LU_SEND_AGID 0
|
||||
#define DVD_HOST_SEND_CHALLENGE 1
|
||||
#define DVD_LU_SEND_KEY1 2
|
||||
#define DVD_LU_SEND_CHALLENGE 3
|
||||
#define DVD_HOST_SEND_KEY2 4
|
||||
|
||||
/* Termination states */
|
||||
#define DVD_AUTH_ESTABLISHED 5
|
||||
#define DVD_AUTH_FAILURE 6
|
||||
|
||||
/* Other functions */
|
||||
#define DVD_LU_SEND_TITLE_KEY 7
|
||||
#define DVD_LU_SEND_ASF 8
|
||||
#define DVD_INVALIDATE_AGID 9
|
||||
#define DVD_LU_SEND_RPC_STATE 10
|
||||
#define DVD_HOST_SEND_RPC_STATE 11
|
||||
|
||||
/* State data */
|
||||
typedef __u8 dvd_key[5]; /* 40-bit value, MSB is first elem. */
|
||||
typedef __u8 dvd_challenge[10]; /* 80-bit value, MSB is first elem. */
|
||||
|
||||
struct dvd_lu_send_agid {
|
||||
__u8 type;
|
||||
unsigned agid : 2;
|
||||
};
|
||||
|
||||
struct dvd_host_send_challenge {
|
||||
__u8 type;
|
||||
unsigned agid : 2;
|
||||
|
||||
dvd_challenge chal;
|
||||
};
|
||||
|
||||
struct dvd_send_key {
|
||||
__u8 type;
|
||||
unsigned agid : 2;
|
||||
|
||||
dvd_key key;
|
||||
};
|
||||
|
||||
struct dvd_lu_send_challenge {
|
||||
__u8 type;
|
||||
unsigned agid : 2;
|
||||
|
||||
dvd_challenge chal;
|
||||
};
|
||||
|
||||
#define DVD_CPM_NO_COPYRIGHT 0
|
||||
#define DVD_CPM_COPYRIGHTED 1
|
||||
|
||||
#define DVD_CP_SEC_NONE 0
|
||||
#define DVD_CP_SEC_EXIST 1
|
||||
|
||||
#define DVD_CGMS_UNRESTRICTED 0
|
||||
#define DVD_CGMS_SINGLE 2
|
||||
#define DVD_CGMS_RESTRICTED 3
|
||||
|
||||
struct dvd_lu_send_title_key {
|
||||
__u8 type;
|
||||
unsigned agid : 2;
|
||||
|
||||
dvd_key title_key;
|
||||
int lba;
|
||||
unsigned cpm : 1;
|
||||
unsigned cp_sec : 1;
|
||||
unsigned cgms : 2;
|
||||
};
|
||||
|
||||
struct dvd_lu_send_asf {
|
||||
__u8 type;
|
||||
unsigned agid : 2;
|
||||
|
||||
unsigned asf : 1;
|
||||
};
|
||||
|
||||
struct dvd_host_send_rpcstate {
|
||||
__u8 type;
|
||||
__u8 pdrc;
|
||||
};
|
||||
|
||||
struct dvd_lu_send_rpcstate {
|
||||
__u8 type : 2;
|
||||
__u8 vra : 3;
|
||||
__u8 ucca : 3;
|
||||
__u8 region_mask;
|
||||
__u8 rpc_scheme;
|
||||
};
|
||||
|
||||
typedef union {
|
||||
__u8 type;
|
||||
|
||||
struct dvd_lu_send_agid lsa;
|
||||
struct dvd_host_send_challenge hsc;
|
||||
struct dvd_send_key lsk;
|
||||
struct dvd_lu_send_challenge lsc;
|
||||
struct dvd_send_key hsk;
|
||||
struct dvd_lu_send_title_key lstk;
|
||||
struct dvd_lu_send_asf lsasf;
|
||||
struct dvd_host_send_rpcstate hrpcs;
|
||||
struct dvd_lu_send_rpcstate lrpcs;
|
||||
} dvd_authinfo;
|
||||
|
||||
|
||||
typedef struct {
|
||||
__u16 report_key_length;
|
||||
__u8 reserved1;
|
||||
__u8 reserved2;
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
__u8 type_code : 2;
|
||||
__u8 vra : 3;
|
||||
__u8 ucca : 3;
|
||||
#elif BYTE_ORDER == LITTLE_ENDIAN
|
||||
__u8 ucca : 3;
|
||||
__u8 vra : 3;
|
||||
__u8 type_code : 2;
|
||||
#endif
|
||||
__u8 region_mask;
|
||||
__u8 rpc_scheme;
|
||||
__u8 reserved3;
|
||||
} rpc_state_t;
|
||||
|
||||
/*
|
||||
* Stuff for the CDROM ioctls
|
||||
*/
|
||||
|
||||
#define CDROMREADTOCHDR 0x5305 /* Read TOC header (cdrom_tochdr) */
|
||||
#define CDROMREADTOCENTRY 0x5306 /* Read TOC entry (cdrom_tocentry) */
|
||||
#define CDROMEJECT 0x5309 /* Ejects the cdrom media */
|
||||
#define CDROMCLOSETRAY 0x5319 /* Reverse of CDROMEJECT */
|
||||
#define CDROM_DRIVE_STATUS 0x5326 /* Get tray position, 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) */
|
||||
|
||||
#define CD_MINS 74 /* max. minutes per CD, not really a limit */
|
||||
#define CD_SECS 60 /* seconds per minute */
|
||||
#define CD_FRAMES 75 /* frames per second */
|
||||
#define CD_MSF_OFFSET 150 /* MSF numbering offset of first frame */
|
||||
|
||||
#define CD_HEAD_SIZE 4 /* header (address) bytes per raw data frame */
|
||||
#define CD_SYNC_SIZE 12 /* 12 sync bytes per raw data frame */
|
||||
#define CD_FRAMESIZE 2048 /* bytes per frame, "cooked" mode */
|
||||
#define CD_FRAMESIZE_RAW 2352 /* bytes per frame, "raw" mode */
|
||||
#define CD_FRAMESIZE_RAW0 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE-CD_HEAD_SIZE) /*2336*/
|
||||
#define CD_FRAMESIZE_RAW1 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE) /*2340*/
|
||||
|
||||
/* CD-ROM address types (cdrom_tocentry.cdte_format) */
|
||||
#define CDROM_LBA 0x01 /* logical block: first frame is #0 */
|
||||
#define CDROM_MSF 0x02 /* minute-second-frame: binary. not bcd here!*/
|
||||
|
||||
/* The leadout track is always 0xAA, regardless of # of tracks on disc */
|
||||
#define CDROM_LEADOUT 0xAA
|
||||
|
||||
/* drive status returned by CDROM_DRIVE_STATUS ioctl */
|
||||
#define CDS_NO_INFO 0 /* if not implemented */
|
||||
#define CDS_NO_DISC 1
|
||||
#define CDS_TRAY_OPEN 2
|
||||
#define CDS_DRIVE_NOT_READY 3
|
||||
#define CDS_DISC_OK 4
|
||||
|
||||
/* For compile compatibility only - we don't support changers */
|
||||
#define CDSL_NONE ((int) (~0U>>1)-1)
|
||||
#define CDSL_CURRENT ((int) (~0U>>1))
|
||||
|
||||
struct cdrom_msf
|
||||
{
|
||||
__u8 cdmsf_min0; /* start minute */
|
||||
__u8 cdmsf_sec0; /* start second */
|
||||
__u8 cdmsf_frame0; /* start frame */
|
||||
__u8 cdmsf_min1; /* end minute */
|
||||
__u8 cdmsf_sec1; /* end second */
|
||||
__u8 cdmsf_frame1; /* end frame */
|
||||
};
|
||||
|
||||
struct cdrom_tochdr
|
||||
{
|
||||
__u8 cdth_trk0; /* start track */
|
||||
__u8 cdth_trk1; /* end track */
|
||||
};
|
||||
|
||||
struct cdrom_msf0
|
||||
{
|
||||
__u8 minute;
|
||||
__u8 second;
|
||||
__u8 frame;
|
||||
};
|
||||
|
||||
union cdrom_addr
|
||||
{
|
||||
struct cdrom_msf0 msf;
|
||||
int lba;
|
||||
};
|
||||
|
||||
struct cdrom_tocentry
|
||||
{
|
||||
__u8 cdte_track;
|
||||
__u8 cdte_adr :4;
|
||||
__u8 cdte_ctrl :4;
|
||||
__u8 cdte_format;
|
||||
union cdrom_addr cdte_addr;
|
||||
__u8 cdte_datamode;
|
||||
};
|
||||
|
||||
struct modesel_head
|
||||
{
|
||||
__u8 reserved1;
|
||||
__u8 medium;
|
||||
__u8 reserved2;
|
||||
__u8 block_desc_length;
|
||||
__u8 density;
|
||||
__u8 number_of_blocks_hi;
|
||||
__u8 number_of_blocks_med;
|
||||
__u8 number_of_blocks_lo;
|
||||
__u8 reserved3;
|
||||
__u8 block_length_hi;
|
||||
__u8 block_length_med;
|
||||
__u8 block_length_lo;
|
||||
};
|
||||
#endif /* _DVD_H_ */
|
698
libmpdvdkit2/bsdi_ioctl.c
Normal file
698
libmpdvdkit2/bsdi_ioctl.c
Normal file
@ -0,0 +1,698 @@
|
||||
#include "config.h"
|
||||
|
||||
/*
|
||||
* Hacked version of the linux cdrom.c kernel module - everything except the
|
||||
* DVD handling ripped out and the rest rewritten to use raw SCSI commands
|
||||
* on BSD/OS 4.2 (but should work with earlier versions as well).
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include </sys/dev/scsi/scsi.h>
|
||||
#include </sys/dev/scsi/scsi_ioctl.h>
|
||||
|
||||
#include "bsdi_dvd.h"
|
||||
|
||||
/*
|
||||
* Now get rid of the override/intercept macro so we can call the real ioctl()
|
||||
* routine!
|
||||
*/
|
||||
#undef ioctl
|
||||
|
||||
#define CMD_READ_10 0x28
|
||||
#define CMD_READ_TOC_PMA_ATIP 0x43
|
||||
#define CMD_READ_CD 0xbe
|
||||
#define CMD_START_STOP_UNIT 0x1b
|
||||
|
||||
#define CMD_SEND_KEY 0xa3
|
||||
#define CMD_REPORT_KEY 0xa4
|
||||
#define CMD_READ_DVD_STRUCTURE 0xad
|
||||
|
||||
#define copy_key(dest,src) memcpy((dest), (src), sizeof(dvd_key))
|
||||
#define copy_chal(dest,src) memcpy((dest), (src), sizeof(dvd_challenge))
|
||||
|
||||
/* Define the Cdrom Generic Command structure */
|
||||
typedef struct cgc
|
||||
{
|
||||
u_char cdb[12];
|
||||
u_char *buf;
|
||||
int buflen;
|
||||
int rw;
|
||||
int timeout;
|
||||
scsi_user_sense_t *sus;
|
||||
} cgc_t;
|
||||
|
||||
static int scsi_cmd(int, cgc_t *);
|
||||
static int cdrom_ioctl(int, u_long, void *);
|
||||
static int cdrom_tray_move(int, int);
|
||||
static int dvd_ioctl(int, u_long, void *);
|
||||
static int debug;
|
||||
|
||||
void dvd_cdrom_debug(int flag)
|
||||
{
|
||||
debug = flag;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the published entry point. Actually applications should simply
|
||||
* include <dvd.h> and not refer to this at all.
|
||||
*/
|
||||
int dvd_cdrom_ioctl(int fd, unsigned long cmd, void *arg)
|
||||
{
|
||||
switch (cmd)
|
||||
{
|
||||
case DVD_AUTH:
|
||||
case DVD_READ_STRUCT:
|
||||
return(dvd_ioctl(fd, cmd, arg));
|
||||
case CDROMREADTOCHDR:
|
||||
case CDROMREADTOCENTRY:
|
||||
case CDROMEJECT:
|
||||
case CDROMREADRAW:
|
||||
case CDROMREADMODE2:
|
||||
case CDROMCLOSETRAY:
|
||||
case CDROM_DRIVE_STATUS:
|
||||
return(cdrom_ioctl(fd, cmd, arg));
|
||||
default:
|
||||
return(ioctl(fd, cmd, arg));
|
||||
}
|
||||
}
|
||||
|
||||
static void setup_report_key(cgc_t *cgc, u_int agid, u_int type)
|
||||
{
|
||||
|
||||
cgc->cdb[0] = CMD_REPORT_KEY;
|
||||
cgc->cdb[10] = type | (agid << 6);
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
case 5:
|
||||
case 8:
|
||||
cgc->buflen = 8;
|
||||
break;
|
||||
case 1:
|
||||
cgc->buflen = 16;
|
||||
break;
|
||||
case 2:
|
||||
case 4:
|
||||
cgc->buflen = 12;
|
||||
break;
|
||||
}
|
||||
cgc->cdb[9] = cgc->buflen;
|
||||
cgc->rw = SUC_READ;;
|
||||
}
|
||||
|
||||
static void setup_send_key(cgc_t *cgc, u_int agid, u_int type)
|
||||
{
|
||||
|
||||
cgc->cdb[0] = CMD_SEND_KEY;
|
||||
cgc->cdb[10] = type | (agid << 6);
|
||||
switch (type)
|
||||
{
|
||||
case 1:
|
||||
cgc->buflen = 16;
|
||||
break;
|
||||
case 3:
|
||||
cgc->buflen = 12;
|
||||
break;
|
||||
case 6:
|
||||
cgc->buflen = 8;
|
||||
break;
|
||||
}
|
||||
cgc->cdb[9] = cgc->buflen;
|
||||
cgc->rw = SUC_WRITE;
|
||||
}
|
||||
|
||||
static void cgc_init(cgc_t *cgc, void *buf, int len, int type)
|
||||
{
|
||||
|
||||
memset(cgc, 0, sizeof (*cgc));
|
||||
if (buf)
|
||||
memset(buf, 0, len);
|
||||
cgc->buf = (u_char *)buf;
|
||||
cgc->buflen = len;
|
||||
cgc->rw = type;
|
||||
cgc->timeout = 5; /* 5 second timeout */
|
||||
}
|
||||
|
||||
static int dvd_do_auth(int fd, dvd_authinfo *ai)
|
||||
{
|
||||
int ret;
|
||||
u_char buf[20];
|
||||
cgc_t cgc;
|
||||
rpc_state_t rpc_state;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
cgc_init(&cgc, buf, 0, SUC_READ);
|
||||
|
||||
switch (ai->type)
|
||||
{
|
||||
case DVD_LU_SEND_AGID: /* LU data send */
|
||||
setup_report_key(&cgc, ai->lsa.agid, 0);
|
||||
if (ret = scsi_cmd(fd, &cgc))
|
||||
return ret;
|
||||
ai->lsa.agid = buf[7] >> 6;
|
||||
break;
|
||||
case DVD_LU_SEND_KEY1:
|
||||
setup_report_key(&cgc, ai->lsk.agid, 2);
|
||||
if (ret = scsi_cmd(fd, &cgc))
|
||||
return ret;
|
||||
copy_key(ai->lsk.key, &buf[4]);
|
||||
break;
|
||||
case DVD_LU_SEND_CHALLENGE:
|
||||
setup_report_key(&cgc, ai->lsc.agid, 1);
|
||||
if (ret = scsi_cmd(fd, &cgc))
|
||||
return ret;
|
||||
copy_chal(ai->lsc.chal, &buf[4]);
|
||||
break;
|
||||
case DVD_LU_SEND_TITLE_KEY: /* Post-auth key */
|
||||
setup_report_key(&cgc, ai->lstk.agid, 4);
|
||||
cgc.cdb[5] = ai->lstk.lba;
|
||||
cgc.cdb[4] = ai->lstk.lba >> 8;
|
||||
cgc.cdb[3] = ai->lstk.lba >> 16;
|
||||
cgc.cdb[2] = ai->lstk.lba >> 24;
|
||||
if (ret = scsi_cmd(fd, &cgc))
|
||||
return ret;
|
||||
ai->lstk.cpm = (buf[4] >> 7) & 1;
|
||||
ai->lstk.cp_sec = (buf[4] >> 6) & 1;
|
||||
ai->lstk.cgms = (buf[4] >> 4) & 3;
|
||||
copy_key(ai->lstk.title_key, &buf[5]);
|
||||
break;
|
||||
case DVD_LU_SEND_ASF:
|
||||
setup_report_key(&cgc, ai->lsasf.agid, 5);
|
||||
if (ret = scsi_cmd(fd, &cgc))
|
||||
return ret;
|
||||
ai->lsasf.asf = buf[7] & 1;
|
||||
break;
|
||||
case DVD_HOST_SEND_CHALLENGE: /* LU data receive (LU changes state) */
|
||||
setup_send_key(&cgc, ai->hsc.agid, 1);
|
||||
buf[1] = 0xe;
|
||||
copy_chal(&buf[4], ai->hsc.chal);
|
||||
if (ret = scsi_cmd(fd, &cgc))
|
||||
return ret;
|
||||
ai->type = DVD_LU_SEND_KEY1;
|
||||
break;
|
||||
case DVD_HOST_SEND_KEY2:
|
||||
setup_send_key(&cgc, ai->hsk.agid, 3);
|
||||
buf[1] = 0xa;
|
||||
copy_key(&buf[4], ai->hsk.key);
|
||||
if (ret = scsi_cmd(fd, &cgc))
|
||||
{
|
||||
ai->type = DVD_AUTH_FAILURE;
|
||||
return ret;
|
||||
}
|
||||
ai->type = DVD_AUTH_ESTABLISHED;
|
||||
break;
|
||||
case DVD_INVALIDATE_AGID:
|
||||
setup_report_key(&cgc, ai->lsa.agid, 0x3f);
|
||||
if (ret = scsi_cmd(fd, &cgc))
|
||||
return ret;
|
||||
break;
|
||||
case DVD_LU_SEND_RPC_STATE: /* Get region settings */
|
||||
setup_report_key(&cgc, 0, 8);
|
||||
memset(&rpc_state, 0, sizeof(rpc_state_t));
|
||||
cgc.buf = (char *) &rpc_state;
|
||||
if (ret = scsi_cmd(fd, &cgc))
|
||||
{
|
||||
ai->lrpcs.type = 0;
|
||||
ai->lrpcs.rpc_scheme = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ai->lrpcs.type = rpc_state.type_code;
|
||||
ai->lrpcs.vra = rpc_state.vra;
|
||||
ai->lrpcs.ucca = rpc_state.ucca;
|
||||
ai->lrpcs.region_mask = rpc_state.region_mask;
|
||||
ai->lrpcs.rpc_scheme = rpc_state.rpc_scheme;
|
||||
}
|
||||
break;
|
||||
case DVD_HOST_SEND_RPC_STATE: /* Set region settings */
|
||||
setup_send_key(&cgc, 0, 6);
|
||||
buf[1] = 6;
|
||||
buf[4] = ai->hrpcs.pdrc;
|
||||
if (ret = scsi_cmd(fd, &cgc))
|
||||
return ret;
|
||||
break;
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dvd_read_physical(int fd, dvd_struct *s)
|
||||
{
|
||||
int ret, i;
|
||||
u_char buf[4 + 4 * 20], *base;
|
||||
struct dvd_layer *layer;
|
||||
cgc_t cgc;
|
||||
|
||||
cgc_init(&cgc, buf, sizeof(buf), SUC_READ);
|
||||
cgc.cdb[0] = CMD_READ_DVD_STRUCTURE;
|
||||
cgc.cdb[6] = s->physical.layer_num;
|
||||
cgc.cdb[7] = s->type;
|
||||
cgc.cdb[9] = cgc.buflen & 0xff;
|
||||
|
||||
if (ret = scsi_cmd(fd, &cgc))
|
||||
return ret;
|
||||
|
||||
base = &buf[4];
|
||||
layer = &s->physical.layer[0];
|
||||
|
||||
/* place the data... really ugly, but at least we won't have to
|
||||
worry about endianess in userspace or here. */
|
||||
for (i = 0; i < 4; ++i, base += 20, ++layer)
|
||||
{
|
||||
memset(layer, 0, sizeof(*layer));
|
||||
layer->book_version = base[0] & 0xf;
|
||||
layer->book_type = base[0] >> 4;
|
||||
layer->min_rate = base[1] & 0xf;
|
||||
layer->disc_size = base[1] >> 4;
|
||||
layer->layer_type = base[2] & 0xf;
|
||||
layer->track_path = (base[2] >> 4) & 1;
|
||||
layer->nlayers = (base[2] >> 5) & 3;
|
||||
layer->track_density = base[3] & 0xf;
|
||||
layer->linear_density = base[3] >> 4;
|
||||
layer->start_sector = base[5] << 16 | base[6] << 8 | base[7];
|
||||
layer->end_sector = base[9] << 16 | base[10] << 8 | base[11];
|
||||
layer->end_sector_l0 = base[13] << 16 | base[14] << 8 | base[15];
|
||||
layer->bca = base[16] >> 7;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dvd_read_copyright(int fd, dvd_struct *s)
|
||||
{
|
||||
int ret;
|
||||
u_char buf[8];
|
||||
cgc_t cgc;
|
||||
|
||||
cgc_init(&cgc, buf, sizeof(buf), SUC_READ);
|
||||
cgc.cdb[0] = CMD_READ_DVD_STRUCTURE;
|
||||
cgc.cdb[6] = s->copyright.layer_num;
|
||||
cgc.cdb[7] = s->type;
|
||||
cgc.cdb[8] = cgc.buflen >> 8;
|
||||
cgc.cdb[9] = cgc.buflen & 0xff;
|
||||
|
||||
if (ret = scsi_cmd(fd, &cgc))
|
||||
return ret;
|
||||
s->copyright.cpst = buf[4];
|
||||
s->copyright.rmi = buf[5];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dvd_read_disckey(int fd, dvd_struct *s)
|
||||
{
|
||||
int ret, size;
|
||||
u_char *buf;
|
||||
cgc_t cgc;
|
||||
|
||||
size = sizeof(s->disckey.value) + 4;
|
||||
|
||||
if ((buf = (u_char *) malloc(size)) == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
cgc_init(&cgc, buf, size, SUC_READ);
|
||||
cgc.cdb[0] = CMD_READ_DVD_STRUCTURE;
|
||||
cgc.cdb[7] = s->type;
|
||||
cgc.cdb[8] = size >> 8;
|
||||
cgc.cdb[9] = size & 0xff;
|
||||
cgc.cdb[10] = s->disckey.agid << 6;
|
||||
|
||||
if (!(ret = scsi_cmd(fd, &cgc)))
|
||||
memcpy(s->disckey.value, &buf[4], sizeof(s->disckey.value));
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dvd_read_bca(int fd, dvd_struct *s)
|
||||
{
|
||||
int ret;
|
||||
u_char buf[4 + 188];
|
||||
cgc_t cgc;
|
||||
|
||||
cgc_init(&cgc, buf, sizeof(buf), SUC_READ);
|
||||
cgc.cdb[0] = CMD_READ_DVD_STRUCTURE;
|
||||
cgc.cdb[7] = s->type;
|
||||
cgc.cdb[9] = cgc.buflen = 0xff;
|
||||
|
||||
if (ret = scsi_cmd(fd, &cgc))
|
||||
return ret;
|
||||
s->bca.len = buf[0] << 8 | buf[1];
|
||||
if (s->bca.len < 12 || s->bca.len > 188)
|
||||
return EIO;
|
||||
memcpy(s->bca.value, &buf[4], s->bca.len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dvd_read_manufact(int fd, dvd_struct *s)
|
||||
{
|
||||
int ret = 0, size;
|
||||
u_char *buf;
|
||||
cgc_t cgc;
|
||||
|
||||
size = sizeof(s->manufact.value) + 4;
|
||||
|
||||
if ((buf = (u_char *) malloc(size)) == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
cgc_init(&cgc, buf, size, SUC_READ);
|
||||
cgc.cdb[0] = CMD_READ_DVD_STRUCTURE;
|
||||
cgc.cdb[7] = s->type;
|
||||
cgc.cdb[8] = size >> 8;
|
||||
cgc.cdb[9] = size & 0xff;
|
||||
|
||||
if (ret = scsi_cmd(fd, &cgc))
|
||||
{
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
s->manufact.len = buf[0] << 8 | buf[1];
|
||||
if (s->manufact.len < 0 || s->manufact.len > 2048)
|
||||
ret = -EIO;
|
||||
else
|
||||
memcpy(s->manufact.value, &buf[4], s->manufact.len);
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dvd_read_struct(int fd, dvd_struct *s)
|
||||
{
|
||||
switch (s->type)
|
||||
{
|
||||
case DVD_STRUCT_PHYSICAL:
|
||||
return dvd_read_physical(fd, s);
|
||||
case DVD_STRUCT_COPYRIGHT:
|
||||
return dvd_read_copyright(fd, s);
|
||||
case DVD_STRUCT_DISCKEY:
|
||||
return dvd_read_disckey(fd, s);
|
||||
case DVD_STRUCT_BCA:
|
||||
return dvd_read_bca(fd, s);
|
||||
case DVD_STRUCT_MANUFACT:
|
||||
return dvd_read_manufact(fd, s);
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static u_char scsi_cdblen[8] = {6, 10, 10, 12, 12, 12, 10, 10};
|
||||
|
||||
static int scsi_cmd(int fd, cgc_t *cgc)
|
||||
{
|
||||
int scsistatus, cdblen;
|
||||
unsigned char *cp;
|
||||
struct scsi_user_cdb suc;
|
||||
|
||||
/* safety checks */
|
||||
if (cgc->rw != SUC_READ && cgc->rw != SUC_WRITE)
|
||||
return(EINVAL);
|
||||
|
||||
suc.suc_flags = cgc->rw;
|
||||
cdblen = scsi_cdblen[(cgc->cdb[0] >> 5) & 7];
|
||||
suc.suc_cdblen = cdblen;
|
||||
bcopy(cgc->cdb, suc.suc_cdb, cdblen);
|
||||
suc.suc_data = cgc->buf;
|
||||
suc.suc_datalen = cgc->buflen;
|
||||
suc.suc_timeout = cgc->timeout;
|
||||
if (ioctl(fd, SCSIRAWCDB, &suc) == -1)
|
||||
return(errno);
|
||||
scsistatus = suc.suc_sus.sus_status;
|
||||
|
||||
/*
|
||||
* If the device returns a scsi sense error and debugging is enabled print
|
||||
* some hopefully useful information on stderr.
|
||||
*/
|
||||
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]);
|
||||
}
|
||||
if (cgc->sus)
|
||||
bcopy(&suc.suc_sus, cgc->sus, sizeof (struct scsi_user_sense));
|
||||
if (scsistatus)
|
||||
return(EIO); /* generic i/o error for unsuccessful status */
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* The entry point for the DVDioctls for BSD/OS.
|
||||
*/
|
||||
static int dvd_ioctl(int fd, u_long cmd, void *arg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case DVD_READ_STRUCT:
|
||||
ret = dvd_read_struct(fd, (dvd_struct *)arg);
|
||||
if (ret)
|
||||
errno = ret;
|
||||
return(ret ? -1 : 0);
|
||||
case DVD_AUTH:
|
||||
ret = dvd_do_auth (fd, (dvd_authinfo *)arg);
|
||||
if (ret)
|
||||
errno = ret;
|
||||
return(ret ? -1 : 0);
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The entry point for the CDROMioctls for BSD/OS
|
||||
*/
|
||||
static int cdrom_read_block(int, cgc_t *, int, int, int, int);
|
||||
static int cdrom_read_cd(int, cgc_t *, int, int, int );
|
||||
int cdrom_blocksize(int, int );
|
||||
|
||||
static inline
|
||||
int msf_to_lba(char m, char s, char f)
|
||||
{
|
||||
return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET;
|
||||
}
|
||||
|
||||
cdrom_ioctl(int fd, u_long cmd, void *arg)
|
||||
{
|
||||
int ret;
|
||||
cgc_t cgc;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case CDROMREADRAW:
|
||||
case CDROMREADMODE1:
|
||||
case CDROMREADMODE2:
|
||||
{
|
||||
struct cdrom_msf *msf;
|
||||
int blocksize = 0, format = 0, lba;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case CDROMREADRAW:
|
||||
blocksize = CD_FRAMESIZE_RAW;
|
||||
break;
|
||||
case CDROMREADMODE1:
|
||||
blocksize = CD_FRAMESIZE;
|
||||
format = 2;
|
||||
break;
|
||||
case CDROMREADMODE2:
|
||||
blocksize = CD_FRAMESIZE_RAW0;
|
||||
break;
|
||||
}
|
||||
msf = (struct cdrom_msf *)arg;
|
||||
lba = msf_to_lba(msf->cdmsf_min0,msf->cdmsf_sec0,
|
||||
msf->cdmsf_frame0);
|
||||
ret = EINVAL;
|
||||
if (lba < 0)
|
||||
break;
|
||||
|
||||
cgc_init(&cgc, arg, blocksize, SUC_READ);
|
||||
ret = cdrom_read_block(fd, &cgc, lba, 1, format, blocksize);
|
||||
if (ret)
|
||||
{
|
||||
/*
|
||||
* SCSI-II devices are not required to support CMD_READ_CD (which specifies
|
||||
* the blocksize to read) so try switching the block size with a mode select,
|
||||
* doing the normal read sector command and then changing the sector size back
|
||||
* to 2048.
|
||||
*
|
||||
* If the program dies before changing the blocksize back sdopen()
|
||||
* in the kernel will fail opens with a message that looks something like:
|
||||
*
|
||||
* "sr1: blksize 2336 not multiple of 512: cannot use"
|
||||
*
|
||||
* At that point the drive has to be power cycled (or reset in some other way).
|
||||
*/
|
||||
if (ret = cdrom_blocksize(fd, blocksize))
|
||||
break;
|
||||
ret = cdrom_read_cd(fd, &cgc, lba, blocksize, 1);
|
||||
ret |= cdrom_blocksize(fd, 2048);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CDROMREADTOCHDR:
|
||||
{
|
||||
struct cdrom_tochdr *tochdr = (struct cdrom_tochdr *) arg;
|
||||
u_char buffer[12];
|
||||
|
||||
cgc_init(&cgc, buffer, sizeof (buffer), SUC_READ);
|
||||
cgc.cdb[0] = CMD_READ_TOC_PMA_ATIP;
|
||||
cgc.cdb[1] = 0x2; /* MSF */
|
||||
cgc.cdb[8] = 12; /* LSB of length */
|
||||
|
||||
ret = scsi_cmd(fd, &cgc);
|
||||
if (!ret)
|
||||
{
|
||||
tochdr->cdth_trk0 = buffer[2];
|
||||
tochdr->cdth_trk1 = buffer[3];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CDROMREADTOCENTRY:
|
||||
{
|
||||
struct cdrom_tocentry *tocentry = (struct cdrom_tocentry *) arg;
|
||||
u_char buffer[12];
|
||||
|
||||
cgc_init(&cgc, buffer, sizeof (buffer), SUC_READ);
|
||||
cgc.cdb[0] = CMD_READ_TOC_PMA_ATIP;
|
||||
cgc.cdb[1] = (tocentry->cdte_format == CDROM_MSF) ? 0x02 : 0;
|
||||
cgc.cdb[6] = tocentry->cdte_track;
|
||||
cgc.cdb[8] = 12; /* LSB of length */
|
||||
|
||||
ret = scsi_cmd(fd, &cgc);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
tocentry->cdte_ctrl = buffer[5] & 0xf;
|
||||
tocentry->cdte_adr = buffer[5] >> 4;
|
||||
tocentry->cdte_datamode = (tocentry->cdte_ctrl & 0x04) ? 1 : 0;
|
||||
if (tocentry->cdte_format == CDROM_MSF)
|
||||
{
|
||||
tocentry->cdte_addr.msf.minute = buffer[9];
|
||||
tocentry->cdte_addr.msf.second = buffer[10];
|
||||
tocentry->cdte_addr.msf.frame = buffer[11];
|
||||
}
|
||||
else
|
||||
tocentry->cdte_addr.lba = (((((buffer[8] << 8)
|
||||
+ buffer[9]) << 8)
|
||||
+ buffer[10]) << 8)
|
||||
+ buffer[11];
|
||||
break;
|
||||
}
|
||||
case CDROMEJECT: /* NO-OP for now */
|
||||
ret = cdrom_tray_move(fd, 1);
|
||||
break;
|
||||
case CDROMCLOSETRAY:
|
||||
ret = cdrom_tray_move(fd, 0);
|
||||
break;
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
case CDROM_DRIVE_STATUS:
|
||||
return(CDS_NO_INFO);
|
||||
break;
|
||||
}
|
||||
errno = ret;
|
||||
return(ret ? -1 : 0);
|
||||
}
|
||||
|
||||
static int cdrom_read_cd(int fd, cgc_t *cgc, int lba, int blocksize, int nblocks)
|
||||
{
|
||||
|
||||
memset(&cgc->cdb, 0, sizeof(cgc->cdb));
|
||||
cgc->cdb[0] = CMD_READ_10;
|
||||
cgc->cdb[2] = (lba >> 24) & 0xff;
|
||||
cgc->cdb[3] = (lba >> 16) & 0xff;
|
||||
cgc->cdb[4] = (lba >> 8) & 0xff;
|
||||
cgc->cdb[5] = lba & 0xff;
|
||||
cgc->cdb[6] = (nblocks >> 16) & 0xff;
|
||||
cgc->cdb[7] = (nblocks >> 8) & 0xff;
|
||||
cgc->cdb[8] = nblocks & 0xff;
|
||||
cgc->buflen = blocksize * nblocks;
|
||||
return(scsi_cmd(fd, cgc));
|
||||
}
|
||||
|
||||
static int cdrom_read_block(int fd, cgc_t *cgc,
|
||||
int lba, int nblocks, int format, int blksize)
|
||||
{
|
||||
|
||||
memset(&cgc->cdb, 0, sizeof(cgc->cdb));
|
||||
cgc->cdb[0] = CMD_READ_CD;
|
||||
/* expected sector size - cdda,mode1,etc. */
|
||||
cgc->cdb[1] = format << 2;
|
||||
/* starting address */
|
||||
cgc->cdb[2] = (lba >> 24) & 0xff;
|
||||
cgc->cdb[3] = (lba >> 16) & 0xff;
|
||||
cgc->cdb[4] = (lba >> 8) & 0xff;
|
||||
cgc->cdb[5] = lba & 0xff;
|
||||
/* number of blocks */
|
||||
cgc->cdb[6] = (nblocks >> 16) & 0xff;
|
||||
cgc->cdb[7] = (nblocks >> 8) & 0xff;
|
||||
cgc->cdb[8] = nblocks & 0xff;
|
||||
cgc->buflen = blksize * nblocks;
|
||||
|
||||
/* set the header info returned */
|
||||
switch (blksize)
|
||||
{
|
||||
case CD_FRAMESIZE_RAW0:
|
||||
cgc->cdb[9] = 0x58;
|
||||
break;
|
||||
case CD_FRAMESIZE_RAW1:
|
||||
cgc->cdb[9] = 0x78;
|
||||
break;
|
||||
case CD_FRAMESIZE_RAW:
|
||||
cgc->cdb[9] = 0xf8;
|
||||
break;
|
||||
default:
|
||||
cgc->cdb[9] = 0x10;
|
||||
}
|
||||
return(scsi_cmd(fd, cgc));
|
||||
}
|
||||
|
||||
static int cdrom_tray_move(int fd, int flag)
|
||||
{
|
||||
cgc_t cgc;
|
||||
|
||||
cgc_init(&cgc, NULL, 0, SUC_READ);
|
||||
cgc.cdb[0] = CMD_START_STOP_UNIT;
|
||||
cgc.cdb[1] = 1; /* immediate */
|
||||
cgc.cdb[4] = flag ? 0x2 : 0x3; /* eject : close */
|
||||
return(scsi_cmd(fd, &cgc));
|
||||
}
|
||||
|
||||
/*
|
||||
* Required when we need to use READ_10 to issue other than 2048 block
|
||||
* reads
|
||||
*/
|
||||
int cdrom_blocksize(int fd, int size)
|
||||
{
|
||||
cgc_t cgc;
|
||||
struct modesel_head mh;
|
||||
|
||||
memset(&mh, 0, sizeof(mh));
|
||||
mh.block_desc_length = 0x08;
|
||||
mh.block_length_med = (size >> 8) & 0xff;
|
||||
mh.block_length_lo = size & 0xff;
|
||||
|
||||
memset(&cgc, 0, sizeof(cgc));
|
||||
cgc.cdb[0] = 0x15;
|
||||
cgc.cdb[1] = 1 << 4;
|
||||
cgc.cdb[4] = 12;
|
||||
cgc.buflen = sizeof(mh);
|
||||
cgc.buf = (u_char *) &mh;
|
||||
cgc.rw = SUC_WRITE;
|
||||
mh.block_desc_length = 0x08;
|
||||
mh.block_length_med = (size >> 8) & 0xff;
|
||||
mh.block_length_lo = size & 0xff;
|
||||
return(scsi_cmd(fd, &cgc));
|
||||
}
|
67
libmpdvdkit2/common.h
Normal file
67
libmpdvdkit2/common.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*****************************************************************************
|
||||
* common.h: common definitions
|
||||
* Collection of useful common types and macros definitions
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1998, 1999, 2000 VideoLAN
|
||||
* $Id$
|
||||
*
|
||||
* Authors: Samuel Hocevar <sam@via.ecp.fr>
|
||||
* Vincent Seguin <seguin@via.ecp.fr>
|
||||
* Gildas Bazin <gbazin@netcourrier.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, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Basic types definitions
|
||||
*****************************************************************************/
|
||||
|
||||
/* Basic types definitions */
|
||||
typedef unsigned char u8;
|
||||
typedef signed char s8;
|
||||
typedef unsigned int u32;
|
||||
typedef signed int s32;
|
||||
|
||||
typedef u8 byte_t;
|
||||
|
||||
#if defined( WIN32 )
|
||||
|
||||
/* several type definitions */
|
||||
# if defined( __MINGW32__ )
|
||||
# if !defined( _OFF_T_ )
|
||||
typedef long long _off_t;
|
||||
typedef _off_t off_t;
|
||||
# define _OFF_T_
|
||||
# else
|
||||
# define off_t long long
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if defined( _MSC_VER )
|
||||
# if !defined( _OFF_T_DEFINED )
|
||||
typedef __int64 off_t;
|
||||
# define _OFF_T_DEFINED
|
||||
# else
|
||||
# define off_t __int64
|
||||
# endif
|
||||
# define stat _stati64
|
||||
# endif
|
||||
|
||||
# ifndef snprintf
|
||||
# define snprintf _snprintf /* snprintf not defined in mingw32 (bug?) */
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
1588
libmpdvdkit2/css.c
Normal file
1588
libmpdvdkit2/css.c
Normal file
File diff suppressed because it is too large
Load Diff
56
libmpdvdkit2/css.h
Normal file
56
libmpdvdkit2/css.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*****************************************************************************
|
||||
* css.h: Structures for DVD authentication and unscrambling
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999-2001 VideoLAN
|
||||
* $Id$
|
||||
*
|
||||
* Author: Stéphane Borel <stef@via.ecp.fr>
|
||||
*
|
||||
* based on:
|
||||
* - css-auth by Derek Fawcus <derek@spider.com>
|
||||
* - DVD CSS ioctls example program by Andrew T. Veliath <andrewtv@usa.net>
|
||||
* - DeCSSPlus by Ethan Hawke
|
||||
* - The Divide and conquer attack by Frank A. Stevenson <frank@funcom.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, USA.
|
||||
*****************************************************************************/
|
||||
#define KEY_SIZE 5
|
||||
|
||||
typedef u8 dvd_key_t[KEY_SIZE];
|
||||
|
||||
typedef struct dvd_title_s
|
||||
{
|
||||
int i_startlb;
|
||||
dvd_key_t p_key;
|
||||
struct dvd_title_s *p_next;
|
||||
} dvd_title_t;
|
||||
|
||||
typedef struct css_s
|
||||
{
|
||||
int i_agid; /* Current Authenication Grant ID. */
|
||||
dvd_key_t p_bus_key; /* Current session key. */
|
||||
dvd_key_t p_disc_key; /* This DVD disc's key. */
|
||||
dvd_key_t p_title_key; /* Current title key. */
|
||||
} css_t;
|
||||
|
||||
/*****************************************************************************
|
||||
* Prototypes in css.c
|
||||
*****************************************************************************/
|
||||
int _dvdcss_test ( dvdcss_t );
|
||||
int _dvdcss_title ( dvdcss_t, int );
|
||||
int _dvdcss_disckey ( dvdcss_t );
|
||||
int _dvdcss_titlekey ( dvdcss_t, int , dvd_key_t );
|
||||
int _dvdcss_unscramble ( u8 *, u8 * );
|
||||
|
392
libmpdvdkit2/csstables.h
Normal file
392
libmpdvdkit2/csstables.h
Normal file
@ -0,0 +1,392 @@
|
||||
/*****************************************************************************
|
||||
* csstables.h: CSS Tables for DVD unscrambling
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999-2001 VideoLAN
|
||||
* $Id$
|
||||
*
|
||||
* Author: Stéphane Borel <stef@via.ecp.fr>
|
||||
*
|
||||
* based on:
|
||||
* - css-auth by Derek Fawcus <derek@spider.com>
|
||||
* - DVD CSS ioctls example program by Andrew T. Veliath <andrewtv@usa.net>
|
||||
* - The Divide and conquer attack by Frank A. Stevenson <frank@funcom.com>
|
||||
* - DeCSSPlus by Ethan Hawke
|
||||
* - DecVOB
|
||||
* see http://www.lemuria.org/DeCSS/ by Tom Vogt for more information.
|
||||
*
|
||||
* 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, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
static u8 p_css_tab1[ 256 ] =
|
||||
{
|
||||
0x33, 0x73, 0x3b, 0x26, 0x63, 0x23, 0x6b, 0x76,
|
||||
0x3e, 0x7e, 0x36, 0x2b, 0x6e, 0x2e, 0x66, 0x7b,
|
||||
0xd3, 0x93, 0xdb, 0x06, 0x43, 0x03, 0x4b, 0x96,
|
||||
0xde, 0x9e, 0xd6, 0x0b, 0x4e, 0x0e, 0x46, 0x9b,
|
||||
0x57, 0x17, 0x5f, 0x82, 0xc7, 0x87, 0xcf, 0x12,
|
||||
0x5a, 0x1a, 0x52, 0x8f, 0xca, 0x8a, 0xc2, 0x1f,
|
||||
0xd9, 0x99, 0xd1, 0x00, 0x49, 0x09, 0x41, 0x90,
|
||||
0xd8, 0x98, 0xd0, 0x01, 0x48, 0x08, 0x40, 0x91,
|
||||
0x3d, 0x7d, 0x35, 0x24, 0x6d, 0x2d, 0x65, 0x74,
|
||||
0x3c, 0x7c, 0x34, 0x25, 0x6c, 0x2c, 0x64, 0x75,
|
||||
0xdd, 0x9d, 0xd5, 0x04, 0x4d, 0x0d, 0x45, 0x94,
|
||||
0xdc, 0x9c, 0xd4, 0x05, 0x4c, 0x0c, 0x44, 0x95,
|
||||
0x59, 0x19, 0x51, 0x80, 0xc9, 0x89, 0xc1, 0x10,
|
||||
0x58, 0x18, 0x50, 0x81, 0xc8, 0x88, 0xc0, 0x11,
|
||||
0xd7, 0x97, 0xdf, 0x02, 0x47, 0x07, 0x4f, 0x92,
|
||||
0xda, 0x9a, 0xd2, 0x0f, 0x4a, 0x0a, 0x42, 0x9f,
|
||||
0x53, 0x13, 0x5b, 0x86, 0xc3, 0x83, 0xcb, 0x16,
|
||||
0x5e, 0x1e, 0x56, 0x8b, 0xce, 0x8e, 0xc6, 0x1b,
|
||||
0xb3, 0xf3, 0xbb, 0xa6, 0xe3, 0xa3, 0xeb, 0xf6,
|
||||
0xbe, 0xfe, 0xb6, 0xab, 0xee, 0xae, 0xe6, 0xfb,
|
||||
0x37, 0x77, 0x3f, 0x22, 0x67, 0x27, 0x6f, 0x72,
|
||||
0x3a, 0x7a, 0x32, 0x2f, 0x6a, 0x2a, 0x62, 0x7f,
|
||||
0xb9, 0xf9, 0xb1, 0xa0, 0xe9, 0xa9, 0xe1, 0xf0,
|
||||
0xb8, 0xf8, 0xb0, 0xa1, 0xe8, 0xa8, 0xe0, 0xf1,
|
||||
0x5d, 0x1d, 0x55, 0x84, 0xcd, 0x8d, 0xc5, 0x14,
|
||||
0x5c, 0x1c, 0x54, 0x85, 0xcc, 0x8c, 0xc4, 0x15,
|
||||
0xbd, 0xfd, 0xb5, 0xa4, 0xed, 0xad, 0xe5, 0xf4,
|
||||
0xbc, 0xfc, 0xb4, 0xa5, 0xec, 0xac, 0xe4, 0xf5,
|
||||
0x39, 0x79, 0x31, 0x20, 0x69, 0x29, 0x61, 0x70,
|
||||
0x38, 0x78, 0x30, 0x21, 0x68, 0x28, 0x60, 0x71,
|
||||
0xb7, 0xf7, 0xbf, 0xa2, 0xe7, 0xa7, 0xef, 0xf2,
|
||||
0xba, 0xfa, 0xb2, 0xaf, 0xea, 0xaa, 0xe2, 0xff
|
||||
};
|
||||
|
||||
static u8 p_css_tab2[ 256 ] =
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x09, 0x08, 0x0b, 0x0a, 0x0d, 0x0c, 0x0f, 0x0e,
|
||||
0x12, 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15,
|
||||
0x1b, 0x1a, 0x19, 0x18, 0x1f, 0x1e, 0x1d, 0x1c,
|
||||
0x24, 0x25, 0x26, 0x27, 0x20, 0x21, 0x22, 0x23,
|
||||
0x2d, 0x2c, 0x2f, 0x2e, 0x29, 0x28, 0x2b, 0x2a,
|
||||
0x36, 0x37, 0x34, 0x35, 0x32, 0x33, 0x30, 0x31,
|
||||
0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38,
|
||||
0x49, 0x48, 0x4b, 0x4a, 0x4d, 0x4c, 0x4f, 0x4e,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
||||
0x5b, 0x5a, 0x59, 0x58, 0x5f, 0x5e, 0x5d, 0x5c,
|
||||
0x52, 0x53, 0x50, 0x51, 0x56, 0x57, 0x54, 0x55,
|
||||
0x6d, 0x6c, 0x6f, 0x6e, 0x69, 0x68, 0x6b, 0x6a,
|
||||
0x64, 0x65, 0x66, 0x67, 0x60, 0x61, 0x62, 0x63,
|
||||
0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78,
|
||||
0x76, 0x77, 0x74, 0x75, 0x72, 0x73, 0x70, 0x71,
|
||||
0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95,
|
||||
0x9b, 0x9a, 0x99, 0x98, 0x9f, 0x9e, 0x9d, 0x9c,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
||||
0x89, 0x88, 0x8b, 0x8a, 0x8d, 0x8c, 0x8f, 0x8e,
|
||||
0xb6, 0xb7, 0xb4, 0xb5, 0xb2, 0xb3, 0xb0, 0xb1,
|
||||
0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8,
|
||||
0xa4, 0xa5, 0xa6, 0xa7, 0xa0, 0xa1, 0xa2, 0xa3,
|
||||
0xad, 0xac, 0xaf, 0xae, 0xa9, 0xa8, 0xab, 0xaa,
|
||||
0xdb, 0xda, 0xd9, 0xd8, 0xdf, 0xde, 0xdd, 0xdc,
|
||||
0xd2, 0xd3, 0xd0, 0xd1, 0xd6, 0xd7, 0xd4, 0xd5,
|
||||
0xc9, 0xc8, 0xcb, 0xca, 0xcd, 0xcc, 0xcf, 0xce,
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
|
||||
0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
|
||||
0xf6, 0xf7, 0xf4, 0xf5, 0xf2, 0xf3, 0xf0, 0xf1,
|
||||
0xed, 0xec, 0xef, 0xee, 0xe9, 0xe8, 0xeb, 0xea,
|
||||
0xe4, 0xe5, 0xe6, 0xe7, 0xe0, 0xe1, 0xe2, 0xe3
|
||||
};
|
||||
|
||||
static u8 p_css_tab3[ 512 ] =
|
||||
{
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
|
||||
0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff
|
||||
};
|
||||
|
||||
static u8 p_css_tab4[ 256 ] =
|
||||
{
|
||||
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
|
||||
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
|
||||
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
|
||||
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
|
||||
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
|
||||
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
|
||||
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
|
||||
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
|
||||
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
|
||||
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
|
||||
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
|
||||
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
|
||||
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
|
||||
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
|
||||
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
|
||||
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
|
||||
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
|
||||
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
|
||||
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
|
||||
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
|
||||
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
|
||||
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
|
||||
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
|
||||
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
|
||||
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
|
||||
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
|
||||
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
|
||||
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
|
||||
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
|
||||
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
|
||||
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
|
||||
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
|
||||
};
|
||||
|
||||
static u8 p_css_tab5[ 256 ] =
|
||||
{
|
||||
0xff, 0x7f, 0xbf, 0x3f, 0xdf, 0x5f, 0x9f, 0x1f,
|
||||
0xef, 0x6f, 0xaf, 0x2f, 0xcf, 0x4f, 0x8f, 0x0f,
|
||||
0xf7, 0x77, 0xb7, 0x37, 0xd7, 0x57, 0x97, 0x17,
|
||||
0xe7, 0x67, 0xa7, 0x27, 0xc7, 0x47, 0x87, 0x07,
|
||||
0xfb, 0x7b, 0xbb, 0x3b, 0xdb, 0x5b, 0x9b, 0x1b,
|
||||
0xeb, 0x6b, 0xab, 0x2b, 0xcb, 0x4b, 0x8b, 0x0b,
|
||||
0xf3, 0x73, 0xb3, 0x33, 0xd3, 0x53, 0x93, 0x13,
|
||||
0xe3, 0x63, 0xa3, 0x23, 0xc3, 0x43, 0x83, 0x03,
|
||||
0xfd, 0x7d, 0xbd, 0x3d, 0xdd, 0x5d, 0x9d, 0x1d,
|
||||
0xed, 0x6d, 0xad, 0x2d, 0xcd, 0x4d, 0x8d, 0x0d,
|
||||
0xf5, 0x75, 0xb5, 0x35, 0xd5, 0x55, 0x95, 0x15,
|
||||
0xe5, 0x65, 0xa5, 0x25, 0xc5, 0x45, 0x85, 0x05,
|
||||
0xf9, 0x79, 0xb9, 0x39, 0xd9, 0x59, 0x99, 0x19,
|
||||
0xe9, 0x69, 0xa9, 0x29, 0xc9, 0x49, 0x89, 0x09,
|
||||
0xf1, 0x71, 0xb1, 0x31, 0xd1, 0x51, 0x91, 0x11,
|
||||
0xe1, 0x61, 0xa1, 0x21, 0xc1, 0x41, 0x81, 0x01,
|
||||
0xfe, 0x7e, 0xbe, 0x3e, 0xde, 0x5e, 0x9e, 0x1e,
|
||||
0xee, 0x6e, 0xae, 0x2e, 0xce, 0x4e, 0x8e, 0x0e,
|
||||
0xf6, 0x76, 0xb6, 0x36, 0xd6, 0x56, 0x96, 0x16,
|
||||
0xe6, 0x66, 0xa6, 0x26, 0xc6, 0x46, 0x86, 0x06,
|
||||
0xfa, 0x7a, 0xba, 0x3a, 0xda, 0x5a, 0x9a, 0x1a,
|
||||
0xea, 0x6a, 0xaa, 0x2a, 0xca, 0x4a, 0x8a, 0x0a,
|
||||
0xf2, 0x72, 0xb2, 0x32, 0xd2, 0x52, 0x92, 0x12,
|
||||
0xe2, 0x62, 0xa2, 0x22, 0xc2, 0x42, 0x82, 0x02,
|
||||
0xfc, 0x7c, 0xbc, 0x3c, 0xdc, 0x5c, 0x9c, 0x1c,
|
||||
0xec, 0x6c, 0xac, 0x2c, 0xcc, 0x4c, 0x8c, 0x0c,
|
||||
0xf4, 0x74, 0xb4, 0x34, 0xd4, 0x54, 0x94, 0x14,
|
||||
0xe4, 0x64, 0xa4, 0x24, 0xc4, 0x44, 0x84, 0x04,
|
||||
0xf8, 0x78, 0xb8, 0x38, 0xd8, 0x58, 0x98, 0x18,
|
||||
0xe8, 0x68, 0xa8, 0x28, 0xc8, 0x48, 0x88, 0x08,
|
||||
0xf0, 0x70, 0xb0, 0x30, 0xd0, 0x50, 0x90, 0x10,
|
||||
0xe0, 0x60, 0xa0, 0x20, 0xc0, 0x40, 0x80, 0x00
|
||||
};
|
||||
|
||||
static u8 p_crypt_tab0[ 256 ] =
|
||||
{
|
||||
0xB7, 0xF4, 0x82, 0x57, 0xDA, 0x4D, 0xDB, 0xE2,
|
||||
0x2F, 0x52, 0x1A, 0xA8, 0x68, 0x5A, 0x8A, 0xFF,
|
||||
0xFB, 0x0E, 0x6D, 0x35, 0xF7, 0x5C, 0x76, 0x12,
|
||||
0xCE, 0x25, 0x79, 0x29, 0x39, 0x62, 0x08, 0x24,
|
||||
0xA5, 0x85, 0x7B, 0x56, 0x01, 0x23, 0x68, 0xCF,
|
||||
0x0A, 0xE2, 0x5A, 0xED, 0x3D, 0x59, 0xB0, 0xA9,
|
||||
0xB0, 0x2C, 0xF2, 0xB8, 0xEF, 0x32, 0xA9, 0x40,
|
||||
0x80, 0x71, 0xAF, 0x1E, 0xDE, 0x8F, 0x58, 0x88,
|
||||
0xB8, 0x3A, 0xD0, 0xFC, 0xC4, 0x1E, 0xB5, 0xA0,
|
||||
0xBB, 0x3B, 0x0F, 0x01, 0x7E, 0x1F, 0x9F, 0xD9,
|
||||
0xAA, 0xB8, 0x3D, 0x9D, 0x74, 0x1E, 0x25, 0xDB,
|
||||
0x37, 0x56, 0x8F, 0x16, 0xBA, 0x49, 0x2B, 0xAC,
|
||||
0xD0, 0xBD, 0x95, 0x20, 0xBE, 0x7A, 0x28, 0xD0,
|
||||
0x51, 0x64, 0x63, 0x1C, 0x7F, 0x66, 0x10, 0xBB,
|
||||
0xC4, 0x56, 0x1A, 0x04, 0x6E, 0x0A, 0xEC, 0x9C,
|
||||
0xD6, 0xE8, 0x9A, 0x7A, 0xCF, 0x8C, 0xDB, 0xB1,
|
||||
0xEF, 0x71, 0xDE, 0x31, 0xFF, 0x54, 0x3E, 0x5E,
|
||||
0x07, 0x69, 0x96, 0xB0, 0xCF, 0xDD, 0x9E, 0x47,
|
||||
0xC7, 0x96, 0x8F, 0xE4, 0x2B, 0x59, 0xC6, 0xEE,
|
||||
0xB9, 0x86, 0x9A, 0x64, 0x84, 0x72, 0xE2, 0x5B,
|
||||
0xA2, 0x96, 0x58, 0x99, 0x50, 0x03, 0xF5, 0x38,
|
||||
0x4D, 0x02, 0x7D, 0xE7, 0x7D, 0x75, 0xA7, 0xB8,
|
||||
0x67, 0x87, 0x84, 0x3F, 0x1D, 0x11, 0xE5, 0xFC,
|
||||
0x1E, 0xD3, 0x83, 0x16, 0xA5, 0x29, 0xF6, 0xC7,
|
||||
0x15, 0x61, 0x29, 0x1A, 0x43, 0x4F, 0x9B, 0xAF,
|
||||
0xC5, 0x87, 0x34, 0x6C, 0x0F, 0x3B, 0xA8, 0x1D,
|
||||
0x45, 0x58, 0x25, 0xDC, 0xA8, 0xA3, 0x3B, 0xD1,
|
||||
0x79, 0x1B, 0x48, 0xF2, 0xE9, 0x93, 0x1F, 0xFC,
|
||||
0xDB, 0x2A, 0x90, 0xA9, 0x8A, 0x3D, 0x39, 0x18,
|
||||
0xA3, 0x8E, 0x58, 0x6C, 0xE0, 0x12, 0xBB, 0x25,
|
||||
0xCD, 0x71, 0x22, 0xA2, 0x64, 0xC6, 0xE7, 0xFB,
|
||||
0xAD, 0x94, 0x77, 0x04, 0x9A, 0x39, 0xCF, 0x7C
|
||||
};
|
||||
|
||||
static u8 p_crypt_tab1[ 256 ] =
|
||||
{
|
||||
0x8C, 0x47, 0xB0, 0xE1, 0xEB, 0xFC, 0xEB, 0x56,
|
||||
0x10, 0xE5, 0x2C, 0x1A, 0x5D, 0xEF, 0xBE, 0x4F,
|
||||
0x08, 0x75, 0x97, 0x4B, 0x0E, 0x25, 0x8E, 0x6E,
|
||||
0x39, 0x5A, 0x87, 0x53, 0xC4, 0x1F, 0xF4, 0x5C,
|
||||
0x4E, 0xE6, 0x99, 0x30, 0xE0, 0x42, 0x88, 0xAB,
|
||||
0xE5, 0x85, 0xBC, 0x8F, 0xD8, 0x3C, 0x54, 0xC9,
|
||||
0x53, 0x47, 0x18, 0xD6, 0x06, 0x5B, 0x41, 0x2C,
|
||||
0x67, 0x1E, 0x41, 0x74, 0x33, 0xE2, 0xB4, 0xE0,
|
||||
0x23, 0x29, 0x42, 0xEA, 0x55, 0x0F, 0x25, 0xB4,
|
||||
0x24, 0x2C, 0x99, 0x13, 0xEB, 0x0A, 0x0B, 0xC9,
|
||||
0xF9, 0x63, 0x67, 0x43, 0x2D, 0xC7, 0x7D, 0x07,
|
||||
0x60, 0x89, 0xD1, 0xCC, 0xE7, 0x94, 0x77, 0x74,
|
||||
0x9B, 0x7E, 0xD7, 0xE6, 0xFF, 0xBB, 0x68, 0x14,
|
||||
0x1E, 0xA3, 0x25, 0xDE, 0x3A, 0xA3, 0x54, 0x7B,
|
||||
0x87, 0x9D, 0x50, 0xCA, 0x27, 0xC3, 0xA4, 0x50,
|
||||
0x91, 0x27, 0xD4, 0xB0, 0x82, 0x41, 0x97, 0x79,
|
||||
0x94, 0x82, 0xAC, 0xC7, 0x8E, 0xA5, 0x4E, 0xAA,
|
||||
0x78, 0x9E, 0xE0, 0x42, 0xBA, 0x28, 0xEA, 0xB7,
|
||||
0x74, 0xAD, 0x35, 0xDA, 0x92, 0x60, 0x7E, 0xD2,
|
||||
0x0E, 0xB9, 0x24, 0x5E, 0x39, 0x4F, 0x5E, 0x63,
|
||||
0x09, 0xB5, 0xFA, 0xBF, 0xF1, 0x22, 0x55, 0x1C,
|
||||
0xE2, 0x25, 0xDB, 0xC5, 0xD8, 0x50, 0x03, 0x98,
|
||||
0xC4, 0xAC, 0x2E, 0x11, 0xB4, 0x38, 0x4D, 0xD0,
|
||||
0xB9, 0xFC, 0x2D, 0x3C, 0x08, 0x04, 0x5A, 0xEF,
|
||||
0xCE, 0x32, 0xFB, 0x4C, 0x92, 0x1E, 0x4B, 0xFB,
|
||||
0x1A, 0xD0, 0xE2, 0x3E, 0xDA, 0x6E, 0x7C, 0x4D,
|
||||
0x56, 0xC3, 0x3F, 0x42, 0xB1, 0x3A, 0x23, 0x4D,
|
||||
0x6E, 0x84, 0x56, 0x68, 0xF4, 0x0E, 0x03, 0x64,
|
||||
0xD0, 0xA9, 0x92, 0x2F, 0x8B, 0xBC, 0x39, 0x9C,
|
||||
0xAC, 0x09, 0x5E, 0xEE, 0xE5, 0x97, 0xBF, 0xA5,
|
||||
0xCE, 0xFA, 0x28, 0x2C, 0x6D, 0x4F, 0xEF, 0x77,
|
||||
0xAA, 0x1B, 0x79, 0x8E, 0x97, 0xB4, 0xC3, 0xF4
|
||||
};
|
||||
|
||||
static u8 p_crypt_tab2[ 256 ] =
|
||||
{
|
||||
0xB7, 0x75, 0x81, 0xD5, 0xDC, 0xCA, 0xDE, 0x66,
|
||||
0x23, 0xDF, 0x15, 0x26, 0x62, 0xD1, 0x83, 0x77,
|
||||
0xE3, 0x97, 0x76, 0xAF, 0xE9, 0xC3, 0x6B, 0x8E,
|
||||
0xDA, 0xB0, 0x6E, 0xBF, 0x2B, 0xF1, 0x19, 0xB4,
|
||||
0x95, 0x34, 0x48, 0xE4, 0x37, 0x94, 0x5D, 0x7B,
|
||||
0x36, 0x5F, 0x65, 0x53, 0x07, 0xE2, 0x89, 0x11,
|
||||
0x98, 0x85, 0xD9, 0x12, 0xC1, 0x9D, 0x84, 0xEC,
|
||||
0xA4, 0xD4, 0x88, 0xB8, 0xFC, 0x2C, 0x79, 0x28,
|
||||
0xD8, 0xDB, 0xB3, 0x1E, 0xA2, 0xF9, 0xD0, 0x44,
|
||||
0xD7, 0xD6, 0x60, 0xEF, 0x14, 0xF4, 0xF6, 0x31,
|
||||
0xD2, 0x41, 0x46, 0x67, 0x0A, 0xE1, 0x58, 0x27,
|
||||
0x43, 0xA3, 0xF8, 0xE0, 0xC8, 0xBA, 0x5A, 0x5C,
|
||||
0x80, 0x6C, 0xC6, 0xF2, 0xE8, 0xAD, 0x7D, 0x04,
|
||||
0x0D, 0xB9, 0x3C, 0xC2, 0x25, 0xBD, 0x49, 0x63,
|
||||
0x8C, 0x9F, 0x51, 0xCE, 0x20, 0xC5, 0xA1, 0x50,
|
||||
0x92, 0x2D, 0xDD, 0xBC, 0x8D, 0x4F, 0x9A, 0x71,
|
||||
0x2F, 0x30, 0x1D, 0x73, 0x39, 0x13, 0xFB, 0x1A,
|
||||
0xCB, 0x24, 0x59, 0xFE, 0x05, 0x96, 0x57, 0x0F,
|
||||
0x1F, 0xCF, 0x54, 0xBE, 0xF5, 0x06, 0x1B, 0xB2,
|
||||
0x6D, 0xD3, 0x4D, 0x32, 0x56, 0x21, 0x33, 0x0B,
|
||||
0x52, 0xE7, 0xAB, 0xEB, 0xA6, 0x74, 0x00, 0x4C,
|
||||
0xB1, 0x7F, 0x82, 0x99, 0x87, 0x0E, 0x5E, 0xC0,
|
||||
0x8F, 0xEE, 0x6F, 0x55, 0xF3, 0x7E, 0x08, 0x90,
|
||||
0xFA, 0xB6, 0x64, 0x70, 0x47, 0x4A, 0x17, 0xA7,
|
||||
0xB5, 0x40, 0x8A, 0x38, 0xE5, 0x68, 0x3E, 0x8B,
|
||||
0x69, 0xAA, 0x9B, 0x42, 0xA5, 0x10, 0x01, 0x35,
|
||||
0xFD, 0x61, 0x9E, 0xE6, 0x16, 0x9C, 0x86, 0xED,
|
||||
0xCD, 0x2E, 0xFF, 0xC4, 0x5B, 0xA0, 0xAE, 0xCC,
|
||||
0x4B, 0x3B, 0x03, 0xBB, 0x1C, 0x2A, 0xAC, 0x0C,
|
||||
0x3F, 0x93, 0xC7, 0x72, 0x7A, 0x09, 0x22, 0x3D,
|
||||
0x45, 0x78, 0xA9, 0xA8, 0xEA, 0xC9, 0x6A, 0xF7,
|
||||
0x29, 0x91, 0xF0, 0x02, 0x18, 0x3A, 0x4E, 0x7C
|
||||
};
|
||||
|
||||
static u8 p_crypt_tab3[ 288 ] =
|
||||
{
|
||||
0x73, 0x51, 0x95, 0xE1, 0x12, 0xE4, 0xC0, 0x58,
|
||||
0xEE, 0xF2, 0x08, 0x1B, 0xA9, 0xFA, 0x98, 0x4C,
|
||||
0xA7, 0x33, 0xE2, 0x1B, 0xA7, 0x6D, 0xF5, 0x30,
|
||||
0x97, 0x1D, 0xF3, 0x02, 0x60, 0x5A, 0x82, 0x0F,
|
||||
0x91, 0xD0, 0x9C, 0x10, 0x39, 0x7A, 0x83, 0x85,
|
||||
0x3B, 0xB2, 0xB8, 0xAE, 0x0C, 0x09, 0x52, 0xEA,
|
||||
0x1C, 0xE1, 0x8D, 0x66, 0x4F, 0xF3, 0xDA, 0x92,
|
||||
0x29, 0xB9, 0xD5, 0xC5, 0x77, 0x47, 0x22, 0x53,
|
||||
0x14, 0xF7, 0xAF, 0x22, 0x64, 0xDF, 0xC6, 0x72,
|
||||
0x12, 0xF3, 0x75, 0xDA, 0xD7, 0xD7, 0xE5, 0x02,
|
||||
0x9E, 0xED, 0xDA, 0xDB, 0x4C, 0x47, 0xCE, 0x91,
|
||||
0x06, 0x06, 0x6D, 0x55, 0x8B, 0x19, 0xC9, 0xEF,
|
||||
0x8C, 0x80, 0x1A, 0x0E, 0xEE, 0x4B, 0xAB, 0xF2,
|
||||
0x08, 0x5C, 0xE9, 0x37, 0x26, 0x5E, 0x9A, 0x90,
|
||||
0x00, 0xF3, 0x0D, 0xB2, 0xA6, 0xA3, 0xF7, 0x26,
|
||||
0x17, 0x48, 0x88, 0xC9, 0x0E, 0x2C, 0xC9, 0x02,
|
||||
0xE7, 0x18, 0x05, 0x4B, 0xF3, 0x39, 0xE1, 0x20,
|
||||
0x02, 0x0D, 0x40, 0xC7, 0xCA, 0xB9, 0x48, 0x30,
|
||||
0x57, 0x67, 0xCC, 0x06, 0xBF, 0xAC, 0x81, 0x08,
|
||||
0x24, 0x7A, 0xD4, 0x8B, 0x19, 0x8E, 0xAC, 0xB4,
|
||||
0x5A, 0x0F, 0x73, 0x13, 0xAC, 0x9E, 0xDA, 0xB6,
|
||||
0xB8, 0x96, 0x5B, 0x60, 0x88, 0xE1, 0x81, 0x3F,
|
||||
0x07, 0x86, 0x37, 0x2D, 0x79, 0x14, 0x52, 0xEA,
|
||||
0x73, 0xDF, 0x3D, 0x09, 0xC8, 0x25, 0x48, 0xD8,
|
||||
0x75, 0x60, 0x9A, 0x08, 0x27, 0x4A, 0x2C, 0xB9,
|
||||
0xA8, 0x8B, 0x8A, 0x73, 0x62, 0x37, 0x16, 0x02,
|
||||
0xBD, 0xC1, 0x0E, 0x56, 0x54, 0x3E, 0x14, 0x5F,
|
||||
0x8C, 0x8F, 0x6E, 0x75, 0x1C, 0x07, 0x39, 0x7B,
|
||||
0x4B, 0xDB, 0xD3, 0x4B, 0x1E, 0xC8, 0x7E, 0xFE,
|
||||
0x3E, 0x72, 0x16, 0x83, 0x7D, 0xEE, 0xF5, 0xCA,
|
||||
0xC5, 0x18, 0xF9, 0xD8, 0x68, 0xAB, 0x38, 0x85,
|
||||
0xA8, 0xF0, 0xA1, 0x73, 0x9F, 0x5D, 0x19, 0x0B,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x33, 0x72, 0x39, 0x25, 0x67, 0x26, 0x6D, 0x71,
|
||||
0x36, 0x77, 0x3C, 0x20, 0x62, 0x23, 0x68, 0x74,
|
||||
0xC3, 0x82, 0xC9, 0x15, 0x57, 0x16, 0x5D, 0x81
|
||||
};
|
||||
|
679
libmpdvdkit2/device.c
Normal file
679
libmpdvdkit2/device.c
Normal file
@ -0,0 +1,679 @@
|
||||
/*****************************************************************************
|
||||
* device.h: DVD device access
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1998-2002 VideoLAN
|
||||
* $Id$
|
||||
*
|
||||
* Authors: Stéphane Borel <stef@via.ecp.fr>
|
||||
* Samuel Hocevar <sam@zoy.org>
|
||||
* Håkan Hjort <d95hjort@dtek.chalmers.se>
|
||||
*
|
||||
* 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, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Preamble
|
||||
*****************************************************************************/
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined( WIN32 )
|
||||
# include <io.h> /* read() */
|
||||
#else
|
||||
# include <sys/uio.h> /* struct iovec */
|
||||
#endif
|
||||
|
||||
#include "dvdcss/dvdcss.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "css.h"
|
||||
#include "libdvdcss.h"
|
||||
#include "ioctl.h"
|
||||
#include "device.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Device reading prototypes, win32 specific
|
||||
*****************************************************************************/
|
||||
#ifdef WIN32
|
||||
int _win32_dvdcss_readv ( int, struct iovec *, int, char * );
|
||||
int _win32_dvdcss_aopen ( dvdcss_t, char );
|
||||
int _win32_dvdcss_aclose ( int );
|
||||
int _win32_dvdcss_aseek ( int, int, int );
|
||||
int _win32_dvdcss_aread ( int, void *, int );
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* readv_*: readv() replacements for iovec-impaired C libraries
|
||||
*****************************************************************************/
|
||||
#if defined( WIN32 )
|
||||
static inline int readv( int i_fd, struct iovec * p_iovec, int i_count )
|
||||
{
|
||||
int i_index, i_len, i_total = 0;
|
||||
unsigned char *p_base;
|
||||
int i_bytes;
|
||||
|
||||
for( i_index = i_count; i_index; i_index-- )
|
||||
{
|
||||
i_len = p_iovec->iov_len;
|
||||
p_base = p_iovec->iov_base;
|
||||
|
||||
/* Loop is unrolled one time to spare the (i_bytes <= 0) test */
|
||||
|
||||
if( i_len > 0 )
|
||||
{
|
||||
i_bytes = read( i_fd, p_base, i_len );
|
||||
|
||||
if( i_bytes < 0 )
|
||||
{
|
||||
/* One of the reads failed, too bad.
|
||||
We won't even bother returning the reads that went ok,
|
||||
and as in the posix spec the file postition is left
|
||||
unspecified after a failure */
|
||||
return -1;
|
||||
}
|
||||
|
||||
i_total += i_bytes;
|
||||
|
||||
if( i_bytes != i_len )
|
||||
{
|
||||
/* we reached the end of the file or a signal interrupted
|
||||
the read */
|
||||
return i_total;
|
||||
}
|
||||
}
|
||||
|
||||
p_iovec++;
|
||||
}
|
||||
|
||||
return i_total;
|
||||
}
|
||||
#endif /* WIN32 */
|
||||
|
||||
int _dvdcss_use_ioctls( dvdcss_t dvdcss )
|
||||
{
|
||||
#if defined( WIN32 )
|
||||
/* Some one need to implement this for Windows */
|
||||
if( WIN2K )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
struct stat fileinfo;
|
||||
int ret;
|
||||
|
||||
ret = fstat( dvdcss->i_fd, &fileinfo );
|
||||
if( ret < 0 )
|
||||
{
|
||||
return 1; /* What to do? Be conservative and try to use the ioctls */
|
||||
}
|
||||
|
||||
/* Complete this list and check that we test for the right things
|
||||
* (I've assumed for all OSs that 'r', (raw) device, are char devices
|
||||
* and those that don't contain/use an 'r' in the name are block devices)
|
||||
*
|
||||
* Linux needs a block device
|
||||
* Solaris needs a char device
|
||||
* Darwin needs a char device
|
||||
* OpenBSD needs a char device
|
||||
* NetBSD needs a char device
|
||||
* FreeBSD can use either the block or the char device
|
||||
* BSD/OS can use either the block or the char device
|
||||
*/
|
||||
|
||||
/* Check if this is a block/char device */
|
||||
if( S_ISBLK( fileinfo.st_mode ) ||
|
||||
S_ISCHR( fileinfo.st_mode ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int _dvdcss_open ( dvdcss_t dvdcss )
|
||||
{
|
||||
char *psz_device = dvdcss->psz_device;
|
||||
|
||||
#if defined( WIN32 )
|
||||
if( WIN2K )
|
||||
{
|
||||
char psz_dvd[7];
|
||||
_snprintf( psz_dvd, 7, "\\\\.\\%c:", psz_device[0] );
|
||||
|
||||
/* To have access to ioctls, we need read and write access to the
|
||||
* device. This is only allowed if you have administrator priviledges
|
||||
* so we allow for a fallback method where ioctls are not available but
|
||||
* we at least have read access to the device.
|
||||
* (See Microsoft Q241374: Read and Write Access Required for SCSI
|
||||
* Pass Through Requests) */
|
||||
(HANDLE) dvdcss->i_fd =
|
||||
CreateFile( psz_dvd, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING,
|
||||
FILE_FLAG_RANDOM_ACCESS, NULL );
|
||||
|
||||
if( (HANDLE) dvdcss->i_fd == INVALID_HANDLE_VALUE )
|
||||
(HANDLE) dvdcss->i_fd =
|
||||
CreateFile( psz_dvd, GENERIC_READ, FILE_SHARE_READ,
|
||||
NULL, OPEN_EXISTING,
|
||||
FILE_FLAG_RANDOM_ACCESS, NULL );
|
||||
|
||||
if( (HANDLE) dvdcss->i_fd == INVALID_HANDLE_VALUE )
|
||||
{
|
||||
_dvdcss_error( dvdcss, "failed opening device" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dvdcss->i_fd = _win32_dvdcss_aopen( dvdcss, psz_device[0] );
|
||||
if( dvdcss->i_fd == -1 )
|
||||
{
|
||||
_dvdcss_error( dvdcss, "failed opening device" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* initialise readv temporary buffer */
|
||||
dvdcss->p_readv_buffer = NULL;
|
||||
dvdcss->i_readv_buf_size = 0;
|
||||
|
||||
#else
|
||||
dvdcss->i_fd = dvdcss->i_read_fd = open( psz_device, 0 );
|
||||
|
||||
if( dvdcss->i_fd == -1 )
|
||||
{
|
||||
_dvdcss_error( dvdcss, "failed opening device" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
int _dvdcss_raw_open ( dvdcss_t dvdcss, char *psz_device )
|
||||
{
|
||||
dvdcss->i_raw_fd = open( psz_device, 0 );
|
||||
|
||||
if( dvdcss->i_raw_fd == -1 )
|
||||
{
|
||||
_dvdcss_error( dvdcss, "failed opening raw device, continuing" );
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dvdcss->i_read_fd = dvdcss->i_raw_fd;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int _dvdcss_close ( dvdcss_t dvdcss )
|
||||
{
|
||||
#if defined( WIN32 )
|
||||
if( WIN2K )
|
||||
{
|
||||
CloseHandle( (HANDLE) dvdcss->i_fd );
|
||||
}
|
||||
else
|
||||
{
|
||||
_win32_dvdcss_aclose( dvdcss->i_fd );
|
||||
}
|
||||
|
||||
/* Free readv temporary buffer */
|
||||
if( dvdcss->p_readv_buffer )
|
||||
{
|
||||
free( dvdcss->p_readv_buffer );
|
||||
dvdcss->p_readv_buffer = NULL;
|
||||
dvdcss->i_readv_buf_size = 0;
|
||||
}
|
||||
|
||||
#else
|
||||
close( dvdcss->i_fd );
|
||||
|
||||
if( dvdcss->i_raw_fd >= 0 )
|
||||
{
|
||||
close( dvdcss->i_raw_fd );
|
||||
dvdcss->i_raw_fd = -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _dvdcss_seek ( dvdcss_t dvdcss, int i_blocks )
|
||||
{
|
||||
#if defined( WIN32 )
|
||||
dvdcss->i_seekpos = i_blocks;
|
||||
|
||||
if( WIN2K )
|
||||
{
|
||||
LARGE_INTEGER li_read;
|
||||
|
||||
#ifndef INVALID_SET_FILE_POINTER
|
||||
#define INVALID_SET_FILE_POINTER ((DWORD)-1)
|
||||
#endif
|
||||
|
||||
li_read.QuadPart = (LONGLONG)i_blocks * DVDCSS_BLOCK_SIZE;
|
||||
|
||||
li_read.LowPart = SetFilePointer( (HANDLE) dvdcss->i_fd,
|
||||
li_read.LowPart,
|
||||
&li_read.HighPart, FILE_BEGIN );
|
||||
if( (li_read.LowPart == INVALID_SET_FILE_POINTER)
|
||||
&& GetLastError() != NO_ERROR)
|
||||
{
|
||||
li_read.QuadPart = -DVDCSS_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
li_read.QuadPart /= DVDCSS_BLOCK_SIZE;
|
||||
return (int)li_read.QuadPart;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ( _win32_dvdcss_aseek( dvdcss->i_fd, i_blocks, SEEK_SET ) );
|
||||
}
|
||||
#else
|
||||
off_t i_read;
|
||||
|
||||
dvdcss->i_seekpos = i_blocks;
|
||||
|
||||
i_read = lseek( dvdcss->i_read_fd,
|
||||
(off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE, SEEK_SET );
|
||||
|
||||
if( i_read < 0 )
|
||||
{
|
||||
_dvdcss_error( dvdcss, "seek error" );
|
||||
}
|
||||
|
||||
return i_read / DVDCSS_BLOCK_SIZE;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
int _dvdcss_read ( dvdcss_t dvdcss, void *p_buffer, int i_blocks )
|
||||
{
|
||||
#if defined( WIN32 )
|
||||
if( WIN2K )
|
||||
{
|
||||
int i_bytes;
|
||||
|
||||
if( !ReadFile( (HANDLE) dvdcss->i_fd, p_buffer,
|
||||
i_blocks * DVDCSS_BLOCK_SIZE,
|
||||
(LPDWORD)&i_bytes, NULL ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return i_bytes / DVDCSS_BLOCK_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return _win32_dvdcss_aread( dvdcss->i_fd, p_buffer, i_blocks );
|
||||
}
|
||||
|
||||
#else
|
||||
int i_ret;
|
||||
/* TODO: partial reads are wrong,i.e 2200/2048 = 1
|
||||
* but the location has advanced 2200 bytes (lseek possition that is) */
|
||||
i_ret = read( dvdcss->i_read_fd, p_buffer,
|
||||
(off_t)i_blocks * DVDCSS_BLOCK_SIZE );
|
||||
if( i_ret < 0 )
|
||||
{
|
||||
_dvdcss_error( dvdcss, "read error" );
|
||||
return i_ret;
|
||||
}
|
||||
|
||||
return i_ret / DVDCSS_BLOCK_SIZE;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
int _dvdcss_readv ( dvdcss_t dvdcss, struct iovec *p_iovec, int i_blocks )
|
||||
{
|
||||
int i_read;
|
||||
|
||||
#if defined( WIN32 )
|
||||
/* Check the size of the readv temp buffer, just in case we need to
|
||||
* realloc something bigger */
|
||||
if( dvdcss->i_readv_buf_size < i_blocks * DVDCSS_BLOCK_SIZE )
|
||||
{
|
||||
dvdcss->i_readv_buf_size = i_blocks * DVDCSS_BLOCK_SIZE;
|
||||
|
||||
if( dvdcss->p_readv_buffer ) free( dvdcss->p_readv_buffer );
|
||||
|
||||
/* Allocate a buffer which will be used as a temporary storage
|
||||
* for readv */
|
||||
dvdcss->p_readv_buffer = malloc( dvdcss->i_readv_buf_size );
|
||||
if( !dvdcss->p_readv_buffer )
|
||||
{
|
||||
_dvdcss_error( dvdcss, " failed (readv)" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
i_read = _win32_dvdcss_readv( dvdcss->i_fd, p_iovec, i_blocks,
|
||||
dvdcss->p_readv_buffer );
|
||||
return i_read;
|
||||
|
||||
#else
|
||||
i_read = readv( dvdcss->i_read_fd, p_iovec, i_blocks );
|
||||
return i_read / DVDCSS_BLOCK_SIZE;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if defined( WIN32 )
|
||||
|
||||
/*****************************************************************************
|
||||
* _win32_dvdcss_readv: vectored read using ReadFile for Win2K and
|
||||
* _win32_dvdcss_aread for win9x
|
||||
*****************************************************************************/
|
||||
int _win32_dvdcss_readv( int i_fd, struct iovec *p_iovec,
|
||||
int i_num_buffers, char *p_tmp_buffer )
|
||||
{
|
||||
int i_index;
|
||||
int i_blocks, i_blocks_total = 0;
|
||||
|
||||
for( i_index = i_num_buffers; i_index; i_index-- )
|
||||
{
|
||||
i_blocks_total += p_iovec[i_index-1].iov_len;
|
||||
}
|
||||
|
||||
if( i_blocks_total <= 0 ) return 0;
|
||||
|
||||
i_blocks_total /= DVDCSS_BLOCK_SIZE;
|
||||
|
||||
if( WIN2K )
|
||||
{
|
||||
unsigned long int i_bytes;
|
||||
if( !ReadFile( (HANDLE)i_fd, p_tmp_buffer,
|
||||
i_blocks_total * DVDCSS_BLOCK_SIZE, &i_bytes, NULL ) )
|
||||
{
|
||||
return -1;
|
||||
/* The read failed... too bad.
|
||||
As in the posix spec the file postition is left
|
||||
unspecified after a failure */
|
||||
}
|
||||
i_blocks = i_bytes / DVDCSS_BLOCK_SIZE;
|
||||
}
|
||||
else /* Win9x */
|
||||
{
|
||||
i_blocks = _win32_dvdcss_aread( i_fd, p_tmp_buffer, i_blocks_total );
|
||||
if( i_blocks < 0 )
|
||||
{
|
||||
return -1; /* idem */
|
||||
}
|
||||
}
|
||||
|
||||
/* We just have to copy the content of the temp buffer into the iovecs */
|
||||
i_index = 0;
|
||||
i_blocks_total = i_blocks;
|
||||
while( i_blocks_total > 0 )
|
||||
{
|
||||
memcpy( p_iovec[i_index].iov_base,
|
||||
&p_tmp_buffer[(i_blocks - i_blocks_total) * DVDCSS_BLOCK_SIZE],
|
||||
p_iovec[i_index].iov_len );
|
||||
/* if we read less blocks than asked, we'll just end up copying
|
||||
garbage, this isn't an issue as we return the number of
|
||||
blocks actually read */
|
||||
i_blocks_total -= ( p_iovec[i_index].iov_len / DVDCSS_BLOCK_SIZE );
|
||||
i_index++;
|
||||
}
|
||||
|
||||
return i_blocks;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* _win32_dvdcss_aopen: open dvd drive (load aspi and init w32_aspidev
|
||||
* structure)
|
||||
*****************************************************************************/
|
||||
int _win32_dvdcss_aopen( dvdcss_t dvdcss, char c_drive )
|
||||
{
|
||||
HMODULE hASPI;
|
||||
DWORD dwSupportInfo;
|
||||
struct w32_aspidev *fd;
|
||||
int i, j, i_hostadapters;
|
||||
long (*lpGetSupport)( void );
|
||||
long (*lpSendCommand)( void* );
|
||||
|
||||
hASPI = LoadLibrary( "wnaspi32.dll" );
|
||||
if( hASPI == NULL )
|
||||
{
|
||||
_dvdcss_error( dvdcss, "unable to load wnaspi32.dll" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
(FARPROC) lpGetSupport = GetProcAddress( hASPI, "GetASPI32SupportInfo" );
|
||||
(FARPROC) lpSendCommand = GetProcAddress( hASPI, "SendASPI32Command" );
|
||||
|
||||
if(lpGetSupport == NULL || lpSendCommand == NULL )
|
||||
{
|
||||
_dvdcss_debug( dvdcss, "unable to get aspi function pointers" );
|
||||
FreeLibrary( hASPI );
|
||||
return -1;
|
||||
}
|
||||
|
||||
dwSupportInfo = lpGetSupport();
|
||||
|
||||
if( HIBYTE( LOWORD ( dwSupportInfo ) ) == SS_NO_ADAPTERS )
|
||||
{
|
||||
_dvdcss_debug( dvdcss, "no host adapters found (aspi)" );
|
||||
FreeLibrary( hASPI );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( HIBYTE( LOWORD ( dwSupportInfo ) ) != SS_COMP )
|
||||
{
|
||||
_dvdcss_error( dvdcss, "unable to initalize aspi layer" );
|
||||
FreeLibrary( hASPI );
|
||||
return -1;
|
||||
}
|
||||
|
||||
i_hostadapters = LOBYTE( LOWORD( dwSupportInfo ) );
|
||||
if( i_hostadapters == 0 )
|
||||
{
|
||||
FreeLibrary( hASPI );
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = malloc( sizeof( struct w32_aspidev ) );
|
||||
if( fd == NULL )
|
||||
{
|
||||
FreeLibrary( hASPI );
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd->i_blocks = 0;
|
||||
fd->hASPI = (long) hASPI;
|
||||
fd->lpSendCommand = lpSendCommand;
|
||||
|
||||
c_drive = c_drive > 'Z' ? c_drive - 'a' : c_drive - 'A';
|
||||
|
||||
for( i = 0; i < i_hostadapters; i++ )
|
||||
{
|
||||
for( j = 0; j < 15; j++ )
|
||||
{
|
||||
struct SRB_GetDiskInfo srbDiskInfo;
|
||||
|
||||
srbDiskInfo.SRB_Cmd = SC_GET_DISK_INFO;
|
||||
srbDiskInfo.SRB_HaId = i;
|
||||
srbDiskInfo.SRB_Flags = 0;
|
||||
srbDiskInfo.SRB_Hdr_Rsvd = 0;
|
||||
srbDiskInfo.SRB_Target = j;
|
||||
srbDiskInfo.SRB_Lun = 0;
|
||||
|
||||
lpSendCommand( (void*) &srbDiskInfo );
|
||||
|
||||
if( (srbDiskInfo.SRB_Status == SS_COMP) &&
|
||||
(srbDiskInfo.SRB_Int13HDriveInfo == c_drive) )
|
||||
{
|
||||
fd->i_sid = MAKEWORD( i, j );
|
||||
return (int) fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free( (void*) fd );
|
||||
FreeLibrary( hASPI );
|
||||
_dvdcss_debug( dvdcss, "unable to get haid and target (aspi)" );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* _win32_dvdcss_aclose: close dvd drive (unload aspi and free w32_aspidev
|
||||
* structure)
|
||||
*****************************************************************************/
|
||||
int _win32_dvdcss_aclose( int i_fd )
|
||||
{
|
||||
struct w32_aspidev *fd = (struct w32_aspidev *) i_fd;
|
||||
|
||||
FreeLibrary( (HMODULE) fd->hASPI );
|
||||
free( (void*) i_fd );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* _win32_dvdcss_aseek: aspi version of _dvdcss_seek
|
||||
*
|
||||
* returns the number of blocks read.
|
||||
*****************************************************************************/
|
||||
int _win32_dvdcss_aseek( int i_fd, int i_blocks, int i_method )
|
||||
{
|
||||
int i_old_blocks;
|
||||
char sz_buf[ DVDCSS_BLOCK_SIZE ];
|
||||
struct w32_aspidev *fd = (struct w32_aspidev *) i_fd;
|
||||
|
||||
i_old_blocks = fd->i_blocks;
|
||||
fd->i_blocks = i_blocks;
|
||||
|
||||
if( _win32_dvdcss_aread( i_fd, sz_buf, 1 ) == -1 )
|
||||
{
|
||||
fd->i_blocks = i_old_blocks;
|
||||
return -1;
|
||||
}
|
||||
|
||||
(fd->i_blocks)--;
|
||||
|
||||
return fd->i_blocks;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* _win32_dvdcss_aread: aspi version of _dvdcss_read
|
||||
*
|
||||
* returns the number of blocks read.
|
||||
*****************************************************************************/
|
||||
int _win32_dvdcss_aread( int i_fd, void *p_data, int i_blocks )
|
||||
{
|
||||
HANDLE hEvent;
|
||||
struct SRB_ExecSCSICmd ssc;
|
||||
struct w32_aspidev *fd = (struct w32_aspidev *) i_fd;
|
||||
|
||||
/* Create the transfer completion event */
|
||||
hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
|
||||
if( hEvent == NULL )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset( &ssc, 0, sizeof( ssc ) );
|
||||
|
||||
ssc.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
||||
ssc.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
||||
ssc.SRB_HaId = LOBYTE( fd->i_sid );
|
||||
ssc.SRB_Target = HIBYTE( fd->i_sid );
|
||||
ssc.SRB_SenseLen = SENSE_LEN;
|
||||
|
||||
ssc.SRB_PostProc = (LPVOID) hEvent;
|
||||
ssc.SRB_BufPointer = p_data;
|
||||
ssc.SRB_CDBLen = 12;
|
||||
|
||||
ssc.CDBByte[0] = 0xA8; /* RAW */
|
||||
ssc.CDBByte[2] = (UCHAR) (fd->i_blocks >> 24);
|
||||
ssc.CDBByte[3] = (UCHAR) (fd->i_blocks >> 16) & 0xff;
|
||||
ssc.CDBByte[4] = (UCHAR) (fd->i_blocks >> 8) & 0xff;
|
||||
ssc.CDBByte[5] = (UCHAR) (fd->i_blocks) & 0xff;
|
||||
|
||||
/* We have to break down the reads into 64kb pieces (ASPI restriction) */
|
||||
if( i_blocks > 32 )
|
||||
{
|
||||
ssc.SRB_BufLen = 32 * DVDCSS_BLOCK_SIZE;
|
||||
ssc.CDBByte[9] = 32;
|
||||
fd->i_blocks += 32;
|
||||
|
||||
/* Initiate transfer */
|
||||
ResetEvent( hEvent );
|
||||
fd->lpSendCommand( (void*) &ssc );
|
||||
|
||||
/* transfer the next 64kb (_win32_dvdcss_aread is called recursively)
|
||||
* We need to check the status of the read on return */
|
||||
if( _win32_dvdcss_aread( i_fd, (u8*) p_data + 32 * DVDCSS_BLOCK_SIZE,
|
||||
i_blocks - 32) < 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is the last transfer */
|
||||
ssc.SRB_BufLen = i_blocks * DVDCSS_BLOCK_SIZE;
|
||||
ssc.CDBByte[9] = (UCHAR) i_blocks;
|
||||
fd->i_blocks += i_blocks;
|
||||
|
||||
/* Initiate transfer */
|
||||
ResetEvent( hEvent );
|
||||
fd->lpSendCommand( (void*) &ssc );
|
||||
|
||||
}
|
||||
|
||||
/* If the command has still not been processed, wait until it's finished */
|
||||
if( ssc.SRB_Status == SS_PENDING )
|
||||
{
|
||||
WaitForSingleObject( hEvent, INFINITE );
|
||||
}
|
||||
CloseHandle( hEvent );
|
||||
|
||||
/* check that the transfer went as planned */
|
||||
if( ssc.SRB_Status != SS_COMP )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return i_blocks;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
57
libmpdvdkit2/device.h
Normal file
57
libmpdvdkit2/device.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*****************************************************************************
|
||||
* device.h: DVD device access
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1998-2002 VideoLAN
|
||||
* $Id$
|
||||
*
|
||||
* Authors: Stéphane Borel <stef@via.ecp.fr>
|
||||
* Samuel Hocevar <sam@zoy.org>
|
||||
* Håkan Hjort <d95hjort@dtek.chalmers.se>
|
||||
*
|
||||
* 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, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* iovec structure: vectored data entry
|
||||
*****************************************************************************/
|
||||
#if defined( WIN32 )
|
||||
# include <io.h> /* read() */
|
||||
#else
|
||||
# include <sys/uio.h> /* struct iovec */
|
||||
#endif
|
||||
|
||||
#if defined( WIN32 )
|
||||
struct iovec
|
||||
{
|
||||
void *iov_base; /* Pointer to data. */
|
||||
size_t iov_len; /* Length of data. */
|
||||
};
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Device reading prototypes
|
||||
*****************************************************************************/
|
||||
int _dvdcss_use_ioctls ( dvdcss_t );
|
||||
int _dvdcss_open ( dvdcss_t );
|
||||
int _dvdcss_close ( dvdcss_t );
|
||||
int _dvdcss_readv ( dvdcss_t, struct iovec *, int );
|
||||
|
||||
/*****************************************************************************
|
||||
* Device reading prototypes, raw-device specific
|
||||
*****************************************************************************/
|
||||
#ifndef WIN32
|
||||
int _dvdcss_raw_open ( dvdcss_t, char * );
|
||||
#endif
|
||||
|
97
libmpdvdkit2/dvdcss.h
Normal file
97
libmpdvdkit2/dvdcss.h
Normal file
@ -0,0 +1,97 @@
|
||||
/**
|
||||
* \file dvdcss.h
|
||||
* \author Stéphane Borel <stef@via.ecp.fr>
|
||||
* \author Samuel Hocevar <sam@zoy.org>
|
||||
* \brief The \e libdvdcss public header.
|
||||
*
|
||||
* This header contains the public types and functions that applications
|
||||
* using \e libdvdcss may use.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 1998-2002 VideoLAN
|
||||
* $Id$
|
||||
*
|
||||
* 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, USA.
|
||||
*/
|
||||
|
||||
#ifndef _DVDCSS_DVDCSS_H
|
||||
#ifndef _DOXYGEN_SKIP_ME
|
||||
#define _DVDCSS_DVDCSS_H 1
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Library instance handle, to be used for each library call. */
|
||||
typedef struct dvdcss_s* dvdcss_t;
|
||||
|
||||
|
||||
/** The block size of a DVD. */
|
||||
#define DVDCSS_BLOCK_SIZE 2048
|
||||
|
||||
/** The default flag to be used by \e libdvdcss functions. */
|
||||
#define DVDCSS_NOFLAGS 0
|
||||
|
||||
/** Flag to ask dvdcss_read() to decrypt the data it reads. */
|
||||
#define DVDCSS_READ_DECRYPT (1 << 0)
|
||||
|
||||
/** Flag to tell dvdcss_seek() it is seeking in MPEG data. */
|
||||
#define DVDCSS_SEEK_MPEG (1 << 0)
|
||||
|
||||
/** Flag to ask dvdcss_seek() to check the current title key. */
|
||||
#define DVDCSS_SEEK_KEY (1 << 1)
|
||||
|
||||
|
||||
/*
|
||||
* Our version number. The variable name contains the interface version.
|
||||
*/
|
||||
extern char * dvdcss_interface_2;
|
||||
|
||||
|
||||
/*
|
||||
* Exported prototypes.
|
||||
*/
|
||||
extern dvdcss_t dvdcss_open ( char *psz_target );
|
||||
extern int dvdcss_close ( dvdcss_t );
|
||||
extern int dvdcss_seek ( dvdcss_t,
|
||||
int i_blocks,
|
||||
int i_flags );
|
||||
extern int dvdcss_read ( dvdcss_t,
|
||||
void *p_buffer,
|
||||
int i_blocks,
|
||||
int i_flags );
|
||||
extern int dvdcss_readv ( dvdcss_t,
|
||||
void *p_iovec,
|
||||
int i_blocks,
|
||||
int i_flags );
|
||||
extern char * dvdcss_error ( dvdcss_t );
|
||||
|
||||
|
||||
/*
|
||||
* Deprecated stuff.
|
||||
*/
|
||||
#ifndef _DOXYGEN_SKIP_ME
|
||||
#define dvdcss_title(a,b) dvdcss_seek(a,b,DVDCSS_SEEK_KEY)
|
||||
#define dvdcss_handle dvdcss_t
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* <dvdcss/dvdcss.h> */
|
57
libmpdvdkit2/error.c
Normal file
57
libmpdvdkit2/error.c
Normal file
@ -0,0 +1,57 @@
|
||||
/*****************************************************************************
|
||||
* error.c: error management functions
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1998-2002 VideoLAN
|
||||
* $Id$
|
||||
*
|
||||
* Author: Samuel Hocevar <sam@zoy.org>
|
||||
*
|
||||
* 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, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "dvdcss/dvdcss.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "css.h"
|
||||
#include "libdvdcss.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Error messages
|
||||
*****************************************************************************/
|
||||
void _dvdcss_error( dvdcss_t dvdcss, char *psz_string )
|
||||
{
|
||||
if( dvdcss->b_errors )
|
||||
{
|
||||
fprintf( stderr, "libdvdcss error: %s\n", psz_string );
|
||||
}
|
||||
|
||||
dvdcss->psz_error = psz_string;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Debug messages
|
||||
*****************************************************************************/
|
||||
void _dvdcss_debug( dvdcss_t dvdcss, char *psz_string )
|
||||
{
|
||||
if( dvdcss->b_debug )
|
||||
{
|
||||
fprintf( stderr, "libdvdcss debug: %s\n", psz_string );
|
||||
}
|
||||
}
|
||||
|
1912
libmpdvdkit2/ioctl.c
Normal file
1912
libmpdvdkit2/ioctl.c
Normal file
File diff suppressed because it is too large
Load Diff
362
libmpdvdkit2/ioctl.h
Normal file
362
libmpdvdkit2/ioctl.h
Normal file
@ -0,0 +1,362 @@
|
||||
/*****************************************************************************
|
||||
* ioctl.h: DVD ioctl replacement function
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999-2001 VideoLAN
|
||||
* $Id$
|
||||
*
|
||||
* Authors: Samuel Hocevar <sam@zoy.org>
|
||||
*
|
||||
* 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, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
int ioctl_ReadCopyright ( int, int, int * );
|
||||
int ioctl_ReadDiscKey ( int, int *, u8 * );
|
||||
int ioctl_ReadTitleKey ( int, int *, int, u8 * );
|
||||
int ioctl_ReportAgid ( int, int * );
|
||||
int ioctl_ReportChallenge ( int, int *, u8 * );
|
||||
int ioctl_ReportKey1 ( int, int *, u8 * );
|
||||
int ioctl_ReportASF ( int, int *, int * );
|
||||
int ioctl_InvalidateAgid ( int, int * );
|
||||
int ioctl_SendChallenge ( int, int *, u8 * );
|
||||
int ioctl_SendKey2 ( int, int *, u8 * );
|
||||
|
||||
#define DVD_KEY_SIZE 5
|
||||
#define DVD_CHALLENGE_SIZE 10
|
||||
#define DVD_DISCKEY_SIZE 2048
|
||||
|
||||
/*****************************************************************************
|
||||
* Common macro, BeOS specific
|
||||
*****************************************************************************/
|
||||
#if defined( SYS_BEOS )
|
||||
#define INIT_RDC( TYPE, SIZE ) \
|
||||
raw_device_command rdc; \
|
||||
u8 p_buffer[ (SIZE) ]; \
|
||||
memset( &rdc, 0, sizeof( raw_device_command ) ); \
|
||||
rdc.data = (char *)p_buffer; \
|
||||
rdc.data_length = (SIZE); \
|
||||
BeInitRDC( &rdc, (TYPE) );
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Common macro, HP-UX specific
|
||||
*****************************************************************************/
|
||||
#if defined( HPUX_SCTL_IO )
|
||||
#define INIT_SCTL_IO( TYPE, SIZE ) \
|
||||
struct sctl_io sctl_io; \
|
||||
u8 p_buffer[ (SIZE) ]; \
|
||||
memset( &sctl_io, 0, sizeof( sctl_io ) ); \
|
||||
sctl_io.data = (void *)p_buffer; \
|
||||
sctl_io.data_length = (SIZE); \
|
||||
HPUXInitSCTL( &sctl_io, (TYPE) );
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Common macro, Solaris specific
|
||||
*****************************************************************************/
|
||||
#if defined( SOLARIS_USCSI )
|
||||
#define USCSI_TIMEOUT( SC, TO ) ( (SC)->uscsi_timeout = (TO) )
|
||||
#define USCSI_RESID( SC ) ( (SC)->uscsi_resid )
|
||||
#define INIT_USCSI( TYPE, SIZE ) \
|
||||
struct uscsi_cmd sc; \
|
||||
union scsi_cdb rs_cdb; \
|
||||
u8 p_buffer[ (SIZE) ]; \
|
||||
memset( &sc, 0, sizeof( struct uscsi_cmd ) ); \
|
||||
sc.uscsi_cdb = (caddr_t)&rs_cdb; \
|
||||
sc.uscsi_bufaddr = p_buffer; \
|
||||
sc.uscsi_buflen = (SIZE); \
|
||||
SolarisInitUSCSI( &sc, (TYPE) );
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Common macro, Darwin specific
|
||||
*****************************************************************************/
|
||||
#if defined( DARWIN_DVD_IOCTL )
|
||||
#define INIT_DVDIOCTL( DKDVD_TYPE, BUFFER_TYPE, FORMAT ) \
|
||||
DKDVD_TYPE dvd; \
|
||||
BUFFER_TYPE dvdbs; \
|
||||
memset( &dvd, 0, sizeof(dvd) ); \
|
||||
memset( &dvdbs, 0, sizeof(dvdbs) ); \
|
||||
dvd.format = FORMAT; \
|
||||
dvd.buffer = &dvdbs; \
|
||||
dvd.bufferLength = sizeof(dvdbs);
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Common macro, win32 (ASPI) specific
|
||||
*****************************************************************************/
|
||||
#if defined( WIN32 )
|
||||
#define INIT_SSC( TYPE, SIZE ) \
|
||||
struct SRB_ExecSCSICmd ssc; \
|
||||
u8 p_buffer[ (SIZE) ]; \
|
||||
memset( &ssc, 0, sizeof( struct SRB_ExecSCSICmd ) ); \
|
||||
ssc.SRB_BufPointer = (char *)p_buffer; \
|
||||
ssc.SRB_BufLen = (SIZE); \
|
||||
WinInitSSC( &ssc, (TYPE) );
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Common macro, QNX specific
|
||||
*****************************************************************************/
|
||||
#if defined( __QNXNTO__ )
|
||||
#define INIT_CPT( TYPE, SIZE ) \
|
||||
CAM_PASS_THRU * p_cpt; \
|
||||
uint8_t * p_buffer; \
|
||||
int structSize = sizeof( CAM_PASS_THRU ) + (SIZE); \
|
||||
p_cpt = (CAM_PASS_THRU *) malloc ( structSize ); \
|
||||
p_buffer = (uint8_t *) p_cpt + sizeof( CAM_PASS_THRU ); \
|
||||
memset( p_cpt, 0, structSize ); \
|
||||
p_cpt->cam_data_ptr = sizeof( CAM_PASS_THRU ); \
|
||||
p_cpt->cam_dxfer_len = (SIZE); \
|
||||
QNXInitCPT( p_cpt, (TYPE) );
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Common macro, OS2 specific
|
||||
*****************************************************************************/
|
||||
#if defined( SYS_OS2 )
|
||||
#define INIT_SSC( TYPE, SIZE ) \
|
||||
struct OS2_ExecSCSICmd sdc; \
|
||||
u8 p_buffer[ (SIZE) ]; \
|
||||
unsigned long ulParamLen; \
|
||||
unsigned long ulDataLen; \
|
||||
memset( &sdc, 0, sizeof( OS2_ExecSCSICmd ) ); \
|
||||
memset( &p_buffer, 0, SIZE ); \
|
||||
sdc.data_length = (SIZE); \
|
||||
ulParamLen = sizeof(sdc); \
|
||||
OS2InitSDC( &sdc, (TYPE) )
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Additional types, OpenBSD specific
|
||||
*****************************************************************************/
|
||||
#if defined( HAVE_OPENBSD_DVD_STRUCT )
|
||||
typedef union dvd_struct dvd_struct;
|
||||
typedef union dvd_authinfo dvd_authinfo;
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Various DVD I/O tables
|
||||
*****************************************************************************/
|
||||
#if defined( SYS_BEOS ) || defined( WIN32 ) || defined ( SOLARIS_USCSI ) || defined ( HPUX_SCTL_IO ) || defined ( __QNXNTO__ ) || defined ( SYS_OS2 )
|
||||
/* The generic packet command opcodes for CD/DVD Logical Units,
|
||||
* From Table 57 of the SFF8090 Ver. 3 (Mt. Fuji) draft standard. */
|
||||
# define GPCMD_READ_DVD_STRUCTURE 0xad
|
||||
# define GPCMD_REPORT_KEY 0xa4
|
||||
# define GPCMD_SEND_KEY 0xa3
|
||||
/* DVD struct types */
|
||||
# define DVD_STRUCT_PHYSICAL 0x00
|
||||
# define DVD_STRUCT_COPYRIGHT 0x01
|
||||
# define DVD_STRUCT_DISCKEY 0x02
|
||||
# define DVD_STRUCT_BCA 0x03
|
||||
# define DVD_STRUCT_MANUFACT 0x04
|
||||
/* Key formats */
|
||||
# define DVD_REPORT_AGID 0x00
|
||||
# define DVD_REPORT_CHALLENGE 0x01
|
||||
# define DVD_SEND_CHALLENGE 0x01
|
||||
# define DVD_REPORT_KEY1 0x02
|
||||
# define DVD_SEND_KEY2 0x03
|
||||
# define DVD_REPORT_TITLE_KEY 0x04
|
||||
# define DVD_REPORT_ASF 0x05
|
||||
# define DVD_SEND_RPC 0x06
|
||||
# define DVD_REPORT_RPC 0x08
|
||||
# define DVD_INVALIDATE_AGID 0x3f
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* win32 ioctl specific
|
||||
*****************************************************************************/
|
||||
#if defined( WIN32 )
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#define IOCTL_DVD_START_SESSION CTL_CODE(FILE_DEVICE_DVD, 0x0400, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_DVD_READ_KEY CTL_CODE(FILE_DEVICE_DVD, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_DVD_SEND_KEY CTL_CODE(FILE_DEVICE_DVD, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_DVD_END_SESSION CTL_CODE(FILE_DEVICE_DVD, 0x0403, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_DVD_GET_REGION CTL_CODE(FILE_DEVICE_DVD, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_DVD_SEND_KEY2 CTL_CODE(FILE_DEVICE_DVD, 0x0406, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||
|
||||
#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE(FILE_DEVICE_CONTROLLER, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||
|
||||
#define DVD_CHALLENGE_KEY_LENGTH (12 + sizeof(DVD_COPY_PROTECT_KEY))
|
||||
#define DVD_BUS_KEY_LENGTH (8 + sizeof(DVD_COPY_PROTECT_KEY))
|
||||
#define DVD_TITLE_KEY_LENGTH (8 + sizeof(DVD_COPY_PROTECT_KEY))
|
||||
#define DVD_DISK_KEY_LENGTH (2048 + sizeof(DVD_COPY_PROTECT_KEY))
|
||||
#define DVD_ASF_LENGTH (sizeof(DVD_ASF) + sizeof(DVD_COPY_PROTECT_KEY))
|
||||
#define DVD_REGION_LENGTH (sizeof(DVD_REGION))
|
||||
|
||||
#define SCSI_IOCTL_DATA_OUT 0
|
||||
#define SCSI_IOCTL_DATA_IN 1
|
||||
|
||||
typedef ULONG DVD_SESSION_ID, *PDVD_SESSION_ID;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DvdChallengeKey = 0x01,
|
||||
DvdBusKey1,
|
||||
DvdBusKey2,
|
||||
DvdTitleKey,
|
||||
DvdAsf,
|
||||
DvdSetRpcKey = 0x6,
|
||||
DvdGetRpcKey = 0x8,
|
||||
DvdDiskKey = 0x80,
|
||||
DvdInvalidateAGID = 0x3f
|
||||
} DVD_KEY_TYPE;
|
||||
|
||||
typedef struct _DVD_COPY_PROTECT_KEY
|
||||
{
|
||||
ULONG KeyLength;
|
||||
DVD_SESSION_ID SessionId;
|
||||
DVD_KEY_TYPE KeyType;
|
||||
ULONG KeyFlags;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
ULONG FileHandle;
|
||||
ULONG Reserved; // used for NT alignment
|
||||
};
|
||||
LARGE_INTEGER TitleOffset;
|
||||
} Parameters;
|
||||
UCHAR KeyData[0];
|
||||
} DVD_COPY_PROTECT_KEY, *PDVD_COPY_PROTECT_KEY;
|
||||
|
||||
typedef struct _DVD_ASF
|
||||
{
|
||||
UCHAR Reserved0[3];
|
||||
UCHAR SuccessFlag:1;
|
||||
UCHAR Reserved1:7;
|
||||
} DVD_ASF, * PDVD_ASF;
|
||||
|
||||
typedef struct _DVD_REGION {
|
||||
UCHAR CopySystem;
|
||||
UCHAR RegionData;
|
||||
UCHAR SystemRegion;
|
||||
UCHAR ResetCount;
|
||||
} DVD_REGION, *PDVD_REGION;
|
||||
|
||||
typedef struct _SCSI_PASS_THROUGH_DIRECT
|
||||
{
|
||||
USHORT Length;
|
||||
UCHAR ScsiStatus;
|
||||
UCHAR PathId;
|
||||
UCHAR TargetId;
|
||||
UCHAR Lun;
|
||||
UCHAR CdbLength;
|
||||
UCHAR SenseInfoLength;
|
||||
UCHAR DataIn;
|
||||
ULONG DataTransferLength;
|
||||
ULONG TimeOutValue;
|
||||
PVOID DataBuffer;
|
||||
ULONG SenseInfoOffset;
|
||||
UCHAR Cdb[16];
|
||||
} SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT;
|
||||
|
||||
/*****************************************************************************
|
||||
* win32 aspi specific
|
||||
*****************************************************************************/
|
||||
|
||||
#define WIN2K ( GetVersion() < 0x80000000 )
|
||||
#define ASPI_HAID 0
|
||||
#define ASPI_TARGET 0
|
||||
|
||||
#define SENSE_LEN 0x0E
|
||||
#define SC_EXEC_SCSI_CMD 0x02
|
||||
#define SC_GET_DISK_INFO 0x06
|
||||
#define SS_COMP 0x01
|
||||
#define SS_PENDING 0x00
|
||||
#define SS_NO_ADAPTERS 0xE8
|
||||
#define SRB_DIR_IN 0x08
|
||||
#define SRB_DIR_OUT 0x10
|
||||
#define SRB_EVENT_NOTIFY 0x40
|
||||
|
||||
struct w32_aspidev
|
||||
{
|
||||
long hASPI;
|
||||
short i_sid;
|
||||
int i_blocks;
|
||||
long (*lpSendCommand)( void* );
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
struct SRB_GetDiskInfo
|
||||
{
|
||||
unsigned char SRB_Cmd;
|
||||
unsigned char SRB_Status;
|
||||
unsigned char SRB_HaId;
|
||||
unsigned char SRB_Flags;
|
||||
unsigned long SRB_Hdr_Rsvd;
|
||||
unsigned char SRB_Target;
|
||||
unsigned char SRB_Lun;
|
||||
unsigned char SRB_DriveFlags;
|
||||
unsigned char SRB_Int13HDriveInfo;
|
||||
unsigned char SRB_Heads;
|
||||
unsigned char SRB_Sectors;
|
||||
unsigned char SRB_Rsvd1[22];
|
||||
};
|
||||
|
||||
struct SRB_ExecSCSICmd
|
||||
{
|
||||
unsigned char SRB_Cmd;
|
||||
unsigned char SRB_Status;
|
||||
unsigned char SRB_HaId;
|
||||
unsigned char SRB_Flags;
|
||||
unsigned long SRB_Hdr_Rsvd;
|
||||
unsigned char SRB_Target;
|
||||
unsigned char SRB_Lun;
|
||||
unsigned short SRB_Rsvd1;
|
||||
unsigned long SRB_BufLen;
|
||||
unsigned char *SRB_BufPointer;
|
||||
unsigned char SRB_SenseLen;
|
||||
unsigned char SRB_CDBLen;
|
||||
unsigned char SRB_HaStat;
|
||||
unsigned char SRB_TargStat;
|
||||
unsigned long *SRB_PostProc;
|
||||
unsigned char SRB_Rsvd2[20];
|
||||
unsigned char CDBByte[16];
|
||||
unsigned char SenseArea[SENSE_LEN+2];
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* OS2 ioctl specific
|
||||
*****************************************************************************/
|
||||
#if defined( SYS_OS2 )
|
||||
|
||||
#define CDROMDISK_EXECMD 0x7A
|
||||
|
||||
#define EX_DIRECTION_IN 0x01
|
||||
#define EX_PLAYING_CHK 0x02
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
struct OS2_ExecSCSICmd
|
||||
{
|
||||
unsigned long id_code; // 'CD01'
|
||||
unsigned short data_length; // length of the Data Packet
|
||||
unsigned short cmd_length; // length of the Command Buffer
|
||||
unsigned short flags; // flags
|
||||
unsigned char command[16]; // Command Buffer for SCSI command
|
||||
|
||||
} OS2_ExecSCSICmd;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
513
libmpdvdkit2/libdvdcss.c
Normal file
513
libmpdvdkit2/libdvdcss.c
Normal file
@ -0,0 +1,513 @@
|
||||
/* libdvdcss.c: DVD reading library.
|
||||
*
|
||||
* Authors: Stéphane Borel <stef@via.ecp.fr>
|
||||
* Samuel Hocevar <sam@zoy.org>
|
||||
* Håkan Hjort <d95hjort@dtek.chalmers.se>
|
||||
*
|
||||
* Copyright (C) 1998-2002 VideoLAN
|
||||
* $Id$
|
||||
*
|
||||
* 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, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \mainpage libdvdcss developer documentation
|
||||
*
|
||||
* \section intro Introduction
|
||||
*
|
||||
* \e libdvdcss is a simple library designed for accessing DVDs like a block
|
||||
* device without having to bother about the decryption. The important features
|
||||
* are:
|
||||
* \li portability: currently supported platforms are GNU/Linux, FreeBSD,
|
||||
* NetBSD, OpenBSD, BSD/OS, BeOS, Windows 95/98, Windows NT/2000, MacOS X,
|
||||
* Solaris, HP-UX and OS/2.
|
||||
* \li adaptability: unlike most similar projects, libdvdcss doesn't require
|
||||
* the region of your drive to be set and will try its best to read from
|
||||
* the disc even in the case of a region mismatch.
|
||||
* \li simplicity: a DVD player can be built around the \e libdvdcss API using
|
||||
* no more than 4 or 5 library calls.
|
||||
*
|
||||
* \e libdvdcss is free software, released under the General Public License.
|
||||
* This ensures that \e libdvdcss remains free and used only with free
|
||||
* software.
|
||||
*
|
||||
* \section api The libdvdcss API
|
||||
*
|
||||
* The complete \e libdvdcss programming interface is documented in the
|
||||
* dvdcss.h file.
|
||||
*
|
||||
* \section env Environment variables
|
||||
*
|
||||
* Some environment variables can be used to change the behaviour of
|
||||
* \e libdvdcss without having to modify the program which uses it. These
|
||||
* variables are:
|
||||
*
|
||||
* \li \b DVDCSS_VERBOSE: sets the verbosity level.
|
||||
* - \c 0 outputs no messages at all.
|
||||
* - \c 1 outputs error messages to stderr.
|
||||
* - \c 2 outputs error messages and debug messages to stderr.
|
||||
*
|
||||
* \li \b DVDCSS_METHOD: sets the authentication and decryption method
|
||||
* that \e libdvdcss will use to read scrambled discs. Can be one
|
||||
* of \c title, \c key or \c disc.
|
||||
* - \c key is the default method. \e libdvdcss will use a set of
|
||||
* calculated player keys to try and get the disc key. This can fail
|
||||
* if the drive does not recognize any of the player keys.
|
||||
* - \c disc is a fallback method when \c key has failed. Instead of
|
||||
* using player keys, \e libdvdcss will crack the disc key using
|
||||
* a brute force algorithm. This process is CPU intensive and requires
|
||||
* 64 MB of memory to store temporary data.
|
||||
* - \c title is the fallback when all other methods have failed. It does
|
||||
* not rely on a key exchange with the DVD drive, but rather uses a
|
||||
* crypto attack to guess the title key. On rare cases this may fail
|
||||
* because there is not enough encrypted data on the disc to perform
|
||||
* a statistical attack, but in the other hand it is the only way to
|
||||
* decrypt a DVD stored on a hard disc, or a DVD with the wrong region
|
||||
* on an RPC2 drive.
|
||||
*
|
||||
* \li \b DVDCSS_RAW_DEVICE: specify the raw device to use.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Preamble
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "dvdcss/dvdcss.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "css.h"
|
||||
#include "libdvdcss.h"
|
||||
#include "ioctl.h"
|
||||
#include "device.h"
|
||||
|
||||
/**
|
||||
* \brief Symbol for version checks.
|
||||
*
|
||||
* The name of this symbol contains the library major number, which makes it
|
||||
* easy to check which \e libdvdcss development headers are installed on the
|
||||
* system with tools such as autoconf.
|
||||
*
|
||||
* The variable itself contains the exact version number of the library,
|
||||
* which can be useful for specific feature needs.
|
||||
*/
|
||||
char * dvdcss_interface_2 = VERSION;
|
||||
|
||||
/**
|
||||
* \brief Open a DVD device or directory and return a dvdcss instance.
|
||||
*
|
||||
* \param psz_target a string containing the target name, for instance
|
||||
* "/dev/hdc" or "E:".
|
||||
* \return a handle to a dvdcss instance or NULL on error.
|
||||
*
|
||||
* Initialize the \e libdvdcss library and open the requested DVD device or
|
||||
* directory. \e libdvdcss checks whether ioctls can be performed on the disc,
|
||||
* and when possible, the disc key is retrieved.
|
||||
*
|
||||
* dvdcss_open() returns a handle to be used for all subsequent \e libdvdcss
|
||||
* calls. If an error occured, NULL is returned.
|
||||
*/
|
||||
extern dvdcss_t dvdcss_open ( char *psz_target )
|
||||
{
|
||||
int i_ret;
|
||||
|
||||
char *psz_method = getenv( "DVDCSS_METHOD" );
|
||||
char *psz_verbose = getenv( "DVDCSS_VERBOSE" );
|
||||
#ifndef WIN32
|
||||
char *psz_raw_device = getenv( "DVDCSS_RAW_DEVICE" );
|
||||
#endif
|
||||
|
||||
dvdcss_t dvdcss;
|
||||
|
||||
/*
|
||||
* Allocate the library structure
|
||||
*/
|
||||
dvdcss = malloc( sizeof( struct dvdcss_s ) );
|
||||
if( dvdcss == NULL )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize structure with default values
|
||||
*/
|
||||
#ifndef WIN32
|
||||
dvdcss->i_raw_fd = -1;
|
||||
#endif
|
||||
dvdcss->p_titles = NULL;
|
||||
dvdcss->psz_device = (char *)strdup( psz_target );
|
||||
dvdcss->psz_error = "no error";
|
||||
dvdcss->i_method = DVDCSS_METHOD_KEY;
|
||||
dvdcss->b_debug = 0;
|
||||
dvdcss->b_errors = 0;
|
||||
|
||||
/*
|
||||
* Find verbosity from DVDCSS_VERBOSE environment variable
|
||||
*/
|
||||
if( psz_verbose != NULL )
|
||||
{
|
||||
switch( atoi( psz_verbose ) )
|
||||
{
|
||||
case 2:
|
||||
dvdcss->b_debug = 1;
|
||||
case 1:
|
||||
dvdcss->b_errors = 1;
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Find method from DVDCSS_METHOD environment variable
|
||||
*/
|
||||
if( psz_method != NULL )
|
||||
{
|
||||
if( !strncmp( psz_method, "key", 4 ) )
|
||||
{
|
||||
dvdcss->i_method = DVDCSS_METHOD_KEY;
|
||||
}
|
||||
else if( !strncmp( psz_method, "disc", 5 ) )
|
||||
{
|
||||
dvdcss->i_method = DVDCSS_METHOD_DISC;
|
||||
}
|
||||
else if( !strncmp( psz_method, "title", 5 ) )
|
||||
{
|
||||
dvdcss->i_method = DVDCSS_METHOD_TITLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
_dvdcss_error( dvdcss, "unknown decrypt method, please choose "
|
||||
"from 'title', 'key' or 'disc'" );
|
||||
free( dvdcss->psz_device );
|
||||
free( dvdcss );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Open device
|
||||
*/
|
||||
i_ret = _dvdcss_open( dvdcss );
|
||||
if( i_ret < 0 )
|
||||
{
|
||||
free( dvdcss->psz_device );
|
||||
free( dvdcss );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dvdcss->b_scrambled = 1; /* Assume the worst */
|
||||
dvdcss->b_ioctls = _dvdcss_use_ioctls( dvdcss );
|
||||
|
||||
if( dvdcss->b_ioctls )
|
||||
{
|
||||
i_ret = _dvdcss_test( dvdcss );
|
||||
if( i_ret < 0 )
|
||||
{
|
||||
/* Disable the CSS ioctls and hope that it works? */
|
||||
_dvdcss_debug( dvdcss,
|
||||
"could not check whether the disc was scrambled" );
|
||||
dvdcss->b_ioctls = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_dvdcss_debug( dvdcss, i_ret ? "disc is scrambled"
|
||||
: "disc is unscrambled" );
|
||||
dvdcss->b_scrambled = i_ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* If disc is CSS protected and the ioctls work, authenticate the drive */
|
||||
if( dvdcss->b_scrambled && dvdcss->b_ioctls )
|
||||
{
|
||||
i_ret = _dvdcss_disckey( dvdcss );
|
||||
|
||||
if( i_ret < 0 )
|
||||
{
|
||||
_dvdcss_close( dvdcss );
|
||||
free( dvdcss->psz_device );
|
||||
free( dvdcss );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
if( psz_raw_device != NULL )
|
||||
{
|
||||
_dvdcss_raw_open( dvdcss, psz_raw_device );
|
||||
}
|
||||
#endif
|
||||
|
||||
return dvdcss;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return a string containing the latest error that occured in the
|
||||
* given \e libdvdcss instance.
|
||||
*
|
||||
* \param dvdcss a \e libdvdcss instance.
|
||||
* \return a null-terminated string containing the latest error message.
|
||||
*
|
||||
* This function returns a constant string containing the latest error that
|
||||
* occured in \e libdvdcss. It can be used to format error messages at your
|
||||
* convenience in your application.
|
||||
*/
|
||||
extern char * dvdcss_error ( dvdcss_t dvdcss )
|
||||
{
|
||||
return dvdcss->psz_error;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Seek in the disc and change the current key if requested.
|
||||
*
|
||||
* \param dvdcss a \e libdvdcss instance.
|
||||
* \param i_blocks an absolute block offset to seek to.
|
||||
* \param i_flags #DVDCSS_NOFLAGS, optionally ored with one of #DVDCSS_SEEK_KEY
|
||||
* or #DVDCSS_SEEK_MPEG.
|
||||
* \return the new position in blocks, or a negative value in case an error
|
||||
* happened.
|
||||
*
|
||||
* This function seeks to the requested position, in logical blocks.
|
||||
*
|
||||
* You typically set \p i_flags to #DVDCSS_NOFLAGS when seeking in a .IFO.
|
||||
*
|
||||
* If #DVDCSS_SEEK_MPEG is specified in \p i_flags and if \e libdvdcss finds it
|
||||
* reasonable to do so (ie, if the dvdcss method is not "title"), the current
|
||||
* title key will be checked and a new one will be calculated if necessary.
|
||||
* This flag is typically used when reading data from a VOB.
|
||||
*
|
||||
* If #DVDCSS_SEEK_KEY is specified, the title key will be always checked,
|
||||
* even with the "title" method. This is equivalent to using the now
|
||||
* deprecated dvdcss_title() call. This flag is typically used when seeking
|
||||
* in a new title.
|
||||
*/
|
||||
extern int dvdcss_seek ( dvdcss_t dvdcss, int i_blocks, int i_flags )
|
||||
{
|
||||
/* title cracking method is too slow to be used at each seek */
|
||||
if( ( ( i_flags & DVDCSS_SEEK_MPEG )
|
||||
&& ( dvdcss->i_method != DVDCSS_METHOD_TITLE ) )
|
||||
|| ( i_flags & DVDCSS_SEEK_KEY ) )
|
||||
{
|
||||
/* check the title key */
|
||||
if( _dvdcss_title( dvdcss, i_blocks ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return _dvdcss_seek( dvdcss, i_blocks );
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Read from the disc and decrypt data if requested.
|
||||
*
|
||||
* \param dvdcss a \e libdvdcss instance.
|
||||
* \param p_buffer a buffer that will contain the data read from the disc.
|
||||
* \param i_blocks the amount of blocks to read.
|
||||
* \param i_flags #DVDCSS_NOFLAGS, optionally ored with #DVDCSS_READ_DECRYPT.
|
||||
* \return the amount of blocks read, or a negative value in case an
|
||||
* error happened.
|
||||
*
|
||||
* This function reads \p i_blocks logical blocks from the DVD.
|
||||
*
|
||||
* You typically set \p i_flags to #DVDCSS_NOFLAGS when reading data from a
|
||||
* .IFO file on the DVD.
|
||||
*
|
||||
* If #DVDCSS_READ_DECRYPT is specified in \p i_flags, dvdcss_read() will
|
||||
* automatically decrypt scrambled sectors. This flag is typically used when
|
||||
* reading data from a .VOB file on the DVD. It has no effect on unscrambled
|
||||
* discs or unscrambled sectors, and can be safely used on those.
|
||||
*
|
||||
* \warning dvdcss_read() expects to be able to write \p i_blocks *
|
||||
* #DVDCSS_BLOCK_SIZE bytes in \p p_buffer.
|
||||
*/
|
||||
extern int dvdcss_read ( dvdcss_t dvdcss, void *p_buffer,
|
||||
int i_blocks,
|
||||
int i_flags )
|
||||
{
|
||||
int i_ret, i_index;
|
||||
|
||||
i_ret = _dvdcss_read( dvdcss, p_buffer, i_blocks );
|
||||
|
||||
if( i_ret <= 0
|
||||
|| !dvdcss->b_scrambled
|
||||
|| !(i_flags & DVDCSS_READ_DECRYPT) )
|
||||
{
|
||||
return i_ret;
|
||||
}
|
||||
|
||||
if( ! memcmp( dvdcss->css.p_title_key, "\0\0\0\0\0", 5 ) )
|
||||
{
|
||||
/* For what we believe is an unencrypted title,
|
||||
* check that there are no encrypted blocks */
|
||||
for( i_index = i_ret; i_index; i_index-- )
|
||||
{
|
||||
if( ((u8*)p_buffer)[0x14] & 0x30 )
|
||||
{
|
||||
_dvdcss_error( dvdcss, "no key but found encrypted block" );
|
||||
/* Only return the initial range of unscrambled blocks? */
|
||||
/* or fail completely? return 0; */
|
||||
break;
|
||||
}
|
||||
p_buffer = (void *) ((u8 *)p_buffer + DVDCSS_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Decrypt the blocks we managed to read */
|
||||
for( i_index = i_ret; i_index; i_index-- )
|
||||
{
|
||||
_dvdcss_unscramble( dvdcss->css.p_title_key, p_buffer );
|
||||
((u8*)p_buffer)[0x14] &= 0x8f;
|
||||
p_buffer = (void *) ((u8 *)p_buffer + DVDCSS_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
return i_ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Read from the disc into multiple buffers and decrypt data if
|
||||
* requested.
|
||||
*
|
||||
* \param dvdcss a \e libdvdcss instance.
|
||||
* \param p_iovec a pointer to an array of iovec structures that will contain
|
||||
* the data read from the disc.
|
||||
* \param i_blocks the amount of blocks to read.
|
||||
* \param i_flags #DVDCSS_NOFLAGS, optionally ored with #DVDCSS_READ_DECRYPT.
|
||||
* \return the amount of blocks read, or a negative value in case an
|
||||
* error happened.
|
||||
*
|
||||
* This function reads \p i_blocks logical blocks from the DVD and writes them
|
||||
* to an array of iovec structures.
|
||||
*
|
||||
* You typically set \p i_flags to #DVDCSS_NOFLAGS when reading data from a
|
||||
* .IFO file on the DVD.
|
||||
*
|
||||
* If #DVDCSS_READ_DECRYPT is specified in \p i_flags, dvdcss_readv() will
|
||||
* automatically decrypt scrambled sectors. This flag is typically used when
|
||||
* reading data from a .VOB file on the DVD. It has no effect on unscrambled
|
||||
* discs or unscrambled sectors, and can be safely used on those.
|
||||
*
|
||||
* \warning dvdcss_readv() expects to be able to write \p i_blocks *
|
||||
* #DVDCSS_BLOCK_SIZE bytes in the buffers pointed by \p p_iovec.
|
||||
* Moreover, all iov_len members of the iovec structures should be
|
||||
* multiples of #DVDCSS_BLOCK_SIZE.
|
||||
*/
|
||||
extern int dvdcss_readv ( dvdcss_t dvdcss, void *p_iovec,
|
||||
int i_blocks,
|
||||
int i_flags )
|
||||
{
|
||||
struct iovec *_p_iovec = (struct iovec *)p_iovec;
|
||||
int i_ret, i_index;
|
||||
void *iov_base;
|
||||
size_t iov_len;
|
||||
|
||||
i_ret = _dvdcss_readv( dvdcss, _p_iovec, i_blocks );
|
||||
|
||||
if( i_ret <= 0
|
||||
|| !dvdcss->b_scrambled
|
||||
|| !(i_flags & DVDCSS_READ_DECRYPT) )
|
||||
{
|
||||
return i_ret;
|
||||
}
|
||||
|
||||
/* Initialize loop for decryption */
|
||||
iov_base = _p_iovec->iov_base;
|
||||
iov_len = _p_iovec->iov_len;
|
||||
|
||||
/* Decrypt the blocks we managed to read */
|
||||
for( i_index = i_ret; i_index; i_index-- )
|
||||
{
|
||||
/* Check that iov_len is a multiple of 2048 */
|
||||
if( iov_len & 0x7ff )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
while( iov_len == 0 )
|
||||
{
|
||||
_p_iovec++;
|
||||
iov_base = _p_iovec->iov_base;
|
||||
iov_len = _p_iovec->iov_len;
|
||||
}
|
||||
|
||||
_dvdcss_unscramble( dvdcss->css.p_title_key, iov_base );
|
||||
((u8*)iov_base)[0x14] &= 0x8f;
|
||||
|
||||
iov_base = (void *) ((u8*)iov_base + DVDCSS_BLOCK_SIZE);
|
||||
iov_len -= DVDCSS_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
return i_ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Close the DVD and clean up the library.
|
||||
*
|
||||
* \param dvdcss a \e libdvdcss instance.
|
||||
* \return zero in case of success, a negative value otherwise.
|
||||
*
|
||||
* This function closes the DVD device and frees all the memory allocated
|
||||
* by \e libdvdcss. On return, the #dvdcss_t is invalidated and may not be
|
||||
* used again.
|
||||
*/
|
||||
extern int dvdcss_close ( dvdcss_t dvdcss )
|
||||
{
|
||||
dvd_title_t *p_title;
|
||||
int i_ret;
|
||||
|
||||
/* Free our list of keys */
|
||||
p_title = dvdcss->p_titles;
|
||||
while( p_title )
|
||||
{
|
||||
dvd_title_t *p_tmptitle = p_title->p_next;
|
||||
free( p_title );
|
||||
p_title = p_tmptitle;
|
||||
}
|
||||
|
||||
i_ret = _dvdcss_close( dvdcss );
|
||||
|
||||
if( i_ret < 0 )
|
||||
{
|
||||
return i_ret;
|
||||
}
|
||||
|
||||
free( dvdcss->psz_device );
|
||||
free( dvdcss );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deprecated. See dvdcss_seek().
|
||||
*/
|
||||
#undef dvdcss_title
|
||||
extern int dvdcss_title ( dvdcss_t dvdcss, int i_block )
|
||||
{
|
||||
return _dvdcss_title( dvdcss, i_block );
|
||||
}
|
||||
|
73
libmpdvdkit2/libdvdcss.h
Normal file
73
libmpdvdkit2/libdvdcss.h
Normal file
@ -0,0 +1,73 @@
|
||||
/*****************************************************************************
|
||||
* private.h: private DVD reading library data
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1998-2001 VideoLAN
|
||||
* $Id$
|
||||
*
|
||||
* Authors: Stéphane Borel <stef@via.ecp.fr>
|
||||
* Samuel Hocevar <sam@zoy.org>
|
||||
*
|
||||
* 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, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* The libdvdcss structure
|
||||
*****************************************************************************/
|
||||
struct dvdcss_s
|
||||
{
|
||||
/* File descriptor */
|
||||
char * psz_device;
|
||||
int i_fd;
|
||||
int i_seekpos;
|
||||
|
||||
/* Decryption stuff */
|
||||
int i_method;
|
||||
css_t css;
|
||||
int b_ioctls;
|
||||
int b_scrambled;
|
||||
dvd_title_t *p_titles;
|
||||
|
||||
/* Error management */
|
||||
char * psz_error;
|
||||
int b_errors;
|
||||
int b_debug;
|
||||
|
||||
#ifdef WIN32
|
||||
char * p_readv_buffer;
|
||||
int i_readv_buf_size;
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
int i_raw_fd;
|
||||
int i_read_fd;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* libdvdcss method: used like init flags
|
||||
*****************************************************************************/
|
||||
#define DVDCSS_METHOD_KEY 0
|
||||
#define DVDCSS_METHOD_DISC 1
|
||||
#define DVDCSS_METHOD_TITLE 2
|
||||
|
||||
/*****************************************************************************
|
||||
* Functions used across the library
|
||||
*****************************************************************************/
|
||||
int _dvdcss_seek ( dvdcss_t, int );
|
||||
int _dvdcss_read ( dvdcss_t, void *, int );
|
||||
|
||||
void _dvdcss_error ( dvdcss_t, char * );
|
||||
void _dvdcss_debug ( dvdcss_t, char * );
|
||||
|
Loading…
Reference in New Issue
Block a user