diff options
author | Uoti Urpala <uau@glyph.nonexistent.invalid> | 2011-03-01 22:37:15 +0200 |
---|---|---|
committer | Uoti Urpala <uau@glyph.nonexistent.invalid> | 2011-03-01 22:37:15 +0200 |
commit | b27e4ca37126e95f806d92bb8a2e38c14965376e (patch) | |
tree | 8dce7baa7cabb4e6dbacf6c72ccae64fb58b30a3 | |
parent | e786c70de9a65c44f575ab8c61ff00fbbd2df585 (diff) |
libdvdcss: drop internal libdvdcss tree
The internal libdvdcss version was only compiled if you used internal
libdvdread too; and libdvdread was not included in the sources, so
that'd only happen if you manually added libdvdread in the build
tree. Keeping libdvdcss for that case probably isn't worth it, so
delete it from the tree. The build system part is still there, so an
internal build is possible if you add the directory back.
-rw-r--r-- | Copyright | 8 | ||||
-rw-r--r-- | libdvdcss/bsdi_dvd.h | 344 | ||||
-rw-r--r-- | libdvdcss/common.h | 85 | ||||
-rw-r--r-- | libdvdcss/css.c | 1731 | ||||
-rw-r--r-- | libdvdcss/css.h | 63 | ||||
-rw-r--r-- | libdvdcss/csstables.h | 395 | ||||
-rw-r--r-- | libdvdcss/device.c | 1090 | ||||
-rw-r--r-- | libdvdcss/device.h | 64 | ||||
-rw-r--r-- | libdvdcss/dvdcss/dvdcss.h | 107 | ||||
-rw-r--r-- | libdvdcss/error.c | 68 | ||||
-rw-r--r-- | libdvdcss/ioctl.c | 2123 | ||||
-rw-r--r-- | libdvdcss/ioctl.h | 434 | ||||
-rw-r--r-- | libdvdcss/libdvdcss.c | 814 | ||||
-rw-r--r-- | libdvdcss/libdvdcss.h | 111 |
14 files changed, 0 insertions, 7437 deletions
@@ -20,14 +20,6 @@ Copyright: Many, see individual files for copyright notices. License: GNU Lesser General Public License -Name: libdvdcss -Version: Subversion r237 + local changes -URL: http://developers.videolan.org/libdvdcss/ -Directory: libdvdcss -Copyright: 1998-2008 VideoLAN -License: GNU General Public License - - Name: mpg123 Version: 0.59s + significant changes URL: http://www.mpg123.de/ 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, - ¶m, 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 */ |