]> git.sesse.net Git - vlc/blobdiff - plugins/dvd/dvd_ioctl.c
* fixes for the Qt plugin compilation under Debian
[vlc] / plugins / dvd / dvd_ioctl.c
index eeb91354784813d7f04f0654221f0f0703be68d5..b2b035529ef8f983239ee43951a76e72afc07bf9 100644 (file)
@@ -2,7 +2,7 @@
  * dvd_ioctl.c: DVD ioctl replacement function
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: dvd_ioctl.c,v 1.2 2001/02/26 12:16:28 sam Exp $
+ * $Id: dvd_ioctl.c,v 1.4 2001/04/02 23:30:41 sam Exp $
  *
  * Authors: Markus Kuespert <ltlBeBoy@beosmail.com>
  *          Samuel Hocevar <sam@zoy.org>
  *****************************************************************************/
 #include "defs.h"
 
+#include <sys/types.h>
 #include <netinet/in.h>
-#ifdef HAVE_SYS_IOCTL_H
-#   include <sys/ioctl.h>
-#endif
 #ifdef HAVE_SYS_DVDIO_H
+#   include <sys/ioctl.h>
 #   include <sys/dvdio.h>
 #endif
 #ifdef LINUX_DVD
+#   include <sys/ioctl.h>
 #   include <linux/cdrom.h>
 #endif
 #ifdef SYS_BEOS
+#   include <sys/ioctl.h>
 #   include <malloc.h>
 #   include <scsi.h>
 #endif
+#ifdef SYS_DARWIN1_3
+#   include <sys/ioctl.h>
+#   include <DVDioctl/DVDioctl.h>
+#endif
 
 #include "common.h"
 #include "intf_msg.h"
 
+#include "dvd_css.h"
 #include "dvd_ioctl.h"
 
 /*****************************************************************************
  * Local prototypes - BeOS specific
  *****************************************************************************/
 #if defined( SYS_BEOS )
-static int  ReadData          ( int i_fd, dvd_struct *p_dvd );
-static int  ReadCopyright     ( int i_fd, dvd_struct *p_dvd );
-static int  ReadKey           ( int i_fd, dvd_struct *p_dvd );
-static int  ReadBCA           ( int i_fd, dvd_struct *p_dvd );
-static int  ReadManufacturer  ( int i_fd, dvd_struct *p_dvd );
-
-static void InitGenericCommand( struct cdrom_generic_command *p_cgc,
-                                void *buf, int i_len, int i_type );
-static void InitReadCommand   ( struct cdrom_generic_command *p_cgc,
-                                unsigned i_agid, unsigned i_type );
-static void InitWriteCommand  ( struct cdrom_generic_command *p_cgc,
-                                unsigned i_agid, unsigned i_type );
-
+static void InitCommand ( struct cdrom_generic_command *p_cgc,
+                          void *buf, int i_len, int i_type );
 static int  SendCommand ( int i_fd, struct cdrom_generic_command *p_cgc );
 #endif
 
 /*****************************************************************************
- * dvd_ioctl: DVD ioctl() wrapper
+ * dvd_ReadKey: 
  *****************************************************************************
- * Since the DVD ioctls do not exist on every machine, we provide this wrapper
- * so that it becomes easier to port them to any architecture.
+ * 
  *****************************************************************************/
