Changeset 8ccd224ce68ba37052c2dfff1d8a34b2c12d32ae

Show
Ignore:
Timestamp:
04/03/01 01:30:41 (7 years ago)
Author:
Sam Hocevar <sam@videolan.org>
git-committer:
Sam Hocevar <sam@videolan.org> 986254241 +0000
git-parent:

[a53dd0f3eb2d0174ead98ca0e3191daf6ee2a775]

git-author:
Sam Hocevar <sam@videolan.org> 986254241 +0000
Message:
  • fixes for the Qt plugin compilation under Debian
  • heavy butchering in the CSS and DVD ioctl code to put all architecture-
    dependent code in dvd_ioctl.c
  • added almost fully-functional /dev/dvd driver for MacOS X in
    extras/DVDioctl; to build it:

% cd extras/DVDioctl
% pbxbuild
% kextload build/DVDioctl.kext # note: kextload has to be run as root

be aware that the license for the DVDioctl kernel extension is
not GPL but APSL, because I borrowed some code from the Darwin kernel.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • INSTALL

    ra0c1805 r8ccd224  
    1717   make distclean 2>/dev/null ; ./configure --prefix=/usr --enable-gnome \ 
    1818      --enable-fb --with-glide --with-ggi --with-sdl --enable-esd \ 
    19       --enable-alsa --enable-mga --enable-gtk --enable-qt && make 
     19      --enable-alsa --enable-mga --enable-gtk --enable-qt --enable-xvideo \ 
     20   && make 
    2021 
    2122If you intend to debug stuff, you may want to disable optimizations: 
     
    2324   make distclean 2>/dev/null ; ./configure --prefix=/usr --enable-gnome \ 
    2425      --enable-fb --with-glide --with-ggi --with-sdl --enable-esd \ 
    25       --enable-alsa --enable-mga --enable-gtk --enable-qt
     26      --enable-alsa --enable-mga --enable-gtk --enable-qt --enable-xvideo
    2627      --disable-optimizatons && make 
    2728 
  • Makefile.in

    r5ff854e r8ccd224  
    7171# 
    7272INCLUDE += @INCLUDE@ 
    73 INCLUDE += -Iinclude -I/usr/local/include 
     73INCLUDE += -Iinclude -Iextras -I/usr/local/include 
    7474 
    7575# 
     
    637637$(PLUGIN_QT): %.o: .dep/%.dpp 
    638638$(PLUGIN_QT): %.o: %.moc 
    639     $(CC) $(CFLAGS) $(PCFLAGS) -I${QTDIR}/include -c -o $@ $(<:%.moc=%.cpp) 
     639    $(CC) $(CFLAGS) $(PCFLAGS) -I/usr/include/qt -I${QTDIR}/include -c -o $@ $(<:%.moc=%.cpp) 
    640640$(PLUGIN_QT:%.o=%.moc): %.moc: %.cpp 
    641641    moc -i $< -o $@ 
  • include/config.h.in

    ra6c6f72 r8ccd224  
    7979 
    8080/* Modules specific debugging - this will produce a lot of output, but can be 
    81  * usefull to track a bug */ 
     81 * useful to track a bug */ 
    8282//#define DEBUG_INTF 
    8383//#define DEBUG_INPUT 
     
    446446#define INTF_WARNING_DEFAULT            12 
    447447 
    448 /* Define to enable messages queues - disabling messages queue can be usefull 
    449  * when debugging, since it allows messages which would not otherwise be printed, 
    450  * due to a crash, to be printed anyway */ 
     448/* Define to enable messages queues - disabling messages queue can be useful 
     449 * when debugging, since it allows messages which would not be printed 
     450 * due to a crash to be printed anyway */ 
    451451#ifndef DEBUG 
    452452#define INTF_MSG_QUEUE 
  • include/defs.h.in

    ra3c6cd9 r8ccd224  
    5252/* Define if you have the vasprintf function.  */ 
    5353#undef HAVE_VASPRINTF 
     54 
     55/* Define if you have the <CoreAudio/AudioHardware.h> header file.  */ 
     56#undef HAVE_COREAUDIO_AUDIOHARDWARE_H 
    5457 
    5558/* Define if you have the <SDL/SDL.h> header file.  */ 
  • plugins/dvd/dvd_css.c

    r28e3820 r8ccd224  
    33 ***************************************************************************** 
    44 * Copyright (C) 1999-2001 VideoLAN 
    5  * $Id: dvd_css.c,v 1.18 2001/03/03 11:01:07 sam Exp $ 
     5 * $Id: dvd_css.c,v 1.19 2001/04/02 23:30:41 sam Exp $ 
    66 * 
    77 * Author: St�ane Borel <stef@via.ecp.fr> 
     
    3939#include <unistd.h> 
    4040#include <string.h> 
    41 #include <fcntl.h> 
    42 #include <netinet/in.h> 
    43 #ifdef HAVE_SYS_IOCTL_H 
    44 # include <sys/ioctl.h> 
    45 #endif 
    46 #ifdef HAVE_SYS_DVDIO_H 
    47 # include <sys/dvdio.h> 
    48 #endif 
    49 #ifdef LINUX_DVD 
    50 # include <linux/cdrom.h> 
    51 #endif 
    5241 
    5342#include "common.h" 
     
    6857 *****************************************************************************/ 
    6958#ifdef HAVE_CSS 
    70 static int  CSSGetASF    ( int i_fd ); 
     59static int  CSSGetASF    ( css_t *p_css ); 
    7160static void CSSCryptKey  ( int i_key_type, int i_varient, 
    7261                           u8 const * pi_challenge, u8* pi_key ); 
     
    8170int CSSTest( int i_fd ) 
    8271{ 
    83     dvd_struct dvd; 
    84  
    85     dvd.type = DVD_STRUCT_COPYRIGHT; 
    86     dvd.copyright.layer_num = 0; 
    87  
    88     if( dvd_ioctl( i_fd, DVD_READ_STRUCT, &dvd ) < 0 ) 
    89     { 
    90         intf_ErrMsg( "css error: DVD ioctl failed" ); 
    91         return -1; 
    92     } 
    93  
    94     return dvd.copyright.cpst; 
     72    int i_ret, i_copyright; 
     73 
     74    i_ret = dvd_ReadCopyright( i_fd, 0 /* i_layer */, &i_copyright ); 
     75 
     76    if( i_ret < 0 ) 
     77    { 
     78        return i_ret; 
     79    } 
     80 
     81    return i_copyright; 
    9582} 
    9683 
     
    10289 * basic unavoidable commands to authenticate device and disc. 
    10390 *****************************************************************************/ 
    104 css_t * CSSInit( int i_fd
     91int CSSInit( css_t * p_css
    10592{ 
    10693#ifdef HAVE_CSS 
    10794    /* structures defined in cdrom.h or dvdio.h */ 
    108     dvd_struct      dvd; 
    109     dvd_authinfo    auth_info; 
    110     css_t *         p_css; 
    111  
    112     int             i_error = -1; 
    113     int             i; 
    114  
    115     p_css = malloc( sizeof(css_t) ); 
    116     if( p_css == NULL ) 
    117     { 
    118         return NULL; 
    119     } 
    120  
    121     p_css->i_fd = i_fd; 
    122  
    123     memset( &auth_info, 0, sizeof(auth_info) ); 
     95    char p_buffer[2048 + 4 + 1]; 
     96    int  i_ret = -1; 
     97    int  i; 
     98 
     99    p_css->i_agid = 0; 
    124100 
    125101    /* Test authentication success */ 
    126     switch( CSSGetASF( i_fd ) ) 
    127     { 
    128     case -1: 
    129         free( p_css ); 
    130         return NULL; 
    131     case 1: 
    132         return p_css; 
    133     case 0: 
    134         intf_WarnMsg( 3, "css info: authenticating" ); 
     102    switch( CSSGetASF( p_css ) ) 
     103    { 
     104        case -1: 
     105            return -1; 
     106 
     107        case 1: 
     108            return 0; 
     109 
     110        case 0: 
     111            intf_WarnMsg( 3, "css info: authenticating" ); 
    135112    } 
    136113 
     
    138115    for( i = 1; i < 4 ; ++i ) 
    139116    { 
    140         intf_WarnMsg( 3, "css info: request AGID %d", i ); 
    141         auth_info.type = DVD_LU_SEND_AGID; 
    142         auth_info.lsa.agid = 0; 
    143         i_error =  dvd_ioctl( i_fd, DVD_AUTH, &auth_info ); 
    144         if( i_error != -1 ) 
    145         { 
    146             /* No error during ioctl: we know if device 
    147              * is authenticated */ 
     117        intf_WarnMsg( 3, "css info: requesting AGID %d", i ); 
     118 
     119        i_ret = dvd_LUSendAgid( p_css ); 
     120 
     121        if( i_ret != -1 ) 
     122        { 
     123            /* No error during ioctl: we know the device is authenticated */ 
    148124            break; 
    149125        } 
    150126 
    151127        intf_ErrMsg( "css error: AGID N/A, invalidating" ); 
    152         auth_info.type = DVD_INVALIDATE_AGID; 
    153         auth_info.lsa.agid = 0; 
    154         dvd_ioctl( i_fd, DVD_AUTH, &auth_info ); 
     128 
     129        p_css->i_agid = 0; 
     130        dvd_InvalidateAgid( p_css ); 
    155131    } 
    156132 
    157133    /* Unable to authenticate without AGID */ 
    158     if( i_error == -1 ) 
     134    if( i_ret == -1 ) 
    159135    { 
    160136        intf_ErrMsg( "css error: could not get AGID" ); 
    161         free( p_css ); 
    162         return NULL; 
     137        return -1; 
    163138    } 
    164139 
     
    167142        p_css->disc.pi_challenge[i] = i; 
    168143    } 
    169  
    170     /* Send AGID to host */ 
    171     auth_info.type = DVD_HOST_SEND_CHALLENGE; 
    172144 
    173145    /* Get challenge from host */ 
    174146    for( i = 0 ; i < 10 ; ++i ) 
    175147    { 
    176         auth_info.hsc.chal[9-i] = p_css->disc.pi_challenge[i]; 
    177     } 
    178     /* Returning data, let LU change state */ 
    179     p_css->i_agid = auth_info.lsa.agid; 
     148        p_buffer[9-i] = p_css->disc.pi_challenge[i]; 
     149    } 
    180150 
    181151    /* Send challenge to LU */ 
    182     if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info )<0 ) 
     152    if( dvd_HostSendChallenge( p_css, p_buffer ) < 0 ) 
    183153    { 
    184154        intf_ErrMsg( "css error: failed sending challenge to LU" ); 
    185         free( p_css ); 
    186         return NULL; 
     155        return -1; 
    187156    } 
    188157 
    189158    /* Get key1 from LU */ 
    190     if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) < 0) 
     159    if( dvd_LUSendKey1( p_css, p_buffer ) < 0) 
    191160    { 
    192161        intf_ErrMsg( "css error: failed getting key1 from LU" ); 
    193         free( p_css ); 
    194         return NULL; 
     162        return -1; 
    195163    } 
    196164 
     
    198166    for( i = 0 ; i < KEY_SIZE ; i++ ) 
    199167    { 
    200         p_css->disc.pi_key1[i] = auth_info.lsk.key[4-i]; 
     168        p_css->disc.pi_key1[i] = p_buffer[4-i]; 
    201169    } 
    202170 
     
    211179            intf_WarnMsg( 3, "css info: drive authentic, using variant %d", i); 
    212180            p_css->disc.i_varient = i; 
    213             auth_info.type = DVD_LU_SEND_CHALLENGE; 
    214181            break; 
    215182        } 
     
    219186    { 
    220187        intf_ErrMsg( "css error: drive would not authenticate" ); 
    221         auth_info.type = DVD_AUTH_FAILURE; 
    222         free( p_css ); 
    223         return NULL; 
     188        return -1; 
    224189    } 
    225190 
    226191    /* Get challenge from LU */ 
    227     if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) < 0 ) 
     192    if( dvd_LUSendChallenge( p_css, p_buffer ) < 0 ) 
    228193    { 
    229194        intf_ErrMsg( "css error: failed getting challenge from LU" ); 
    230         free( p_css ); 
    231         return NULL; 
     195        return -1; 
    232196    } 
    233197 
     
    235199    for( i = 0 ; i < 10 ; ++i ) 
    236200    { 
    237         p_css->disc.pi_challenge[i] = auth_info.hsc.chal[9-i]; 
     201        p_css->disc.pi_challenge[i] = p_buffer[9-i]; 
    238202    } 
    239203 
    240204    CSSCryptKey( 1, p_css->disc.i_varient, p_css->disc.pi_challenge, 
    241                                                     p_css->disc.pi_key2 ); 
    242     auth_info.type = DVD_HOST_SEND_KEY2; 
     205                                               p_css->disc.pi_key2 ); 
    243206 
    244207    /* Get key2 from host */ 
    245208    for( i = 0 ; i < KEY_SIZE ; ++i ) 
    246209    { 
    247         auth_info.hsk.key[4-i] = p_css->disc.pi_key2[i]; 
    248     } 
    249     /* Returning data, let LU change state */ 
     210        p_buffer[4-i] = p_css->disc.pi_key2[i]; 
     211    } 
    250212 
    251213    /* Send key2 to LU */ 
    252     if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) < 0 ) 
    253     { 
    254         intf_ErrMsg( "css error: failed sending key2 to LU (expected)" ); 
    255         free( p_css ); 
    256         return NULL; 
    257     } 
    258  
    259     if( auth_info.type == DVD_AUTH_ESTABLISHED ) 
    260     { 
    261         intf_WarnMsg( 3, "css info: authentication established" ); 
    262     } 
    263     else if( auth_info.type == DVD_AUTH_FAILURE ) 
    264     { 
    265         intf_ErrMsg( "css error: DVD authentication failed" ); 
    266         free( p_css ); 
    267         return NULL; 
    268     } 
     214    if( dvd_HostSendKey2( p_css, p_buffer ) < 0 ) 
     215    { 
     216        intf_ErrMsg( "css error: failed sending key2 to LU" ); 
     217        return -1; 
     218    } 
     219 
     220    intf_WarnMsg( 3, "css info: authentication established" ); 
    269221 
    270222    memcpy( p_css->disc.pi_challenge, p_css->disc.pi_key1, KEY_SIZE ); 
    271223    memcpy( p_css->disc.pi_challenge+KEY_SIZE, p_css->disc.pi_key2, KEY_SIZE ); 
    272     CSSCryptKey( 2, p_css->disc.i_varient, 
    273                     p_css->disc.pi_challenge, 
    274                     p_css->disc.pi_key_check ); 
     224    CSSCryptKey( 2, p_css->disc.i_varient, p_css->disc.pi_challenge, 
     225                                               p_css->disc.pi_key_check ); 
    275226 
    276227    intf_WarnMsg( 1, "css info: received Session Key" ); 
     
    278229    if( p_css->i_agid < 0 ) 
    279230    { 
    280         free( p_css ); 
    281         return NULL; 
     231        return -1; 
    282232    } 
    283233 
    284234    /* Test authentication success */ 
    285     switch( CSSGetASF( i_fd ) ) 
    286     { 
    287     case -1: 
    288         free( p_css ); 
    289         return NULL; 
    290     case 1: 
    291         return p_css; 
    292     case 0: 
    293         intf_WarnMsg( 3, "css info: getting disc key" ); 
     235    switch( CSSGetASF( p_css ) ) 
     236    { 
     237        case -1: 
     238            return -1; 
     239 
     240        case 1: 
     241            return 0; 
     242 
     243        case 0: 
     244            intf_WarnMsg( 3, "css info: getting disc key" ); 
    294245    } 
    295246 
    296247    /* Get encrypted disc key */ 
    297     dvd.type = DVD_STRUCT_DISCKEY; 
    298     dvd.disckey.agid = p_css->i_agid; 
    299     memset( dvd.disckey.value, 0, 2048 ); 
    300  
    301     if( dvd_ioctl( i_fd, DVD_READ_STRUCT, &dvd ) < 0 ) 
     248    if( dvd_ReadKey( p_css, p_buffer ) < 0 ) 
    302249    { 
    303250        intf_ErrMsg( "css error: could not read Disc Key" ); 
    304         free( p_css ); 
    305         return NULL; 
    306     } 
    307 #if 1 
     251        return -1; 
     252    } 
     253 
    308254    /* Unencrypt disc key using bus key */ 
    309     for( i = 0 ; i < sizeof(dvd.disckey.value) ; i++ ) 
    310     { 
    311         dvd.disckey.value[i] ^= p_css->disc.pi_key_check[4 - (i % KEY_SIZE)]; 
    312     } 
    313     memcpy( p_css->disc.pi_key_check, dvd.disckey.value, 2048 ); 
    314 #endif 
     255    for( i = 0 ; i < 2048 ; i++ ) 
     256    { 
     257        p_buffer[ i ] ^= p_css->disc.pi_key_check[ 4 - (i % KEY_SIZE) ]; 
     258    } 
     259    memcpy( p_css->disc.pi_key_check, p_buffer, 2048 ); 
     260 
    315261    /* Test authentication success */ 
    316     switch( CSSGetASF( i_fd ) ) 
    317     { 
    318     case -1: 
    319     case 0: 
    320         free( p_css )
    321         return NULL; 
    322     case 1: 
    323         return p_css
    324     } 
    325  
    326     return p_css
     262    switch( CSSGetASF( p_css ) ) 
     263    { 
     264        case -1: 
     265        case 0: 
     266            return -1
     267 
     268        case 1: 
     269            return 0
     270    } 
     271 
     272    return 0
    327273 
    328274#else /* HAVE_CSS */ 
    329275    intf_ErrMsg( "css error: CSS decryption is disabled in this module" ); 
    330276 
    331     return NULL; 
     277    return -1; 
     278 
    332279#endif /* HAVE_CSS */ 
    333280} 
     
    443390            } 
    444391 
    445             /* Stop search if we find one occurance of the key  
     392            /* Stop search if we find one occurence of the key  
    446393             * I have never found a DVD for which it is not enough 
    447394             * but we should take care of that */ 
     
    594541 *  1 either. 
    595542 *****************************************************************************/ 
    596 static int CSSGetASF( int i_fd
     543static int CSSGetASF( css_t *p_css
    597544{ 
    598     dvd_authinfo    auth_info; 
    599  
    600     auth_info.type = DVD_LU_SEND_ASF; 
    601     auth_info.lsasf.asf = 0; 
    602  
    603     for( auth_info.lsasf.agid = 0 ; auth_info.lsasf.agid < 4 ; 
    604                                                     auth_info.lsasf.agid++ ) 
    605     { 
    606         if( !( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) ) ) 
    607         { 
    608             intf_WarnMsg( 3, "css info: %sauthenticated", 
    609                           auth_info.lsasf.asf ? "" : "not " ); 
    610             return auth_info.lsasf.asf; 
     545    int i_oldagid = p_css->i_agid, i_asf = 0; 
     546 
     547    for( p_css->i_agid = 0 ; p_css->i_agid < 4 ; p_css->i_agid++ ) 
     548    { 
     549        if( dvd_LUSendASF( p_css, &i_asf ) == 0 ) 
     550        { 
     551            intf_WarnMsg( 3, "css info: %sauthenticated", i_asf ? "":"not " ); 
     552 
     553            p_css->i_agid = i_oldagid; 
     554            return i_asf; 
    611555        } 
    612556    } 
     
    614558    /* The ioctl process has failed */ 
    615559    intf_ErrMsg( "css error: GetASF fatal error" ); 
     560 
     561    p_css->i_agid = i_oldagid; 
    616562    return -1; 
    617563} 
  • plugins/dvd/dvd_css.h

    rdc0df7c r8ccd224  
    33 ***************************************************************************** 
    44 * Copyright (C) 1999-2001 VideoLAN 
    5  * $Id: dvd_css.h,v 1.5 2001/03/03 07:07:01 stef Exp $ 
     5 * $Id: dvd_css.h,v 1.6 2001/04/02 23:30:41 sam Exp $ 
    66 * 
    77 * Author: St�ane Borel <stef@via.ecp.fr> 
     
    5656    dvd_key_t       pi_title_key; 
    5757} css_t; 
     58 
  • plugins/dvd/dvd_ioctl.c

    r4eb6464 r8ccd224  
    33 ***************************************************************************** 
    44 * Copyright (C) 1999-2001 VideoLAN 
    5  * $Id: dvd_ioctl.c,v 1.3 2001/03/05 11:53:44 sam Exp $ 
     5 * $Id: dvd_ioctl.c,v 1.4 2001/04/02 23:30:41 sam Exp $ 
    66 * 
    77 * Authors: Markus Kuespert <ltlBeBoy@beosmail.com> 
     
    3030#include <sys/types.h> 
    3131#include <netinet/in.h> 
    32 #ifdef HAVE_SYS_IOCTL_H 
     32#ifdef HAVE_SYS_DVDIO_H 
    3333#   include <sys/ioctl.h> 
    34 #endif 
    35 #ifdef HAVE_SYS_DVDIO_H 
    3634#   include <sys/dvdio.h> 
    3735#endif 
    3836#ifdef LINUX_DVD 
     37#   include <sys/ioctl.h> 
    3938#   include <linux/cdrom.h> 
    4039#endif 
    4140#ifdef SYS_BEOS 
     41#   include <sys/ioctl.h> 
    4242#   include <malloc.h> 
    4343#   include <scsi.h> 
    4444#endif 
     45#ifdef SYS_DARWIN1_3 
     46#   include <sys/ioctl.h> 
     47#   include <DVDioctl/DVDioctl.h> 
     48#endif 
    4549 
    4650#include "common.h" 
    4751#include "intf_msg.h" 
    4852 
     53#include "dvd_css.h" 
    4954#include "dvd_ioctl.h" 
    5055 
     
    5358 *****************************************************************************/ 
    5459#if defined( SYS_BEOS ) 
    55 static int  ReadData          ( int i_fd, dvd_struct *p_dvd ); 
    56 static int  ReadCopyright     ( int i_fd, dvd_struct *p_dvd ); 
    57 static int  ReadKey           ( int i_fd, dvd_struct *p_dvd ); 
    58 static int  ReadBCA           ( int i_fd, dvd_struct *p_dvd ); 
    59 static int  ReadManufacturer  ( int i_fd, dvd_struct *p_dvd ); 
    60  
    61 static void InitGenericCommand( struct cdrom_generic_command *p_cgc, 
    62                                 void *buf, int i_len, int i_type ); 
    63 static void InitReadCommand   ( struct cdrom_generic_command *p_cgc, 
    64                                 unsigned i_agid, unsigned i_type ); 
    65 static void InitWriteCommand  ( struct cdrom_generic_command *p_cgc, 
    66                                 unsigned i_agid, unsigned i_type ); 
    67  
     60static void InitCommand ( struct cdrom_generic_command *p_cgc, 
     61                          void *buf, int i_len, int i_type ); 
    6862static int  SendCommand ( int i_fd, struct cdrom_generic_command *p_cgc ); 
    6963#endif 
    7064 
    7165/***************************************************************************** 
    72  * dvd_ioctl: DVD ioctl() wrapper 
    73  ***************************************************************************** 
    74  * Since the DVD ioctls do not exist on every machine, we provide this wrapper 
    75  * so that it becomes easier to port them to any architecture. 
    76  *****************************************************************************/ 
    77 int dvd_ioctl( int i_fd, unsigned long i_op, void *p_arg ) 
    78 
    79 #if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD ) 
    80     return( ioctl( i_fd, i_op, p_arg ) ); 
    81  
    82 #elif defined( SYS_BEOS ) 
    83  
    84     int           i_ret; 
    85     unsigned char buf[20]; 
    86  
    87     struct cdrom_generic_command p_cgc; 
    88  
    89     dvd_struct *p_dvd = (dvd_struct *)p_arg; 
    90     dvd_authinfo *p_authinfo = (dvd_authinfo *)p_arg; 
    91  
    92     switch ( i_op ) 
    93     { 
    94         case DVD_AUTH: /* Request type is "authentication" */ 
    95         { 
    96             memset( buf, 0, sizeof( buf ) ); 
    97             InitGenericCommand( &p_cgc, buf, 0, CGC_DATA_READ ); 
    98  
    99             switch( p_authinfo->type ) 
    100             { 
    101                 case DVD_LU_SEND_AGID: /* LU data send */ 
    102  
    103                     intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_AGID" ); 
    104  
    105                     InitReadCommand( &p_cgc, p_authinfo->lsa.agid, 0 ); 
    106  
    107                     i_ret = SendCommand( i_fd, &p_cgc ); 
    108  
    109                     p_authinfo->lsa.agid = buf[7] >> 6; 
    110  
    111                     return i_ret; 
    112  
    113                 case DVD_LU_SEND_KEY1: 
    114  
    115                     intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_KEY1" ); 
    116  
    117                     InitReadCommand( &p_cgc, p_authinfo->lsk.agid, 2 ); 
    118  
    119                     i_ret = SendCommand( i_fd, &p_cgc ); 
    120  
    121                     /* Copy the key */ 
    122                     memcpy( p_authinfo->lsk.key, &buf[4], sizeof(dvd_key) ); 
    123  
    124                     return i_ret; 
    125  
    126                 case DVD_LU_SEND_CHALLENGE: 
    127  
    128                     intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_CHALLENGE" ); 
    129  
    130                     InitReadCommand( &p_cgc, p_authinfo->lsc.agid, 1 ); 
    131  
    132                     i_ret = SendCommand( i_fd, &p_cgc ); 
    133  
    134                     /* Copy the challenge */ 
    135                     memcpy( p_authinfo->lsc.chal, &buf[4], 
    136                             sizeof(dvd_challenge) ); 
    137  
    138                     return i_ret; 
    139  
    140                 case DVD_LU_SEND_TITLE_KEY: /* Post-auth key */ 
    141  
    142                     intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_TITLE_KEY" ); 
    143  
    144                     InitReadCommand( &p_cgc, p_authinfo->lstk.agid, 4 ); 
    145  
    146                     p_cgc.cmd[5] = p_authinfo->lstk.lba; 
    147                     p_cgc.cmd[4] = p_authinfo->lstk.lba >> 8; 
    148                     p_cgc.cmd[3] = p_authinfo->lstk.lba >> 16; 
    149                     p_cgc.cmd[2] = p_authinfo->lstk.lba >> 24; 
    150  
    151                     i_ret = SendCommand( i_fd, &p_cgc ); 
    152  
    153                     p_authinfo->lstk.cpm = (buf[4] >> 7) & 1; 
    154                     p_authinfo->lstk.cp_sec = (buf[4] >> 6) & 1; 
    155                     p_authinfo->lstk.cgms = (buf[4] >> 4) & 3; 
    156  
    157                     /* Copy the key */ 
    158                     memcpy( p_authinfo->lstk.title_key, &buf[5], 
    159                             sizeof(dvd_key) ); 
    160  
    161                     return i_ret; 
    162  
    163                 case DVD_LU_SEND_ASF: 
    164  
    165                     intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_ASF" ); 
    166  
    167                     InitReadCommand( &p_cgc, p_authinfo->lsasf.agid, 5 ); 
    168  
    169                     i_ret = SendCommand( i_fd, &p_cgc ); 
    170  
    171                     p_authinfo->lsasf.asf = buf[7] & 1; 
    172  
    173                     return i_ret; 
    174  
    175                 case DVD_HOST_SEND_CHALLENGE: /* LU data receive */ 
    176  
    177                     intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_CHALLENGE" ); 
    178  
    179                     InitWriteCommand( &p_cgc, p_authinfo->hsc.agid, 1 ); 
    180                     buf[1] = 0xe; 
    181  
    182                     /* Copy the challenge */ 
    183                     memcpy( &buf[4], p_authinfo->hsc.chal, 
    184                             sizeof(dvd_challenge) ); 
    185  
    186                     if( (i_ret = SendCommand(i_fd, &p_cgc)) ) 
    187                     { 
    188                         return i_ret; 
    189                     } 
    190  
    191                     p_authinfo->type = DVD_LU_SEND_KEY1; 
    192  
    193                     return 0; 
    194  
    195                 case DVD_HOST_SEND_KEY2: 
    196  
    197                     intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_KEY2" ); 
    198  
    199                     InitWriteCommand( &p_cgc, p_authinfo->hsk.agid, 3 ); 
    200                     buf[1] = 0xa; 
    201  
    202                     /* Copy the key */ 
    203                     memcpy( &buf[4], p_authinfo->hsk.key, sizeof(dvd_key) ); 
    204  
    205                     if( (i_ret = SendCommand(i_fd, &p_cgc)) ) 
    206                     { 
    207                         p_authinfo->type = DVD_AUTH_FAILURE; 
    208                         return i_ret; 
    209                     } 
    210  
    211                     p_authinfo->type = DVD_AUTH_ESTABLISHED; 
    212  
    213                     return 0; 
    214  
    215                 case DVD_INVALIDATE_AGID: /* Misc */ 
    216  
    217                     intf_WarnMsg( 2, "css DoAuth: DVD_INVALIDATE_AGID" ); 
    218  
    219                     InitReadCommand( &p_cgc, p_authinfo->lsa.agid, 0x3f ); 
    220  
    221                 return SendCommand( i_fd, &p_cgc ); 
    222  
    223                 case DVD_LU_SEND_RPC_STATE: /* Get region settings */ 
    224  
    225                     intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_RPC_STATE " 
    226                                      "(unimplemented)" ); 
    227  
    228         #if 0 
    229                     p_dvdetup_report_key( &p_cgc, 0, 8 ); 
    230                     memset( &rpc_state, 0, sizeof(rpc_state_t) ); 
    231                     p_cgc.buffer = (char *) &rpc_state; 
    232  
    233                     if( (i_ret = SendCommand(i_fd, &p_cgc)) ) 
    234                     { 
    235                         return i_ret; 
    236                     } 
    237  
    238                     p_authinfo->lrpcs.type = rpc_state.type_code; 
    239                     p_authinfo->lrpcs.vra = rpc_state.vra; 
    240                     p_authinfo->lrpcs.ucca = rpc_state.ucca; 
    241                     p_authinfo->lrpcs.region_mask = rpc_state.region_mask; 
    242                     p_authinfo->lrpcs.rpc_scheme = rpc_state.rpc_scheme; 
    243         #endif 
    244  
    245                     return 0; 
    246  
    247                 case DVD_HOST_SEND_RPC_STATE: /* Set region settings */ 
    248  
    249                     intf_WarnMsg( 2, "css DoAuth: DVD_HOST_SEND_RPC_STATE" ); 
    250  
    251                     InitWriteCommand( &p_cgc, 0, 6 ); 
    252                     buf[1] = 6; 
    253                     buf[4] = p_authinfo->hrpcs.pdrc; 
    254  
    255                     return SendCommand( i_fd, &p_cgc ); 
    256  
    257                 default: 
    258                     intf_ErrMsg( "css DoAuth: invalid DVD key ioctl" ); 
    259                     return -1; 
    260  
    261             } 
    262         } 
    263  
    264         case DVD_READ_STRUCT: /* Request type is "read structure" */ 
    265         { 
    266             switch( p_dvd->type ) 
    267             { 
    268                 case DVD_STRUCT_PHYSICAL: 
    269  
    270                     intf_WarnMsg( 2, "css ReadStruct: DVD_STRUCT_PHYSICAL" ); 
    271  
    272                     return ReadData( i_fd, p_dvd ); 
    273  
    274                 case DVD_STRUCT_COPYRIGHT: 
    275  
    276                     intf_WarnMsg( 2, "css ReadStruct: DVD_STRUCT_COPYRIGHT" ); 
    277  
    278                     return ReadCopyright( i_fd, p_dvd ); 
    279  
    280                 case DVD_STRUCT_DISCKEY: 
    281  
    282                     intf_WarnMsg( 2, "css ReadStruct: DVD_STRUCT_DISCKEY" ); 
    283  
    284                     return ReadKey( i_fd, p_dvd ); 
    285  
    286                 case DVD_STRUCT_BCA: 
    287  
    288                     intf_WarnMsg( 2, "css ReadStruct: DVD_STRUCT_BCA" ); 
    289  
    290                     return ReadBCA( i_fd, p_dvd ); 
    291  
    292                 case DVD_STRUCT_MANUFACT: 
    293  
    294                     intf_WarnMsg( 2, "css ReadStruct: DVD_STRUCT_MANUFACT" ); 
    295  
    296                     return ReadManufacturer( i_fd, p_dvd ); 
    297  
    298                 default: 
    299                     intf_WarnMsg( 2, "css ReadStruct: invalid request (%d)", 
    300                                   p_dvd->type ); 
    301  
    302                     return -1; 
    303             } 
    304         } 
    305  
    306         default: /* Unknown request type */ 
    307         { 
    308             intf_ErrMsg( "css error: unknown command 0x%x", i_op ); 
    309             return -1; 
    310         } 
    311     } 
    312 #else 
    313  
    314     return -1; 
    315 #endif 
    316 
    317  
    318 /* Local prototypes */ 
    319  
    320 #if defined( SYS_BEOS ) 
    321 /***************************************************************************** 
    322  * ReadData: Get data structure information from the DVD. 
    323  *****************************************************************************/ 
    324 static int ReadData( int i_fd, dvd_struct *p_dvd ) 
    325 
    326     int i_ret, i; 
    327     u_char buf[4 + 4 * 20], *base; 
    328     struct dvd_layer *layer; 
    329     struct cdrom_generic_command cgc; 
    330  
    331     InitGenericCommand( &cgc, buf, sizeof(buf), CGC_DATA_READ ); 
    332  
    333     cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; 
    334     cgc.cmd[6] = p_dvd->physical.layer_num; 
    335     cgc.cmd[7] = p_dvd->type; 
    336     cgc.cmd[9] = cgc.buflen & 0xff; 
    337  
    338     if( (i_ret = SendCommand(i_fd, &cgc)) ) 
     66 * dvd_ReadKey:  
     67 ***************************************************************************** 
     68 *  
     69 *****************************************************************************/ 
     70int dvd_ReadKey( css_t *p_css, u8 *p_key ) 
     71
     72#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD ) 
     73    int i_ret; 
     74    dvd_struct dvd; 
     75 
     76    dvd.type = DVD_STRUCT_DISCKEY; 
     77    dvd.disckey.agid = p_css->i_agid; 
     78 
     79    memset( dvd.disckey.value, 0, 2048 ); 
     80 
     81    i_ret = ioctl( p_css->i_fd, DVD_READ_STRUCT, &dvd ); 
     82 
     83    if( i_ret < 0 ) 
    33984    { 
    34085        return i_ret; 
    34186    } 
    34287 
    343     base = &buf[4]; 
    344     layer = &p_dvd->physical.layer[0]; 
    345  
    346     /* place the data... really ugly, but at least we won't have to 
    347      * worry about endianess in userspace or here. */ 
    348     for( i = 0; i < 4; ++i, base += 20, ++layer ) 
    349     { 
    350         memset( layer, 0, sizeof(*layer) ); 
    351  
    352         layer->book_version = base[0] & 0xf; 
    353         layer->book_type = base[0] >> 4; 
    354         layer->min_rate = base[1] & 0xf; 
    355         layer->disc_size = base[1] >> 4; 
    356         layer->layer_type = base[2] & 0xf; 
    357         layer->track_path = (base[2] >> 4) & 1; 
    358         layer->nlayers = (base[2] >> 5) & 3; 
    359         layer->track_density = base[3] & 0xf; 
    360         layer->linear_density = base[3] >> 4; 
    361         layer->start_sector = base[5] << 16 | base[6] << 8 | base[7]; 
    362         layer->end_sector = base[9] << 16 | base[10] << 8 | base[11]; 
    363         layer->end_sector_l0 = base[13] << 16 | base[14] << 8 | base[15]; 
    364         layer->bca = base[16] >> 7; 
    365     } 
    366  
    367     return 0; 
    368 
    369  
    370 /***************************************************************************** 
    371  * ReadCopyright: get copyright information from the DVD. 
    372  *****************************************************************************/ 
    373 static int ReadCopyright( int i_fd, dvd_struct *p_dvd ) 
    374 
    375     int i_ret; 
    376     u_char buf[8]; 
    377     struct cdrom_generic_command cgc; 
    378  
    379     InitGenericCommand( &cgc, buf, sizeof(buf), CGC_DATA_READ ); 
     88    memcpy( p_key, dvd.disckey.value, 2048 ); 
     89    return i_ret; 
     90 
     91#elif defined( SYS_BEOS ) 
     92    int i_ret, size; 
     93    u8 p_buf[ 2048 + 4]; 
     94    struct cdrom_generic_command cgc; 
     95 
     96    size = 2048 + 4; 
     97 
     98    InitCommand( &cgc, p_buf, size, CGC_DATA_READ ); 
    38099 
    381100    cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; 
    382     cgc.cmd[6] = p_dvd->copyright.layer_num; 
    383     cgc.cmd[7] = p_dvd->type; 
    384     cgc.cmd[8] = cgc.buflen >> 8; 
    385     cgc.cmd[9] = cgc.buflen & 0xff; 
    386  
    387     if( (i_ret = SendCommand(i_fd, &cgc)) ) 
     101 
     102    cgc.cmd[7] = DVD_STRUCT_DISCKEY; 
     103    cgc.cmd[8] = size >> 8; 
     104    cgc.cmd[9] = size & 0xff; 
     105    cgc.cmd[10] = p_css->i_agid << 6; 
     106 
     107    i_ret = SendCommand( p_css->i_fd, &cgc ); 
     108 
     109    if( i_ret < 0 ) 
    388110    { 
    389111        return i_ret; 
    390112    } 
    391113 
    392     p_dvd->copyright.cpst = buf[4]; 
    393     p_dvd->copyright.rmi = buf[5]; 
    394  
     114    memcpy( p_key, p_buf + 4, 2048 ); 
     115    return i_ret; 
     116 
     117#else 
     118    return -1; 
     119 
     120#endif 
     121
     122 
     123/***************************************************************************** 
     124 * dvd_ReadCopyright:  
     125 ***************************************************************************** 
     126 *  
     127 *****************************************************************************/ 
     128int dvd_ReadCopyright( int i_fd, int i_layer, int *pi_copyright ) 
     129
     130#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD ) 
     131    int i_ret; 
     132    dvd_struct dvd; 
     133 
     134    dvd.type = DVD_STRUCT_COPYRIGHT; 
     135    dvd.copyright.layer_num = i_layer; 
     136 
     137    i_ret = ioctl( i_fd, DVD_READ_STRUCT, &dvd ); 
     138 
     139    *pi_copyright = dvd.copyright.cpst; 
     140    return i_ret; 
     141 
     142#elif defined( SYS_BEOS ) 
     143    int i_ret; 
     144    u8 p_buf[8]; 
     145    struct cdrom_generic_command cgc; 
     146 
     147    InitCommand( &cgc, p_buf, sizeof(p_buf), CGC_DATA_READ ); 
     148 
     149    cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; 
     150 
     151    cgc.cmd[6] = i_layer; 
     152    cgc.cmd[7] = DVD_STRUCT_COPYRIGHT; 
     153    cgc.cmd[8] = cgc.buflen >> 8; 
     154    cgc.cmd[9] = cgc.buflen & 0xff; 
     155 
     156    i_ret = SendCommand( i_fd, &cgc ); 
     157 
     158    *pi_copyright = p_buf[4]; 
     159    return i_ret; 
     160 
     161#elif defined( SYS_DARWIN1_3 ) 
     162    intf_ErrMsg( "css error: DVD ioctls not fully functional yet" ); 
     163    intf_ErrMsg( "css error: assuming disc is unencrypted" ); 
     164 
     165    *pi_copyright = 0; 
    395166    return 0; 
    396 
    397  
    398 /***************************************************************************** 
    399  * ReadKey: get a key from the DVD. 
    400  *****************************************************************************/ 
    401 static int ReadKey( int i_fd, dvd_struct *p_dvd ) 
    402 
    403     int i_ret, size; 
    404     u_char *buf; 
    405     struct cdrom_generic_command cgc; 
    406  
    407     size = sizeof( p_dvd->disckey.value ) + 4; 
    408  
    409 #if 0 
    410     if ((buf = (u_char *) kmalloc(size, GFP_KERNEL)) == NULL) 
    411     { 
    412         return -ENOMEM; 
    413     } 
    414 #endif 
    415     buf = (u_char *) malloc( size ); 
    416  
    417     InitGenericCommand( &cgc, buf, size, CGC_DATA_READ ); 
    418  
    419     cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; 
    420     cgc.cmd[7] = p_dvd->type; 
    421     cgc.cmd[8] = size >> 8; 
    422     cgc.cmd[9] = size & 0xff; 
    423     cgc.cmd[10] = p_dvd->disckey.agid << 6; 
    424  
    425     if( !(i_ret = SendCommand(i_fd, &cgc)) ) 
    426     { 
    427         memcpy( p_dvd->disckey.value, &buf[4], sizeof(p_dvd->disckey.value) ); 
    428     } 
    429  
    430     free( buf ); 
    431     return i_ret; 
    432 
    433  
    434 /***************************************************************************** 
    435  * ReadBCA: read the Burst Cutting Area of a DVD. 
    436  ***************************************************************************** 
    437  * The BCA is a special part of the DVD which is used to burn additional 
    438  * data after it has been manufactured. DIVX is an exemple. 
    439