aboutsummaryrefslogtreecommitdiffhomepage
path: root/libdvdcss
diff options
context:
space:
mode:
Diffstat (limited to 'libdvdcss')
-rw-r--r--libdvdcss/bsdi_dvd.h344
-rw-r--r--libdvdcss/common.h85
-rw-r--r--libdvdcss/css.c1731
-rw-r--r--libdvdcss/css.h63
-rw-r--r--libdvdcss/csstables.h395
-rw-r--r--libdvdcss/device.c1090
-rw-r--r--libdvdcss/device.h64
-rw-r--r--libdvdcss/dvdcss/dvdcss.h107
-rw-r--r--libdvdcss/error.c68
-rw-r--r--libdvdcss/ioctl.c2123
-rw-r--r--libdvdcss/ioctl.h434
-rw-r--r--libdvdcss/libdvdcss.c814
-rw-r--r--libdvdcss/libdvdcss.h111
13 files changed, 0 insertions, 7429 deletions
diff --git a/libdvdcss/bsdi_dvd.h b/libdvdcss/bsdi_dvd.h
deleted file mode 100644
index 2c50c898b1..0000000000
--- a/libdvdcss/bsdi_dvd.h
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * $Id$
-*/
-
-#ifndef DVDCSS_BSDI_DVD_H
-#define DVDCSS_BSDI_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 CDROM_DISC_STATUS 0x5327 /* Get disc type, etc. */
-#define CDROMREADMODE2 0x530c /* Read CDROM mode 2 data (2336 Bytes) */
-#define CDROMREADMODE1 0x530d /* Read CDROM mode 1 data (2048 Bytes) */
-#define CDROMREADRAW 0x5314 /* read data in raw mode (2352 bytes) */
-
-#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!*/
-
-/* bit to tell whether track is data or audio (cdrom_tocentry.cdte_ctrl) */
-#define CDROM_DATA_TRACK 0x04
-
-/* The leadout track is always 0xAA, regardless of # of tracks on disc */
-#define CDROM_LEADOUT 0xAA
-
-/* 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
-
-/*
- * Return values for CDROM_DISC_STATUS ioctl.
- * Can also return CDS_NO_INFO and CDS_NO_DISC from above
-*/
-#define CDS_AUDIO 100
-#define CDS_DATA_1 101
-#define CDS_DATA_2 102
-#define CDS_XA_2_1 103
-#define CDS_XA_2_2 104
-#define CDS_MIXED 105
-
-/* For compile compatibility only - we don't support changers */
-#define CDSL_NONE ((int) (~0U>>1)-1)
-#define CDSL_CURRENT ((int) (~0U>>1))
-
-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;
-};
-
-typedef struct
-{
- int data;
- int audio;
- int cdi;
- int xa;
- int error;
-} tracktype;
-
-#endif /* DVDCSS_BSDI_DVD_H */
diff --git a/libdvdcss/common.h b/libdvdcss/common.h
deleted file mode 100644
index bee5aadd50..0000000000
--- a/libdvdcss/common.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*****************************************************************************
- * common.h: common definitions
- * Collection of useful common types and macros definitions
- *****************************************************************************
- * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id$
- *
- * Authors: Sam 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 libdvdcss; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *****************************************************************************/
-
-#ifndef DVDCSS_COMMON_H
-#define DVDCSS_COMMON_H
-
-/*****************************************************************************
- * Basic types definitions
- *****************************************************************************/
-#if defined( HAVE_STDINT_H )
-# include <stdint.h>
-#elif defined( HAVE_INTTYPES_H )
-# include <inttypes.h>
-#elif defined( SYS_CYGWIN )
-# include <sys/types.h>
- /* Cygwin only defines half of these... */
- typedef u_int8_t uint8_t;
- typedef u_int32_t uint32_t;
-#else
- /* Fallback types (very x86-centric, sorry) */
- typedef unsigned char uint8_t;
- typedef signed char int8_t;
- typedef unsigned int uint32_t;
- typedef signed int int32_t;
-#endif
-
-#if defined( WIN32 )
-
-# ifndef PATH_MAX
-# define PATH_MAX MAX_PATH
-# endif
-
-/* several type definitions */
-# if defined( __MINGW32__ )
-# define lseek _lseeki64
-# 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 )
-# define lseek _lseeki64
-# 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
-
-#endif /* DVDCSS_COMMON_H */
diff --git a/libdvdcss/css.c b/libdvdcss/css.c
deleted file mode 100644
index 886a803efd..0000000000
--- a/libdvdcss/css.c
+++ /dev/null
@@ -1,1731 +0,0 @@
-/*****************************************************************************
- * css.c: Functions for DVD authentication and descrambling
- *****************************************************************************
- * Copyright (C) 1999-2008 VideoLAN
- * $Id$
- *
- * Authors: Stéphane Borel <stef@via.ecp.fr>
- * Håkan Hjort <d95hjort@dtek.chalmers.se>
- *
- * 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>
- * (see http://www-2.cs.cmu.edu/~dst/DeCSS/FrankStevenson/index.html)
- * - DeCSSPlus by Ethan Hawke
- * - DecVOB
- * see http://www.lemuria.org/DeCSS/ by Tom Vogt for more information.
- *
- * This library 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 library 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 library; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifdef HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#include <fcntl.h>
-
-#ifdef HAVE_LIMITS_H
-# include <limits.h>
-#endif
-
-#include "dvdcss/dvdcss.h"
-
-#include "common.h"
-#include "css.h"
-#include "libdvdcss.h"
-#include "csstables.h"
-#include "ioctl.h"
-#include "device.h"
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static void PrintKey ( dvdcss_t, char *, uint8_t const * );
-
-static int GetBusKey ( dvdcss_t );
-static int GetASF ( dvdcss_t );
-
-static void CryptKey ( int, int, uint8_t const *, uint8_t * );
-static void DecryptKey ( uint8_t,
- uint8_t const *, uint8_t const *, uint8_t * );
-
-static int DecryptDiscKey ( dvdcss_t, uint8_t const *, dvd_key_t );
-static int CrackDiscKey ( dvdcss_t, uint8_t * );
-
-static void DecryptTitleKey ( dvd_key_t, dvd_key_t );
-static int RecoverTitleKey ( int, uint8_t const *,
- uint8_t const *, uint8_t const *, uint8_t * );
-static int CrackTitleKey ( dvdcss_t, int, int, dvd_key_t );
-
-static int AttackPattern ( uint8_t const[], int, uint8_t * );
-#if 0
-static int AttackPadding ( uint8_t const[], int, uint8_t * );
-#endif
-
-/*****************************************************************************
- * _dvdcss_test: check if the disc is encrypted or not
- *****************************************************************************
- * Sets b_scrambled, b_ioctls
- *****************************************************************************/
-void _dvdcss_test( dvdcss_t dvdcss )
-{
- char const *psz_type, *psz_rpc;
- int i_ret, i_copyright, i_type, i_mask, i_rpc;
-
- i_ret = ioctl_ReadCopyright( dvdcss->i_fd, 0 /* i_layer */, &i_copyright );
-
- if( i_ret < 0 )
- {
- /* Maybe we didn't have enough privileges to read the copyright
- * (see ioctl_ReadCopyright comments).
- * Apparently, on unencrypted DVDs _dvdcss_disckey() always fails, so
- * we can check this as a workaround. */
-#ifdef WIN32
- i_ret = 0;
-#else
- /* Since it's the first ioctl we try to issue, we add a notice */
- print_error( dvdcss, "css error: could not get \"copyright\""
- " information, make sure there is a DVD in the drive,"
- " and that you have used the correct device node." );
- /* Try without ioctls */
- dvdcss->b_ioctls = 0;
-#endif
- i_copyright = 1;
- if( _dvdcss_disckey( dvdcss ) < 0 )
- {
- i_copyright = 0;
- }
- }
-
- print_debug( dvdcss, "disc reports copyright information 0x%x",
- i_copyright );
- dvdcss->b_scrambled = i_copyright;
-
- i_ret = ioctl_ReportRPC( dvdcss->i_fd, &i_type, &i_mask, &i_rpc);
-
- if( i_ret < 0 )
- {
- print_error( dvdcss, "css error: could not get RPC status, region-free drive?" );
- return;
- }
-
- switch( i_rpc )
- {
- case 0: psz_rpc = "RPC-I"; break;
- case 1: psz_rpc = "RPC-II"; break;
- default: psz_rpc = "unknown RPC scheme"; break;
- }
-
- switch( i_type )
- {
- case 0: psz_type = "no region code set"; break;
- case 1: psz_type = "region code set"; break;
- case 2: psz_type = "one region change remaining"; break;
- case 3: psz_type = "region code set permanently"; break;
- default: psz_type = "unknown status"; break;
- }
-
- print_debug( dvdcss, "drive region mask 0x%x, %s, %s",
- i_mask, psz_rpc, psz_type );
-
- if( i_copyright && i_rpc == 1 && i_type == 0 )
- {
- print_error( dvdcss, "css error: drive will prevent access to "
- "scrambled data" );
- }
-}
-
-/*****************************************************************************
- * _dvdcss_title: crack or decrypt the current title key if needed
- *****************************************************************************
- * This function should only be called by dvdcss->pf_seek and should eventually
- * not be external if possible.
- *****************************************************************************/
-int _dvdcss_title ( dvdcss_t dvdcss, int i_block )
-{
- dvd_title_t *p_title;
- dvd_title_t *p_newtitle;
- dvd_key_t p_title_key;
- int i_fd, i_ret = -1, b_cache = 0;
-
- if( ! dvdcss->b_scrambled )
- {
- return 0;
- }
-
- /* Check if we've already cracked this key */
- p_title = dvdcss->p_titles;
- while( p_title != NULL
- && p_title->p_next != NULL
- && p_title->p_next->i_startlb <= i_block )
- {
- p_title = p_title->p_next;
- }
-
- if( p_title != NULL
- && p_title->i_startlb == i_block )
- {
- /* We've already cracked this key, nothing to do */
- memcpy( dvdcss->css.p_title_key, p_title->p_key, sizeof(dvd_key_t) );
- return 0;
- }
-
- /* Check whether the key is in our disk cache */
- if( dvdcss->psz_cachefile[0] )
- {
- /* XXX: be careful, we use sprintf and not snprintf */
- sprintf( dvdcss->psz_block, "%.10x", i_block );
- i_fd = open( dvdcss->psz_cachefile, O_RDONLY );
- b_cache = 1;
-
- if( i_fd >= 0 )
- {
- char psz_key[KEY_SIZE * 3];
- unsigned int k0, k1, k2, k3, k4;
-
- psz_key[KEY_SIZE * 3 - 1] = '\0';
-
- if( read( i_fd, psz_key, KEY_SIZE * 3 - 1 ) == KEY_SIZE * 3 - 1
- && sscanf( psz_key, "%x:%x:%x:%x:%x",
- &k0, &k1, &k2, &k3, &k4 ) == 5 )
- {
- p_title_key[0] = k0;
- p_title_key[1] = k1;
- p_title_key[2] = k2;
- p_title_key[3] = k3;
- p_title_key[4] = k4;
- PrintKey( dvdcss, "title key found in cache ", p_title_key );
-
- /* Don't try to save it again */
- b_cache = 0;
- i_ret = 1;
- }
-
- close( i_fd );
- }
- }
-
- /* Crack or decrypt CSS title key for current VTS */
- if( i_ret < 0 )
- {
- i_ret = _dvdcss_titlekey( dvdcss, i_block, p_title_key );
-
- if( i_ret < 0 )
- {
- print_error( dvdcss, "fatal error in vts css key" );
- return i_ret;
- }
-
- if( i_ret == 0 )
- {
- print_debug( dvdcss, "unencrypted title" );
- /* We cache this anyway, so we don't need to check again. */
- }
- }
-
- /* Key is valid, we store it on disk. */
- if( dvdcss->psz_cachefile[0] && b_cache )
- {
- i_fd = open( dvdcss->psz_cachefile, O_RDWR|O_CREAT, 0644 );
- if( i_fd >= 0 )
- {
- char psz_key[KEY_SIZE * 3 + 2];
-
- sprintf( psz_key, "%02x:%02x:%02x:%02x:%02x\r\n",
- p_title_key[0], p_title_key[1], p_title_key[2],
- p_title_key[3], p_title_key[4] );
-
- write( i_fd, psz_key, KEY_SIZE * 3 + 1 );
- close( i_fd );
- }
- }
-
- /* Find our spot in the list */
- p_newtitle = NULL;
- p_title = dvdcss->p_titles;
- while( ( p_title != NULL ) && ( p_title->i_startlb < i_block ) )
- {
- p_newtitle = p_title;
- p_title = p_title->p_next;
- }
-
- /* Save the found title */
- p_title = p_newtitle;
-
- /* Write in the new title and its key */
- p_newtitle = malloc( sizeof( dvd_title_t ) );
- p_newtitle->i_startlb = i_block;
- memcpy( p_newtitle->p_key, p_title_key, KEY_SIZE );
-
- /* Link it at the head of the (possibly empty) list */
- if( p_title == NULL )
- {
- p_newtitle->p_next = dvdcss->p_titles;
- dvdcss->p_titles = p_newtitle;
- }
- /* Link the new title inside the list */
- else
- {
- p_newtitle->p_next = p_title->p_next;
- p_title->p_next = p_newtitle;
- }
-
- memcpy( dvdcss->css.p_title_key, p_title_key, KEY_SIZE );
- return 0;
-}
-
-/*****************************************************************************
- * _dvdcss_disckey: get disc key.
- *****************************************************************************
- * This function should only be called if DVD ioctls are present.
- * It will set dvdcss->i_method = DVDCSS_METHOD_TITLE if it fails to find
- * a valid disc key.
- * Two decryption methods are offered:
- * -disc key hash crack,
- * -decryption with player keys if they are available.
- *****************************************************************************/
-int _dvdcss_disckey( dvdcss_t dvdcss )
-{
- unsigned char p_buffer[ DVD_DISCKEY_SIZE ];
- dvd_key_t p_disc_key;
- int i;
-
- if( GetBusKey( dvdcss ) < 0 )
- {
- return -1;
- }
-
- /* Get encrypted disc key */
- if( ioctl_ReadDiscKey( dvdcss->i_fd, &dvdcss->css.i_agid, p_buffer ) < 0 )
- {
- print_error( dvdcss, "ioctl ReadDiscKey failed" );
- return -1;
- }
-
- /* This should have invaidated the AGID and got us ASF=1. */
- if( GetASF( dvdcss ) != 1 )
- {
- /* Region mismatch (or region not set) is the most likely source. */
- print_error( dvdcss,
- "ASF not 1 after reading disc key (region mismatch?)" );
- ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
- return -1;
- }
-
- /* Shuffle disc key using bus key */
- for( i = 0 ; i < DVD_DISCKEY_SIZE ; i++ )
- {
- p_buffer[ i ] ^= dvdcss->css.p_bus_key[ 4 - (i % KEY_SIZE) ];
- }
-
- /* Decrypt disc key */
- switch( dvdcss->i_method )
- {
- case DVDCSS_METHOD_KEY:
-
- /* Decrypt disc key with player key. */
- PrintKey( dvdcss, "decrypting disc key ", p_buffer );
- if( ! DecryptDiscKey( dvdcss, p_buffer, p_disc_key ) )
- {
- PrintKey( dvdcss, "decrypted disc key is ", p_disc_key );
- break;
- }
- print_debug( dvdcss, "failed to decrypt the disc key, "
- "faulty drive/kernel? "
- "cracking title keys instead" );
-
- /* Fallback, but not to DISC as the disc key might be faulty */
- memset( p_disc_key, 0, KEY_SIZE );
- dvdcss->i_method = DVDCSS_METHOD_TITLE;
- break;
-
- case DVDCSS_METHOD_DISC:
-
- /* Crack Disc key to be able to use it */
- memcpy( p_disc_key, p_buffer, KEY_SIZE );
- PrintKey( dvdcss, "cracking disc key ", p_disc_key );
- if( ! CrackDiscKey( dvdcss, p_disc_key ) )
- {
- PrintKey( dvdcss, "cracked disc key is ", p_disc_key );
- break;
- }
- print_debug( dvdcss, "failed to crack the disc key" );
- memset( p_disc_key, 0, KEY_SIZE );
- dvdcss->i_method = DVDCSS_METHOD_TITLE;
- break;
-
- default:
-
- print_debug( dvdcss, "disc key needs not be decrypted" );
- memset( p_disc_key, 0, KEY_SIZE );
- break;
- }
-
- memcpy( dvdcss->css.p_disc_key, p_disc_key, KEY_SIZE );
-
- return 0;
-}
-
-
-/*****************************************************************************
- * _dvdcss_titlekey: get title key.
- *****************************************************************************/
-int _dvdcss_titlekey( dvdcss_t dvdcss, int i_pos, dvd_key_t p_title_key )
-{
- static uint8_t p_garbage[ DVDCSS_BLOCK_SIZE ]; /* we never read it back */
- uint8_t p_key[ KEY_SIZE ];
- int i, i_ret = 0;
-
- if( dvdcss->b_ioctls && ( dvdcss->i_method == DVDCSS_METHOD_KEY ||
- dvdcss->i_method == DVDCSS_METHOD_DISC ) )
- {
- /* We have a decrypted Disc key and the ioctls are available,
- * read the title key and decrypt it.
- */
-
- print_debug( dvdcss, "getting title key at block %i the classic way",
- i_pos );
-
- /* We need to authenticate again every time to get a new session key */
- if( GetBusKey( dvdcss ) < 0 )
- {
- i_ret = -1;
- }
-
- /* Get encrypted title key */
- if( ioctl_ReadTitleKey( dvdcss->i_fd, &dvdcss->css.i_agid,
- i_pos, p_key ) < 0 )
- {
- print_debug( dvdcss,
- "ioctl ReadTitleKey failed (region mismatch?)" );
- i_ret = -1;
- }
-
- /* Test ASF, it will be reset to 0 if we got a Region error */
- switch( GetASF( dvdcss ) )
- {
- case -1:
- /* An error getting the ASF status, something must be wrong. */
- print_debug( dvdcss, "lost ASF requesting title key" );
- ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
- i_ret = -1;
- break;
-
- case 0:
- /* This might either be a title that has no key,
- * or we encountered a region error. */
- print_debug( dvdcss, "lost ASF requesting title key" );
- break;
-
- case 1:
- /* Drive status is ok. */
- /* If the title key request failed, but we did not loose ASF,
- * we might stil have the AGID. Other code assume that we
- * will not after this so invalidate it(?). */
- if( i_ret < 0 )
- {
- ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
- }
- break;
- }
-
- if( !( i_ret < 0 ) )
- {
- /* Decrypt title key using the bus key */
- for( i = 0 ; i < KEY_SIZE ; i++ )
- {
- p_key[ i ] ^= dvdcss->css.p_bus_key[ 4 - (i % KEY_SIZE) ];
- }
-
- /* If p_key is all zero then there really wasn't any key present
- * even though we got to read it without an error. */
- if( !( p_key[0] | p_key[1] | p_key[2] | p_key[3] | p_key[4] ) )
- {
- i_ret = 0;
- }
- else
- {
- PrintKey( dvdcss, "initial disc key ", dvdcss->css.p_disc_key );
- DecryptTitleKey( dvdcss->css.p_disc_key, p_key );
- PrintKey( dvdcss, "decrypted title key ", p_key );
- i_ret = 1;
- }
-
- /* All went well either there wasn't a key or we have it now. */
- memcpy( p_title_key, p_key, KEY_SIZE );
- PrintKey( dvdcss, "title key is ", p_title_key );
-
- return i_ret;
- }
-
- /* The title key request failed */
- print_debug( dvdcss, "resetting drive and cracking title key" );
-
- /* Read an unscrambled sector and reset the drive */
- dvdcss->pf_seek( dvdcss, 0 );
- dvdcss->pf_read( dvdcss, p_garbage, 1 );
- dvdcss->pf_seek( dvdcss, 0 );
- _dvdcss_disckey( dvdcss );
-
- /* Fallback */
- }
-
- /* METHOD is TITLE, we can't use the ioctls or requesting the title key
- * failed above. For these cases we try to crack the key instead. */
-
- /* For now, the read limit is 9Gb / 2048 = 4718592 sectors. */
- i_ret = CrackTitleKey( dvdcss, i_pos, 4718592, p_key );
-
- memcpy( p_title_key, p_key, KEY_SIZE );
- PrintKey( dvdcss, "title key is ", p_title_key );
-
- return i_ret;
-}
-
-/*****************************************************************************
- * _dvdcss_unscramble: does the actual descrambling of data
- *****************************************************************************
- * sec : sector to unscramble
- * key : title key for this sector
- *****************************************************************************/
-int _dvdcss_unscramble( dvd_key_t p_key, uint8_t *p_sec )
-{
- unsigned int i_t1, i_t2, i_t3, i_t4, i_t5, i_t6;
- uint8_t *p_end = p_sec + DVDCSS_BLOCK_SIZE;
-
- /* PES_scrambling_control */
- if( !(p_sec[0x14] & 0x30) )
- {
- return 0;
- }
-
- i_t1 = (p_key[0] ^ p_sec[0x54]) | 0x100;
- i_t2 = p_key[1] ^ p_sec[0x55];
- i_t3 = (p_key[2] | (p_key[3] << 8) |
- (p_key[4] << 16)) ^ (p_sec[0x56] |
- (p_sec[0x57] << 8) | (p_sec[0x58] << 16));
- i_t4 = i_t3 & 7;
- i_t3 = i_t3 * 2 + 8 - i_t4;
- p_sec += 0x80;
- i_t5 = 0;
-
- while( p_sec != p_end )
- {
- i_t4 = p_css_tab2[i_t2] ^ p_css_tab3[i_t1];
- i_t2 = i_t1>>1;
- i_t1 = ( ( i_t1 & 1 ) << 8 ) ^ i_t4;
- i_t4 = p_css_tab5[i_t4];
- i_t6 = ((((((( i_t3 >> 3 ) ^ i_t3 ) >> 1 ) ^
- i_t3 ) >> 8 ) ^ i_t3 ) >> 5 ) & 0xff;
- i_t3 = (i_t3 << 8 ) | i_t6;
- i_t6 = p_css_tab4[i_t6];
- i_t5 += i_t6 + i_t4;
- *p_sec = p_css_tab1[*p_sec] ^ ( i_t5 & 0xff );
- p_sec++;
- i_t5 >>= 8;
- }
-
- return 0;
-}
-
-/* Following functions are local */
-
-/*****************************************************************************
- * GetBusKey : Go through the CSS Authentication process
- *****************************************************************************
- * It simulates the mutual authentication between logical unit and host,
- * and stops when a session key (called bus key) has been established.
- * Always do the full auth sequence. Some drives seem to lie and always
- * respond with ASF=1. For instance the old DVD roms on Compaq Armada says
- * that ASF=1 from the start and then later fail with a 'read of scrambled
- * block without authentication' error.
- *****************************************************************************/
-static int GetBusKey( dvdcss_t dvdcss )
-{
- uint8_t p_buffer[10];
- uint8_t p_challenge[2*KEY_SIZE];
- dvd_key_t p_key1;
- dvd_key_t p_key2;
- dvd_key_t p_key_check;
- uint8_t i_variant = 0;
- int i_ret = -1;
- int i;
-
- print_debug( dvdcss, "requesting AGID" );
- i_ret = ioctl_ReportAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
-
- /* We might have to reset hung authentication processes in the drive
- * by invalidating the corresponding AGID'. As long as we haven't got
- * an AGID, invalidate one (in sequence) and try again. */
- for( i = 0; i_ret == -1 && i < 4 ; ++i )
- {
- print_debug( dvdcss, "ioctl ReportAgid failed, "
- "invalidating AGID %d", i );
-
- /* This is really _not good_, should be handled by the OS.
- * Invalidating an AGID could make another process fail somewhere
- * in its authentication process. */
- dvdcss->css.i_agid = i;
- ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
-
- print_debug( dvdcss, "requesting AGID" );
- i_ret = ioctl_ReportAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
- }
-
- /* Unable to authenticate without AGID */
- if( i_ret == -1 )
- {
- print_error( dvdcss, "ioctl ReportAgid failed, fatal" );
- return -1;
- }
-
- /* Setup a challenge, any values should work */
- for( i = 0 ; i < 10; ++i )
- {
- p_challenge[i] = i;
- }
-
- /* Get challenge from host */
- for( i = 0 ; i < 10 ; ++i )
- {
- p_buffer[9-i] = p_challenge[i];
- }
-
- /* Send challenge to LU */
- if( ioctl_SendChallenge( dvdcss->i_fd,
- &dvdcss->css.i_agid, p_buffer ) < 0 )
- {
- print_error( dvdcss, "ioctl SendChallenge failed" );
- ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
- return -1;
- }
-
- /* Get key1 from LU */
- if( ioctl_ReportKey1( dvdcss->i_fd, &dvdcss->css.i_agid, p_buffer ) < 0)
- {
- print_error( dvdcss, "ioctl ReportKey1 failed" );
- ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
- return -1;
- }
-
- /* Send key1 to host */
- for( i = 0 ; i < KEY_SIZE ; i++ )
- {
- p_key1[i] = p_buffer[4-i];
- }
-
- for( i = 0 ; i < 32 ; ++i )
- {
- CryptKey( 0, i, p_challenge, p_key_check );
-
- if( memcmp( p_key_check, p_key1, KEY_SIZE ) == 0 )
- {
- print_debug( dvdcss, "drive authenticated, using variant %d", i );
- i_variant = i;
- break;
- }
- }
-
- if( i == 32 )
- {
- print_error( dvdcss, "drive would not authenticate" );
- ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
- return -1;
- }
-
- /* Get challenge from LU */
- if( ioctl_ReportChallenge( dvdcss->i_fd,
- &dvdcss->css.i_agid, p_buffer ) < 0 )
- {
- print_error( dvdcss, "ioctl ReportKeyChallenge failed" );
- ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
- return -1;
- }
-
- /* Send challenge to host */
- for( i = 0 ; i < 10 ; ++i )
- {
- p_challenge[i] = p_buffer[9-i];
- }
-
- CryptKey( 1, i_variant, p_challenge, p_key2 );
-
- /* Get key2 from host */
- for( i = 0 ; i < KEY_SIZE ; ++i )
- {
- p_buffer[4-i] = p_key2[i];
- }
-
- /* Send key2 to LU */
- if( ioctl_SendKey2( dvdcss->i_fd, &dvdcss->css.i_agid, p_buffer ) < 0 )
- {
- print_error( dvdcss, "ioctl SendKey2 failed" );
- ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
- return -1;
- }
-
- /* The drive has accepted us as authentic. */
- print_debug( dvdcss, "authentication established" );
-
- memcpy( p_challenge, p_key1, KEY_SIZE );
- memcpy( p_challenge + KEY_SIZE, p_key2, KEY_SIZE );
-
- CryptKey( 2, i_variant, p_challenge, dvdcss->css.p_bus_key );
-
- return 0;
-}
-
-/*****************************************************************************
- * PrintKey : debug function that dumps a key value
- *****************************************************************************/
-static void PrintKey( dvdcss_t dvdcss, char *prefix, uint8_t const *data )
-{
- print_debug( dvdcss, "%s%02x:%02x:%02x:%02x:%02x", prefix,
- data[0], data[1], data[2], data[3], data[4] );
-}
-
-/*****************************************************************************
- * GetASF : Get Authentication success flag
- *****************************************************************************
- * Returns :
- * -1 on ioctl error,
- * 0 if the device needs to be authenticated,
- * 1 either.
- *****************************************************************************/
-static int GetASF( dvdcss_t dvdcss )
-{
- int i_asf = 0;
-
- if( ioctl_ReportASF( dvdcss->i_fd, NULL, &i_asf ) != 0 )
- {
- /* The ioctl process has failed */
- print_error( dvdcss, "GetASF fatal error" );
- return -1;
- }
-
- if( i_asf )
- {
- print_debug( dvdcss, "GetASF authenticated, ASF=1" );
- }
- else
- {
- print_debug( dvdcss, "GetASF not authenticated, ASF=0" );
- }
-
- return i_asf;
-}
-
-/*****************************************************************************
- * CryptKey : shuffles bits and unencrypt keys.
- *****************************************************************************
- * Used during authentication and disc key negociation in GetBusKey.
- * i_key_type : 0->key1, 1->key2, 2->buskey.
- * i_variant : between 0 and 31.
- *****************************************************************************/
-static void CryptKey( int i_key_type, int i_variant,
- uint8_t const *p_challenge, uint8_t *p_key )
-{
- /* Permutation table for challenge */
- uint8_t pp_perm_challenge[3][10] =
- { { 1, 3, 0, 7, 5, 2, 9, 6, 4, 8 },
- { 6, 1, 9, 3, 8, 5, 7, 4, 0, 2 },
- { 4, 0, 3, 5, 7, 2, 8, 6, 1, 9 } };
-
- /* Permutation table for variant table for key2 and buskey */
- uint8_t pp_perm_variant[2][32] =
- { { 0x0a, 0x08, 0x0e, 0x0c, 0x0b, 0x09, 0x0f, 0x0d,
- 0x1a, 0x18, 0x1e, 0x1c, 0x1b, 0x19, 0x1f, 0x1d,
- 0x02, 0x00, 0x06, 0x04, 0x03, 0x01, 0x07, 0x05,
- 0x12, 0x10, 0x16, 0x14, 0x13, 0x11, 0x17, 0x15 },
- { 0x12, 0x1a, 0x16, 0x1e, 0x02, 0x0a, 0x06, 0x0e,
- 0x10, 0x18, 0x14, 0x1c, 0x00, 0x08, 0x04, 0x0c,
- 0x13, 0x1b, 0x17, 0x1f, 0x03, 0x0b, 0x07, 0x0f,
- 0x11, 0x19, 0x15, 0x1d, 0x01, 0x09, 0x05, 0x0d } };
-
- uint8_t p_variants[32] =
- { 0xB7, 0x74, 0x85, 0xD0, 0xCC, 0xDB, 0xCA, 0x73,
- 0x03, 0xFE, 0x31, 0x03, 0x52, 0xE0, 0xB7, 0x42,
- 0x63, 0x16, 0xF2, 0x2A, 0x79, 0x52, 0xFF, 0x1B,
- 0x7A, 0x11, 0xCA, 0x1A, 0x9B, 0x40, 0xAD, 0x01 };
-
- /* The "secret" key */
- uint8_t p_secret[5] = { 0x55, 0xD6, 0xC4, 0xC5, 0x28 };
-
- uint8_t p_bits[30], p_scratch[10], p_tmp1[5], p_tmp2[5];
- uint8_t i_lfsr0_o; /* 1 bit used */
- uint8_t i_lfsr1_o; /* 1 bit used */
- uint8_t i_css_variant, i_cse, i_index, i_combined, i_carry;
- uint8_t i_val = 0;
- uint32_t i_lfsr0, i_lfsr1;
- int i_term = 0;
- int i_bit;
- int i;
-
- for (i = 9; i >= 0; --i)
- p_scratch[i] = p_challenge[pp_perm_challenge[i_key_type][i]];
-
- i_css_variant = ( i_key_type == 0 ) ? i_variant :
- pp_perm_variant[i_key_type-1][i_variant];
-
- /*
- * This encryption engine implements one of 32 variations
- * one the same theme depending upon the choice in the
- * variant parameter (0 - 31).
- *
- * The algorithm itself manipulates a 40 bit input into
- * a 40 bit output.
- * The parameter 'input' is 80 bits. It consists of
- * the 40 bit input value that is to be encrypted followed
- * by a 40 bit seed value for the pseudo random number
- * generators.
- */
-
- /* Feed the secret into the input values such that
- * we alter the seed to the LFSR's used above, then
- * generate the bits to play with.
- */
- for( i = 5 ; --i >= 0 ; )
- {
- p_tmp1[i] = p_scratch[5 + i] ^ p_secret[i] ^ p_crypt_tab2[i];
- }
-
- /*
- * We use two LFSR's (seeded from some of the input data bytes) to
- * generate two streams of pseudo-random bits. These two bit streams
- * are then combined by simply adding with carry to generate a final
- * sequence of pseudo-random bits which is stored in the buffer that
- * 'output' points to the end of - len is the size of this buffer.
- *
- * The first LFSR is of degree 25, and has a polynomial of:
- * x^13 + x^5 + x^4 + x^1 + 1
- *
- * The second LSFR is of degree 17, and has a (primitive) polynomial of:
- * x^15 + x^1 + 1
- *
- * I don't know if these polynomials are primitive modulo 2, and thus
- * represent maximal-period LFSR's.
- *
- *
- * Note that we take the output of each LFSR from the new shifted in
- * bit, not the old shifted out bit. Thus for ease of use the LFSR's
- * are implemented in bit reversed order.
- *
- */
-
- /* In order to ensure that the LFSR works we need to ensure that the
- * initial values are non-zero. Thus when we initialise them from
- * the seed, we ensure that a bit is set.
- */
- i_lfsr0 = ( p_tmp1[0] << 17 ) | ( p_tmp1[1] << 9 ) |
- (( p_tmp1[2] & ~7 ) << 1 ) | 8 | ( p_tmp1[2] & 7 );
- i_lfsr1 = ( p_tmp1[3] << 9 ) | 0x100 | p_tmp1[4];
-
- i_index = sizeof(p_bits);
- i_carry = 0;
-
- do
- {
- for( i_bit = 0, i_val = 0 ; i_bit < 8 ; ++i_bit )
- {
-
- i_lfsr0_o = ( ( i_lfsr0 >> 24 ) ^ ( i_lfsr0 >> 21 ) ^
- ( i_lfsr0 >> 20 ) ^ ( i_lfsr0 >> 12 ) ) & 1;
- i_lfsr0 = ( i_lfsr0 << 1 ) | i_lfsr0_o;
-
- i_lfsr1_o = ( ( i_lfsr1 >> 16 ) ^ ( i_lfsr1 >> 2 ) ) & 1;
- i_lfsr1 = ( i_lfsr1 << 1 ) | i_lfsr1_o;
-
- i_combined = !i_lfsr1_o + i_carry + !i_lfsr0_o;
- /* taking bit 1 */
- i_carry = ( i_combined >> 1 ) & 1;
- i_val |= ( i_combined & 1 ) << i_bit;
- }
-
- p_bits[--i_index] = i_val;
- } while( i_index > 0 );
-
- /* This term is used throughout the following to
- * select one of 32 different variations on the
- * algorithm.
- */
- i_cse = p_variants[i_css_variant] ^ p_crypt_tab2[i_css_variant];
-
- /* Now the actual blocks doing the encryption. Each
- * of these works on 40 bits at a time and are quite
- * similar.
- */
- i_index = 0;
- for( i = 5, i_term = 0 ; --i >= 0 ; i_term = p_scratch[i] )
- {
- i_index = p_bits[25 + i] ^ p_scratch[i];
- i_index = p_crypt_tab1[i_index] ^ ~p_crypt_tab2[i_index] ^ i_cse;
-
- p_tmp1[i] = p_crypt_tab2[i_index] ^ p_crypt_tab3[i_index] ^ i_term;
- }
- p_tmp1[4] ^= p_tmp1[0];
-
- for( i = 5, i_term = 0 ; --i >= 0 ; i_term = p_tmp1[i] )
- {
- i_index = p_bits[20 + i] ^ p_tmp1[i];
- i_index = p_crypt_tab1[i_index] ^ ~p_crypt_tab2[i_index] ^ i_cse;
-
- p_tmp2[i] = p_crypt_tab2[i_index] ^ p_crypt_tab3[i_index] ^ i_term;
- }
- p_tmp2[4] ^= p_tmp2[0];
-
- for( i = 5, i_term = 0 ; --i >= 0 ; i_term = p_tmp2[i] )
- {
- i_index = p_bits[15 + i] ^ p_tmp2[i];
- i_index = p_crypt_tab1[i_index] ^ ~p_crypt_tab2[i_index] ^ i_cse;
- i_index = p_crypt_tab2[i_index] ^ p_crypt_tab3[i_index] ^ i_term;
-
- p_tmp1[i] = p_crypt_tab0[i_index] ^ p_crypt_tab2[i_index];
- }
- p_tmp1[4] ^= p_tmp1[0];
-
- for( i = 5, i_term = 0 ; --i >= 0 ; i_term = p_tmp1[i] )
- {
- i_index = p_bits[10 + i] ^ p_tmp1[i];
- i_index = p_crypt_tab1[i_index] ^ ~p_crypt_tab2[i_index] ^ i_cse;
-
- i_index = p_crypt_tab2[i_index] ^ p_crypt_tab3[i_index] ^ i_term;
-
- p_tmp2[i] = p_crypt_tab0[i_index] ^ p_crypt_tab2[i_index];
- }
- p_tmp2[4] ^= p_tmp2[0];
-
- for( i = 5, i_term = 0 ; --i >= 0 ; i_term = p_tmp2[i] )
- {
- i_index = p_bits[5 + i] ^ p_tmp2[i];
- i_index = p_crypt_tab1[i_index] ^ ~p_crypt_tab2[i_index] ^ i_cse;
-
- p_tmp1[i] = p_crypt_tab2[i_index] ^ p_crypt_tab3[i_index] ^ i_term;
- }
- p_tmp1[4] ^= p_tmp1[0];
-
- for(i = 5, i_term = 0 ; --i >= 0 ; i_term = p_tmp1[i] )
- {
- i_index = p_bits[i] ^ p_tmp1[i];
- i_index = p_crypt_tab1[i_index] ^ ~p_crypt_tab2[i_index] ^ i_cse;
-
- p_key[i] = p_crypt_tab2[i_index] ^ p_crypt_tab3[i_index] ^ i_term;
- }
-
- return;
-}
-
-/*****************************************************************************
- * DecryptKey: decrypt p_crypted with p_key.
- *****************************************************************************
- * Used to decrypt the disc key, with a player key, after requesting it
- * in _dvdcss_disckey and to decrypt title keys, with a disc key, requested
- * in _dvdcss_titlekey.
- * The player keys and the resulting disc key are only used as KEKs
- * (key encryption keys).
- * Decryption is slightly dependant on the type of key:
- * -for disc key, invert is 0x00,
- * -for title key, invert if 0xff.
- *****************************************************************************/
-static void DecryptKey( uint8_t invert, uint8_t const *p_key,
- uint8_t const *p_crypted, uint8_t *p_result )
-{
- unsigned int i_lfsr1_lo;
- unsigned int i_lfsr1_hi;
- unsigned int i_lfsr0;
- unsigned int i_combined;
- uint8_t o_lfsr0;
- uint8_t o_lfsr1;
- uint8_t k[5];
- int i;
-
- i_lfsr1_lo = p_key[0] | 0x100;
- i_lfsr1_hi = p_key[1];
-
- i_lfsr0 = ( ( p_key[4] << 17 )
- | ( p_key[3] << 9 )
- | ( p_key[2] << 1 ) )
- + 8 - ( p_key[2] & 7 );
- i_lfsr0 = ( p_css_tab4[i_lfsr0 & 0xff] << 24 ) |
- ( p_css_tab4[( i_lfsr0 >> 8 ) & 0xff] << 16 ) |
- ( p_css_tab4[( i_lfsr0 >> 16 ) & 0xff] << 8 ) |
- p_css_tab4[( i_lfsr0 >> 24 ) & 0xff];
-
- i_combined = 0;
- for( i = 0 ; i < KEY_SIZE ; ++i )
- {
- o_lfsr1 = p_css_tab2[i_lfsr1_hi] ^ p_css_tab3[i_lfsr1_lo];
- i_lfsr1_hi = i_lfsr1_lo >> 1;
- i_lfsr1_lo = ( ( i_lfsr1_lo & 1 ) << 8 ) ^ o_lfsr1;
- o_lfsr1 = p_css_tab4[o_lfsr1];
-
- o_lfsr0 = ((((((( i_lfsr0 >> 8 ) ^ i_lfsr0 ) >> 1 )
- ^ i_lfsr0 ) >> 3 ) ^ i_lfsr0 ) >> 7 );
- i_lfsr0 = ( i_lfsr0 >> 8 ) | ( o_lfsr0 << 24 );
-
- i_combined += ( o_lfsr0 ^ invert ) + o_lfsr1;
- k[i] = i_combined & 0xff;
- i_combined >>= 8;
- }
-
- p_result[4] = k[4] ^ p_css_tab1[p_crypted[4]] ^ p_crypted[3];
- p_result[3] = k[3] ^ p_css_tab1[p_crypted[3]] ^ p_crypted[2];
- p_result[2] = k[2] ^ p_css_tab1[p_crypted[2]] ^ p_crypted[1];
- p_result[1] = k[1] ^ p_css_tab1[p_crypted[1]] ^ p_crypted[0];
- p_result[0] = k[0] ^ p_css_tab1[p_crypted[0]] ^ p_result[4];
-
- p_result[4] = k[4] ^ p_css_tab1[p_result[4]] ^ p_result[3];
- p_result[3] = k[3] ^ p_css_tab1[p_result[3]] ^ p_result[2];
- p_result[2] = k[2] ^ p_css_tab1[p_result[2]] ^ p_result[1];
- p_result[1] = k[1] ^ p_css_tab1[p_result[1]] ^ p_result[0];
- p_result[0] = k[0] ^ p_css_tab1[p_result[0]];
-
- return;
-}
-
-/*****************************************************************************
- * player_keys: alternate DVD player keys
- *****************************************************************************
- * These player keys were generated using Frank A. Stevenson's PlayerKey
- * cracker. A copy of his article can be found here:
- * http://www-2.cs.cmu.edu/~dst/DeCSS/FrankStevenson/mail2.txt
- *****************************************************************************/
-static const dvd_key_t player_keys[] =
-{
- { 0x01, 0xaf, 0xe3, 0x12, 0x80 },
- { 0x12, 0x11, 0xca, 0x04, 0x3b },
- { 0x14, 0x0c, 0x9e, 0xd0, 0x09 },
- { 0x14, 0x71, 0x35, 0xba, 0xe2 },
- { 0x1a, 0xa4, 0x33, 0x21, 0xa6 },
- { 0x26, 0xec, 0xc4, 0xa7, 0x4e },
- { 0x2c, 0xb2, 0xc1, 0x09, 0xee },
- { 0x2f, 0x25, 0x9e, 0x96, 0xdd },
- { 0x33, 0x2f, 0x49, 0x6c, 0xe0 },
- { 0x35, 0x5b, 0xc1, 0x31, 0x0f },
- { 0x36, 0x67, 0xb2, 0xe3, 0x85 },
- { 0x39, 0x3d, 0xf1, 0xf1, 0xbd },
- { 0x3b, 0x31, 0x34, 0x0d, 0x91 },
- { 0x45, 0xed, 0x28, 0xeb, 0xd3 },
- { 0x48, 0xb7, 0x6c, 0xce, 0x69 },
- { 0x4b, 0x65, 0x0d, 0xc1, 0xee },
- { 0x4c, 0xbb, 0xf5, 0x5b, 0x23 },
- { 0x51, 0x67, 0x67, 0xc5, 0xe0 },
- { 0x53, 0x94, 0xe1, 0x75, 0xbf },
- { 0x57, 0x2c, 0x8b, 0x31, 0xae },
- { 0x63, 0xdb, 0x4c, 0x5b, 0x4a },
- { 0x7b, 0x1e, 0x5e, 0x2b, 0x57 },
- { 0x85, 0xf3, 0x85, 0xa0, 0xe0 },
- { 0xab, 0x1e, 0xe7, 0x7b, 0x72 },
- { 0xab, 0x36, 0xe3, 0xeb, 0x76 },
- { 0xb1, 0xb8, 0xf9, 0x38, 0x03 },
- { 0xb8, 0x5d, 0xd8, 0x53, 0xbd },
- { 0xbf, 0x92, 0xc3, 0xb0, 0xe2 },
- { 0xcf, 0x1a, 0xb2, 0xf8, 0x0a },
- { 0xec, 0xa0, 0xcf, 0xb3, 0xff },
- { 0xfc, 0x95, 0xa9, 0x87, 0x35 }
-};
-
-/*****************************************************************************
- * DecryptDiscKey
- *****************************************************************************
- * Decryption of the disc key with player keys: try to decrypt the disc key
- * from every position with every player key.
- * p_struct_disckey: the 2048 byte DVD_STRUCT_DISCKEY data
- * p_disc_key: result, the 5 byte disc key
- *****************************************************************************/
-static int DecryptDiscKey( dvdcss_t dvdcss, uint8_t const *p_struct_disckey,
- dvd_key_t p_disc_key )
-{
- uint8_t p_verify[KEY_SIZE];
- unsigned int i, n = 0;
-
- /* Decrypt disc key with the above player keys */
- for( n = 0; n < sizeof(player_keys) / sizeof(dvd_key_t); n++ )
- {
- PrintKey( dvdcss, "trying player key ", player_keys[n] );
-
- for( i = 1; i < 409; i++ )
- {
- /* Check if player key n is the right key for position i. */
- DecryptKey( 0, player_keys[n], p_struct_disckey + 5 * i,
- p_disc_key );
-
- /* The first part in the struct_disckey block is the
- * 'disc key' encrypted with itself. Using this we
- * can check if we decrypted the correct key. */
- DecryptKey( 0, p_disc_key, p_struct_disckey, p_verify );
-
- /* If the position / player key pair worked then return. */
- if( memcmp( p_disc_key, p_verify, KEY_SIZE ) == 0 )
- {
- return 0;
- }
- }
- }
-
- /* Have tried all combinations of positions and keys,
- * and we still didn't succeed. */
- memset( p_disc_key, 0, KEY_SIZE );
- return -1;
-}
-
-/*****************************************************************************
- * DecryptTitleKey
- *****************************************************************************
- * Decrypt the title key using the disc key.
- * p_disc_key: result, the 5 byte disc key
- * p_titlekey: the encrypted title key, gets overwritten by the decrypted key
- *****************************************************************************/
-static void DecryptTitleKey( dvd_key_t p_disc_key, dvd_key_t p_titlekey )
-{
- DecryptKey( 0xff, p_disc_key, p_titlekey, p_titlekey );
-}
-
-/*****************************************************************************
- * CrackDiscKey: brute force disc key
- * CSS hash reversal function designed by Frank Stevenson
- *****************************************************************************
- * This function uses a big amount of memory to crack the disc key from the
- * disc key hash, if player keys are not available.
- *****************************************************************************/
-#define K1TABLEWIDTH 10
-
-/*
- * Simple function to test if a candidate key produces the given hash
- */
-static int investigate( unsigned char *hash, unsigned char *ckey )
-{
- unsigned char key[KEY_SIZE];
-
- DecryptKey( 0, ckey, hash, key );
-
- return memcmp( key, ckey, KEY_SIZE );
-}
-
-static int CrackDiscKey( dvdcss_t dvdcss, uint8_t *p_disc_key )
-{
- unsigned char B[5] = { 0,0,0,0,0 }; /* Second Stage of mangle cipher */
- unsigned char C[5] = { 0,0,0,0,0 }; /* Output Stage of mangle cipher
- * IntermediateKey */
- unsigned char k[5] = { 0,0,0,0,0 }; /* Mangling cipher key
- * Also output from CSS( C ) */
- unsigned char out1[5]; /* five first output bytes of LFSR1 */
- unsigned char out2[5]; /* five first output bytes of LFSR2 */
- unsigned int lfsr1a; /* upper 9 bits of LFSR1 */
- unsigned int lfsr1b; /* lower 8 bits of LFSR1 */
- unsigned int tmp, tmp2, tmp3, tmp4,tmp5;
- int i,j;
- unsigned int nStepA; /* iterator for LFSR1 start state */
- unsigned int nStepB; /* iterator for possible B[0] */
- unsigned int nTry; /* iterator for K[1] possibilities */
- unsigned int nPossibleK1; /* #of possible K[1] values */
- unsigned char* K1table; /* Lookup table for possible K[1] */
- unsigned int* BigTable; /* LFSR2 startstate indexed by
- * 1,2,5 output byte */
-
- /*
- * Prepare tables for hash reversal
- */
-
- /* initialize lookup tables for k[1] */
- K1table = malloc( 65536 * K1TABLEWIDTH );
- memset( K1table, 0 , 65536 * K1TABLEWIDTH );
- if( K1table == NULL )
- {
- return -1;
- }
-
- tmp = p_disc_key[0] ^ p_css_tab1[ p_disc_key[1] ];
- for( i = 0 ; i < 256 ; i++ ) /* k[1] */
- {
- tmp2 = p_css_tab1[ tmp ^ i ]; /* p_css_tab1[ B[1] ]*/
-
- for( j = 0 ; j < 256 ; j++ ) /* B[0] */
- {
- tmp3 = j ^ tmp2 ^ i; /* C[1] */
- tmp4 = K1table[ K1TABLEWIDTH * ( 256 * j + tmp3 ) ]; /* count of entries here */
- tmp4++;
-/*
- if( tmp4 == K1TABLEWIDTH )
- {
- print_debug( dvdcss, "Table disaster %d", tmp4 );
- }
-*/
- if( tmp4 < K1TABLEWIDTH )
- {
- K1table[ K1TABLEWIDTH * ( 256 * j + tmp3 ) + tmp4 ] = i;
- }
- K1table[ K1TABLEWIDTH * ( 256 * j + tmp3 ) ] = tmp4;
- }
- }
-
- /* Initing our Really big table */
- BigTable = malloc( 16777216 * sizeof(int) );
- memset( BigTable, 0 , 16777216 * sizeof(int) );
- if( BigTable == NULL )
- {
- return -1;
- }
-
- tmp3 = 0;
-
- print_debug( dvdcss, "initializing the big table" );
-
- for( i = 0 ; i < 16777216 ; i++ )
- {
- tmp = (( i + i ) & 0x1fffff0 ) | 0x8 | ( i & 0x7 );
-
- for( j = 0 ; j < 5 ; j++ )
- {
- tmp2=((((((( tmp >> 3 ) ^ tmp ) >> 1 ) ^ tmp ) >> 8 )
- ^ tmp ) >> 5 ) & 0xff;
- tmp = ( tmp << 8) | tmp2;
- out2[j] = p_css_tab4[ tmp2 ];
- }
-
- j = ( out2[0] << 16 ) | ( out2[1] << 8 ) | out2[4];
- BigTable[j] = i;
- }
-
- /*
- * We are done initing, now reverse hash
- */
- tmp5 = p_disc_key[0] ^ p_css_tab1[ p_disc_key[1] ];
-
- for( nStepA = 0 ; nStepA < 65536 ; nStepA ++ )
- {
- lfsr1a = 0x100 | ( nStepA >> 8 );
- lfsr1b = nStepA & 0xff;
-
- /* Generate 5 first output bytes from lfsr1 */
- for( i = 0 ; i < 5 ; i++ )
- {
- tmp = p_css_tab2[ lfsr1b ] ^ p_css_tab3[ lfsr1a ];
- lfsr1b = lfsr1a >> 1;
- lfsr1a = ((lfsr1a&1)<<8) ^ tmp;
- out1[ i ] = p_css_tab4[ tmp ];
- }
-
- /* cumpute and cache some variables */
- C[0] = nStepA >> 8;
- C[1] = nStepA & 0xff;
- tmp = p_disc_key[3] ^ p_css_tab1[ p_disc_key[4] ];
- tmp2 = p_css_tab1[ p_disc_key[0] ];
-
- /* Search through all possible B[0] */
- for( nStepB = 0 ; nStepB < 256 ; nStepB++ )
- {
- /* reverse parts of the mangling cipher */
- B[0] = nStepB;
- k[0] = p_css_tab1[ B[0] ] ^ C[0];
- B[4] = B[0] ^ k[0] ^ tmp2;
- k[4] = B[4] ^ tmp;
- nPossibleK1 = K1table[ K1TABLEWIDTH * (256 * B[0] + C[1]) ];
-
- /* Try out all possible values for k[1] */
- for( nTry = 0 ; nTry < nPossibleK1 ; nTry++ )
- {
- k[1] = K1table[ K1TABLEWIDTH * (256 * B[0] + C[1]) + nTry + 1 ];
- B[1] = tmp5 ^ k[1];
-
- /* reconstruct output from LFSR2 */
- tmp3 = ( 0x100 + k[0] - out1[0] );
- out2[0] = tmp3 & 0xff;
- tmp3 = tmp3 & 0x100 ? 0x100 : 0xff;
- tmp3 = ( tmp3 + k[1] - out1[1] );
- out2[1] = tmp3 & 0xff;
- tmp3 = ( 0x100 + k[4] - out1[4] );
- out2[4] = tmp3 & 0xff; /* Can be 1 off */
-
- /* test first possible out2[4] */
- tmp4 = ( out2[0] << 16 ) | ( out2[1] << 8 ) | out2[4];
- tmp4 = BigTable[ tmp4 ];
- C[2] = tmp4 & 0xff;
- C[3] = ( tmp4 >> 8 ) & 0xff;
- C[4] = ( tmp4 >> 16 ) & 0xff;
- B[3] = p_css_tab1[ B[4] ] ^ k[4] ^ C[4];
- k[3] = p_disc_key[2] ^ p_css_tab1[ p_disc_key[3] ] ^ B[3];
- B[2] = p_css_tab1[ B[3] ] ^ k[3] ^ C[3];
- k[2] = p_disc_key[1] ^ p_css_tab1[ p_disc_key[2] ] ^ B[2];
-
- if( ( B[1] ^ p_css_tab1[ B[2] ] ^ k[ 2 ] ) == C[ 2 ] )
- {
- if( ! investigate( &p_disc_key[0] , &C[0] ) )
- {
- goto end;
- }
- }
-
- /* Test second possible out2[4] */
- out2[4] = ( out2[4] + 0xff ) & 0xff;
- tmp4 = ( out2[0] << 16 ) | ( out2[1] << 8 ) | out2[4];
- tmp4 = BigTable[ tmp4 ];
- C[2] = tmp4 & 0xff;
- C[3] = ( tmp4 >> 8 ) & 0xff;
- C[4] = ( tmp4 >> 16 ) & 0xff;
- B[3] = p_css_tab1[ B[4] ] ^ k[4] ^ C[4];
- k[3] = p_disc_key[2] ^ p_css_tab1[ p_disc_key[3] ] ^ B[3];
- B[2] = p_css_tab1[ B[3] ] ^ k[3] ^ C[3];
- k[2] = p_disc_key[1] ^ p_css_tab1[ p_disc_key[2] ] ^ B[2];
-
- if( ( B[1] ^ p_css_tab1[ B[2] ] ^ k[ 2 ] ) == C[ 2 ] )
- {
- if( ! investigate( &p_disc_key[0] , &C[0] ) )
- {
- goto end;
- }
- }
- }
- }
- }
-
-end:
-
- memcpy( p_disc_key, &C[0], KEY_SIZE );
-
- free( K1table );
- free( BigTable );
-
- return 0;
-}
-
-/*****************************************************************************
- * RecoverTitleKey: (title) key recovery from cipher and plain text
- * Function designed by Frank Stevenson
- *****************************************************************************
- * Called from Attack* which are in turn called by CrackTitleKey. Given
- * a guessed(?) plain text and the cipher text. Returns -1 on failure.
- *****************************************************************************/
-static int RecoverTitleKey( int i_start, uint8_t const *p_crypted,
- uint8_t const *p_decrypted,
- uint8_t const *p_sector_seed, uint8_t *p_key )
-{
- uint8_t p_buffer[10];
- unsigned int i_t1, i_t2, i_t3, i_t4, i_t5, i_t6;
- unsigned int i_try;
- unsigned int i_candidate;
- unsigned int i, j;
- int i_exit = -1;
-
- for( i = 0 ; i < 10 ; i++ )
- {
- p_buffer[i] = p_css_tab1[p_crypted[i]] ^ p_decrypted[i];
- }
-
- for( i_try = i_start ; i_try < 0x10000 ; i_try++ )
- {
- i_t1 = i_try >> 8 | 0x100;
- i_t2 = i_try & 0xff;
- i_t3 = 0; /* not needed */
- i_t5 = 0;
-
- /* iterate cipher 4 times to reconstruct LFSR2 */
- for( i = 0 ; i < 4 ; i++ )
- {
- /* advance LFSR1 normaly */
- i_t4 = p_css_tab2[i_t2] ^ p_css_tab3[i_t1];
- i_t2 = i_t1 >> 1;
- i_t1 = ( ( i_t1 & 1 ) << 8 ) ^ i_t4;
- i_t4 = p_css_tab5[i_t4];
- /* deduce i_t6 & i_t5 */
- i_t6 = p_buffer[i];
- if( i_t5 )
- {
- i_t6 = ( i_t6 + 0xff ) & 0x0ff;
- }
- if( i_t6 < i_t4 )
- {
- i_t6 += 0x100;
- }
- i_t6 -= i_t4;
- i_t5 += i_t6 + i_t4;
- i_t6 = p_css_tab4[ i_t6 ];
- /* feed / advance i_t3 / i_t5 */
- i_t3 = ( i_t3 << 8 ) | i_t6;
- i_t5 >>= 8;
- }
-
- i_candidate = i_t3;
-
- /* iterate 6 more times to validate candidate key */
- for( ; i < 10 ; i++ )
- {
- i_t4 = p_css_tab2[i_t2] ^ p_css_tab3[i_t1];
- i_t2 = i_t1 >> 1;
- i_t1 = ( ( i_t1 & 1 ) << 8 ) ^ i_t4;
- i_t4 = p_css_tab5[i_t4];
- i_t6 = ((((((( i_t3 >> 3 ) ^ i_t3 ) >> 1 ) ^
- i_t3 ) >> 8 ) ^ i_t3 ) >> 5 ) & 0xff;
- i_t3 = ( i_t3 << 8 ) | i_t6;
- i_t6 = p_css_tab4[i_t6];
- i_t5 += i_t6 + i_t4;
- if( ( i_t5 & 0xff ) != p_buffer[i] )
- {
- break;
- }
-
- i_t5 >>= 8;
- }
-
- if( i == 10 )
- {
- /* Do 4 backwards steps of iterating t3 to deduce initial state */
- i_t3 = i_candidate;
- for( i = 0 ; i < 4 ; i++ )
- {
- i_t1 = i_t3 & 0xff;
- i_t3 = ( i_t3 >> 8 );
- /* easy to code, and fast enough bruteforce
- * search for byte shifted in */
- for( j = 0 ; j < 256 ; j++ )
- {
- i_t3 = ( i_t3 & 0x1ffff ) | ( j << 17 );
- i_t6 = ((((((( i_t3 >> 3 ) ^ i_t3 ) >> 1 ) ^
- i_t3 ) >> 8 ) ^ i_t3 ) >> 5 ) & 0xff;
- if( i_t6 == i_t1 )
- {
- break;
- }
- }
- }
-
- i_t4 = ( i_t3 >> 1 ) - 4;
- for( i_t5 = 0 ; i_t5 < 8; i_t5++ )
- {
- if( ( ( i_t4 + i_t5 ) * 2 + 8 - ( (i_t4 + i_t5 ) & 7 ) )
- == i_t3 )
- {
- p_key[0] = i_try>>8;
- p_key[1] = i_try & 0xFF;
- p_key[2] = ( ( i_t4 + i_t5 ) >> 0 ) & 0xFF;
- p_key[3] = ( ( i_t4 + i_t5 ) >> 8 ) & 0xFF;
- p_key[4] = ( ( i_t4 + i_t5 ) >> 16 ) & 0xFF;
- i_exit = i_try + 1;
- }
- }
- }
- }
-
- if( i_exit >= 0 )
- {
- p_key[0] ^= p_sector_seed[0];
- p_key[1] ^= p_sector_seed[1];
- p_key[2] ^= p_sector_seed[2];
- p_key[3] ^= p_sector_seed[3];
- p_key[4] ^= p_sector_seed[4];
- }
-
- return i_exit;
-}
-
-
-/******************************************************************************
- * Various pieces for the title crack engine.
- ******************************************************************************
- * The length of the PES packet is located at 0x12-0x13.
- * The the copyrigth protection bits are located at 0x14 (bits 0x20 and 0x10).
- * The data of the PES packet begins at 0x15 (if there isn't any PTS/DTS)
- * or at 0x?? if there are both PTS and DTS's.
- * The seed value used with the unscrambling key is the 5 bytes at 0x54-0x58.
- * The scrabled part of a sector begins at 0x80.
- *****************************************************************************/
-
-/* Statistics */
-static int i_tries = 0, i_success = 0;
-
-/*****************************************************************************
- * CrackTitleKey: try to crack title key from the contents of a VOB.
- *****************************************************************************
- * This function is called by _dvdcss_titlekey to find a title key, if we've
- * chosen to crack title key instead of decrypting it with the disc key.
- * The DVD should have been opened and be in an authenticated state.
- * i_pos is the starting sector, i_len is the maximum number of sectors to read
- *****************************************************************************/
-static int CrackTitleKey( dvdcss_t dvdcss, int i_pos, int i_len,
- dvd_key_t p_titlekey )
-{
- uint8_t p_buf[ DVDCSS_BLOCK_SIZE ];
- const uint8_t p_packstart[4] = { 0x00, 0x00, 0x01, 0xba };
- int i_reads = 0;
- int i_encrypted = 0;
- int b_stop_scanning = 0;
- int b_read_error = 0;
- int i_ret;
-
- print_debug( dvdcss, "cracking title key at block %i", i_pos );
-
- i_tries = 0;
- i_success = 0;
-
- do
- {
- i_ret = dvdcss->pf_seek( dvdcss, i_pos );
-
- if( i_ret != i_pos )
- {
- print_error( dvdcss, "seek failed" );
- }
-
- i_ret = dvdcss_read( dvdcss, p_buf, 1, DVDCSS_NOFLAGS );
-
- /* Either we are at the end of the physical device or the auth
- * have failed / were not done and we got a read error. */
- if( i_ret <= 0 )
- {
- if( i_ret == 0 )
- {
- print_debug( dvdcss, "read returned 0 (end of device?)" );
- }
- else if( !b_read_error )
- {
- print_debug( dvdcss, "read error at block %i, resorting to "
- "secret arcanes to recover", i_pos );
-
- /* Reset the drive before trying to continue */
- _dvdcss_close( dvdcss );
- _dvdcss_open( dvdcss );
-
- b_read_error = 1;
- continue;
- }
- break;
- }
-
- /* Stop when we find a non MPEG stream block.
- * (We must have reached the end of the stream).
- * For now, allow all blocks that begin with a start code. */
- if( memcmp( p_buf, p_packstart, 3 ) )
- {
- print_debug( dvdcss, "non MPEG block found at block %i "
- "(end of title)", i_pos );
- break;
- }
-
- if( p_buf[0x0d] & 0x07 )
- print_debug( dvdcss, "stuffing in pack header" );
-
- /* PES_scrambling_control does not exist in a system_header,
- * a padding_stream or a private_stream2 (and others?). */
- if( p_buf[0x14] & 0x30 && ! ( p_buf[0x11] == 0xbb
- || p_buf[0x11] == 0xbe
- || p_buf[0x11] == 0xbf ) )
- {
- i_encrypted++;
-
- if( AttackPattern(p_buf, i_reads, p_titlekey) > 0 )
- {
- b_stop_scanning = 1;
- }
-#if 0
- if( AttackPadding(p_buf, i_reads, p_titlekey) > 0 )
- {
- b_stop_scanning = 1;
- }
-#endif
- }
-
- i_pos++;
- i_len--;
- i_reads++;
-
- /* Emit a progress indication now and then. */
- if( !( i_reads & 0xfff ) )
- {
- print_debug( dvdcss, "at block %i, still cracking...", i_pos );
- }
-
- /* Stop after 2000 blocks if we haven't seen any encrypted blocks. */
- if( i_reads >= 2000 && i_encrypted == 0 ) break;
-
- } while( !b_stop_scanning && i_len > 0);
-
- if( !b_stop_scanning )
- {
- print_debug( dvdcss, "end of title reached" );
- }
-
- /* Print some statistics. */
- print_debug( dvdcss, "successful attempts %d/%d, scrambled blocks %d/%d",
- i_success, i_tries, i_encrypted, i_reads );
-
- if( i_success > 0 /* b_stop_scanning */ )
- {
- print_debug( dvdcss, "vts key initialized" );
- return 1;
- }
-
- if( i_encrypted == 0 && i_reads > 0 )
- {
- memset( p_titlekey, 0, KEY_SIZE );
- print_debug( dvdcss, "no scrambled sectors found" );
- return 0;
- }
-
- memset( p_titlekey, 0, KEY_SIZE );
- return -1;
-}
-
-
-/******************************************************************************
- * The original Ethan Hawke (DeCSSPlus) attack (modified).
- ******************************************************************************
- * Tries to find a repeating pattern just before the encrypted part starts.
- * Then it guesses that the plain text for first encrypted bytes are
- * a contiuation of that pattern.
- *****************************************************************************/
-static int AttackPattern( uint8_t const p_sec[ DVDCSS_BLOCK_SIZE ],
- int i_pos, uint8_t *p_key )
-{
- unsigned int i_best_plen = 0;
- unsigned int i_best_p = 0;
- unsigned int i, j;
-
- /* For all cycle length from 2 to 48 */
- for( i = 2 ; i < 0x30 ; i++ )
- {
- /* Find the number of bytes that repeats in cycles. */
- for( j = i + 1;
- j < 0x80 && ( p_sec[0x7F - (j%i)] == p_sec[0x7F - j] );
- j++ )
- {
- /* We have found j repeating bytes with a cycle length i. */
- if( j > i_best_plen )
- {
- i_best_plen = j;
- i_best_p = i;
- }
- }
- }
-
- /* We need at most 10 plain text bytes?, so a make sure that we
- * have at least 20 repeated bytes and that they have cycled at
- * least one time. */
- if( ( i_best_plen > 3 ) && ( i_best_plen / i_best_p >= 2) )
- {
- int res;
-
- i_tries++;
- memset( p_key, 0, KEY_SIZE );
- res = RecoverTitleKey( 0, &p_sec[0x80],
- &p_sec[ 0x80 - (i_best_plen / i_best_p) * i_best_p ],
- &p_sec[0x54] /* key_seed */, p_key );
- i_success += ( res >= 0 );
-#if 0
- if( res >= 0 )
- {
- fprintf( stderr, "key is %02x:%02x:%02x:%02x:%02x ",
- p_key[0], p_key[1], p_key[2], p_key[3], p_key[4] );
- fprintf( stderr, "at block %5d pattern len %3d period %3d %s\n",
- i_pos, i_best_plen, i_best_p, (res>=0?"y":"n") );
- }
-#endif
- return ( res >= 0 );
- }
-
- return 0;
-}
-
-
-#if 0
-/******************************************************************************
- * Encrypted Padding_stream attack.
- ******************************************************************************
- * DVD specifies that there must only be one type of data in every sector.
- * Every sector is one pack and so must obviously be 2048 bytes long.
- * For the last pice of video data before a VOBU boundary there might not
- * be exactly the right amount of data to fill a sector. Then one has to
- * pad the pack to 2048 bytes. For just a few bytes this is done in the
- * header but for any large amount you insert a PES packet from the
- * Padding stream. This looks like 0x00 00 01 be xx xx ff ff ...
- * where xx xx is the length of the padding stream.
- *****************************************************************************/
-static int AttackPadding( uint8_t const p_sec[ DVDCSS_BLOCK_SIZE ],
- int i_pos, uint8_t *p_key )
-{
- unsigned int i_pes_length;
- /*static int i_tries = 0, i_success = 0;*/
-
- i_pes_length = (p_sec[0x12]<<8) | p_sec[0x13];
-
- /* Coverd by the test below but usfull for debuging. */
- if( i_pes_length == DVDCSS_BLOCK_SIZE - 0x14 ) return 0;
-
- /* There must be room for at least 4? bytes of padding stream,
- * and it must be encrypted.
- * sector size - pack/pes header - padding startcode - padding length */
- if( ( DVDCSS_BLOCK_SIZE - 0x14 - 4 - 2 - i_pes_length < 4 ) ||
- ( p_sec[0x14 + i_pes_length + 0] == 0x00 &&
- p_sec[0x14 + i_pes_length + 1] == 0x00 &&
- p_sec[0x14 + i_pes_length + 2] == 0x01 ) )
- {
- fprintf( stderr, "plain %d %02x:%02x:%02x:%02x (type %02x sub %02x)\n",
- DVDCSS_BLOCK_SIZE - 0x14 - 4 - 2 - i_pes_length,
- p_sec[0x14 + i_pes_length + 0],
- p_sec[0x14 + i_pes_length + 1],
- p_sec[0x14 + i_pes_length + 2],
- p_sec[0x14 + i_pes_length + 3],
- p_sec[0x11], p_sec[0x17 + p_sec[0x16]]);
- return 0;
- }
-
- /* If we are here we know that there is a where in the pack a
- encrypted PES header is (startcode + length). It's never more
- than two packets in the pack, so we 'know' the length. The
- plaintext at offset (0x14 + i_pes_length) will then be
- 00 00 01 e0/bd/be xx xx, in the case of be the following bytes
- are also known. */
-
- /* An encrypted SPU PES packet with another encrypted PES packet following.
- Normaly if the following was a padding stream that would be in plain
- text. So it will be another SPU PES packet. */
- if( p_sec[0x11] == 0xbd &&
- p_sec[0x17 + p_sec[0x16]] >= 0x20 &&
- p_sec[0x17 + p_sec[0x16]] <= 0x3f )
- {
- i_tries++;
- }
-
- /* A Video PES packet with another encrypted PES packet following.
- * No reason execpt for time stamps to break the data into two packets.
- * So it's likely that the following PES packet is a padding stream. */
- if( p_sec[0x11] == 0xe0 )
- {
- i_tries++;
- }
-
- if( 1 )
- {
- /*fprintf( stderr, "key is %02x:%02x:%02x:%02x:%02x ",
- p_key[0], p_key[1], p_key[2], p_key[3], p_key[4] );*/
- fprintf( stderr, "at block %5d padding len %4d "
- "type %02x sub %02x\n", i_pos, i_pes_length,
- p_sec[0x11], p_sec[0x17 + p_sec[0x16]]);
- }
-
- return 0;
-}
-#endif
diff --git a/libdvdcss/css.h b/libdvdcss/css.h
deleted file mode 100644
index 0838f26c45..0000000000
--- a/libdvdcss/css.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*****************************************************************************
- * 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 libdvdcss; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *****************************************************************************/
-
-#ifndef DVDCSS_CSS_H
-#define DVDCSS_CSS_H
-
-#include "dvdcss/dvdcss.h"
-
-#define KEY_SIZE 5
-
-typedef uint8_t 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
- *****************************************************************************/
-void _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 ( uint8_t *, uint8_t * );
-
-#endif /* DVDCSS_CSS_H */
diff --git a/libdvdcss/csstables.h b/libdvdcss/csstables.h
deleted file mode 100644
index 84c3ebf85c..0000000000
--- a/libdvdcss/csstables.h
+++ /dev/null
@@ -1,395 +0,0 @@
-/*****************************************************************************
- * 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 libdvdcss; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *****************************************************************************/
-
-#ifndef DVDCSS_CSSTABLES_H
-#define DVDCSS_CSSTABLES_H
-
-static uint8_t 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 uint8_t 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 uint8_t 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 uint8_t 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 uint8_t 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 uint8_t 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 uint8_t 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 uint8_t 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 uint8_t 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
-};
-
-#endif /* DVDCSS_CSSTABLES_H */
diff --git a/libdvdcss/device.c b/libdvdcss/device.c
deleted file mode 100644
index 98507f4ea5..0000000000
--- a/libdvdcss/device.c
+++ /dev/null
@@ -1,1090 +0,0 @@
-/*****************************************************************************
- * device.h: DVD device access
- *****************************************************************************
- * Copyright (C) 1998-2006 VideoLAN
- * $Id$
- *
- * Authors: Stéphane Borel <stef@via.ecp.fr>
- * Sam Hocevar <sam@zoy.org>
- * Håkan Hjort <d95hjort@dtek.chalmers.se>
- *
- * This library 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 library 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 library; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#ifdef HAVE_ERRNO_H
-# include <errno.h>
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifdef HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-#include <fcntl.h>
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#ifdef HAVE_LIMITS_H
-# include <limits.h>
-#endif
-
-#if defined( WIN32 ) && !defined( SYS_CYGWIN )
-# include <io.h> /* read() */
-#else
-# include <sys/uio.h> /* struct iovec */
-#endif
-
-#ifdef DARWIN_DVD_IOCTL
-# include <paths.h>
-# include <CoreFoundation/CoreFoundation.h>
-# include <IOKit/IOKitLib.h>
-# include <IOKit/IOBSD.h>
-# include <IOKit/storage/IOMedia.h>
-# include <IOKit/storage/IOCDMedia.h>
-# include <IOKit/storage/IODVDMedia.h>
-#endif
-
-#ifdef SYS_OS2
-# define INCL_DOS
-# define INCL_DOSDEVIOCTL
-# include <os2.h>
-# include <io.h> /* setmode() */
-# include <fcntl.h> /* O_BINARY */
-#endif
-
-#include "dvdcss/dvdcss.h"
-
-#include "common.h"
-#include "css.h"
-#include "libdvdcss.h"
-#include "ioctl.h"
-#include "device.h"
-
-/*****************************************************************************
- * Device reading prototypes
- *****************************************************************************/
-static int libc_open ( dvdcss_t, char const * );
-static int libc_seek ( dvdcss_t, int );
-static int libc_read ( dvdcss_t, void *, int );
-static int libc_readv ( dvdcss_t, struct iovec *, int );
-
-#ifdef WIN32
-static int win2k_open ( dvdcss_t, char const * );
-static int aspi_open ( dvdcss_t, char const * );
-static int win2k_seek ( dvdcss_t, int );
-static int aspi_seek ( dvdcss_t, int );
-static int win2k_read ( dvdcss_t, void *, int );
-static int aspi_read ( dvdcss_t, void *, int );
-static int win_readv ( dvdcss_t, struct iovec *, int );
-
-static int aspi_read_internal ( int, void *, int );
-#elif defined( SYS_OS2 )
-static int os2_open ( dvdcss_t, char const * );
-/* just use macros for libc */
-# define os2_seek libc_seek
-# define os2_read libc_read
-# define os2_readv libc_readv
-#endif
-
-int _dvdcss_use_ioctls( dvdcss_t dvdcss )
-{
-#if defined( WIN32 )
- if( dvdcss->b_file )
- {
- return 0;
- }
-
- /* FIXME: implement this for Windows */
- if( WIN2K )
- {
- return 1;
- }
- else
- {
- return 1;
- }
-#elif defined( SYS_OS2 )
- ULONG ulMode;
-
- if( DosQueryFHState( dvdcss->i_fd, &ulMode ) != 0 )
- return 1; /* What to do? Be conservative and try to use the ioctls */
-
- if( ulMode & OPEN_FLAGS_DASD )
- return 1;
-
- return 0;
-#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
-}
-
-void _dvdcss_check ( dvdcss_t dvdcss )
-{
-#if defined( WIN32 )
- DWORD drives;
- int i;
-#elif defined( DARWIN_DVD_IOCTL )
- io_object_t next_media;
- mach_port_t master_port;
- kern_return_t kern_result;
- io_iterator_t media_iterator;
- CFMutableDictionaryRef classes_to_match;
-#elif defined( SYS_OS2 )
-#pragma pack( 1 )
- struct
- {
- BYTE bCmdInfo;
- BYTE bDrive;
- } param;
-
- struct
- {
- BYTE abEBPB[31];
- USHORT usCylinders;
- BYTE bDevType;
- USHORT usDevAttr;
- } data;
-#pragma pack()
-
- ULONG ulParamLen;
- ULONG ulDataLen;
- ULONG rc;
-
- int i;
-#else
- char *ppsz_devices[] = { "/dev/dvd", "/dev/cdrom", "/dev/hdc", NULL };
- int i, i_fd;
-#endif
-
- /* If the device name is non-null, return */
- if( dvdcss->psz_device[0] )
- {
- return;
- }
-
-#if defined( WIN32 )
- drives = GetLogicalDrives();
-
- for( i = 0; drives; i++ )
- {
- char psz_device[5];
- DWORD cur = 1 << i;
- UINT i_ret;
-
- if( (drives & cur) == 0 )
- {
- continue;
- }
- drives &= ~cur;
-
- sprintf( psz_device, "%c:\\", 'A' + i );
- i_ret = GetDriveType( psz_device );
- if( i_ret != DRIVE_CDROM )
- {
- continue;
- }
-
- /* Remove trailing backslash */
- psz_device[2] = '\0';
-
- /* FIXME: we want to differenciate between CD and DVD drives
- * using DeviceIoControl() */
- print_debug( dvdcss, "defaulting to drive `%s'", psz_device );
- free( dvdcss->psz_device );
- dvdcss->psz_device = strdup( psz_device );
- return;
- }
-#elif defined( DARWIN_DVD_IOCTL )
-
- kern_result = IOMasterPort( MACH_PORT_NULL, &master_port );
- if( kern_result != KERN_SUCCESS )
- {
- return;
- }
-
- classes_to_match = IOServiceMatching( kIODVDMediaClass );
- if( classes_to_match == NULL )
- {
- return;
- }
-
- CFDictionarySetValue( classes_to_match, CFSTR( kIOMediaEjectableKey ),
- kCFBooleanTrue );
-
- kern_result = IOServiceGetMatchingServices( master_port, classes_to_match,
- &media_iterator );
- if( kern_result != KERN_SUCCESS )
- {
- return;
- }
-
- next_media = IOIteratorNext( media_iterator );
- for( ; ; )
- {
- char psz_buf[0x32];
- size_t i_pathlen;
- CFTypeRef psz_path;
-
- next_media = IOIteratorNext( media_iterator );
- if( next_media == 0 )
- {
- break;
- }
-
- psz_path = IORegistryEntryCreateCFProperty( next_media,
- CFSTR( kIOBSDNameKey ),
- kCFAllocatorDefault,
- 0 );
- if( psz_path == NULL )
- {
- IOObjectRelease( next_media );
- continue;
- }
-
- snprintf( psz_buf, sizeof(psz_buf), "%s%c", _PATH_DEV, 'r' );
- i_pathlen = strlen( psz_buf );
-
- if( CFStringGetCString( psz_path,
- (char*)&psz_buf + i_pathlen,
- sizeof(psz_buf) - i_pathlen,
- kCFStringEncodingASCII ) )
- {
- print_debug( dvdcss, "defaulting to drive `%s'", psz_buf );
- CFRelease( psz_path );
- IOObjectRelease( next_media );
- IOObjectRelease( media_iterator );
- free( dvdcss->psz_device );
- dvdcss->psz_device = strdup( psz_buf );
- return;
- }
-
- CFRelease( psz_path );
-
- IOObjectRelease( next_media );
- }
-
- IOObjectRelease( media_iterator );
-#elif defined( SYS_OS2 )
- for( i = 0; i < 26; i++ )
- {
- param.bCmdInfo = 0;
- param.bDrive = i;
-
- rc = DosDevIOCtl( ( HFILE )-1, IOCTL_DISK, DSK_GETDEVICEPARAMS,
- &param, sizeof( param ), &ulParamLen,
- &data, sizeof( data ), &ulDataLen );
-
- if( rc == 0 )
- {
- /* Check for removable and for cylinders */
- if( ( data.usDevAttr & 1 ) == 0 && data.usCylinders == 0xFFFF )
- {
- char psz_dvd[] = "A:";
-
- psz_dvd[0] += i;
-
- print_debug( dvdcss, "defaulting to drive `%s'", psz_dvd );
- free( dvdcss->psz_device );
- dvdcss->psz_device = strdup( psz_dvd );
- return;
- }
- }
- }
-#else
- for( i = 0; ppsz_devices[i]; i++ )
- {
- i_fd = open( ppsz_devices[i], 0 );
- if( i_fd != -1 )
- {
- print_debug( dvdcss, "defaulting to drive `%s'", ppsz_devices[i] );
- close( i_fd );
- free( dvdcss->psz_device );
- dvdcss->psz_device = strdup( ppsz_devices[i] );
- return;
- }
- }
-#endif
-
- print_error( dvdcss, "could not find a suitable default drive" );
-}
-
-int _dvdcss_open ( dvdcss_t dvdcss )
-{
- char const *psz_device = dvdcss->psz_device;
-
- print_debug( dvdcss, "opening target `%s'", psz_device );
-
-#if defined( WIN32 )
- dvdcss->b_file = 1;
- /* If device is "X:" or "X:\", we are not actually opening a file. */
- if (psz_device[0] && psz_device[1] == ':' &&
- (!psz_device[2] || (psz_device[2] == '\\' && !psz_device[3])))
- dvdcss->b_file = 0;
-
- /* Initialize readv temporary buffer */
- dvdcss->p_readv_buffer = NULL;
- dvdcss->i_readv_buf_size = 0;
-
- if( !dvdcss->b_file && WIN2K )
- {
- print_debug( dvdcss, "using Win2K API for access" );
- dvdcss->pf_seek = win2k_seek;
- dvdcss->pf_read = win2k_read;
- dvdcss->pf_readv = win_readv;
- return win2k_open( dvdcss, psz_device );
- }
- else if( !dvdcss->b_file )
- {
- print_debug( dvdcss, "using ASPI for access" );
- dvdcss->pf_seek = aspi_seek;
- dvdcss->pf_read = aspi_read;
- dvdcss->pf_readv = win_readv;
- return aspi_open( dvdcss, psz_device );
- }
- else
-#elif defined( SYS_OS2 )
- /* If device is "X:" or "X:\", we are not actually opening a file. */
- if( psz_device[0] && psz_device[1] == ':' &&
- ( !psz_device[2] || ( psz_device[2] == '\\' && !psz_device[3] ) ) )
- {
- print_debug( dvdcss, "using OS2 API for access" );
- dvdcss->pf_seek = os2_seek;
- dvdcss->pf_read = os2_read;
- dvdcss->pf_readv = os2_readv;
- return os2_open( dvdcss, psz_device );
- }
- else
-#endif
- {
- print_debug( dvdcss, "using libc for access" );
- dvdcss->pf_seek = libc_seek;
- dvdcss->pf_read = libc_read;
- dvdcss->pf_readv = libc_readv;
- return libc_open( dvdcss, psz_device );
- }
-}
-
-#if !defined(WIN32) && !defined(SYS_OS2)
-int _dvdcss_raw_open ( dvdcss_t dvdcss, char const *psz_device )
-{
- dvdcss->i_raw_fd = open( psz_device, 0 );
-
- if( dvdcss->i_raw_fd == -1 )
- {
- print_debug( dvdcss, "cannot open %s (%s)",
- psz_device, strerror(errno) );
- print_error( dvdcss, "failed to open raw device, but 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( dvdcss->b_file )
- {
- close( dvdcss->i_fd );
- }
- else if( WIN2K )
- {
- CloseHandle( (HANDLE) dvdcss->i_fd );
- }
- else /* ASPI */
- {
- struct w32_aspidev *fd = (struct w32_aspidev *) dvdcss->i_fd;
-
- /* Unload aspi and free w32_aspidev structure */
- FreeLibrary( (HMODULE) fd->hASPI );
- free( (void*) 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;
- }
-
- return 0;
-#else
- close( dvdcss->i_fd );
-
-#ifndef SYS_OS2
- if( dvdcss->i_raw_fd >= 0 )
- {
- close( dvdcss->i_raw_fd );
- dvdcss->i_raw_fd = -1;
- }
-#endif
-
- return 0;
-#endif
-}
-
-/* Following functions are local */
-
-/*****************************************************************************
- * Open commands.
- *****************************************************************************/
-static int libc_open ( dvdcss_t dvdcss, char const *psz_device )
-{
-#if !defined( WIN32 ) && !defined( SYS_OS2 )
- dvdcss->i_fd = dvdcss->i_read_fd = open( psz_device, 0 );
-#else
- dvdcss->i_fd = dvdcss->i_read_fd = open( psz_device, O_BINARY );
-#endif
-
- if( dvdcss->i_fd == -1 )
- {
- print_debug( dvdcss, "cannot open %s (%s)",
- psz_device, strerror(errno) );
- print_error( dvdcss, "failed to open device" );
- return -1;
- }
-
- dvdcss->i_pos = 0;
-
- return 0;
-}
-
-#if defined( WIN32 )
-static int win2k_open ( dvdcss_t dvdcss, char const *psz_device )
-{
- char psz_dvd[7];
- _snprintf( psz_dvd, 7, "\\\\.\\%c:", psz_device[0] );
-
- /* To work around an M$ bug in IOCTL_DVD_READ_STRUCTURE, we need read
- * _and_ write access to the device (so we can make SCSI Pass Through
- * Requests). Unfortunately this is only allowed if you have
- * administrator priviledges so we allow for a fallback method with
- * only read access to the device (in this case ioctl_ReadCopyright()
- * won't send back the right result).
- * (See Microsoft Q241374: Read and Write Access Required for SCSI
- * Pass Through Requests) */
- dvdcss->i_fd = (int)
- 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 )
- dvdcss->i_fd = (int)
- CreateFile( psz_dvd, GENERIC_READ, FILE_SHARE_READ,
- NULL, OPEN_EXISTING,
- FILE_FLAG_RANDOM_ACCESS, NULL );
-
- if( (HANDLE) dvdcss->i_fd == INVALID_HANDLE_VALUE )
- {
- print_error( dvdcss, "failed opening device" );
- return -1;
- }
-
- dvdcss->i_pos = 0;
-
- return 0;
-}
-
-static int aspi_open( dvdcss_t dvdcss, char const * psz_device )
-{
- HMODULE hASPI;
- DWORD dwSupportInfo;
- struct w32_aspidev *fd;
- int i, j, i_hostadapters;
- GETASPI32SUPPORTINFO lpGetSupport;
- SENDASPI32COMMAND lpSendCommand;
- char c_drive = psz_device[0];
-
- /* load aspi and init w32_aspidev structure */
- hASPI = LoadLibrary( "wnaspi32.dll" );
- if( hASPI == NULL )
- {
- print_error( dvdcss, "unable to load wnaspi32.dll" );
- return -1;
- }
-
- lpGetSupport = (GETASPI32SUPPORTINFO) GetProcAddress( hASPI, "GetASPI32SupportInfo" );
- lpSendCommand = (SENDASPI32COMMAND) GetProcAddress( hASPI, "SendASPI32Command" );
-
- if(lpGetSupport == NULL || lpSendCommand == NULL )
- {
- print_error( dvdcss, "unable to get aspi function pointers" );
- FreeLibrary( hASPI );
- return -1;
- }
-
- dwSupportInfo = lpGetSupport();
-
- if( HIBYTE( LOWORD ( dwSupportInfo ) ) == SS_NO_ADAPTERS )
- {
- print_error( dvdcss, "no ASPI adapters found" );
- FreeLibrary( hASPI );
- return -1;
- }
-
- if( HIBYTE( LOWORD ( dwSupportInfo ) ) != SS_COMP )
- {
- print_error( dvdcss, "unable to initalize aspi layer" );
- FreeLibrary( hASPI );
- return -1;
- }
-
- i_hostadapters = LOBYTE( LOWORD( dwSupportInfo ) );
- if( i_hostadapters == 0 )
- {
- print_error( dvdcss, "no ASPI adapters ready" );
- FreeLibrary( hASPI );
- return -1;
- }
-
- fd = malloc( sizeof( struct w32_aspidev ) );
- if( fd == NULL )
- {
- print_error( dvdcss, "not enough memory" );
- 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) )
- {
- /* Make sure this is a cdrom device */
- struct SRB_GDEVBlock srbGDEVBlock;
-
- memset( &srbGDEVBlock, 0, sizeof(struct SRB_GDEVBlock) );
- srbGDEVBlock.SRB_Cmd = SC_GET_DEV_TYPE;
- srbGDEVBlock.SRB_HaId = i;
- srbGDEVBlock.SRB_Target = j;
-
- lpSendCommand( (void*) &srbGDEVBlock );
-
- if( ( srbGDEVBlock.SRB_Status == SS_COMP ) &&
- ( srbGDEVBlock.SRB_DeviceType == DTYPE_CDROM ) )
- {
- fd->i_sid = MAKEWORD( i, j );
- dvdcss->i_fd = (int) fd;
- dvdcss->i_pos = 0;
- return 0;
- }
- else
- {
- free( (void*) fd );
- FreeLibrary( hASPI );
- print_error( dvdcss,"this is not a cdrom drive" );
- return -1;
- }
- }
- }
- }
-
- free( (void*) fd );
- FreeLibrary( hASPI );
- print_error( dvdcss, "unable to get haid and target (aspi)" );
- return -1;
-}
-#endif
-
-#ifdef SYS_OS2
-static int os2_open ( dvdcss_t dvdcss, char const *psz_device )
-{
- char psz_dvd[] = "X:";
- HFILE hfile;
- ULONG ulAction;
- ULONG rc;
-
- psz_dvd[0] = psz_device[0];
-
- rc = DosOpenL( ( PSZ )psz_dvd, &hfile, &ulAction, 0, FILE_NORMAL,
- OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW,
- OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE | OPEN_FLAGS_DASD,
- NULL );
-
- if( rc )
- {
- print_error( dvdcss, "failed to open device" );
- return -1;
- }
-
- setmode( hfile, O_BINARY );
-
- dvdcss->i_fd = dvdcss->i_read_fd = hfile;
-
- dvdcss->i_pos = 0;
-
- return 0;
-}
-#endif
-
-/*****************************************************************************
- * Seek commands.
- *****************************************************************************/
-static int libc_seek( dvdcss_t dvdcss, int i_blocks )
-{
- off_t i_seek;
-
- if( dvdcss->i_pos == i_blocks )
- {
- /* We are already in position */
- return i_blocks;
- }
-
- i_seek = (off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE;
- i_seek = lseek( dvdcss->i_read_fd, i_seek, SEEK_SET );
-
- if( i_seek < 0 )
- {
- print_error( dvdcss, "seek error" );
- dvdcss->i_pos = -1;
- return i_seek;
- }
-
- dvdcss->i_pos = i_seek / DVDCSS_BLOCK_SIZE;
-
- return dvdcss->i_pos;
-}
-
-#if defined( WIN32 )
-static int win2k_seek( dvdcss_t dvdcss, int i_blocks )
-{
- LARGE_INTEGER li_seek;
-
-#ifndef INVALID_SET_FILE_POINTER
-# define INVALID_SET_FILE_POINTER ((DWORD)-1)
-#endif
-
- if( dvdcss->i_pos == i_blocks )
- {
- /* We are already in position */
- return i_blocks;
- }
-
- li_seek.QuadPart = (LONGLONG)i_blocks * DVDCSS_BLOCK_SIZE;
-
- li_seek.LowPart = SetFilePointer( (HANDLE) dvdcss->i_fd,
- li_seek.LowPart,
- &li_seek.HighPart, FILE_BEGIN );
- if( (li_seek.LowPart == INVALID_SET_FILE_POINTER)
- && GetLastError() != NO_ERROR)
- {
- dvdcss->i_pos = -1;
- return -1;
- }
-
- dvdcss->i_pos = li_seek.QuadPart / DVDCSS_BLOCK_SIZE;
-
- return dvdcss->i_pos;
-}
-
-static int aspi_seek( dvdcss_t dvdcss, int i_blocks )
-{
- int i_old_blocks;
- char sz_buf[ DVDCSS_BLOCK_SIZE ];
- struct w32_aspidev *fd = (struct w32_aspidev *) dvdcss->i_fd;
-
- if( dvdcss->i_pos == i_blocks )
- {
- /* We are already in position */
- return i_blocks;
- }
-
- i_old_blocks = fd->i_blocks;
- fd->i_blocks = i_blocks;
-
- if( aspi_read_internal( dvdcss->i_fd, sz_buf, 1 ) == -1 )
- {
- fd->i_blocks = i_old_blocks;
- dvdcss->i_pos = -1;
- return -1;
- }
-
- (fd->i_blocks)--;
-
- dvdcss->i_pos = fd->i_blocks;
-
- return dvdcss->i_pos;
-}
-#endif
-
-/*****************************************************************************
- * Read commands.
- *****************************************************************************/
-static int libc_read ( dvdcss_t dvdcss, void *p_buffer, int i_blocks )
-{
- off_t i_size, i_ret;
-
- i_size = (off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE;
- i_ret = read( dvdcss->i_read_fd, p_buffer, i_size );
-
- if( i_ret < 0 )
- {
- print_error( dvdcss, "read error" );
- dvdcss->i_pos = -1;
- return i_ret;
- }
-
- /* Handle partial reads */
- if( i_ret != i_size )
- {
- int i_seek;
-
- dvdcss->i_pos = -1;
- i_seek = libc_seek( dvdcss, i_ret / DVDCSS_BLOCK_SIZE );
- if( i_seek < 0 )
- {
- return i_seek;
- }
-
- /* We have to return now so that i_pos isn't clobbered */
- return i_ret / DVDCSS_BLOCK_SIZE;
- }
-
- dvdcss->i_pos += i_ret / DVDCSS_BLOCK_SIZE;
- return i_ret / DVDCSS_BLOCK_SIZE;
-}
-
-#if defined( WIN32 )
-static int win2k_read ( dvdcss_t dvdcss, void *p_buffer, int i_blocks )
-{
- int i_bytes;
-
- if( !ReadFile( (HANDLE) dvdcss->i_fd, p_buffer,
- i_blocks * DVDCSS_BLOCK_SIZE,
- (LPDWORD)&i_bytes, NULL ) )
- {
- dvdcss->i_pos = -1;
- return -1;
- }
-
- dvdcss->i_pos += i_bytes / DVDCSS_BLOCK_SIZE;
- return i_bytes / DVDCSS_BLOCK_SIZE;
-}
-
-static int aspi_read ( dvdcss_t dvdcss, void *p_buffer, int i_blocks )
-{
- int i_read = aspi_read_internal( dvdcss->i_fd, p_buffer, i_blocks );
-
- if( i_read < 0 )
- {
- dvdcss->i_pos = -1;
- return i_read;
- }
-
- dvdcss->i_pos += i_read;
- return i_read;
-}
-#endif
-
-/*****************************************************************************
- * Readv commands.
- *****************************************************************************/
-static int libc_readv ( dvdcss_t dvdcss, struct iovec *p_iovec, int i_blocks )
-{
-#if defined( WIN32 )
- int i_index, i_len, i_total = 0;
- unsigned char *p_base;
- int i_bytes;
-
- for( i_index = i_blocks;
- i_index;
- i_index--, p_iovec++ )
- {
- i_len = p_iovec->iov_len;
- p_base = p_iovec->iov_base;
-
- if( i_len <= 0 )
- {
- continue;
- }
-
- i_bytes = read( dvdcss->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 */
- dvdcss->i_pos = -1;
- 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 a partial read. */
- int i_seek;
-
- dvdcss->i_pos = -1;
- i_seek = libc_seek( dvdcss, i_total / DVDCSS_BLOCK_SIZE );
- if( i_seek < 0 )
- {
- return i_seek;
- }
-
- /* We have to return now so that i_pos isn't clobbered */
- return i_total / DVDCSS_BLOCK_SIZE;
- }
- }
-
- dvdcss->i_pos += i_total / DVDCSS_BLOCK_SIZE;
- return i_total / DVDCSS_BLOCK_SIZE;
-#else
- int i_read = readv( dvdcss->i_read_fd, p_iovec, i_blocks );
-
- if( i_read < 0 )
- {
- dvdcss->i_pos = -1;
- return i_read;
- }
-
- dvdcss->i_pos += i_read / DVDCSS_BLOCK_SIZE;
- return i_read / DVDCSS_BLOCK_SIZE;
-#endif
-}
-
-#if defined( WIN32 )
-/*****************************************************************************
- * win_readv: vectored read using ReadFile for Win2K and ASPI for win9x
- *****************************************************************************/
-static int win_readv ( dvdcss_t dvdcss, struct iovec *p_iovec, int i_blocks )
-{
- int i_index;
- int i_blocks_read, i_blocks_total = 0;
-
- /* 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 )
- {
- print_error( dvdcss, " failed (readv)" );
- dvdcss->i_pos = -1;
- return -1;
- }
- }
-
- for( i_index = i_blocks; 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)dvdcss->i_fd, dvdcss->p_readv_buffer,
- i_blocks_total * DVDCSS_BLOCK_SIZE, &i_bytes, NULL ) )
- {
- /* The read failed... too bad.
- * As in the posix spec the file postition is left
- * unspecified after a failure */
- dvdcss->i_pos = -1;
- return -1;
- }
- i_blocks_read = i_bytes / DVDCSS_BLOCK_SIZE;
- }
- else /* Win9x */
- {
- i_blocks_read = aspi_read_internal( dvdcss->i_fd,
- dvdcss->p_readv_buffer,
- i_blocks_total );
- if( i_blocks_read < 0 )
- {
- /* See above */
- dvdcss->i_pos = -1;
- return -1;
- }
- }
-
- /* We just have to copy the content of the temp buffer into the iovecs */
- for( i_index = 0, i_blocks_total = i_blocks_read;
- i_blocks_total > 0;
- i_index++ )
- {
- memcpy( p_iovec[i_index].iov_base,
- dvdcss->p_readv_buffer + (i_blocks_read - 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 );
- }
-
- dvdcss->i_pos += i_blocks_read;
- return i_blocks_read;
-}
-
-static int aspi_read_internal( 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 (aspi_read_internal is called recursively)
- * We need to check the status of the read on return */
- if( aspi_read_internal( i_fd,
- (uint8_t*) 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
-
diff --git a/libdvdcss/device.h b/libdvdcss/device.h
deleted file mode 100644
index ddaa18eb98..0000000000
--- a/libdvdcss/device.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*****************************************************************************
- * device.h: DVD device access
- *****************************************************************************
- * Copyright (C) 1998-2002 VideoLAN
- * $Id$
- *
- * Authors: Stéphane Borel <stef@via.ecp.fr>
- * Sam 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 libdvdcss; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *****************************************************************************/
-
-#ifndef DVDCSS_DEVICE_H
-#define DVDCSS_DEVICE_H
-
-/*****************************************************************************
- * iovec structure: vectored data entry
- *****************************************************************************/
-#if defined( WIN32 ) && !defined( SYS_CYGWIN )
-# include <io.h> /* read() */
-#else
-# include <sys/types.h>
-# include <sys/uio.h> /* struct iovec */
-#endif
-
-#include "dvdcss/dvdcss.h"
-
-#if defined( WIN32 ) && !defined( SYS_CYGWIN )
-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 );
-void _dvdcss_check ( dvdcss_t );
-int _dvdcss_open ( dvdcss_t );
-int _dvdcss_close ( dvdcss_t );
-
-/*****************************************************************************
- * Device reading prototypes, raw-device specific
- *****************************************************************************/
-#if !defined(WIN32) && !defined(SYS_OS2)
-int _dvdcss_raw_open ( dvdcss_t, char const * );
-#endif
-
-#endif /* DVDCSS_DEVICE_H */
diff --git a/libdvdcss/dvdcss/dvdcss.h b/libdvdcss/dvdcss/dvdcss.h
deleted file mode 100644
index 8ef98f6e77..0000000000
--- a/libdvdcss/dvdcss/dvdcss.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * \file dvdcss.h
- * \author Stéphane Borel <stef@via.ecp.fr>
- * \author Sam 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-2008 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 libdvdcss; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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)
-
-
-#if defined(LIBDVDCSS_EXPORTS)
-#define LIBDVDCSS_EXPORT __declspec(dllexport) extern
-#elif defined(LIBDVDCSS_IMPORTS)
-#define LIBDVDCSS_EXPORT __declspec(dllimport) extern
-#else
-#define LIBDVDCSS_EXPORT extern
-#endif
-
-/*
- * Our version number. The variable name contains the interface version.
- */
-LIBDVDCSS_EXPORT char * dvdcss_interface_2;
-
-
-/*
- * Exported prototypes.
- */
-LIBDVDCSS_EXPORT dvdcss_t dvdcss_open ( char *psz_target );
-LIBDVDCSS_EXPORT int dvdcss_close ( dvdcss_t );
-LIBDVDCSS_EXPORT int dvdcss_seek ( dvdcss_t,
- int i_blocks,
- int i_flags );
-LIBDVDCSS_EXPORT int dvdcss_read ( dvdcss_t,
- void *p_buffer,
- int i_blocks,
- int i_flags );
-LIBDVDCSS_EXPORT int dvdcss_readv ( dvdcss_t,
- void *p_iovec,
- int i_blocks,
- int i_flags );
-LIBDVDCSS_EXPORT char * dvdcss_error ( dvdcss_t );
-
-LIBDVDCSS_EXPORT int dvdcss_is_scrambled ( 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 */
diff --git a/libdvdcss/error.c b/libdvdcss/error.c
deleted file mode 100644
index 794f4841ac..0000000000
--- a/libdvdcss/error.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*****************************************************************************
- * error.c: error management functions
- *****************************************************************************
- * Copyright (C) 1998-2002 VideoLAN
- * $Id$
- *
- * Author: Sam Hocevar <sam@zoy.org>
- *
- * This library 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 library 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 library; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *****************************************************************************/
-
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#ifdef HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-
-#ifdef HAVE_LIMITS_H
-# include <limits.h>
-#endif
-
-#include "dvdcss/dvdcss.h"
-
-#include "common.h"
-#include "css.h"
-#include "libdvdcss.h"
-
-/*****************************************************************************
- * Error messages
- *****************************************************************************/
-void _print_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
- *****************************************************************************/
-#if 0
-void _print_debug( dvdcss_t dvdcss, char *psz_string )
-{
- if( dvdcss->b_debug )
- {
- fprintf( stderr, "libdvdcss debug: %s\n", psz_string );
- }
-}
-#endif
-
diff --git a/libdvdcss/ioctl.c b/libdvdcss/ioctl.c
deleted file mode 100644
index 5c7e615327..0000000000
--- a/libdvdcss/ioctl.c
+++ /dev/null
@@ -1,2123 +0,0 @@
-/*****************************************************************************
- * ioctl.c: DVD ioctl replacement function
- *****************************************************************************
- * Copyright (C) 1999-2001 VideoLAN
- * $Id$
- *
- * Authors: Markus Kuespert <ltlBeBoy@beosmail.com>
- * Sam Hocevar <sam@zoy.org>
- * Jon Lech Johansen <jon-vl@nanocrew.net>
- * Håkan Hjort <d95hjort@dtek.chalmers.se>
- * Eugenio Jarosiewicz <ej0@cise.ufl.edu>
- * David Siebörger <drs-videolan@rucus.ru.ac.za>
- * Alex Strelnikov <lelik@os2.ru>
- * Gildas Bazin <gbazin@netcourrier.com>
- *
- * This library 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 library 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 library; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#include "config.h"
-
-#include <stdio.h>
-
-#include <string.h> /* memcpy(), memset() */
-#include <sys/types.h>
-
-#if defined( WIN32 )
-# include <windows.h>
-# include <winioctl.h>
-#elif defined ( SYS_OS2 )
-# define INCL_DOSFILEMGR
-# define INCL_DOSDEVICES
-# define INCL_DOSDEVIOCTL
-# define INCL_DOSERRORS
-# include <os2.h>
-# include <sys/ioctl.h>
-#else
-# include <netinet/in.h>
-# include <sys/ioctl.h>
-#endif
-
-#ifdef DVD_STRUCT_IN_SYS_CDIO_H
-# include <sys/cdio.h>
-#endif
-#ifdef DVD_STRUCT_IN_SYS_DVDIO_H
-# include <sys/dvdio.h>
-#endif
-#ifdef DVD_STRUCT_IN_LINUX_CDROM_H
-# include <linux/cdrom.h>
-#endif
-#ifdef DVD_STRUCT_IN_DVD_H
-# include <dvd.h>
-#endif
-#ifdef DVD_STRUCT_IN_BSDI_DVDIOCTL_DVD_H
-# include "bsdi_dvd.h"
-#endif
-#ifdef SYS_BEOS
-# include <malloc.h>
-# include <scsi.h>
-#endif
-#ifdef HPUX_SCTL_IO
-# include <sys/scsi.h>
-#endif
-#ifdef SOLARIS_USCSI
-# include <dlfcn.h>
-# include <unistd.h>
-# include <stropts.h>
-# include <sys/scsi/scsi_types.h>
-# include <sys/scsi/impl/uscsi.h>
-#endif
-#ifdef DARWIN_DVD_IOCTL
-# include <IOKit/storage/IODVDMediaBSDClient.h>
-#endif
-#ifdef __QNXNTO__
-# include <sys/mman.h>
-# include <sys/dcmd_cam.h>
-#endif
-
-#include "common.h"
-
-#include "ioctl.h"
-
-/*****************************************************************************
- * Local prototypes, BeOS specific
- *****************************************************************************/
-#if defined( SYS_BEOS )
-static void BeInitRDC ( raw_device_command *, int );
-#endif
-
-/*****************************************************************************
- * Local prototypes, HP-UX specific
- *****************************************************************************/
-#if defined( HPUX_SCTL_IO )
-static void HPUXInitSCTL ( struct sctl_io *sctl_io, int i_type );
-#endif
-
-/*****************************************************************************
- * Local prototypes, Solaris specific
- *****************************************************************************/
-#if defined( SOLARIS_USCSI )
-static void SolarisInitUSCSI( struct uscsi_cmd *p_sc, int i_type );
-static int SolarisSendUSCSI( int fd, struct uscsi_cmd *p_sc );
-#endif
-
-/*****************************************************************************
- * Local prototypes, win32 (aspi) specific
- *****************************************************************************/
-#if defined( WIN32 )
-static void WinInitSPTD ( SCSI_PASS_THROUGH_DIRECT *, int );
-static void WinInitSSC ( struct SRB_ExecSCSICmd *, int );
-static int WinSendSSC ( int, struct SRB_ExecSCSICmd * );
-#endif
-
-/*****************************************************************************
- * Local prototypes, QNX specific
- *****************************************************************************/
-#if defined( __QNXNTO__ )
-static void QNXInitCPT ( CAM_PASS_THRU *, int );
-#endif
-
-/*****************************************************************************
- * Local prototypes, OS2 specific
- *****************************************************************************/
-#if defined( SYS_OS2 )
-static void OS2InitSDC( struct OS2_ExecSCSICmd *, int );
-#endif
-
-/*****************************************************************************
- * ioctl_ReadCopyright: check whether the disc is encrypted or not
- *****************************************************************************/
-int ioctl_ReadCopyright( int i_fd, int i_layer, int *pi_copyright )
-{
- int i_ret;
-
-#if defined( HAVE_LINUX_DVD_STRUCT )
- dvd_struct dvd;
-
- memset( &dvd, 0, sizeof( dvd ) );
- dvd.type = DVD_STRUCT_COPYRIGHT;
- dvd.copyright.layer_num = i_layer;
-
- i_ret = ioctl( i_fd, DVD_READ_STRUCT, &dvd );
-
- *pi_copyright = dvd.copyright.cpst;
-
-#elif defined( HAVE_BSD_DVD_STRUCT )
- struct dvd_struct dvd;
-
- memset( &dvd, 0, sizeof( dvd ) );
- dvd.format = DVD_STRUCT_COPYRIGHT;
- dvd.layer_num = i_layer;
-
- i_ret = ioctl( i_fd, DVDIOCREADSTRUCTURE, &dvd );
-
- *pi_copyright = dvd.cpst;
-
-#elif defined( SYS_BEOS )
- INIT_RDC( GPCMD_READ_DVD_STRUCTURE, 8 );
-
- rdc.command[ 6 ] = i_layer;
- rdc.command[ 7 ] = DVD_STRUCT_COPYRIGHT;
-
- i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
-
- *pi_copyright = p_buffer[ 4 ];
-
-#elif defined( HPUX_SCTL_IO )
- INIT_SCTL_IO( GPCMD_READ_DVD_STRUCTURE, 8 );
-
- sctl_io.cdb[ 6 ] = i_layer;
- sctl_io.cdb[ 7 ] = DVD_STRUCT_COPYRIGHT;
-
- i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
-
- *pi_copyright = p_buffer[ 4 ];
-
-#elif defined( SOLARIS_USCSI )
- INIT_USCSI( GPCMD_READ_DVD_STRUCTURE, 8 );
-
- rs_cdb.cdb_opaque[ 6 ] = i_layer;
- rs_cdb.cdb_opaque[ 7 ] = DVD_STRUCT_COPYRIGHT;
-
- i_ret = SolarisSendUSCSI(i_fd, &sc);
-
- if( i_ret < 0 || sc.uscsi_status ) {
- i_ret = -1;
- }
-
- *pi_copyright = p_buffer[ 4 ];
- /* s->copyright.rmi = p_buffer[ 5 ]; */
-
-#elif defined( DARWIN_DVD_IOCTL )
- INIT_DVDIOCTL( dk_dvd_read_structure_t, DVDCopyrightInfo,
- kDVDStructureFormatCopyrightInfo );
-
- dvd.layer = i_layer;
-
- i_ret = ioctl( i_fd, DKIOCDVDREADSTRUCTURE, &dvd );
-
- *pi_copyright = dvdbs.copyrightProtectionSystemType;
-
-#elif defined( WIN32 )
- if( WIN2K ) /* NT/2k/XP */
- {
- INIT_SPTD( GPCMD_READ_DVD_STRUCTURE, 8 );
-
- /* When using IOCTL_DVD_READ_STRUCTURE and
- DVD_COPYRIGHT_DESCRIPTOR, CopyrightProtectionType
- seems to be always 6 ???
- To work around this MS bug we try to send a raw scsi command
- instead (if we've got enough privileges to do so). */
-
- sptd.Cdb[ 6 ] = i_layer;
- sptd.Cdb[ 7 ] = DVD_STRUCT_COPYRIGHT;
-
- i_ret = SEND_SPTD( i_fd, &sptd, &tmp );
-
- if( i_ret == 0 )
- {
- *pi_copyright = p_buffer[ 4 ];
- }
- }
- else
- {
- INIT_SSC( GPCMD_READ_DVD_STRUCTURE, 8 );
-
- ssc.CDBByte[ 6 ] = i_layer;
- ssc.CDBByte[ 7 ] = DVD_STRUCT_COPYRIGHT;
-
- i_ret = WinSendSSC( i_fd, &ssc );
-
- *pi_copyright = p_buffer[ 4 ];
- }
-
-#elif defined( __QNXNTO__ )
-
- INIT_CPT( GPCMD_READ_DVD_STRUCTURE, 8 );
-
- p_cpt->cam_cdb[ 6 ] = i_layer;
- p_cpt->cam_cdb[ 7 ] = DVD_STRUCT_COPYRIGHT;
-
- i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
-
- *pi_copyright = p_buffer[4];
-
-#elif defined( SYS_OS2 )
- INIT_SSC( GPCMD_READ_DVD_STRUCTURE, 8 );
-
- sdc.command[ 6 ] = i_layer;
- sdc.command[ 7 ] = DVD_STRUCT_COPYRIGHT;
-
- i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
- &sdc, sizeof(sdc), &ulParamLen,
- p_buffer, sizeof(p_buffer), &ulDataLen);
-
- *pi_copyright = p_buffer[ 4 ];
-
-#else
-# error "DVD ioctls are unavailable on this system"
-
-#endif
- return i_ret;
-}
-
-/*****************************************************************************
- * ioctl_ReadDiscKey: get the disc key
- *****************************************************************************/
-int ioctl_ReadDiscKey( int i_fd, int *pi_agid, uint8_t *p_key )
-{
- int i_ret;
-
-#if defined( HAVE_LINUX_DVD_STRUCT )
- dvd_struct dvd;
-
- memset( &dvd, 0, sizeof( dvd ) );
- dvd.type = DVD_STRUCT_DISCKEY;
- dvd.disckey.agid = *pi_agid;
- memset( dvd.disckey.value, 0, DVD_DISCKEY_SIZE );
-
- i_ret = ioctl( i_fd, DVD_READ_STRUCT, &dvd );
-
- if( i_ret < 0 )
- {
- return i_ret;
- }
-
- memcpy( p_key, dvd.disckey.value, DVD_DISCKEY_SIZE );
-
-#elif defined( HAVE_BSD_DVD_STRUCT )
- struct dvd_struct dvd;
-
- memset( &dvd, 0, sizeof( dvd ) );
- dvd.format = DVD_STRUCT_DISCKEY;
- dvd.agid = *pi_agid;
- memset( dvd.data, 0, DVD_DISCKEY_SIZE );
-
- i_ret = ioctl( i_fd, DVDIOCREADSTRUCTURE, &dvd );
-
- if( i_ret < 0 )
- {
- return i_ret;
- }
-
- memcpy( p_key, dvd.data, DVD_DISCKEY_SIZE );
-
-#elif defined( SYS_BEOS )
- INIT_RDC( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
-
- rdc.command[ 7 ] = DVD_STRUCT_DISCKEY;
- rdc.command[ 10 ] = *pi_agid << 6;
-
- i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
-
- if( i_ret < 0 )
- {
- return i_ret;
- }
-
- memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );
-
-#elif defined( HPUX_SCTL_IO )
- INIT_SCTL_IO( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
-
- sctl_io.cdb[ 7 ] = DVD_STRUCT_DISCKEY;
- sctl_io.cdb[ 10 ] = *pi_agid << 6;
-
- i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
-
- if( i_ret < 0 )
- {
- return i_ret;
- }
-
- memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );
-
-#elif defined( SOLARIS_USCSI )
- INIT_USCSI( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
-
- rs_cdb.cdb_opaque[ 7 ] = DVD_STRUCT_DISCKEY;
- rs_cdb.cdb_opaque[ 10 ] = *pi_agid << 6;
-
- i_ret = SolarisSendUSCSI( i_fd, &sc );
-
- if( i_ret < 0 || sc.uscsi_status )
- {
- i_ret = -1;
- return i_ret;
- }
-
- memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );
-
-#elif defined( DARWIN_DVD_IOCTL )
- INIT_DVDIOCTL( dk_dvd_read_structure_t, DVDDiscKeyInfo,
- kDVDStructureFormatDiscKeyInfo );
-
- dvd.grantID = *pi_agid;
-
- i_ret = ioctl( i_fd, DKIOCDVDREADSTRUCTURE, &dvd );
-
- memcpy( p_key, dvdbs.discKeyStructures, DVD_DISCKEY_SIZE );
-
-#elif defined( WIN32 )
- if( WIN2K ) /* NT/2k/XP */
- {
- DWORD tmp;
- uint8_t buffer[DVD_DISK_KEY_LENGTH];
- PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
-
- memset( &buffer, 0, sizeof( buffer ) );
-
- key->KeyLength = DVD_DISK_KEY_LENGTH;
- key->SessionId = *pi_agid;
- key->KeyType = DvdDiskKey;
- key->KeyFlags = 0;
-
- i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
- key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
-
- if( i_ret < 0 )
- {
- return i_ret;
- }
-
- memcpy( p_key, key->KeyData, DVD_DISCKEY_SIZE );
- }
- else
- {
- INIT_SSC( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
-
- ssc.CDBByte[ 7 ] = DVD_STRUCT_DISCKEY;
- ssc.CDBByte[ 10 ] = *pi_agid << 6;
-
- i_ret = WinSendSSC( i_fd, &ssc );
-
- if( i_ret < 0 )
- {
- return i_ret;
- }
-
- memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );
- }
-
-#elif defined( __QNXNTO__ )
-
- INIT_CPT( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
-
- p_cpt->cam_cdb[ 7 ] = DVD_STRUCT_DISCKEY;
- p_cpt->cam_cdb[ 10 ] = *pi_agid << 6;
-
- i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
-
- memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );
-
-#elif defined ( SYS_OS2 )
- INIT_SSC( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
-
- sdc.command[ 7 ] = DVD_STRUCT_DISCKEY;
- sdc.command[ 10 ] = *pi_agid << 6;
-
- i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
- &sdc, sizeof(sdc), &ulParamLen,
- p_buffer, sizeof(p_buffer), &ulDataLen);
-
- if( i_ret < 0 )
- {
- return i_ret;
- }
-
- memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );
-
-#else
-# error "DVD ioctls are unavailable on this system"
-
-#endif
- return i_ret;
-}
-
-/*****************************************************************************
- * ioctl_ReadTitleKey: get the title key
- *****************************************************************************/
-int ioctl_ReadTitleKey( int i_fd, int *pi_agid, int i_pos, uint8_t *p_key )
-{
- int i_ret;
-
-#if defined( HAVE_LINUX_DVD_STRUCT )
- dvd_authinfo auth_info;
-
- memset( &auth_info, 0, sizeof( auth_info ) );
- auth_info.type = DVD_LU_SEND_TITLE_KEY;
- auth_info.lstk.agid = *pi_agid;
- auth_info.lstk.lba = i_pos;
-
- i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
-
- memcpy( p_key, auth_info.lstk.title_key, DVD_KEY_SIZE );
-
-#elif defined( HAVE_BSD_DVD_STRUCT )
- struct dvd_authinfo auth_info;
-
- memset( &auth_info, 0, sizeof( auth_info ) );
- auth_info.format = DVD_REPORT_TITLE_KEY;
- auth_info.agid = *pi_agid;
- auth_info.lba = i_pos;
-
- i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );
-
- memcpy( p_key, auth_info.keychal, DVD_KEY_SIZE );
-
-#elif defined( SYS_BEOS )
- INIT_RDC( GPCMD_REPORT_KEY, 12 );
-
- rdc.command[ 2 ] = ( i_pos >> 24 ) & 0xff;
- rdc.command[ 3 ] = ( i_pos >> 16 ) & 0xff;
- rdc.command[ 4 ] = ( i_pos >> 8 ) & 0xff;
- rdc.command[ 5 ] = ( i_pos ) & 0xff;
- rdc.command[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);
-
- i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
-
- memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
-
-#elif defined( HPUX_SCTL_IO )
- INIT_SCTL_IO( GPCMD_REPORT_KEY, 12 );
-
- sctl_io.cdb[ 2 ] = ( i_pos >> 24 ) & 0xff;
- sctl_io.cdb[ 3 ] = ( i_pos >> 16 ) & 0xff;
- sctl_io.cdb[ 4 ] = ( i_pos >> 8 ) & 0xff;
- sctl_io.cdb[ 5 ] = ( i_pos ) & 0xff;
- sctl_io.cdb[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);
-
- i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
-
- memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
-
-#elif defined( SOLARIS_USCSI )
- INIT_USCSI( GPCMD_REPORT_KEY, 12 );
-
- rs_cdb.cdb_opaque[ 2 ] = ( i_pos >> 24 ) & 0xff;
- rs_cdb.cdb_opaque[ 3 ] = ( i_pos >> 16 ) & 0xff;
- rs_cdb.cdb_opaque[ 4 ] = ( i_pos >> 8 ) & 0xff;
- rs_cdb.cdb_opaque[ 5 ] = ( i_pos ) & 0xff;
- rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);
-
- i_ret = SolarisSendUSCSI( i_fd, &sc );
-
- if( i_ret < 0 || sc.uscsi_status )
- {
- i_ret = -1;
- }
-
- /* Do we want to return the cp_sec flag perhaps? */
- /* a->lstk.cpm = (buf[ 4 ] >> 7) & 1; */
- /* a->lstk.cp_sec = (buf[ 4 ] >> 6) & 1; */
- /* a->lstk.cgms = (buf[ 4 ] >> 4) & 3; */
-
- memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
-
-#elif defined( DARWIN_DVD_IOCTL )
- INIT_DVDIOCTL( dk_dvd_report_key_t, DVDTitleKeyInfo,
- kDVDKeyFormatTitleKey );
-
- dvd.address = i_pos;
- dvd.grantID = *pi_agid;
- dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
-
- i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
-
- memcpy( p_key, dvdbs.titleKeyValue, DVD_KEY_SIZE );
-
-#elif defined( WIN32 )
- if( WIN2K ) /* NT/2k/XP */
- {
- DWORD tmp;
- uint8_t buffer[DVD_TITLE_KEY_LENGTH];
- PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
-
- memset( &buffer, 0, sizeof( buffer ) );
-
- key->KeyLength = DVD_TITLE_KEY_LENGTH;
- key->SessionId = *pi_agid;
- key->KeyType = DvdTitleKey;
- key->KeyFlags = 0;
- key->Parameters.TitleOffset.QuadPart = (LONGLONG) i_pos *
- 2048 /*DVDCSS_BLOCK_SIZE*/;
-
- i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
- key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
-
- memcpy( p_key, key->KeyData, DVD_KEY_SIZE );
- }
- else
- {
- INIT_SSC( GPCMD_REPORT_KEY, 12 );
-
- ssc.CDBByte[ 2 ] = ( i_pos >> 24 ) & 0xff;
- ssc.CDBByte[ 3 ] = ( i_pos >> 16 ) & 0xff;
- ssc.CDBByte[ 4 ] = ( i_pos >> 8 ) & 0xff;
- ssc.CDBByte[ 5 ] = ( i_pos ) & 0xff;
- ssc.CDBByte[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);
-
- i_ret = WinSendSSC( i_fd, &ssc );
-
- memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
- }
-
-#elif defined( __QNXNTO__ )
-
- INIT_CPT( GPCMD_REPORT_KEY, 12 );
-
- p_cpt->cam_cdb[ 2 ] = ( i_pos >> 24 ) & 0xff;
- p_cpt->cam_cdb[ 3 ] = ( i_pos >> 16 ) & 0xff;
- p_cpt->cam_cdb[ 4 ] = ( i_pos >> 8 ) & 0xff;
- p_cpt->cam_cdb[ 5 ] = ( i_pos ) & 0xff;
- p_cpt->cam_cdb[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);
-
- i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
-
- memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
-
-#elif defined( SYS_OS2 )
- INIT_SSC( GPCMD_REPORT_KEY, 12 );
-
- sdc.command[ 2 ] = ( i_pos >> 24 ) & 0xff;
- sdc.command[ 3 ] = ( i_pos >> 16 ) & 0xff;
- sdc.command[ 4 ] = ( i_pos >> 8 ) & 0xff;
- sdc.command[ 5 ] = ( i_pos ) & 0xff;
- sdc.command[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);
-
- i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
- &sdc, sizeof(sdc), &ulParamLen,
- p_buffer, sizeof(p_buffer), &ulDataLen);
-
- memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
-
-#else
-# error "DVD ioctls are unavailable on this system"
-
-#endif
-
- return i_ret;
-}
-
-
-/*****************************************************************************
- * ioctl_ReportAgid: get AGID from the drive
- *****************************************************************************/
-int ioctl_ReportAgid( int i_fd, int *pi_agid )
-{
- int i_ret;
-
-#if defined( HAVE_LINUX_DVD_STRUCT )
- dvd_authinfo auth_info;
-
- memset( &auth_info, 0, sizeof( auth_info ) );
- auth_info.type = DVD_LU_SEND_AGID;
- auth_info.lsa.agid = *pi_agid;
-
- i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
-
- *pi_agid = auth_info.lsa.agid;
-
-#elif defined( HAVE_BSD_DVD_STRUCT )
- struct dvd_authinfo auth_info;
-
- memset( &auth_info, 0, sizeof( auth_info ) );
- auth_info.format = DVD_REPORT_AGID;
- auth_info.agid = *pi_agid;
-
- i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );
-
- *pi_agid = auth_info.agid;
-
-#elif defined( SYS_BEOS )
- INIT_RDC( GPCMD_REPORT_KEY, 8 );
-
- rdc.command[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
-
- i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
-
- *pi_agid = p_buffer[ 7 ] >> 6;
-
-#elif defined( HPUX_SCTL_IO )
- INIT_SCTL_IO( GPCMD_REPORT_KEY, 8 );
-
- sctl_io.cdb[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
-
- i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
-
- *pi_agid = p_buffer[ 7 ] >> 6;
-
-#elif defined( SOLARIS_USCSI )
- INIT_USCSI( GPCMD_REPORT_KEY, 8 );
-
- rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
-
- i_ret = SolarisSendUSCSI( i_fd, &sc );
-
- if( i_ret < 0 || sc.uscsi_status )
- {
- i_ret = -1;
- }
-
- *pi_agid = p_buffer[ 7 ] >> 6;
-
-#elif defined( DARWIN_DVD_IOCTL )
- INIT_DVDIOCTL( dk_dvd_report_key_t, DVDAuthenticationGrantIDInfo,
- kDVDKeyFormatAGID_CSS );
-
- dvd.grantID = *pi_agid;
- dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
-
- i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
-
- *pi_agid = dvdbs.grantID;
-
-#elif defined( WIN32 )
- if( WIN2K ) /* NT/2k/XP */
- {
- ULONG id;
- DWORD tmp;
-
- i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_START_SESSION,
- &tmp, 4, &id, sizeof( id ), &tmp, NULL ) ? 0 : -1;
-
- *pi_agid = id;
- }
- else
- {
- INIT_SSC( GPCMD_REPORT_KEY, 8 );
-
- ssc.CDBByte[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
-
- i_ret = WinSendSSC( i_fd, &ssc );
-
- *pi_agid = p_buffer[ 7 ] >> 6;
- }
-
-#elif defined( __QNXNTO__ )
-
- INIT_CPT( GPCMD_REPORT_KEY, 8 );
-
- p_cpt->cam_cdb[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
-
- i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
-
- *pi_agid = p_buffer[ 7 ] >> 6;
-
-#elif defined( SYS_OS2 )
- INIT_SSC( GPCMD_REPORT_KEY, 8 );
-
- sdc.command[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
-
- i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
- &sdc, sizeof(sdc), &ulParamLen,
- p_buffer, sizeof(p_buffer), &ulDataLen);
-
- *pi_agid = p_buffer[ 7 ] >> 6;
-
-#else
-# error "DVD ioctls are unavailable on this system"
-
-#endif
- return i_ret;
-}
-
-/*****************************************************************************
- * ioctl_ReportChallenge: get challenge from the drive
- *****************************************************************************/
-int ioctl_ReportChallenge( int i_fd, int *pi_agid, uint8_t *p_challenge )
-{
- int i_ret;
-
-#if defined( HAVE_LINUX_DVD_STRUCT )
- dvd_authinfo auth_info;
-
- memset( &auth_info, 0, sizeof( auth_info ) );
- auth_info.type = DVD_LU_SEND_CHALLENGE;
- auth_info.lsc.agid = *pi_agid;
-
- i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
-
- memcpy( p_challenge, auth_info.lsc.chal, DVD_CHALLENGE_SIZE );
-
-#elif defined( HAVE_BSD_DVD_STRUCT )
- struct dvd_authinfo auth_info;
-
- memset( &auth_info, 0, sizeof( auth_info ) );
- auth_info.format = DVD_REPORT_CHALLENGE;
- auth_info.agid = *pi_agid;
-
- i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );
-
- memcpy( p_challenge, auth_info.keychal, DVD_CHALLENGE_SIZE );
-
-#elif defined( SYS_BEOS )
- INIT_RDC( GPCMD_REPORT_KEY, 16 );
-
- rdc.command[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
-
- i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
-
- memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
-
-#elif defined( HPUX_SCTL_IO )
- INIT_SCTL_IO( GPCMD_REPORT_KEY, 16 );
-
- sctl_io.cdb[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
-
- i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
-
- memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
-
-#elif defined( SOLARIS_USCSI )
- INIT_USCSI( GPCMD_REPORT_KEY, 16 );
-
- rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
-
- i_ret = SolarisSendUSCSI( i_fd, &sc );
-
- if( i_ret < 0 || sc.uscsi_status )
- {
- i_ret = -1;
- }
-
- memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
-
-#elif defined( DARWIN_DVD_IOCTL )
- INIT_DVDIOCTL( dk_dvd_report_key_t, DVDChallengeKeyInfo,
- kDVDKeyFormatChallengeKey );
-
- dvd.grantID = *pi_agid;
-
- i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
-
- memcpy( p_challenge, dvdbs.challengeKeyValue, DVD_CHALLENGE_SIZE );
-
-#elif defined( WIN32 )
- if( WIN2K ) /* NT/2k/XP */
- {
- DWORD tmp;
- uint8_t buffer[DVD_CHALLENGE_KEY_LENGTH];
- PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
-
- memset( &buffer, 0, sizeof( buffer ) );
-
- key->KeyLength = DVD_CHALLENGE_KEY_LENGTH;
- key->SessionId = *pi_agid;
- key->KeyType = DvdChallengeKey;
- key->KeyFlags = 0;
-
- i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
- key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
-
- if( i_ret < 0 )
- {
- return i_ret;
- }
-
- memcpy( p_challenge, key->KeyData, DVD_CHALLENGE_SIZE );
- }
- else
- {
- INIT_SSC( GPCMD_REPORT_KEY, 16 );
-
- ssc.CDBByte[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
-
- i_ret = WinSendSSC( i_fd, &ssc );
-
- memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
- }
-
-#elif defined( __QNXNTO__ )
-
- INIT_CPT( GPCMD_REPORT_KEY, 16 );
-
- p_cpt->cam_cdb[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
-
- i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
-
- memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
-
-#elif defined( SYS_OS2 )
- INIT_SSC( GPCMD_REPORT_KEY, 16 );
-
- sdc.command[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
-
- i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
- &sdc, sizeof(sdc), &ulParamLen,
- p_buffer, sizeof(p_buffer), &ulDataLen);
-
- memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
-
-#else
-# error "DVD ioctls are unavailable on this system"
-
-#endif
- return i_ret;
-}
-
-/*****************************************************************************
- * ioctl_ReportASF: get ASF from the drive
- *****************************************************************************/
-int ioctl_ReportASF( int i_fd, int *pi_remove_me, int *pi_asf )
-{
- int i_ret;
-
-#if defined( HAVE_LINUX_DVD_STRUCT )
- dvd_authinfo auth_info;
-
- memset( &auth_info, 0, sizeof( auth_info ) );
- auth_info.type = DVD_LU_SEND_ASF;
- auth_info.lsasf.asf = *pi_asf;
-
- i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
-
- *pi_asf = auth_info.lsasf.asf;
-
-#elif defined( HAVE_BSD_DVD_STRUCT )
- struct dvd_authinfo auth_info;
-
- memset( &auth_info, 0, sizeof( auth_info ) );
- auth_info.format = DVD_REPORT_ASF;
- auth_info.asf = *pi_asf;
-
- i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );
-
- *pi_asf = auth_info.asf;
-
-#elif defined( SYS_BEOS )
- INIT_RDC( GPCMD_REPORT_KEY, 8 );
-
- rdc.command[ 10 ] = DVD_REPORT_ASF;
-
- i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
-
- *pi_asf = p_buffer[ 7 ] & 1;
-
-#elif defined( HPUX_SCTL_IO )
- INIT_SCTL_IO( GPCMD_REPORT_KEY, 8 );
-
- sctl_io.cdb[ 10 ] = DVD_REPORT_ASF;
-
- i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
-
- *pi_asf = p_buffer[ 7 ] & 1;
-
-#elif defined( SOLARIS_USCSI )
- INIT_USCSI( GPCMD_REPORT_KEY, 8 );
-
- rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_ASF;
-
- i_ret = SolarisSendUSCSI( i_fd, &sc );
-
- if( i_ret < 0 || sc.uscsi_status )
- {
- i_ret = -1;
- }
-
- *pi_asf = p_buffer[ 7 ] & 1;
-
-#elif defined( DARWIN_DVD_IOCTL )
- INIT_DVDIOCTL( dk_dvd_report_key_t, DVDAuthenticationSuccessFlagInfo,
- kDVDKeyFormatASF );
-
- i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
-
- *pi_asf = dvdbs.successFlag;
-
-#elif defined( WIN32 )
- if( WIN2K ) /* NT/2k/XP */
- {
- DWORD tmp;
- uint8_t buffer[DVD_ASF_LENGTH];
- PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
-
- memset( &buffer, 0, sizeof( buffer ) );
-
- key->KeyLength = DVD_ASF_LENGTH;
- key->KeyType = DvdAsf;
- key->KeyFlags = 0;
-
- ((PDVD_ASF)key->KeyData)->SuccessFlag = *pi_asf;
-
- i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
- key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
-
- if( i_ret < 0 )
- {
- return i_ret;
- }
-
- *pi_asf = ((PDVD_ASF)key->KeyData)->SuccessFlag;
- }
- else
- {
- INIT_SSC( GPCMD_REPORT_KEY, 8 );
-
- ssc.CDBByte[ 10 ] = DVD_REPORT_ASF;
-
- i_ret = WinSendSSC( i_fd, &ssc );
-
- *pi_asf = p_buffer[ 7 ] & 1;
- }
-
-#elif defined( __QNXNTO__ )
-
- INIT_CPT( GPCMD_REPORT_KEY, 8 );
-
- p_cpt->cam_cdb[ 10 ] = DVD_REPORT_ASF;
-
- i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
-
- *pi_asf = p_buffer[ 7 ] & 1;
-
-#elif defined( SYS_OS2 )
- INIT_SSC( GPCMD_REPORT_KEY, 8 );
-
- sdc.command[ 10 ] = DVD_REPORT_ASF;
-
- i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
- &sdc, sizeof(sdc), &ulParamLen,
- p_buffer, sizeof(p_buffer), &ulDataLen);
-
- *pi_asf = p_buffer[ 7 ] & 1;
-
-#else
-# error "DVD ioctls are unavailable on this system"
-
-#endif
- return i_ret;
-}
-
-/*****************************************************************************
- * ioctl_ReportKey1: get the first key from the drive
- *****************************************************************************/
-int ioctl_ReportKey1( int i_fd, int *pi_agid, uint8_t *p_key )
-{
- int i_ret;
-
-#if defined( HAVE_LINUX_DVD_STRUCT )
- dvd_authinfo auth_info;
-
- memset( &auth_info, 0, sizeof( auth_info ) );
- auth_info.type = DVD_LU_SEND_KEY1;
- auth_info.lsk.agid = *pi_agid;
-
- i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
-
- memcpy( p_key, auth_info.lsk.key, DVD_KEY_SIZE );
-
-#elif defined( HAVE_BSD_DVD_STRUCT )
- struct dvd_authinfo auth_info;
-
- memset( &auth_info, 0, sizeof( auth_info ) );
- auth_info.format = DVD_REPORT_KEY1;
- auth_info.agid = *pi_agid;
-
- i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );
-
- memcpy( p_key, auth_info.keychal, DVD_KEY_SIZE );
-
-#elif defined( SYS_BEOS )
- INIT_RDC( GPCMD_REPORT_KEY, 12 );
-
- rdc.command[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6);
-
- i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
-
- memcpy( p_key, p_buffer + 4, DVD_KEY_SIZE );
-
-#elif defined( HPUX_SCTL_IO )
- INIT_SCTL_IO( GPCMD_REPORT_KEY, 12 );
-
- sctl_io.cdb[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6);
-
- i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
-
- memcpy( p_key, p_buffer + 4, DVD_KEY_SIZE );
-
-#elif defined( SOLARIS_USCSI )
- INIT_USCSI( GPCMD_REPORT_KEY, 12 );
-
- rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6);
-
- i_ret = SolarisSendUSCSI( i_fd, &sc );
-
- if( i_ret < 0 || sc.uscsi_status )
- {
- i_ret = -1;
- }
-
- memcpy( p_key, p_buffer + 4, DVD_KEY_SIZE );
-
-#elif defined( DARWIN_DVD_IOCTL )
- INIT_DVDIOCTL( dk_dvd_report_key_t, DVDKey1Info,
- kDVDKeyFormatKey1 );
-
- dvd.grantID = *pi_agid;
-
- i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
-
- memcpy( p_key, dvdbs.key1Value, DVD_KEY_SIZE );
-
-#elif defined( WIN32 )
- if( WIN2K ) /* NT/2k/XP */
- {
- DWORD tmp;
- uint8_t buffer[DVD_BUS_KEY_LENGTH];
- PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
-
- memset( &buffer, 0, sizeof( buffer ) );
-
- key->KeyLength = DVD_BUS_KEY_LENGTH;
- key->SessionId = *pi_agid;
- key->KeyType = DvdBusKey1;
- key->KeyFlags = 0;
-
- i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
- key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
-
- memcpy( p_key, key->KeyData, DVD_KEY_SIZE );
- }
- else
- {
- INIT_SSC( GPCMD_REPORT_KEY, 12 );
-
- ssc.CDBByte[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6);
-
- i_ret = WinSendSSC( i_fd, &ssc );
-
- memcpy( p_key, p_buffer + 4, DVD_KEY_SIZE );
- }
-
-#elif defined( __QNXNTO__ )
-
- INIT_CPT( GPCMD_REPORT_KEY, 12 );
-
- p_cpt->cam_cdb[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6);
-
- i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
-
- memcpy( p_key, p_buffer + 4, DVD_KEY_SIZE );
-
-#elif defined( SYS_OS2 )
- INIT_SSC( GPCMD_REPORT_KEY, 12 );
-
- sdc.command[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6);
-
- i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
- &sdc, sizeof(sdc), &ulParamLen,
- p_buffer, sizeof(p_buffer), &ulDataLen);
-
- memcpy( p_key, p_buffer + 4, DVD_KEY_SIZE );
-
-#else
-# error "DVD ioctls are unavailable on this system"
-
-#endif
- return i_ret;
-}
-
-/*****************************************************************************
- * ioctl_InvalidateAgid: invalidate the current AGID
- *****************************************************************************/
-int ioctl_InvalidateAgid( int i_fd, int *pi_agid )
-{
- int i_ret;
-
-#if defined( HAVE_LINUX_DVD_STRUCT )
- dvd_authinfo auth_info;
-
- memset( &auth_info, 0, sizeof( auth_info ) );
- auth_info.type = DVD_INVALIDATE_AGID;
- auth_info.lsa.agid = *pi_agid;
-
- i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
-
-#elif defined( HAVE_BSD_DVD_STRUCT )
- struct dvd_authinfo auth_info;
-
- memset( &auth_info, 0, sizeof( auth_info ) );
- auth_info.format = DVD_INVALIDATE_AGID;
- auth_info.agid = *pi_agid;
-
- i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );
-
-#elif defined( SYS_BEOS )
- INIT_RDC( GPCMD_REPORT_KEY, 0 );
-
- rdc.command[ 10 ] = DVD_INVALIDATE_AGID | (*pi_agid << 6);
-
- i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
-
-#elif defined( HPUX_SCTL_IO )
- INIT_SCTL_IO( GPCMD_REPORT_KEY, 0 );
-
- sctl_io.cdb[ 10 ] = DVD_INVALIDATE_AGID | (*pi_agid << 6);
-
- i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
-
-#elif defined( SOLARIS_USCSI )
- INIT_USCSI( GPCMD_REPORT_KEY, 0 );
-
- rs_cdb.cdb_opaque[ 10 ] = DVD_INVALIDATE_AGID | (*pi_agid << 6);
-
- i_ret = SolarisSendUSCSI( i_fd, &sc );
-
- if( i_ret < 0 || sc.uscsi_status )
- {
- i_ret = -1;
- }
-
-#elif defined( DARWIN_DVD_IOCTL )
- INIT_DVDIOCTL( dk_dvd_send_key_t, DVDAuthenticationGrantIDInfo,
- kDVDKeyFormatAGID_Invalidate );
-
- dvd.grantID = *pi_agid;
-
- i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
-
-#elif defined( WIN32 )
- if( WIN2K ) /* NT/2k/XP */
- {
- DWORD tmp;
-
- i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_END_SESSION,
- pi_agid, sizeof( *pi_agid ), NULL, 0, &tmp, NULL ) ? 0 : -1;
- }
- else
- {
-#if defined( __MINGW32__ )
- INIT_SSC( GPCMD_REPORT_KEY, 0 );
-#else
- INIT_SSC( GPCMD_REPORT_KEY, 1 );
-
- ssc.SRB_BufLen = 0;
- ssc.CDBByte[ 8 ] = 0;
- ssc.CDBByte[ 9 ] = 0;
-#endif
-
- ssc.CDBByte[ 10 ] = DVD_INVALIDATE_AGID | (*pi_agid << 6);
-
- i_ret = WinSendSSC( i_fd, &ssc );
- }
-
-#elif defined( __QNXNTO__ )
-
- INIT_CPT( GPCMD_REPORT_KEY, 0 );
-
- p_cpt->cam_cdb[ 10 ] = DVD_INVALIDATE_AGID | (*pi_agid << 6);
-
- i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
-
-#elif defined( SYS_OS2 )
- INIT_SSC( GPCMD_REPORT_KEY, 1 );
-
- sdc.data_length = 0;
- sdc.command[ 8 ] = 0;
- sdc.command[ 9 ] = 0;
-
- sdc.command[ 10 ] = DVD_INVALIDATE_AGID | (*pi_agid << 6);
-
- i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
- &sdc, sizeof(sdc), &ulParamLen,
- NULL, 0, &ulDataLen);
-#else
-# error "DVD ioctls are unavailable on this system"
-
-#endif
- return i_ret;
-}
-
-/*****************************************************************************
- * ioctl_SendChallenge: send challenge to the drive
- *****************************************************************************/
-int ioctl_SendChallenge( int i_fd, int *pi_agid, uint8_t *p_challenge )
-{
- int i_ret;
-
-#if defined( HAVE_LINUX_DVD_STRUCT )
- dvd_authinfo auth_info;
-
- memset( &auth_info, 0, sizeof( auth_info ) );
- auth_info.type = DVD_HOST_SEND_CHALLENGE;
- auth_info.hsc.agid = *pi_agid;
-
- memcpy( auth_info.hsc.chal, p_challenge, DVD_CHALLENGE_SIZE );
-
- i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
-
-#elif defined( HAVE_BSD_DVD_STRUCT )
- struct dvd_authinfo auth_info;
-
- memset( &auth_info, 0, sizeof( auth_info ) );
- auth_info.format = DVD_SEND_CHALLENGE;
- auth_info.agid = *pi_agid;
-
- memcpy( auth_info.keychal, p_challenge, DVD_CHALLENGE_SIZE );
-
- i_ret = ioctl( i_fd, DVDIOCSENDKEY, &auth_info );
-
-#elif defined( SYS_BEOS )
- INIT_RDC( GPCMD_SEND_KEY, 16 );
-
- rdc.command[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
-
- p_buffer[ 1 ] = 0xe;
- memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
-
- i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
-
-#elif defined( HPUX_SCTL_IO )
- INIT_SCTL_IO( GPCMD_SEND_KEY, 16 );
-
- sctl_io.cdb[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
-
- p_buffer[ 1 ] = 0xe;
- memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
-
- i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
-
-#elif defined( SOLARIS_USCSI )
- INIT_USCSI( GPCMD_SEND_KEY, 16 );
-
- rs_cdb.cdb_opaque[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
-
- p_buffer[ 1 ] = 0xe;
- memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
-
- if( SolarisSendUSCSI( i_fd, &sc ) < 0 || sc.uscsi_status )
- {
- return -1;
- }
-
- i_ret = 0;
-
-#elif defined( DARWIN_DVD_IOCTL )
- INIT_DVDIOCTL( dk_dvd_send_key_t, DVDChallengeKeyInfo,
- kDVDKeyFormatChallengeKey );
-
- dvd.grantID = *pi_agid;
- dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
-
- dvdbs.dataLength[ 1 ] = 0xe;
- memcpy( dvdbs.challengeKeyValue, p_challenge, DVD_CHALLENGE_SIZE );
-
- i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
-
-#elif defined( WIN32 )
- if( WIN2K ) /* NT/2k/XP */
- {
- DWORD tmp;
- uint8_t buffer[DVD_CHALLENGE_KEY_LENGTH];
- PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
-
- memset( &buffer, 0, sizeof( buffer ) );
-
- key->KeyLength = DVD_CHALLENGE_KEY_LENGTH;
- key->SessionId = *pi_agid;
- key->KeyType = DvdChallengeKey;
- key->KeyFlags = 0;
-
- memcpy( key->KeyData, p_challenge, DVD_CHALLENGE_SIZE );
-
- i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_SEND_KEY, key,
- key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
- }
- else
- {
- INIT_SSC( GPCMD_SEND_KEY, 16 );
-
- ssc.CDBByte[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
-
- p_buffer[ 1 ] = 0xe;
- memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
-
- i_ret = WinSendSSC( i_fd, &ssc );
- }
-
-#elif defined( __QNXNTO__ )
-
- INIT_CPT( GPCMD_SEND_KEY, 16 );
-
- p_cpt->cam_cdb[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
-
- p_buffer[ 1 ] = 0xe;
- memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
-
- i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
-
-#elif defined( SYS_OS2 )
- INIT_SSC( GPCMD_SEND_KEY, 16 );
-
- sdc.command[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
-
- p_buffer[ 1 ] = 0xe;
- memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
-
- i_ret = DosDevIOCtl( i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
- &sdc, sizeof(sdc), &ulParamLen,
- p_buffer, sizeof(p_buffer), &ulDataLen );
-
-#else
-# error "DVD ioctls are unavailable on this system"
-
-#endif
- return i_ret;
-}
-
-/*****************************************************************************
- * ioctl_SendKey2: send the second key to the drive
- *****************************************************************************/
-int ioctl_SendKey2( int i_fd, int *pi_agid, uint8_t *p_key )
-{
- int i_ret;
-
-#if defined( HAVE_LINUX_DVD_STRUCT )
- dvd_authinfo auth_info;
-
- memset( &auth_info, 0, sizeof( auth_info ) );
- auth_info.type = DVD_HOST_SEND_KEY2;
- auth_info.hsk.agid = *pi_agid;
-
- memcpy( auth_info.hsk.key, p_key, DVD_KEY_SIZE );
-
- i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
-
-#elif defined( HAVE_BSD_DVD_STRUCT )
- struct dvd_authinfo auth_info;
-
- memset( &auth_info, 0, sizeof( auth_info ) );
- auth_info.format = DVD_SEND_KEY2;
- auth_info.agid = *pi_agid;
-
- memcpy( auth_info.keychal, p_key, DVD_KEY_SIZE );
-
- i_ret = ioctl( i_fd, DVDIOCSENDKEY, &auth_info );
-
-#elif defined( SYS_BEOS )
- INIT_RDC( GPCMD_SEND_KEY, 12 );
-
- rdc.command[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
-
- p_buffer[ 1 ] = 0xa;
- memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
-
- i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
-
-#elif defined( HPUX_SCTL_IO )
- INIT_SCTL_IO( GPCMD_SEND_KEY, 12 );
-
- sctl_io.cdb[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
-
- p_buffer[ 1 ] = 0xa;
- memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
-
- i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
-
-#elif defined( SOLARIS_USCSI )
- INIT_USCSI( GPCMD_SEND_KEY, 12 );
-
- rs_cdb.cdb_opaque[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
-
- p_buffer[ 1 ] = 0xa;
- memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
-
- if( SolarisSendUSCSI( i_fd, &sc ) < 0 || sc.uscsi_status )
- {
- return -1;
- }
-
- i_ret = 0;
-
-#elif defined( DARWIN_DVD_IOCTL )
- INIT_DVDIOCTL( dk_dvd_send_key_t, DVDKey2Info,
- kDVDKeyFormatKey2 );
-
- dvd.grantID = *pi_agid;
- dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
-
- dvdbs.dataLength[ 1 ] = 0xa;
- memcpy( dvdbs.key2Value, p_key, DVD_KEY_SIZE );
-
- i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
-
-#elif defined( WIN32 )
- if( WIN2K ) /* NT/2k/XP */
- {
- DWORD tmp;
- uint8_t buffer[DVD_BUS_KEY_LENGTH];
- PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
-
- memset( &buffer, 0, sizeof( buffer ) );
-
- key->KeyLength = DVD_BUS_KEY_LENGTH;
- key->SessionId = *pi_agid;
- key->KeyType = DvdBusKey2;
- key->KeyFlags = 0;
-
- memcpy( key->KeyData, p_key, DVD_KEY_SIZE );
-
- i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_SEND_KEY, key,
- key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
- }
- else
- {
- INIT_SSC( GPCMD_SEND_KEY, 12 );
-
- ssc.CDBByte[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
-
- p_buffer[ 1 ] = 0xa;
- memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
-
- i_ret = WinSendSSC( i_fd, &ssc );
- }
-
-#elif defined( __QNXNTO__ )
-
- INIT_CPT( GPCMD_SEND_KEY, 12 );
-
- p_cpt->cam_cdb[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
-
- p_buffer[ 1 ] = 0xa;
- memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
-
- i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
-
-#elif defined( SYS_OS2 )
- INIT_SSC( GPCMD_SEND_KEY, 12 );
-
- sdc.command[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
-
- p_buffer[ 1 ] = 0xa;
- memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
-
- i_ret = DosDevIOCtl( i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
- &sdc, sizeof(sdc), &ulParamLen,
- p_buffer, sizeof(p_buffer), &ulDataLen );
-
-#else
-# error "DVD ioctls are unavailable on this system"
-
-#endif
- return i_ret;
-}
-
-/*****************************************************************************
- * ioctl_ReportRPC: get RPC status for the drive
- *****************************************************************************/
-int ioctl_ReportRPC( int i_fd, int *p_type, int *p_mask, int *p_scheme )
-{
- int i_ret;
-
-#if defined( HAVE_LINUX_DVD_STRUCT ) && defined( DVD_LU_SEND_RPC_STATE )
- dvd_authinfo auth_info;
-
- memset( &auth_info, 0, sizeof( auth_info ) );
- auth_info.type = DVD_LU_SEND_RPC_STATE;
-
- i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
-
- *p_type = auth_info.lrpcs.type;
- *p_mask = auth_info.lrpcs.region_mask;
- *p_scheme = auth_info.lrpcs.rpc_scheme;
-
-#elif defined( HAVE_LINUX_DVD_STRUCT )
- /* FIXME: OpenBSD doesn't know this */
- i_ret = -1;
-
-#elif defined( HAVE_BSD_DVD_STRUCT )
- struct dvd_authinfo auth_info;
-
- memset( &auth_info, 0, sizeof( auth_info ) );
- auth_info.format = DVD_REPORT_RPC;
-
- i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );
-
- *p_type = auth_info.reg_type;
- *p_mask = auth_info.region; // ??
- *p_scheme = auth_info.rpc_scheme;
-
-#elif defined( SYS_BEOS )
- INIT_RDC( GPCMD_REPORT_KEY, 8 );
-
- rdc.command[ 10 ] = DVD_REPORT_RPC;
-
- i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
-
- *p_type = p_buffer[ 4 ] >> 6;
- *p_mask = p_buffer[ 5 ];
- *p_scheme = p_buffer[ 6 ];
-
-#elif defined( HPUX_SCTL_IO )
- INIT_SCTL_IO( GPCMD_REPORT_KEY, 8 );
-
- sctl_io.cdb[ 10 ] = DVD_REPORT_RPC;
-
- i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
-
- *p_type = p_buffer[ 4 ] >> 6;
- *p_mask = p_buffer[ 5 ];
- *p_scheme = p_buffer[ 6 ];
-
-#elif defined( SOLARIS_USCSI )
- INIT_USCSI( GPCMD_REPORT_KEY, 8 );
-
- rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_RPC;
-
- i_ret = SolarisSendUSCSI( i_fd, &sc );
-
- if( i_ret < 0 || sc.uscsi_status )
- {
- i_ret = -1;
- }
-
- *p_type = p_buffer[ 4 ] >> 6;
- *p_mask = p_buffer[ 5 ];
- *p_scheme = p_buffer[ 6 ];
-
-#elif defined( DARWIN_DVD_IOCTL )
- INIT_DVDIOCTL( dk_dvd_report_key_t, DVDRegionPlaybackControlInfo,
- kDVDKeyFormatRegionState );
-
- dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
-
- i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
-
- *p_type = dvdbs.typeCode;
- *p_mask = dvdbs.driveRegion;
- *p_scheme = dvdbs.rpcScheme;
-
-#elif defined( WIN32 )
- if( WIN2K ) /* NT/2k/XP */
- {
- DWORD tmp;
- uint8_t buffer[DVD_RPC_KEY_LENGTH];
- PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
-
- memset( &buffer, 0, sizeof( buffer ) );
-
- key->KeyLength = DVD_RPC_KEY_LENGTH;
- key->KeyType = DvdGetRpcKey;
- key->KeyFlags = 0;
-
- i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
- key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
-
- if( i_ret < 0 )
- {
- return i_ret;
- }
-
- *p_type = ((PDVD_RPC_KEY)key->KeyData)->TypeCode;
- *p_mask = ((PDVD_RPC_KEY)key->KeyData)->RegionMask;
- *p_scheme = ((PDVD_RPC_KEY)key->KeyData)->RpcScheme;
- }
- else
- {
- INIT_SSC( GPCMD_REPORT_KEY, 8 );
-
- ssc.CDBByte[ 10 ] = DVD_REPORT_RPC;
-
- i_ret = WinSendSSC( i_fd, &ssc );
-
- *p_type = p_buffer[ 4 ] >> 6;
- *p_mask = p_buffer[ 5 ];
- *p_scheme = p_buffer[ 6 ];
- }
-
-#elif defined( __QNXNTO__ )
-
- INIT_CPT( GPCMD_REPORT_KEY, 8 );
-
- p_cpt->cam_cdb[ 10 ] = DVD_REPORT_RPC;
-
- i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
-
- *p_type = p_buffer[ 4 ] >> 6;
- *p_mask = p_buffer[ 5 ];
- *p_scheme = p_buffer[ 6 ];
-
-#elif defined( SYS_OS2 )
- INIT_SSC( GPCMD_REPORT_KEY, 8 );
-
- sdc.command[ 10 ] = DVD_REPORT_RPC;
-
- i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
- &sdc, sizeof(sdc), &ulParamLen,
- p_buffer, sizeof(p_buffer), &ulDataLen);
-
- *p_type = p_buffer[ 4 ] >> 6;
- *p_mask = p_buffer[ 5 ];
- *p_scheme = p_buffer[ 6 ];
-
-#else
-# error "DVD ioctls are unavailable on this system"
-
-#endif
- return i_ret;
-}
-
-/*****************************************************************************
- * ioctl_SendRPC: set RPC status for the drive
- *****************************************************************************/
-int ioctl_SendRPC( int i_fd, int i_pdrc )
-{
- int i_ret;
-
-#if defined( HAVE_LINUX_DVD_STRUCT ) && defined( DVD_HOST_SEND_RPC_STATE )
- dvd_authinfo auth_info;
-
- memset( &auth_info, 0, sizeof( auth_info ) );
- auth_info.type = DVD_HOST_SEND_RPC_STATE;
- auth_info.hrpcs.pdrc = i_pdrc;
-
- i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
-
-#elif defined( HAVE_LINUX_DVD_STRUCT )
- /* FIXME: OpenBSD doesn't know this */
- i_ret = -1;
-
-#elif defined( HAVE_BSD_DVD_STRUCT )
- struct dvd_authinfo auth_info;
-
- memset( &auth_info, 0, sizeof( auth_info ) );
- auth_info.format = DVD_SEND_RPC;
- auth_info.region = i_pdrc;
-
- i_ret = ioctl( i_fd, DVDIOCSENDKEY, &auth_info );
-
-#elif defined( SYS_BEOS )
- INIT_RDC( GPCMD_SEND_KEY, 8 );
-
- rdc.command[ 10 ] = DVD_SEND_RPC;
-
- p_buffer[ 1 ] = 6;
- p_buffer[ 4 ] = i_pdrc;
-
- i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
-
-#elif defined( HPUX_SCTL_IO )
- INIT_SCTL_IO( GPCMD_SEND_KEY, 8 );
-
- sctl_io.cdb[ 10 ] = DVD_SEND_RPC;
-
- p_buffer[ 1 ] = 6;
- p_buffer[ 4 ] = i_pdrc;
-
- i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
-
-#elif defined( SOLARIS_USCSI )
- INIT_USCSI( GPCMD_SEND_KEY, 8 );
-
- rs_cdb.cdb_opaque[ 10 ] = DVD_SEND_RPC;
-
- p_buffer[ 1 ] = 6;
- p_buffer[ 4 ] = i_pdrc;
-
- i_ret = SolarisSendUSCSI( i_fd, &sc );
-
- if( i_ret < 0 || sc.uscsi_status )
- {
- i_ret = -1;
- }
-
-#elif defined( DARWIN_DVD_IOCTL )
- INIT_DVDIOCTL( dk_dvd_send_key_t, DVDRegionPlaybackControlInfo,
- kDVDKeyFormatSetRegion );
-
- dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
- dvdbs.driveRegion = i_pdrc;
-
- i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
-
-#elif defined( WIN32 )
- if( WIN2K ) /* NT/2k/XP */
- {
- INIT_SPTD( GPCMD_SEND_KEY, 8 );
-
- sptd.Cdb[ 10 ] = DVD_SEND_RPC;
-
- p_buffer[ 1 ] = 6;
- p_buffer[ 4 ] = i_pdrc;
-
- i_ret = SEND_SPTD( i_fd, &sptd, &tmp );
- }
- else
- {
- INIT_SSC( GPCMD_SEND_KEY, 8 );
-
- ssc.CDBByte[ 10 ] = DVD_SEND_RPC;
-
- p_buffer[ 1 ] = 6;
- p_buffer[ 4 ] = i_pdrc;
-
- i_ret = WinSendSSC( i_fd, &ssc );
- }
-
-#elif defined( __QNXNTO__ )
-
- INIT_CPT( GPCMD_SEND_KEY, 8 );
-
- p_cpt->cam_cdb[ 10 ] = DVD_SEND_RPC;
-
- p_buffer[ 1 ] = 6;
- p_buffer[ 4 ] = i_pdrc;
-
- i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
-
-#elif defined( SYS_OS2 )
- INIT_SSC( GPCMD_SEND_KEY, 8 );
-
- sdc.command[ 10 ] = DVD_SEND_RPC;
-
- p_buffer[ 1 ] = 6;
- p_buffer[ 4 ] = i_pdrc;
-
- i_ret = DosDevIOCtl( i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
- &sdc, sizeof(sdc), &ulParamLen,
- p_buffer, sizeof(p_buffer), &ulDataLen );
-
-#else
-# error "DVD ioctls are unavailable on this system"
-
-#endif
- return i_ret;
-}
-
-/* Local prototypes */
-
-#if defined( SYS_BEOS )
-/*****************************************************************************
- * BeInitRDC: initialize a RDC structure for the BeOS kernel
- *****************************************************************************
- * This function initializes a BeOS raw device command structure for future
- * use, either a read command or a write command.
- *****************************************************************************/
-static void BeInitRDC( raw_device_command *p_rdc, int i_type )
-{
- memset( p_rdc->data, 0, p_rdc->data_length );
-
- switch( i_type )
- {
- case GPCMD_SEND_KEY:
- /* leave the flags to 0 */
- break;
-
- case GPCMD_READ_DVD_STRUCTURE: case GPCMD_REPORT_KEY:
- p_rdc->flags = B_RAW_DEVICE_DATA_IN; break; }
-
- p_rdc->command[ 0 ] = i_type;
-
- p_rdc->command[ 8 ] = (p_rdc->data_length >> 8) & 0xff;
- p_rdc->command[ 9 ] = p_rdc->data_length & 0xff;
- p_rdc->command_length = 12;
-
- p_rdc->sense_data = NULL;
- p_rdc->sense_data_length = 0;
-
- p_rdc->timeout = 1000000;
-}
-#endif
-
-#if defined( HPUX_SCTL_IO )
-/*****************************************************************************
- * HPUXInitSCTL: initialize a sctl_io structure for the HP-UX kernel
- *****************************************************************************
- * This function initializes a HP-UX command structure for future
- * use, either a read command or a write command.
- *****************************************************************************/
-static void HPUXInitSCTL( struct sctl_io *sctl_io, int i_type )
-{
- memset( sctl_io->data, 0, sctl_io->data_length );
-
- switch( i_type )
- {
- case GPCMD_SEND_KEY:
- /* leave the flags to 0 */
- break;
-
- case GPCMD_READ_DVD_STRUCTURE:
- case GPCMD_REPORT_KEY:
- sctl_io->flags = SCTL_READ;
- break;
- }
-
- sctl_io->cdb[ 0 ] = i_type;
-
- sctl_io->cdb[ 8 ] = (sctl_io->data_length >> 8) & 0xff;
- sctl_io->cdb[ 9 ] = sctl_io->data_length & 0xff;
- sctl_io->cdb_length = 12;
-
- sctl_io->max_msecs = 1000000;
-}
-#endif
-
-#if defined( SOLARIS_USCSI )
-/*****************************************************************************
- * SolarisInitUSCSI: initialize a USCSICMD structure for the Solaris kernel
- *****************************************************************************
- * This function initializes a Solaris userspace scsi command structure for
- * future use, either a read command or a write command.
- *****************************************************************************/
-static void SolarisInitUSCSI( struct uscsi_cmd *p_sc, int i_type )
-{
- union scsi_cdb *rs_cdb;
- memset( p_sc->uscsi_cdb, 0, sizeof( union scsi_cdb ) );
- memset( p_sc->uscsi_bufaddr, 0, p_sc->uscsi_buflen );
-
- switch( i_type )
- {
- case GPCMD_SEND_KEY:
- p_sc->uscsi_flags = USCSI_ISOLATE | USCSI_WRITE;
- break;
-
- case GPCMD_READ_DVD_STRUCTURE:
- case GPCMD_REPORT_KEY:
- p_sc->uscsi_flags = USCSI_ISOLATE | USCSI_READ;
- break;
- }
-
- rs_cdb = (union scsi_cdb *)p_sc->uscsi_cdb;
-
- rs_cdb->scc_cmd = i_type;
-
- rs_cdb->cdb_opaque[ 8 ] = (p_sc->uscsi_buflen >> 8) & 0xff;
- rs_cdb->cdb_opaque[ 9 ] = p_sc->uscsi_buflen & 0xff;
- p_sc->uscsi_cdblen = 12;
-
- USCSI_TIMEOUT( p_sc, 15 );
-}
-
-/*****************************************************************************
- * SolarisSendUSCSI: send a USCSICMD structure to the Solaris kernel
- * for execution
- *****************************************************************************
- * When available, this function uses the function smedia_uscsi_cmd()
- * from Solaris' libsmedia library (Solaris 9 or newer) to execute the
- * USCSI command. smedia_uscsi_cmd() allows USCSI commands for
- * non-root users on removable media devices on Solaris 9; sending the
- * USCSI command directly to the device using the USCSICMD ioctl fails
- * with an EPERM error on Solaris 9.
- *
- * The code will fall back to the USCSICMD ioctl method, when
- * libsmedia.so is not available or does not export the
- * smedia_uscsi_cmd() function (on Solaris releases upto and including
- * Solaris 8). Fortunatelly, on these old releases non-root users are
- * allowed to perform USCSICMD ioctls on removable media devices.
- *****************************************************************************/
-static int SolarisSendUSCSI( int i_fd, struct uscsi_cmd *p_sc )
-{
- void *p_handle;
-
- /* We use static variables to keep track of the libsmedia symbols, which
- * is harmless even in a multithreaded program because the library and
- * its symbols will always be mapped at the same address. */
- static int b_tried = 0;
- static int b_have_sm = 0;
- static void * (*p_get_handle) ( int32_t );
- static int (*p_uscsi_cmd) ( void *, struct uscsi_cmd * );
- static int (*p_release_handle) ( void * );
-
- if( !b_tried )
- {
- void *p_lib;
-
- p_lib = dlopen( "libsmedia.so", RTLD_NOW );
- if( p_lib )
- {
- p_get_handle = dlsym( p_lib, "smedia_get_handle" );
- p_uscsi_cmd = dlsym( p_lib, "smedia_uscsi_cmd" );
- p_release_handle = dlsym( p_lib, "smedia_release_handle" );
-
- if( p_get_handle && p_uscsi_cmd && p_release_handle )
- {
- b_have_sm = 1;
- }
- else
- {
- dlclose( p_lib );
- }
- }
-
- b_tried = 1;
- }
-
- if( b_have_sm && (p_handle = p_get_handle(i_fd)) )
- {
- int i_ret = p_uscsi_cmd( p_handle, p_sc );
- p_release_handle( p_handle );
- return i_ret;
- }
-
- return ioctl( i_fd, USCSICMD, p_sc );
-}
-#endif
-
-#if defined( WIN32 )
-/*****************************************************************************
- * WinInitSPTD: initialize a sptd structure
- *****************************************************************************
- * This function initializes a SCSI pass through command structure for future
- * use, either a read command or a write command.
- *****************************************************************************/
-static void WinInitSPTD( SCSI_PASS_THROUGH_DIRECT *p_sptd, int i_type )
-{
- memset( p_sptd->DataBuffer, 0, p_sptd->DataTransferLength );
-
- switch( i_type )
- {
- case GPCMD_SEND_KEY:
- p_sptd->DataIn = SCSI_IOCTL_DATA_OUT;
- break;
-
- case GPCMD_READ_DVD_STRUCTURE:
- case GPCMD_REPORT_KEY:
- p_sptd->DataIn = SCSI_IOCTL_DATA_IN;
- break;
- }
-
- p_sptd->Cdb[ 0 ] = i_type;
- p_sptd->Cdb[ 8 ] = (uint8_t)(p_sptd->DataTransferLength >> 8) & 0xff;
- p_sptd->Cdb[ 9 ] = (uint8_t) p_sptd->DataTransferLength & 0xff;
- p_sptd->CdbLength = 12;
-
- p_sptd->TimeOutValue = 2;
-}
-
-/*****************************************************************************
- * WinInitSSC: initialize a ssc structure for the win32 aspi layer
- *****************************************************************************
- * This function initializes a ssc raw device command structure for future
- * use, either a read command or a write command.
- *****************************************************************************/
-static void WinInitSSC( struct SRB_ExecSCSICmd *p_ssc, int i_type )
-{
- memset( p_ssc->SRB_BufPointer, 0, p_ssc->SRB_BufLen );
-
- switch( i_type )
- {
- case GPCMD_SEND_KEY:
- p_ssc->SRB_Flags = SRB_DIR_OUT;
- break;
-
- case GPCMD_READ_DVD_STRUCTURE:
- case GPCMD_REPORT_KEY:
- p_ssc->SRB_Flags = SRB_DIR_IN;
- break;
- }
-
- p_ssc->SRB_Cmd = SC_EXEC_SCSI_CMD;
- p_ssc->SRB_Flags |= SRB_EVENT_NOTIFY;
-
- p_ssc->CDBByte[ 0 ] = i_type;
-
- p_ssc->CDBByte[ 8 ] = (uint8_t)(p_ssc->SRB_BufLen >> 8) & 0xff;
- p_ssc->CDBByte[ 9 ] = (uint8_t) p_ssc->SRB_BufLen & 0xff;
- p_ssc->SRB_CDBLen = 12;
-
- p_ssc->SRB_SenseLen = SENSE_LEN;
-}
-
-/*****************************************************************************
- * WinSendSSC: send a ssc structure to the aspi layer
- *****************************************************************************/
-static int WinSendSSC( int i_fd, struct SRB_ExecSCSICmd *p_ssc )
-{
- HANDLE hEvent = NULL;
- struct w32_aspidev *fd = (struct w32_aspidev *) i_fd;
-
- hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
- if( hEvent == NULL )
- {
- return -1;
- }
-
- p_ssc->SRB_PostProc = hEvent;
- p_ssc->SRB_HaId = LOBYTE( fd->i_sid );
- p_ssc->SRB_Target = HIBYTE( fd->i_sid );
-
- ResetEvent( hEvent );
- if( fd->lpSendCommand( (void*) p_ssc ) == SS_PENDING )
- WaitForSingleObject( hEvent, INFINITE );
-
- CloseHandle( hEvent );
-
- return p_ssc->SRB_Status == SS_COMP ? 0 : -1;
-}
-#endif
-
-#if defined( __QNXNTO__ )
-/*****************************************************************************
- * QNXInitCPT: initialize a CPT structure for QNX Neutrino
- *****************************************************************************
- * This function initializes a cpt command structure for future use,
- * either a read command or a write command.
- *****************************************************************************/
-static void QNXInitCPT( CAM_PASS_THRU * p_cpt, int i_type )
-{
- switch( i_type )
- {
- case GPCMD_SEND_KEY:
- p_cpt->cam_flags = CAM_DIR_OUT;
- break;
-
- case GPCMD_READ_DVD_STRUCTURE:
- case GPCMD_REPORT_KEY:
- p_cpt->cam_flags = CAM_DIR_IN;
- break;
- }
-
- p_cpt->cam_cdb[0] = i_type;
-
- p_cpt->cam_cdb[ 8 ] = (p_cpt->cam_dxfer_len >> 8) & 0xff;
- p_cpt->cam_cdb[ 9 ] = p_cpt->cam_dxfer_len & 0xff;
- p_cpt->cam_cdb_len = 12;
-
- p_cpt->cam_timeout = CAM_TIME_DEFAULT;
-}
-#endif
-
-#if defined( SYS_OS2 )
-/*****************************************************************************
- * OS2InitSDC: initialize a SDC structure for the Execute SCSI-command
- *****************************************************************************
- * This function initializes a OS2 'execute SCSI command' structure for
- * future use, either a read command or a write command.
- *****************************************************************************/
-static void OS2InitSDC( struct OS2_ExecSCSICmd *p_sdc, int i_type )
-{
- switch( i_type )
- {
- case GPCMD_SEND_KEY:
- p_sdc->flags = 0;
- break;
-
- case GPCMD_READ_DVD_STRUCTURE:
- case GPCMD_REPORT_KEY:
- p_sdc->flags = EX_DIRECTION_IN;
- break;
- }
-
- p_sdc->command[ 0 ] = i_type;
- p_sdc->command[ 8 ] = (p_sdc->data_length >> 8) & 0xff;
- p_sdc->command[ 9 ] = p_sdc->data_length & 0xff;
- p_sdc->id_code = 0x31304443; // 'CD01'
- p_sdc->cmd_length = 12;
-}
-#endif
diff --git a/libdvdcss/ioctl.h b/libdvdcss/ioctl.h
deleted file mode 100644
index ebc972eb7c..0000000000
--- a/libdvdcss/ioctl.h
+++ /dev/null
@@ -1,434 +0,0 @@
-/*****************************************************************************
- * ioctl.h: DVD ioctl replacement function
- *****************************************************************************
- * Copyright (C) 1999-2001 VideoLAN
- * $Id$
- *
- * Authors: Sam 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 libdvdcss; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *****************************************************************************/
-
-#ifndef DVDCSS_IOCTL_H
-#define DVDCSS_IOCTL_H
-
-int ioctl_ReadCopyright ( int, int, int * );
-int ioctl_ReadDiscKey ( int, int *, uint8_t * );
-int ioctl_ReadTitleKey ( int, int *, int, uint8_t * );
-int ioctl_ReportAgid ( int, int * );
-int ioctl_ReportChallenge ( int, int *, uint8_t * );
-int ioctl_ReportKey1 ( int, int *, uint8_t * );
-int ioctl_ReportASF ( int, int *, int * );
-int ioctl_InvalidateAgid ( int, int * );
-int ioctl_SendChallenge ( int, int *, uint8_t * );
-int ioctl_SendKey2 ( int, int *, uint8_t * );
-int ioctl_ReportRPC ( int, int *, int *, int * );
-int ioctl_SendRPC ( int, int );
-
-#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; \
- uint8_t p_buffer[ (SIZE)+1 ]; \
- 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; \
- uint8_t p_buffer[ (SIZE)+1 ]; \
- 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; \
- uint8_t p_buffer[ (SIZE)+1 ]; \
- memset( &sc, 0, sizeof( struct uscsi_cmd ) ); \
- sc.uscsi_cdb = (caddr_t)&rs_cdb; \
- sc.uscsi_bufaddr = (caddr_t)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 specific
- *****************************************************************************/
-#if defined( WIN32 )
-#define INIT_SPTD( TYPE, SIZE ) \
- DWORD tmp; \
- SCSI_PASS_THROUGH_DIRECT sptd; \
- uint8_t p_buffer[ (SIZE) ]; \
- memset( &sptd, 0, sizeof( SCSI_PASS_THROUGH_DIRECT ) ); \
- sptd.Length = sizeof( SCSI_PASS_THROUGH_DIRECT ); \
- sptd.DataBuffer = p_buffer; \
- sptd.DataTransferLength = (SIZE); \
- WinInitSPTD( &sptd, (TYPE) );
-#define SEND_SPTD( DEV, SPTD, TMP ) \
- (DeviceIoControl( (HANDLE)(DEV), IOCTL_SCSI_PASS_THROUGH_DIRECT, \
- (SPTD), sizeof( SCSI_PASS_THROUGH_DIRECT ), \
- (SPTD), sizeof( SCSI_PASS_THROUGH_DIRECT ), \
- (TMP), NULL ) ? 0 : -1)
-#define INIT_SSC( TYPE, SIZE ) \
- struct SRB_ExecSCSICmd ssc; \
- uint8_t p_buffer[ (SIZE)+1 ]; \
- 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; \
- uint8_t p_buffer[ (SIZE)+1 ]; \
- 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_DVD_READ_STRUCTURE CTL_CODE(FILE_DEVICE_DVD, 0x0450, METHOD_BUFFERED, FILE_READ_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_RPC_KEY_LENGTH (sizeof(DVD_RPC_KEY) + sizeof(DVD_COPY_PROTECT_KEY))
-#define DVD_ASF_LENGTH (sizeof(DVD_ASF) + sizeof(DVD_COPY_PROTECT_KEY))
-
-#define DVD_COPYRIGHT_MASK 0x00000040
-#define DVD_NOT_COPYRIGHTED 0x00000000
-#define DVD_COPYRIGHTED 0x00000040
-
-#define DVD_SECTOR_PROTECT_MASK 0x00000020
-#define DVD_SECTOR_NOT_PROTECTED 0x00000000
-#define DVD_SECTOR_PROTECTED 0x00000020
-
-#define SCSI_IOCTL_DATA_OUT 0
-#define SCSI_IOCTL_DATA_IN 1
-
-typedef ULONG DVD_SESSION_ID, *PDVD_SESSION_ID;
-
-typedef enum DVD_STRUCTURE_FORMAT {
- DvdPhysicalDescriptor,
- DvdCopyrightDescriptor,
- DvdDiskKeyDescriptor,
- DvdBCADescriptor,
- DvdManufacturerDescriptor,
- DvdMaxDescriptor
-} DVD_STRUCTURE_FORMAT, *PDVD_STRUCTURE_FORMAT;
-
-typedef struct DVD_READ_STRUCTURE {
- LARGE_INTEGER BlockByteOffset;
- DVD_STRUCTURE_FORMAT Format;
- DVD_SESSION_ID SessionId;
- UCHAR LayerNumber;
-} DVD_READ_STRUCTURE, *PDVD_READ_STRUCTURE;
-
-typedef struct DVD_COPYRIGHT_DESCRIPTOR {
- UCHAR CopyrightProtectionType;
- UCHAR RegionManagementInformation;
- USHORT Reserved;
-} DVD_COPYRIGHT_DESCRIPTOR, *PDVD_COPYRIGHT_DESCRIPTOR;
-
-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_RPC_KEY
-{
- UCHAR UserResetsAvailable:3;
- UCHAR ManufacturerResetsAvailable:3;
- UCHAR TypeCode:2;
- UCHAR RegionMask;
- UCHAR RpcScheme;
- UCHAR Reserved2[1];
-} DVD_RPC_KEY, * PDVD_RPC_KEY;
-
-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
- *****************************************************************************/
-
-typedef DWORD (CALLBACK *GETASPI32SUPPORTINFO)(VOID);
-typedef DWORD (CALLBACK *SENDASPI32COMMAND)(LPVOID);
-
-#define WIN2K ( GetVersion() < 0x80000000 )
-#define ASPI_HAID 0
-#define ASPI_TARGET 0
-#define DTYPE_CDROM 0x05
-
-#define SENSE_LEN 0x0E
-#define SC_GET_DEV_TYPE 0x01
-#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;
- SENDASPI32COMMAND lpSendCommand;
-};
-
-#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_GDEVBlock
-{
- 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_DeviceType;
- unsigned char SRB_Rsvd1;
-};
-
-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
-
-#endif /* DVDCSS_IOCTL_H */
diff --git a/libdvdcss/libdvdcss.c b/libdvdcss/libdvdcss.c
deleted file mode 100644
index e3b60e1fe2..0000000000
--- a/libdvdcss/libdvdcss.c
+++ /dev/null
@@ -1,814 +0,0 @@
-/* libdvdcss.c: DVD reading library.
- *
- * Authors: Stéphane Borel <stef@via.ecp.fr>
- * Sam Hocevar <sam@zoy.org>
- * Håkan Hjort <d95hjort@dtek.chalmers.se>
- *
- * Copyright (C) 1998-2008 VideoLAN
- * $Id$
- *
- * This library 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 library 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 library; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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. Exact usage will
- * depend on your operating system, the Linux utility to set up raw devices
- * is \c raw(8) for instance. Please note that on most operating systems,
- * using a raw device requires highly aligned buffers: Linux requires a
- * 2048 bytes alignment (which is the size of a DVD sector).
- *
- * \li \b DVDCSS_CACHE: specify a directory in which to store title key
- * values. This will speed up descrambling of DVDs which are in the
- * cache. The DVDCSS_CACHE directory is created if it does not exist,
- * and a subdirectory is created named after the DVD's title or
- * manufacturing date. If DVDCSS_CACHE is not set or is empty, \e libdvdcss
- * will use the default value which is "${HOME}/.dvdcss/" under Unix and
- * "C:\Documents and Settings\$USER\Application Data\dvdcss\" under Win32.
- * The special value "off" disables caching.
- */
-
-/*
- * Preamble
- */
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifdef HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-#ifdef HAVE_PWD_H
-# include <pwd.h>
-#endif
-#include <fcntl.h>
-#include <errno.h>
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#ifdef HAVE_LIMITS_H
-# include <limits.h>
-#endif
-
-#ifdef HAVE_DIRECT_H
-# include <direct.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 occurred, NULL is returned.
- */
-LIBDVDCSS_EXPORT dvdcss_t dvdcss_open ( char *psz_target )
-{
- char psz_buffer[PATH_MAX];
- int i_ret;
-
- char *psz_method = getenv( "DVDCSS_METHOD" );
- char *psz_verbose = getenv( "DVDCSS_VERBOSE" );
- char *psz_cache = getenv( "DVDCSS_CACHE" );
-#if !defined(WIN32) && !defined(SYS_OS2)
- 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
- */
-#if !defined(WIN32) && !defined(SYS_OS2)
- 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->psz_cachefile[0] = '\0';
- dvdcss->b_debug = 0;
- dvdcss->b_errors = 0;
-
- /*
- * Find verbosity from DVDCSS_VERBOSE environment variable
- */
- if( psz_verbose != NULL )
- {
- int i = atoi( psz_verbose );
-
- if( i >= 2 ) dvdcss->b_debug = i;
- if( i >= 1 ) dvdcss->b_errors = 1;
- }
-
- /*
- * 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
- {
- print_error( dvdcss, "unknown decrypt method, please choose "
- "from 'title', 'key' or 'disc'" );
- free( dvdcss->psz_device );
- free( dvdcss );
- return NULL;
- }
- }
-
- /*
- * If DVDCSS_CACHE was not set, try to guess a default value
- */
- if( psz_cache == NULL || psz_cache[0] == '\0' )
- {
-#ifdef HAVE_DIRECT_H
- typedef HRESULT( WINAPI *SHGETFOLDERPATH )
- ( HWND, int, HANDLE, DWORD, LPTSTR );
-
-# define CSIDL_FLAG_CREATE 0x8000
-# define CSIDL_APPDATA 0x1A
-# define SHGFP_TYPE_CURRENT 0
-
- char psz_home[MAX_PATH];
- HINSTANCE p_dll;
- SHGETFOLDERPATH p_getpath;
-
- *psz_home = '\0';
-
- /* Load the shfolder dll to retrieve SHGetFolderPath */
- p_dll = LoadLibrary( "shfolder.dll" );
- if( p_dll )
- {
- p_getpath = (void*)GetProcAddress( p_dll, "SHGetFolderPathA" );
- if( p_getpath )
- {
- /* Get the "Application Data" folder for the current user */
- if( p_getpath( NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE,
- NULL, SHGFP_TYPE_CURRENT, psz_home ) == S_OK )
- {
- FreeLibrary( p_dll );
- }
- else
- {
- *psz_home = '\0';
- }
- }
- FreeLibrary( p_dll );
- }
-
- /* Cache our keys in
- * C:\Documents and Settings\$USER\Application Data\dvdcss\ */
- if( *psz_home )
- {
- snprintf( psz_buffer, PATH_MAX, "%s/dvdcss", psz_home );
- psz_buffer[PATH_MAX-1] = '\0';
- psz_cache = psz_buffer;
- }
-#else
- char *psz_home = NULL;
-# ifdef HAVE_PWD_H
- struct passwd *p_pwd;
-
- /* Try looking in password file for home dir. */
- p_pwd = getpwuid(getuid());
- if( p_pwd )
- {
- psz_home = p_pwd->pw_dir;
- }
-# endif
-
- if( psz_home == NULL )
- {
- psz_home = getenv( "HOME" );
- }
- if( psz_home == NULL )
- {
- psz_home = getenv( "USERPROFILE" );
- }
-
- /* Cache our keys in ${HOME}/.dvdcss/ */
- if( psz_home )
- {
- int home_pos = 0;
-
-#ifdef SYS_OS2
- if( *psz_home == '/' || *psz_home == '\\')
- {
- char *psz_unixroot = getenv("UNIXROOT");
-
- if( psz_unixroot &&
- psz_unixroot[0] &&
- psz_unixroot[1] == ':' &&
- psz_unixroot[2] == '\0')
- {
- strcpy( psz_buffer, psz_unixroot );
- home_pos = 2;
- }
- }
-#endif
- snprintf( psz_buffer + home_pos, PATH_MAX - home_pos,
- "%s/.dvdcss", psz_home );
- psz_buffer[PATH_MAX-1] = '\0';
- psz_cache = psz_buffer;
- }
-#endif
- }
-
- /*
- * Find cache dir from the DVDCSS_CACHE environment variable
- */
- if( psz_cache != NULL )
- {
- if( psz_cache[0] == '\0' || !strcmp( psz_cache, "off" ) )
- {
- psz_cache = NULL;
- }
- /* Check that we can add the ID directory and the block filename */
- else if( strlen( psz_cache ) + 1 + 32 + 1 + (KEY_SIZE * 2) + 10 + 1
- > PATH_MAX )
- {
- print_error( dvdcss, "cache directory name is too long" );
- psz_cache = NULL;
- }
- }
-
- /*
- * Open device
- */
- _dvdcss_check( dvdcss );
- 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 )
- {
- _dvdcss_test( dvdcss );
- }
-
- /* 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 )
- {
- print_debug( dvdcss, "could not get disc key" );
- }
- }
- else
- {
- memset( dvdcss->css.p_disc_key, 0, KEY_SIZE );
- }
-
- /* If the cache is enabled, write the cache directory tag */
- if( psz_cache )
- {
- char *psz_tag = "Signature: 8a477f597d28d172789f06886806bc55\r\n"
- "# This file is a cache directory tag created by libdvdcss.\r\n"
- "# For information about cache directory tags, see:\r\n"
- "# http://www.brynosaurus.com/cachedir/\r\n";
- char psz_tagfile[PATH_MAX + 1 + 12 + 1];
- int i_fd;
-
- sprintf( psz_tagfile, "%s/CACHEDIR.TAG", psz_cache );
- i_fd = open( psz_tagfile, O_RDWR|O_CREAT, 0644 );
- if( i_fd >= 0 )
- {
- write( i_fd, psz_tag, strlen(psz_tag) );
- close( i_fd );
- }
- }
-
- /* If the cache is enabled, extract a unique disc ID */
- if( psz_cache )
- {
- uint8_t p_sector[DVDCSS_BLOCK_SIZE];
- char psz_key[1 + KEY_SIZE * 2 + 1];
- char *psz_title;
- uint8_t *psz_serial;
- int i;
-
- /* We read sector 0. If it starts with 0x000001ba (BE), we are
- * reading a VOB file, and we should not cache anything. */
-
- i_ret = dvdcss->pf_seek( dvdcss, 0 );
- if( i_ret != 0 )
- {
- goto nocache;
- }
-
- i_ret = dvdcss->pf_read( dvdcss, p_sector, 1 );
- if( i_ret != 1 )
- {
- goto nocache;
- }
-
- if( p_sector[0] == 0x00 && p_sector[1] == 0x00
- && p_sector[2] == 0x01 && p_sector[3] == 0xba )
- {
- goto nocache;
- }
-
- /* The data we are looking for is at sector 16 (32768 bytes):
- * - offset 40: disc title (32 uppercase chars)
- * - offset 813: manufacturing date + serial no (16 digits) */
-
- i_ret = dvdcss->pf_seek( dvdcss, 16 );
- if( i_ret != 16 )
- {
- goto nocache;
- }
-
- i_ret = dvdcss->pf_read( dvdcss, p_sector, 1 );
- if( i_ret != 1 )
- {
- goto nocache;
- }
-
- /* Get the disc title */
- psz_title = (char *)p_sector + 40;
- psz_title[32] = '\0';
-
- for( i = 0 ; i < 32 ; i++ )
- {
- if( psz_title[i] <= ' ' )
- {
- psz_title[i] = '\0';
- break;
- }
- else if( psz_title[i] == '/' || psz_title[i] == '\\' )
- {
- psz_title[i] = '-';
- }
- }
-
- /* Get the date + serial */
- psz_serial = p_sector + 813;
- psz_serial[16] = '\0';
-
- /* Check that all characters are digits, otherwise convert. */
- for( i = 0 ; i < 16 ; i++ )
- {
- if( psz_serial[i] < '0' || psz_serial[i] > '9' )
- {
- char psz_tmp[16 + 1];
- sprintf( psz_tmp,
- "%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
- psz_serial[0], psz_serial[1], psz_serial[2],
- psz_serial[3], psz_serial[4], psz_serial[5],
- psz_serial[6], psz_serial[7] );
- memcpy( psz_serial, psz_tmp, 16 );
- break;
- }
- }
-
- /* Get disk key, since some discs have got same title, manufacturing
- * date and serial number, but different keys */
- if( dvdcss->b_scrambled )
- {
- psz_key[0] = '-';
- for( i = 0; i < KEY_SIZE; i++ )
- {
- sprintf( &psz_key[1+i*2], "%.2x", dvdcss->css.p_disc_key[i] );
- }
- psz_key[1 + KEY_SIZE * 2] = '\0';
- }
- else
- {
- psz_key[0] = 0;
- }
-
- /* We have a disc name or ID, we can create the cache dir */
- i = sprintf( dvdcss->psz_cachefile, "%s", psz_cache );
-#if !defined( WIN32 ) || defined( SYS_CYGWIN )
- i_ret = mkdir( dvdcss->psz_cachefile, 0755 );
-#else
- i_ret = mkdir( dvdcss->psz_cachefile );
-#endif
- if( i_ret < 0 && errno != EEXIST )
- {
- print_error( dvdcss, "failed creating cache directory" );
- dvdcss->psz_cachefile[0] = '\0';
- goto nocache;
- }
-
- i += sprintf( dvdcss->psz_cachefile + i, "/%s-%s%s", psz_title,
- psz_serial, psz_key );
-#if !defined( WIN32 ) || defined( SYS_CYGWIN )
- i_ret = mkdir( dvdcss->psz_cachefile, 0755 );
-#else
- i_ret = mkdir( dvdcss->psz_cachefile );
-#endif
- if( i_ret < 0 && errno != EEXIST )
- {
- print_error( dvdcss, "failed creating cache subdirectory" );
- dvdcss->psz_cachefile[0] = '\0';
- goto nocache;
- }
- i += sprintf( dvdcss->psz_cachefile + i, "/");
-
- /* Pointer to the filename we will use. */
- dvdcss->psz_block = dvdcss->psz_cachefile + i;
-
- print_debug( dvdcss, "using CSS key cache dir: %s",
- dvdcss->psz_cachefile );
- }
- nocache:
-
-#if !defined(WIN32) && !defined(SYS_OS2)
- if( psz_raw_device != NULL )
- {
- _dvdcss_raw_open( dvdcss, psz_raw_device );
- }
-#endif
-
- /* Seek at the beginning, just for safety. */
- dvdcss->pf_seek( dvdcss, 0 );
-
- return dvdcss;
-}
-
-/**
- * \brief Return a string containing the latest error that occurred 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
- * occurred in \e libdvdcss. It can be used to format error messages at your
- * convenience in your application.
- */
-LIBDVDCSS_EXPORT 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.
- */
-LIBDVDCSS_EXPORT 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->pf_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.
- */
-LIBDVDCSS_EXPORT int dvdcss_read ( dvdcss_t dvdcss, void *p_buffer,
- int i_blocks,
- int i_flags )
-{
- int i_ret, i_index;
-
- i_ret = dvdcss->pf_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( ((uint8_t*)p_buffer)[0x14] & 0x30 )
- {
- print_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 *) ((uint8_t *)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 );
- ((uint8_t*)p_buffer)[0x14] &= 0x8f;
- p_buffer = (void *) ((uint8_t *)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.
- */
-LIBDVDCSS_EXPORT 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->pf_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 );
- ((uint8_t*)iov_base)[0x14] &= 0x8f;
-
- iov_base = (void *) ((uint8_t*)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.
- */
-LIBDVDCSS_EXPORT 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
-LIBDVDCSS_EXPORT int dvdcss_title ( dvdcss_t dvdcss, int i_block )
-{
- return _dvdcss_title( dvdcss, i_block );
-}
-
-/**
- * \brief Return 1 if the DVD is scrambled, 0 otherwise.
- *
- * \param dvdcss a \e libdvdcss instance.
- * \return 1 if the DVD is scrambled, 0 otherwise.
- *
- * This function returns whether the DVD is scrambled.
- */
-LIBDVDCSS_EXPORT int dvdcss_is_scrambled ( dvdcss_t dvdcss )
-{
- return dvdcss->b_scrambled;
-}
-
diff --git a/libdvdcss/libdvdcss.h b/libdvdcss/libdvdcss.h
deleted file mode 100644
index 6db228c1ca..0000000000
--- a/libdvdcss/libdvdcss.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*****************************************************************************
- * libdvdcss.h: private DVD reading library data
- *****************************************************************************
- * Copyright (C) 1998-2001 VideoLAN
- * $Id$
- *
- * Authors: Stéphane Borel <stef@via.ecp.fr>
- * Sam 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 libdvdcss; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *****************************************************************************/
-
-#ifndef DVDCSS_LIBDVDCSS_H
-#define DVDCSS_LIBDVDCSS_H
-
-#include "dvdcss/dvdcss.h"
-#include "css.h"
-
-struct iovec;
-
-/*****************************************************************************
- * The libdvdcss structure
- *****************************************************************************/
-struct dvdcss_s
-{
- /* File descriptor */
- char * psz_device;
- int i_fd;
- int i_read_fd;
- int i_pos;
-
- /* File handling */
- int ( * pf_seek ) ( dvdcss_t, int );
- int ( * pf_read ) ( dvdcss_t, void *, int );
- int ( * pf_readv ) ( dvdcss_t, struct iovec *, int );
-
- /* Decryption stuff */
- int i_method;
- css_t css;
- int b_ioctls;
- int b_scrambled;
- dvd_title_t *p_titles;
-
- /* Key cache directory and pointer to the filename */
- char psz_cachefile[PATH_MAX];
- char * psz_block;
-
- /* Error management */
- char * psz_error;
- int b_errors;
- int b_debug;
-
-#ifdef WIN32
- int b_file;
- char * p_readv_buffer;
- int i_readv_buf_size;
-#endif
-
-#if !defined(WIN32) && !defined(SYS_OS2)
- int i_raw_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
- *****************************************************************************/
-#define print_error(dvdcss,msg) _print_error(dvdcss,msg)
-#if defined( _MSC_VER )
-#include <stdarg.h>
-__forceinline void print_debug(dvdcss_t dvdcss, const char *msg,...)
-{
- va_list args;
-
- fprintf( stderr, "libdvdcss debug: " );
- va_start( args, msg );
- vfprintf( stderr, msg, args );
- va_end( args );
- fprintf( stderr, "\n" );
-}
-#else
-#define print_debug(dvdcss,msg,args...) \
- if( dvdcss->b_debug ) \
- { \
- fprintf( stderr, "libdvdcss debug: " ); \
- fprintf( stderr, msg, ##args ); \
- fprintf( stderr, "\n" ); \
- }
-#endif
-
-void _print_error ( dvdcss_t, char * );
-
-#endif /* DVDCSS_LIBDVDCSS_H */