-int dvd_ioctl( int i_fd, unsigned long i_op, void *p_arg )
+int dvd_ReadKey( css_t *p_css, u8 *p_key )
 {
 #if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
-    return( ioctl( i_fd, i_op, p_arg ) );
-
-#elif defined( SYS_BEOS )
+    int i_ret;
+    dvd_struct dvd;
 
-    int           i_ret;
-    unsigned char buf[20];
+    dvd.type = DVD_STRUCT_DISCKEY;
+    dvd.disckey.agid = p_css->i_agid;
 
-    struct cdrom_generic_command p_cgc;
+    memset( dvd.disckey.value, 0, 2048 );
 
-    dvd_struct *p_dvd = (dvd_struct *)p_arg;
-    dvd_authinfo *p_authinfo = (dvd_authinfo *)p_arg;
+    i_ret = ioctl( p_css->i_fd, DVD_READ_STRUCT, &dvd );
 
-    switch ( i_op )
+    if( i_ret < 0 )
     {
-        case DVD_AUTH: /* Request type is "authentication" */
-        {
-            memset( buf, 0, sizeof( buf ) );
-            InitGenericCommand( &p_cgc, buf, 0, CGC_DATA_READ );
-
-            switch( p_authinfo->type )
-            {
-                case DVD_LU_SEND_AGID: /* LU data send */
-
-                    intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_AGID" );
-
-                    InitReadCommand( &p_cgc, p_authinfo->lsa.agid, 0 );
-
-                    i_ret = SendCommand( i_fd, &p_cgc );
-
-                    p_authinfo->lsa.agid = buf[7] >> 6;
-
-                    return i_ret;
-
-                case DVD_LU_SEND_KEY1:
-
-                    intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_KEY1" );
-
-                    InitReadCommand( &p_cgc, p_authinfo->lsk.agid, 2 );
+        return i_ret;
+    }
 
-                    i_ret = SendCommand( i_fd, &p_cgc );
+    memcpy( p_key, dvd.disckey.value, 2048 );
+    return i_ret;
 
-                    /* Copy the key */
-                    memcpy( p_authinfo->lsk.key, &buf[4], sizeof(dvd_key) );
+#elif defined( SYS_BEOS )
+    int i_ret, size;
+    u8 p_buf[ 2048 + 4];
+    struct cdrom_generic_command cgc;
 
-                    return i_ret;
+    size = 2048 + 4;
 
-                case DVD_LU_SEND_CHALLENGE:
+    InitCommand( &cgc, p_buf, size, CGC_DATA_READ );
 
-                    intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_CHALLENGE" );
+    cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
 
-                    InitReadCommand( &p_cgc, p_authinfo->lsc.agid, 1 );
+    cgc.cmd[7] = DVD_STRUCT_DISCKEY;
+    cgc.cmd[8] = size >> 8;
+    cgc.cmd[9] = size & 0xff;
+    cgc.cmd[10] = p_css->i_agid << 6;
 
-                    i_ret = SendCommand( i_fd, &p_cgc );
+    i_ret = SendCommand( p_css->i_fd, &cgc );
 
-                    /* Copy the challenge */
-                    memcpy( p_authinfo->lsc.chal, &buf[4],
-                            sizeof(dvd_challenge) );
+    if( i_ret < 0 )
+    {
+        return i_ret;
+    }
 
-                    return i_ret;
+    memcpy( p_key, p_buf + 4, 2048 );
+    return i_ret;
 
-                case DVD_LU_SEND_TITLE_KEY: /* Post-auth key */
+#else
+    return -1;
 
-                    intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_TITLE_KEY" );
+#endif
+}
 
-                    InitReadCommand( &p_cgc, p_authinfo->lstk.agid, 4 );
+/*****************************************************************************
+ * dvd_ReadCopyright: 
+ *****************************************************************************
+ * 
+ *****************************************************************************/
+int dvd_ReadCopyright( int i_fd, int i_layer, int *pi_copyright )
+{
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+    int i_ret;
+    dvd_struct dvd;
 
-                    p_cgc.cmd[5] = p_authinfo->lstk.lba;
-                    p_cgc.cmd[4] = p_authinfo->lstk.lba >> 8;
-                    p_cgc.cmd[3] = p_authinfo->lstk.lba >> 16;
-                    p_cgc.cmd[2] = p_authinfo->lstk.lba >> 24;
+    dvd.type = DVD_STRUCT_COPYRIGHT;
+    dvd.copyright.layer_num = i_layer;
 
-                    i_ret = SendCommand( i_fd, &p_cgc );
+    i_ret = ioctl( i_fd, DVD_READ_STRUCT, &dvd );
 
-                    p_authinfo->lstk.cpm = (buf[4] >> 7) & 1;
-                    p_authinfo->lstk.cp_sec = (buf[4] >> 6) & 1;
-                    p_authinfo->lstk.cgms = (buf[4] >> 4) & 3;
+    *pi_copyright = dvd.copyright.cpst;
+    return i_ret;
 
-                    /* Copy the key */
-                    memcpy( p_authinfo->lstk.title_key, &buf[5],
-                            sizeof(dvd_key) );
+#elif defined( SYS_BEOS )
+    int i_ret;
+    u8 p_buf[8];
+    struct cdrom_generic_command cgc;
 
-                    return i_ret;
+    InitCommand( &cgc, p_buf, sizeof(p_buf), CGC_DATA_READ );
 
-                case DVD_LU_SEND_ASF:
+    cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
 
-                    intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_ASF" );
+    cgc.cmd[6] = i_layer;
+    cgc.cmd[7] = DVD_STRUCT_COPYRIGHT;
+    cgc.cmd[8] = cgc.buflen >> 8;
+    cgc.cmd[9] = cgc.buflen & 0xff;
 
-                    InitReadCommand( &p_cgc, p_authinfo->lsasf.agid, 5 );
+    i_ret = SendCommand( i_fd, &cgc );
 
-                    i_ret = SendCommand( i_fd, &p_cgc );
+    *pi_copyright = p_buf[4];
+    return i_ret;
 
-                    p_authinfo->lsasf.asf = buf[7] & 1;
+#elif defined( SYS_DARWIN1_3 )
+    intf_ErrMsg( "css error: DVD ioctls not fully functional yet" );
+    intf_ErrMsg( "css error: assuming disc is unencrypted" );
 
-                    return i_ret;
+    *pi_copyright = 0;
+    return 0;
 
-                case DVD_HOST_SEND_CHALLENGE: /* LU data receive */
+#else
+    return -1;
 
-                    intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_CHALLENGE" );
+#endif
+}
 
-                    InitWriteCommand( &p_cgc, p_authinfo->hsc.agid, 1 );
-                    buf[1] = 0xe;
+/*****************************************************************************
+ * dvd_LUSendAgid: 
+ *****************************************************************************
+ * 
+ *****************************************************************************/
+int dvd_LUSendAgid( css_t *p_css )
+{
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+    int i_ret;
+    dvd_authinfo auth_info;
 
-                    /* Copy the challenge */
-                    memcpy( &buf[4], p_authinfo->hsc.chal,
-                            sizeof(dvd_challenge) );
+    auth_info.type = DVD_LU_SEND_AGID;
+    auth_info.lsa.agid = p_css->i_agid;
 
-                    if( (i_ret = SendCommand(i_fd, &p_cgc)) )
-                    {
-                        return i_ret;
-                    }
+    i_ret = ioctl( p_css->i_fd, DVD_AUTH, &auth_info );
 
-                    p_authinfo->type = DVD_LU_SEND_KEY1;
+    p_css->i_agid = auth_info.lsa.agid;
+    return i_ret;
 
-                    return 0;
+#elif defined( SYS_BEOS )
+    u8 p_buf[8];
+    int i_ret;
+    struct cdrom_generic_command cgc;
 
-                case DVD_HOST_SEND_KEY2:
+    //memset( p_buf, 0, sizeof( p_buf ) );
 
-                    intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_KEY2" );
+    InitCommand( &cgc, p_buf, 0, CGC_DATA_READ );
 
-                    InitWriteCommand( &p_cgc, p_authinfo->hsk.agid, 3 );
-                    buf[1] = 0xa;
+    cgc.cmd[0] = GPCMD_REPORT_KEY;
+    cgc.cmd[10] = 0x00 | (p_css->i_agid << 6);
+    cgc.buflen = 8;
+    cgc.cmd[9] = cgc.buflen;
+    cgc.data_direction = CGC_DATA_READ;
 
-                    /* Copy the key */
-                    memcpy( &buf[4], p_authinfo->hsk.key, sizeof(dvd_key) );
+    i_ret = SendCommand( p_css->i_fd, &cgc );
 
-                    if( (i_ret = SendCommand(i_fd, &p_cgc)) )
-                    {
-                        p_authinfo->type = DVD_AUTH_FAILURE;
-                        return i_ret;
-                    }
+    p_css->i_agid = p_buf[7] >> 6;
+    return i_ret;
 
-                    p_authinfo->type = DVD_AUTH_ESTABLISHED;
+#else
+    return -1;
 
-                    return 0;
+#endif
+}
 
-                case DVD_INVALIDATE_AGID: /* Misc */
+/*****************************************************************************
+ * dvd_InvalidateAgid: 
+ *****************************************************************************
+ * 
+ *****************************************************************************/
+int dvd_InvalidateAgid( css_t *p_css )
+{
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+    int i_ret;
+    dvd_authinfo auth_info;
 
-                    intf_WarnMsg( 2, "css DoAuth: DVD_INVALIDATE_AGID" );
+    auth_info.type = DVD_INVALIDATE_AGID;
+    auth_info.lsa.agid = p_css->i_agid;
 
-                    InitReadCommand( &p_cgc, p_authinfo->lsa.agid, 0x3f );
+    i_ret = ioctl( p_css->i_fd, DVD_AUTH, &auth_info );
 
-                   return SendCommand( i_fd, &p_cgc );
+    p_css->i_agid = auth_info.lsa.agid;
+    return i_ret;
 
-                case DVD_LU_SEND_RPC_STATE: /* Get region settings */
+#elif defined( SYS_BEOS )
+    u8 p_buf[0];
+    struct cdrom_generic_command cgc;
 
-                    intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_RPC_STATE "
-                                     "(unimplemented)" );
+    //memset( p_buf, 0, sizeof( p_buf ) );
 
-        #if 0
-                    p_dvdetup_report_key( &p_cgc, 0, 8 );
-                    memset( &rpc_state, 0, sizeof(rpc_state_t) );
-                    p_cgc.buffer = (char *) &rpc_state;
+    InitCommand( &cgc, p_buf, 0, CGC_DATA_READ );
 
-                    if( (i_ret = SendCommand(i_fd, &p_cgc)) )
-                    {
-                        return i_ret;
-                    }
+    cgc.cmd[0] = GPCMD_REPORT_KEY;
+    cgc.cmd[10] = 0x3f | (p_css->i_agid << 6);
+    cgc.cmd[9] = cgc.buflen = 0;
+    cgc.data_direction = CGC_DATA_READ;
 
-                    p_authinfo->lrpcs.type = rpc_state.type_code;
-                    p_authinfo->lrpcs.vra = rpc_state.vra;
-                    p_authinfo->lrpcs.ucca = rpc_state.ucca;
-                    p_authinfo->lrpcs.region_mask = rpc_state.region_mask;
-                    p_authinfo->lrpcs.rpc_scheme = rpc_state.rpc_scheme;
-        #endif
+    return SendCommand( p_css->i_fd, &cgc );
 
-                    return 0;
+#else
+    return -1;
 
-                case DVD_HOST_SEND_RPC_STATE: /* Set region settings */
+#endif
+}
 
-                    intf_WarnMsg( 2, "css DoAuth: DVD_HOST_SEND_RPC_STATE" );
+/*****************************************************************************
+ * dvd_HostSendChallenge: 
+ *****************************************************************************
+ * 
+ *****************************************************************************/
+int dvd_HostSendChallenge( css_t *p_css, u8 *p_challenge )
+{
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+    dvd_authinfo auth_info;
 
-                    InitWriteCommand( &p_cgc, 0, 6 );
-                    buf[1] = 6;
-                    buf[4] = p_authinfo->hrpcs.pdrc;
+    auth_info.type = DVD_HOST_SEND_CHALLENGE;
 
-                    return SendCommand( i_fd, &p_cgc );
+    memcpy( auth_info.hsc.chal, p_challenge, sizeof(dvd_challenge) );
 
-                default:
-                    intf_ErrMsg( "css DoAuth: invalid DVD key ioctl" );
-                    return -1;
+    return ioctl( p_css->i_fd, DVD_AUTH, &auth_info );
 
-            }
-        }
+#elif defined( SYS_BEOS )
+    u8 p_buf[16];
+    struct cdrom_generic_command cgc;
 
-        case DVD_READ_STRUCT: /* Request type is "read structure" */
-        {
-            switch( p_dvd->type )
-            {
-                case DVD_STRUCT_PHYSICAL:
+    //memset( p_buf, 0, sizeof( p_buf ) );
 
-                    intf_WarnMsg( 2, "css ReadStruct: DVD_STRUCT_PHYSICAL" );
+    InitCommand( &cgc, p_buf, 0, CGC_DATA_READ );
 
-                    return ReadData( i_fd, p_dvd );
+    cgc.cmd[0] = GPCMD_SEND_KEY;
+    cgc.cmd[10] = 0x01 | (p_css->i_agid << 6);
+    cgc.buflen = 16;
+    cgc.cmd[9] = cgc.buflen;
+    cgc.data_direction = CGC_DATA_WRITE;
 
-                case DVD_STRUCT_COPYRIGHT:
+    p_buf[1] = 0xe;
+    memcpy( p_buf + 4, p_challenge, sizeof(dvd_challenge) );
 
-                    intf_WarnMsg( 2, "css ReadStruct: DVD_STRUCT_COPYRIGHT" );
+    return SendCommand( p_css->i_fd, &cgc );
 
-                    return ReadCopyright( i_fd, p_dvd );
+#else
+    return -1;
 
-                case DVD_STRUCT_DISCKEY:
+#endif
+}
 
-                    intf_WarnMsg( 2, "css ReadStruct: DVD_STRUCT_DISCKEY" );
+/*****************************************************************************
+ * dvd_LUSendASF: 
+ *****************************************************************************
+ * 
+ *****************************************************************************/
+int dvd_LUSendASF( css_t *p_css, int *pi_asf )
+{
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+    int i_ret;
+    dvd_authinfo auth_info;
 
-                    return ReadKey( i_fd, p_dvd );
+    auth_info.type = DVD_LU_SEND_ASF;
+    auth_info.lsasf.agid = p_css->i_agid;
+    auth_info.lsasf.asf = *pi_asf;
 
-                case DVD_STRUCT_BCA:
+    i_ret = ioctl( p_css->i_fd, DVD_AUTH, &auth_info );
 
-                    intf_WarnMsg( 2, "css ReadStruct: DVD_STRUCT_BCA" );
+    *pi_asf = auth_info.lsasf.asf;
+    return i_ret;
 
-                    return ReadBCA( i_fd, p_dvd );
+#elif defined( SYS_BEOS )
+    int i_ret;
+    u8 p_buf[8];
+    struct cdrom_generic_command cgc;
 
-                case DVD_STRUCT_MANUFACT:
+    //memset( p_buf, 0, sizeof( p_buf ) );
 
-                    intf_WarnMsg( 2, "css ReadStruct: DVD_STRUCT_MANUFACT" );
+    InitCommand( &cgc, p_buf, 0, CGC_DATA_READ );
 
-                    return ReadManufacturer( i_fd, p_dvd );
+    cgc.cmd[0] = GPCMD_REPORT_KEY;
+    cgc.cmd[10] = 0x05 | (p_css->i_agid << 6);
+    cgc.buflen = 8;
+    cgc.cmd[9] = cgc.buflen;
+    cgc.data_direction = CGC_DATA_READ;
 
-                default:
-                    intf_WarnMsg( 2, "css ReadStruct: invalid request (%d)",
-                                  p_dvd->type );
+    i_ret = SendCommand( p_css->i_fd, &cgc );
 
-                    return -1;
-            }
-        }
+    *pi_asf = p_buf[7] & 1;
+    return i_ret;
 
-        default: /* Unknown request type */
-        {
-            intf_ErrMsg( "css error: unknown command 0x%x", i_op );
-            return -1;
-        }
-    }
 #else
-
     return -1;
+
 #endif
 }
 
-/* Local prototypes */
-
-#if defined( SYS_BEOS )
 /*****************************************************************************
- * ReadData: Get data structure information from the DVD.
+ * dvd_LUSendChallenge: 
+ *****************************************************************************
+ * 
  *****************************************************************************/
-static int ReadData( int i_fd, dvd_struct *p_dvd )
+int dvd_LUSendChallenge( css_t *p_css, u8 *p_challenge )
 {
-    int i_ret, i;
-    u_char buf[4 + 4 * 20], *base;
-    struct dvd_layer *layer;
-    struct cdrom_generic_command cgc;
-
-    InitGenericCommand( &cgc, buf, sizeof(buf), CGC_DATA_READ );
-
-    cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
-    cgc.cmd[6] = p_dvd->physical.layer_num;
-    cgc.cmd[7] = p_dvd->type;
-    cgc.cmd[9] = cgc.buflen & 0xff;
-
-    if( (i_ret = SendCommand(i_fd, &cgc)) )
-    {
-        return i_ret;
-    }
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+    int i_ret;
+    dvd_authinfo auth_info;
 
-    base = &buf[4];
-    layer = &p_dvd->physical.layer[0];
+    auth_info.type = DVD_LU_SEND_CHALLENGE;
 
-    /* place the data... really ugly, but at least we won't have to
-     * worry about endianess in userspace or here. */
-    for( i = 0; i < 4; ++i, base += 20, ++layer )
-    {
-        memset( layer, 0, sizeof(*layer) );
-
-        layer->book_version = base[0] & 0xf;
-        layer->book_type = base[0] >> 4;
-        layer->min_rate = base[1] & 0xf;
-        layer->disc_size = base[1] >> 4;
-        layer->layer_type = base[2] & 0xf;
-        layer->track_path = (base[2] >> 4) & 1;
-        layer->nlayers = (base[2] >> 5) & 3;
-        layer->track_density = base[3] & 0xf;
-        layer->linear_density = base[3] >> 4;
-        layer->start_sector = base[5] << 16 | base[6] << 8 | base[7];
-        layer->end_sector = base[9] << 16 | base[10] << 8 | base[11];
-        layer->end_sector_l0 = base[13] << 16 | base[14] << 8 | base[15];
-        layer->bca = base[16] >> 7;
-    }
+    i_ret = ioctl( p_css->i_fd, DVD_AUTH, &auth_info );
 
-    return 0;
-}
+    memcpy( p_challenge, auth_info.lsc.chal, sizeof(dvd_challenge) );
+    return i_ret;
 
-/*****************************************************************************
- * ReadCopyright: get copyright information from the DVD.
- *****************************************************************************/
-static int ReadCopyright( int i_fd, dvd_struct *p_dvd )
-{
+#elif defined( SYS_BEOS )
     int i_ret;
-    u_char buf[8];
+    u8 p_buf[16];
     struct cdrom_generic_command cgc;
 
-    InitGenericCommand( &cgc, buf, sizeof(buf), CGC_DATA_READ );
+    //memset( p_buf, 0, sizeof( p_buf ) );
 
-    cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
-    cgc.cmd[6] = p_dvd->copyright.layer_num;
-    cgc.cmd[7] = p_dvd->type;
-    cgc.cmd[8] = cgc.buflen >> 8;
-    cgc.cmd[9] = cgc.buflen & 0xff;
+    InitCommand( &cgc, p_buf, 0, CGC_DATA_READ );
 
-    if( (i_ret = SendCommand(i_fd, &cgc)) )
-    {
-        return i_ret;
-    }
+    cgc.cmd[0] = GPCMD_REPORT_KEY;
+    cgc.cmd[10] = 0x01 | (p_css->i_agid << 6);
+    cgc.buflen = 16;
+    cgc.cmd[9] = cgc.buflen;
+    cgc.data_direction = CGC_DATA_READ;
 
-    p_dvd->copyright.cpst = buf[4];
-    p_dvd->copyright.rmi = buf[5];
+    i_ret = SendCommand( p_css->i_fd, &cgc );
 
-    return 0;
+    memcpy( p_challenge, p_buf + 4, sizeof(dvd_challenge) );
+    return i_ret;
+
+#else
+    return -1;
+
+#endif
 }
 
 /*****************************************************************************
- * ReadKey: get a key from the DVD.
+ * dvd_LUSendKey1: 
+ *****************************************************************************
+ * 
  *****************************************************************************/
-static int ReadKey( int i_fd, dvd_struct *p_dvd )
+int dvd_LUSendKey1( css_t *p_css, u8 *p_key )
 {
-    int i_ret, size;
-    u_char *buf;
-    struct cdrom_generic_command cgc;
-
-    size = sizeof( p_dvd->disckey.value ) + 4;
-
-#if 0
-    if ((buf = (u_char *) kmalloc(size, GFP_KERNEL)) == NULL)
-    {
-        return -ENOMEM;
-    }
-#endif
-    buf = (u_char *) malloc( size );
-
-    InitGenericCommand( &cgc, buf, size, CGC_DATA_READ );
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+    int i_ret;
+    dvd_authinfo auth_info;
 
-    cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
-    cgc.cmd[7] = p_dvd->type;
-    cgc.cmd[8] = size >> 8;
-    cgc.cmd[9] = size & 0xff;
-    cgc.cmd[10] = p_dvd->disckey.agid << 6;
+    auth_info.type = DVD_LU_SEND_KEY1;
+    auth_info.lsk.agid = p_css->i_agid;
 
-    if( !(i_ret = SendCommand(i_fd, &cgc)) )
-    {
-        memcpy( p_dvd->disckey.value, &buf[4], sizeof(p_dvd->disckey.value) );
-    }
+    i_ret = ioctl( p_css->i_fd, DVD_AUTH, &auth_info );
 
-    free( buf );
+    memcpy( p_key, auth_info.lsk.key, sizeof(dvd_key) );
     return i_ret;
-}
 
-/*****************************************************************************
- * ReadBCA: read the Burst Cutting Area of a DVD.
- *****************************************************************************
- * The BCA is a special part of the DVD which is used to burn additional
- * data after it has been manufactured. DIVX is an exemple.
- *****************************************************************************/
-static int ReadBCA( int i_fd, dvd_struct *p_dvd )
-{
+#elif defined( SYS_BEOS )
     int i_ret;
-    u_char buf[4 + 188];
+    u8 p_buf[12];
     struct cdrom_generic_command cgc;
 
-    InitGenericCommand( &cgc, buf, sizeof(buf), CGC_DATA_READ );
+    //memset( p_buf, 0, sizeof( p_buf ) );
 
-    cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
-    cgc.cmd[7] = p_dvd->type;
-    cgc.cmd[9] = cgc.buflen = 0xff;
+    InitCommand( &cgc, p_buf, 0, CGC_DATA_READ );
 
-    if( (i_ret = SendCommand(i_fd, &cgc)) )
-    {
-        return i_ret;
-    }
+    cgc.cmd[0] = GPCMD_REPORT_KEY;
+    cgc.cmd[10] = 0x02 | (p_css->i_agid << 6);
+    cgc.buflen = 12;
+    cgc.cmd[9] = cgc.buflen;
+    cgc.data_direction = CGC_DATA_READ;
 
-    p_dvd->bca.len = buf[0] << 8 | buf[1];
-    if( p_dvd->bca.len < 12 || p_dvd->bca.len > 188 )
-    {
-        intf_ErrMsg( "css error: invalid BCA length (%d)", p_dvd->bca.len );
-        return -1;
-    }
+    i_ret = SendCommand( p_css->i_fd, &cgc );
 
-    memcpy( p_dvd->bca.value, &buf[4], p_dvd->bca.len );
+    memcpy( p_key, p_buf + 4, sizeof(dvd_key) );
+    return i_ret;
 
-    return 0;
+#else
+    return -1;
+
+#endif
 }
 
 /*****************************************************************************
- * ReadManufacturer: get manufacturer information from the DVD.
+ * dvd_HostSendKey2: 
+ *****************************************************************************
+ * 
  *****************************************************************************/
-static int ReadManufacturer( int i_fd, dvd_struct *p_dvd )
+int dvd_HostSendKey2( css_t *p_css, u8 *p_key )
 {
-    int i_ret = 0, size;
-    u_char *buf;
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+    dvd_authinfo auth_info;
+
+    auth_info.type = DVD_HOST_SEND_KEY2;
+    auth_info.hsk.agid = p_css->i_agid;
+
+    memcpy( auth_info.hsk.key, p_key, sizeof(dvd_key) );
+
+    return ioctl( p_css->i_fd, DVD_AUTH, &auth_info );
+
+#elif defined( SYS_BEOS )
+    u8 p_buf[12];
     struct cdrom_generic_command cgc;
 
-    size = sizeof( p_dvd->manufact.value ) + 4;
+    //memset( p_buf, 0, sizeof( p_buf ) );
 
-#if 0
-    if( (buf = (u_char *) kmalloc(size, GFP_KERNEL)) == NULL )
-    {
-        return -ENOMEM;
-    }
-#endif
-    buf = (u_char *) malloc(size);
+    InitCommand( &cgc, p_buf, 0, CGC_DATA_READ );
 
-    InitGenericCommand( &cgc, buf, size, CGC_DATA_READ );
+    cgc.cmd[0] = GPCMD_SEND_KEY;
+    cgc.cmd[10] = 0x3 | (p_css->i_agid << 6);
+    cgc.buflen = 12;
+    cgc.cmd[9] = cgc.buflen;
+    cgc.data_direction = CGC_DATA_WRITE;
 
-    cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
-    cgc.cmd[7] = p_dvd->type;
-    cgc.cmd[8] = size >> 8;
-    cgc.cmd[9] = size & 0xff;
+    p_buf[1] = 0xa;
+    memcpy( p_buf + 4, p_key, sizeof(dvd_key) );
 
-    if( (i_ret = SendCommand(i_fd, &cgc)) )
-    {
-        return i_ret;
-    }
+    return SendCommand( p_css->i_fd, &cgc );
 
-    p_dvd->manufact.len = buf[0] << 8 | buf[1];
-    if( p_dvd->manufact.len < 0 || p_dvd->manufact.len > 2048 )
-    {
-        intf_ErrMsg( "css error: invalid manufacturer info length (%d)",
-                     p_dvd->bca.len );
-        i_ret = -1;
-    }
-    else
-    {
-        memcpy( p_dvd->manufact.value, &buf[4], p_dvd->manufact.len );
-    }
+#else
+    return -1;
 
-    free( buf );
-    return i_ret;
+#endif
 }
 
+/* Local prototypes */
+
+#if defined( SYS_BEOS )
 /*****************************************************************************
- * InitGenericCommand: initialize a CGC structure
+ * InitCommand: initialize a CGC structure
  *****************************************************************************
  * This function initializes a CDRom Generic Command structure for
  * future use, either a read command or a write command.
  *****************************************************************************/
-static void InitGenericCommand( struct cdrom_generic_command *p_cgc,
-                                void *buf, int i_len, int i_type )
+static void InitCommand( struct cdrom_generic_command *p_cgc,
+                         void *p_buf, int i_len, int i_type )
 {
     memset( p_cgc, 0, sizeof( struct cdrom_generic_command ) );
 
-    if( buf != NULL )
+    if( p_buf != NULL )
     {
-        memset( buf, 0, i_len );
+        memset( p_buf, 0, i_len );
     }
 
-    p_cgc->buffer = ( char * )buf;
+    p_cgc->buffer = ( char * )p_buf;
     p_cgc->buflen = i_len;
     p_cgc->data_direction = i_type;
     p_cgc->timeout = 255;
 }
 
-/*****************************************************************************
- * InitReadCommand: fill a CGC structure for reading purposes.
- *****************************************************************************
- * This function fills a CDRom Generic Command for a command which will
- * read data from the DVD.
- *****************************************************************************/
-static void InitReadCommand( struct cdrom_generic_command *p_cgc,
-                             unsigned i_agid, unsigned i_type )
-{
-    p_cgc->cmd[0] = GPCMD_REPORT_KEY;
-    p_cgc->cmd[10] = i_type | (i_agid << 6);
-
-    /* FIXME: check what i_type means */
-    switch( i_type )
-    {
-        case 0:
-        case 8:
-        case 5:
-            p_cgc->buflen = 8;
-            break;
-
-        case 1:
-            p_cgc->buflen = 16;
-            break;
-
-        case 2:
-        case 4:
-            p_cgc->buflen = 12;
-            break;
-    }
-
-    p_cgc->cmd[9] = p_cgc->buflen;
-    p_cgc->data_direction = CGC_DATA_READ;
-}
-
-/*****************************************************************************
- * InitWriteCommand: fill a CGC structure for writing purposes.
- *****************************************************************************
- * This function fills a CDRom Generic Command for a command which will
- * send data to the DVD.
- *****************************************************************************/
-static void InitWriteCommand( struct cdrom_generic_command *p_cgc,
-                              unsigned i_agid, unsigned i_type )
-{
-    p_cgc->cmd[0] = GPCMD_SEND_KEY;
-    p_cgc->cmd[10] = i_type | (i_agid << 6);
-
-    /* FIXME: check what i_type means */
-    switch( i_type )
-    {
-        case 1:
-            p_cgc->buflen = 16;
-            break;
-
-        case 3:
-            p_cgc->buflen = 12;
-            break;
-
-        case 6:
-            p_cgc->buflen = 8;
-            break;
-    }
-
-    p_cgc->cmd[9] = p_cgc->buflen;
-    p_cgc->data_direction = CGC_DATA_WRITE;
-}
-
 /*****************************************************************************
  * SendCommand: send a raw device command to the DVD drive.
  *****************************************************************************