Commit 57801bcb authored by Sam Hocevar's avatar Sam Hocevar

  * additional enhancements to the OS X DVD ioctl module
  * big cleaning of the BeOS DVD ioctl code, got rid of all Linuxisms
parent 0fee43a4
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2000 Apple Computer, Inc. All rights reserved. * Copyright (C) 1998-2000 Apple Computer, Inc. All rights reserved.
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: DVDioctl.cpp,v 1.1 2001/04/02 23:30:41 sam Exp $ * $Id: DVDioctl.cpp,v 1.2 2001/04/04 02:49:18 sam Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -29,6 +29,9 @@ ...@@ -29,6 +29,9 @@
* it is still in use * it is still in use
*****************************************************************************/ *****************************************************************************/
//XXX: uncomment to activate the key exchange ioctls - may hang the machine
//#define ACTIVATE_DANGEROUS_IOCTL 1
/***************************************************************************** /*****************************************************************************
* Preamble * Preamble
*****************************************************************************/ *****************************************************************************/
...@@ -49,8 +52,9 @@ extern "C" ...@@ -49,8 +52,9 @@ extern "C"
#include <IOKit/IOLib.h> #include <IOKit/IOLib.h>
#include <IOKit/IOService.h> #include <IOKit/IOService.h>
#include <IOKit/storage/IODVDMedia.h>
#include <IOKit/storage/IOMedia.h> #include <IOKit/storage/IOMedia.h>
#include <IOKit/storage/IODVDMedia.h>
#include <IOKit/storage/IODVDBlockStorageDriver.h>
#include "DVDioctl.h" #include "DVDioctl.h"
...@@ -84,17 +88,17 @@ typedef struct buf buf_t; ...@@ -84,17 +88,17 @@ typedef struct buf buf_t;
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
static int DVDClose ( dev_t, int, int, struct proc * ); static int DVDClose ( dev_t, int, int, struct proc * );
static int DVDIoctl ( dev_t, u_long, caddr_t, int, struct proc * ); static int DVDBlockIoctl ( dev_t, u_long, caddr_t, int, struct proc * );
static int DVDOpen ( dev_t, int, int, struct proc * ); static int DVDOpen ( dev_t, int, int, struct proc * );
static int DVDSize ( dev_t ); static int DVDSize ( dev_t );
static void DVDStrategy ( buf_t * ); static void DVDStrategy ( buf_t * );
static int DVDReadWrite( dkr_t, dkrtype_t ); static int DVDReadWrite ( dkr_t, dkrtype_t );
static void DVDReadWriteCompletion( void *, void *, IOReturn, UInt64 ); static void DVDReadWriteCompletion( void *, void *, IOReturn, UInt64 );
static struct bdevsw device_functions = static struct bdevsw device_functions =
{ {
DVDOpen, DVDClose, DVDStrategy, DVDIoctl, eno_dump, DVDSize, D_DISK DVDOpen, DVDClose, DVDStrategy, DVDBlockIoctl, eno_dump, DVDSize, D_DISK
}; };
/***************************************************************************** /*****************************************************************************
...@@ -106,6 +110,7 @@ static bool b_inuse; ...@@ -106,6 +110,7 @@ static bool b_inuse;
static int i_major; static int i_major;
static void *p_node; static void *p_node;
static IODVDMedia *p_dvd; static IODVDMedia *p_dvd;
static IODVDBlockStorageDriver *p_drive;
/***************************************************************************** /*****************************************************************************
* DKR_GET_DEV: borrowed from IOMediaBSDClient.cpp * DKR_GET_DEV: borrowed from IOMediaBSDClient.cpp
...@@ -249,6 +254,7 @@ bool DVDioctl::init( OSDictionary *p_dict = 0 ) ...@@ -249,6 +254,7 @@ bool DVDioctl::init( OSDictionary *p_dict = 0 )
p_node = NULL; p_node = NULL;
p_dvd = NULL; p_dvd = NULL;
p_drive = NULL;
i_major = -1; i_major = -1;
b_inuse = false; b_inuse = false;
...@@ -341,20 +347,6 @@ void DVDioctl::free( void ) ...@@ -341,20 +347,6 @@ void DVDioctl::free( void )
super::free( ); super::free( );
} }
#if 0
IOReturn DVDioctl::report( IODVDMedia *DVD, IOMemoryDescriptor *buffer, const DVDKeyClass keyClass, const UInt32 lba, const UInt8 agid, const DVDKeyFormat keyFormat )
{
IOLog( "DVD ioctl: reportkey\n" );
return DVD->getProvider()->reportKey( buffer, keyClass, lba, agid, keyFormat );
}
IOReturn DVDioctl::send( IODVDMedia *DVD, IOMemoryDescriptor *buffer, const DVDKeyClass keyClass, const UInt32 lba, const DVDKeyFormat keyFormat )
{
IOLog( "DVD ioctl: sendkey\n" );
return DVD->getProvider()->sendKey( buffer, keyClass, lba, keyFormat );
}
#endif
/* following functions are local */ /* following functions are local */
/***************************************************************************** /*****************************************************************************
...@@ -363,7 +355,6 @@ IOReturn DVDioctl::send( IODVDMedia *DVD, IOMemoryDescriptor *buffer, const DVDK ...@@ -363,7 +355,6 @@ IOReturn DVDioctl::send( IODVDMedia *DVD, IOMemoryDescriptor *buffer, const DVDK
static int DVDOpen( dev_t dev, int flags, int devtype, struct proc * ) static int DVDOpen( dev_t dev, int flags, int devtype, struct proc * )
{ {
IOStorageAccess level; IOStorageAccess level;
int i_err;
/* Check that the device hasn't already been opened */ /* Check that the device hasn't already been opened */
if( b_inuse ) if( b_inuse )
...@@ -408,19 +399,18 @@ static int DVDOpen( dev_t dev, int flags, int devtype, struct proc * ) ...@@ -408,19 +399,18 @@ static int DVDOpen( dev_t dev, int flags, int devtype, struct proc * )
level = (flags & FWRITE) ? kIOStorageAccessReaderWriter level = (flags & FWRITE) ? kIOStorageAccessReaderWriter
: kIOStorageAccessReader; : kIOStorageAccessReader;
if( p_dvd->open( p_this, 0, level) ) if( ! p_dvd->open( p_this, 0, level) )
{
log( LOG_INFO, "DVD ioctl: IODVDMedia->open()\n" );
i_err = 0;
}
else
{ {
log( LOG_INFO, "DVD ioctl: IODVDMedia object busy\n" ); log( LOG_INFO, "DVD ioctl: IODVDMedia object busy\n" );
b_inuse = false; b_inuse = false;
i_err = EBUSY; return EBUSY;
} }
return i_err; p_drive = p_dvd->getProvider();
log( LOG_INFO, "DVD ioctl: IODVDMedia->open()\n" );
return 0;
} }
/***************************************************************************** /*****************************************************************************
...@@ -430,6 +420,9 @@ static int DVDClose( dev_t dev, int flags, int devtype, struct proc * ) ...@@ -430,6 +420,9 @@ static int DVDClose( dev_t dev, int flags, int devtype, struct proc * )
{ {
/* Release the device */ /* Release the device */
p_dvd->close( p_this ); p_dvd->close( p_this );
p_dvd = NULL;
p_drive = NULL;
b_inuse = false; b_inuse = false;
log( LOG_INFO, "DVD ioctl: IODVDMedia->close()\n" ); log( LOG_INFO, "DVD ioctl: IODVDMedia->close()\n" );
...@@ -455,27 +448,59 @@ static void DVDStrategy( buf_t * bp ) ...@@ -455,27 +448,59 @@ static void DVDStrategy( buf_t * bp )
} }
/***************************************************************************** /*****************************************************************************
* DVDIoctl: issue an ioctl on the device * DVDBlockIoctl: issue an ioctl on the block device
*****************************************************************************/ *****************************************************************************/
static int DVDIoctl( dev_t dev, u_long cmd, caddr_t addr, int flags, static int DVDBlockIoctl( dev_t dev, u_long cmd, caddr_t addr, int flags,
struct proc *p ) struct proc *p )
{ {
dvdioctl_data_t * p_data = (dvdioctl_data_t *)addr;
switch( cmd ) switch( cmd )
{ {
case IODVD_READ_STRUCTURE: case IODVD_READ_STRUCTURE:
//log( LOG_INFO, "DVD ioctl: IODVD_READ_STRUCTURE\n" );
log( LOG_INFO, "DVD ioctl: IODVD_READ_STRUCTURE\n" );
return 0; return 0;
case IODVD_SEND_KEY: case IODVD_SEND_KEY:
//log( LOG_INFO, "DVD ioctl: IODVD_SEND_KEY\n" );
return 0; log( LOG_INFO, "DVD ioctl: send key to `%s', "
"buf %d, format %d, class %d, agid %d\n",
p_drive->getDeviceTypeName(),
(int)p_data->p_buffer, p_data->i_keyformat,
p_data->i_keyclass, p_data->i_agid );
#ifdef ACTIVATE_DANGEROUS_IOCTL
return p_drive->sendKey( (IOMemoryDescriptor *)p_data->p_buffer,
(DVDKeyClass)p_data->i_keyclass,
p_data->i_agid,
(DVDKeyFormat)p_data->i_keyformat );
#else
return -1;
#endif
case IODVD_REPORT_KEY: case IODVD_REPORT_KEY:
//log( LOG_INFO, "DVD ioctl: IODVD_REPORT_KEY\n" );
return 0; log( LOG_INFO, "DVD ioctl: report key from `%s', "
p_drive->getDeviceTypeName(),
"buf %d, class %d, lba %d, agid %d, format %d\n",
(int)p_data->p_buffer, p_data->i_keyclass, p_data->i_lba,
p_data->i_agid, p_data->i_keyformat );
#ifdef ACTIVATE_DANGEROUS_IOCTL
return p_drive->reportKey( (IOMemoryDescriptor *)p_data->p_buffer,
(DVDKeyClass)p_data->i_keyclass,
p_data->i_lba, p_data->i_agid,
(DVDKeyFormat)p_data->i_keyformat );
#else
return -1;
#endif
default: default:
//log( LOG_INFO, "DVD ioctl: unknown ioctl\n" );
log( LOG_INFO, "DVD ioctl: unknown ioctl\n" );
return EINVAL; return EINVAL;
} }
} }
...@@ -591,7 +616,7 @@ static void DVDReadWriteCompletion( void * target, ...@@ -591,7 +616,7 @@ static void DVDReadWriteCompletion( void * target,
if ( status != kIOReturnSuccess ) if ( status != kIOReturnSuccess )
{ {
IOLog( "%s: %s.\n", /*p_this->name*/ "DVD ioctl", IOLog( "DVD ioctl: %s (is the disc authenticated ?)\n",
p_this->stringFromReturn(status) ); p_this->stringFromReturn(status) );
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* DVDioctl.h: Linux-like DVD driver for Darwin and MacOS X * DVDioctl.h: Linux-like DVD driver for Darwin and MacOS X
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: DVDioctl.h,v 1.1 2001/04/02 23:30:41 sam Exp $ * $Id: DVDioctl.h,v 1.2 2001/04/04 02:49:18 sam Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -21,8 +21,49 @@ ...@@ -21,8 +21,49 @@
* under the License. * under the License.
*****************************************************************************/ *****************************************************************************/
struct sum { int a, b, r; }; #if defined(KERNEL)
#define IODVD_READ_STRUCTURE _IOWR('B', 1, struct sum) /* Everything has already been defined */
#define IODVD_SEND_KEY _IOWR('B', 2, struct sum) #else
#define IODVD_REPORT_KEY _IOWR('B', 3, struct sum) enum DVDKeyFormat
{
kCSSAGID = 0x00,
kChallengeKey = 0x01,
kKey1 = 0x02,
kKey2 = 0x03,
kTitleKey = 0x04,
kASF = 0x05,
kSetRegion = 0x06,
kRPCState = 0x08,
kCSS2AGID = 0x10,
kCPRMAGID = 0x11,
kInvalidateAGID = 0x3f
};
enum DVDKeyClass
{
kCSS_CSS2_CPRM = 0x00,
kRSSA = 0x01
};
#endif
typedef struct dvdioctl_data
{
void *p_buffer;
#if defined(KERNEL)
UInt32 i_lba;
UInt8 i_agid;
#else
u32 i_lba;
u8 i_agid;
#endif
int i_keyclass;
int i_keyformat;
} dvdioctl_data_t;
#define IODVD_READ_STRUCTURE _IOWR('B', 1, dvdioctl_data_t)
#define IODVD_SEND_KEY _IOWR('B', 2, dvdioctl_data_t)
#define IODVD_REPORT_KEY _IOWR('B', 3, dvdioctl_data_t)
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* dvd_css.c: Functions for DVD authentification and unscrambling * dvd_css.c: Functions for DVD authentification and unscrambling
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: dvd_css.c,v 1.19 2001/04/02 23:30:41 sam Exp $ * $Id: dvd_css.c,v 1.20 2001/04/04 02:49:18 sam Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -71,7 +71,7 @@ int CSSTest( int i_fd ) ...@@ -71,7 +71,7 @@ int CSSTest( int i_fd )
{ {
int i_ret, i_copyright; int i_ret, i_copyright;
i_ret = dvd_ReadCopyright( i_fd, 0 /* i_layer */, &i_copyright ); i_ret = ioctl_ReadCopyright( i_fd, 0 /* i_layer */, &i_copyright );
if( i_ret < 0 ) if( i_ret < 0 )
{ {
...@@ -105,10 +105,11 @@ int CSSInit( css_t * p_css ) ...@@ -105,10 +105,11 @@ int CSSInit( css_t * p_css )
return -1; return -1;
case 1: case 1:
intf_WarnMsg( 3, "css info: already authenticated" );
return 0; return 0;
case 0: case 0:
intf_WarnMsg( 3, "css info: authenticating" ); intf_WarnMsg( 3, "css info: need to authenticate" );
} }
/* Init sequence, request AGID */ /* Init sequence, request AGID */
...@@ -116,7 +117,7 @@ int CSSInit( css_t * p_css ) ...@@ -116,7 +117,7 @@ int CSSInit( css_t * p_css )
{ {
intf_WarnMsg( 3, "css info: requesting AGID %d", i ); intf_WarnMsg( 3, "css info: requesting AGID %d", i );
i_ret = dvd_LUSendAgid( p_css ); i_ret = ioctl_LUSendAgid( p_css );
if( i_ret != -1 ) if( i_ret != -1 )
{ {
...@@ -127,7 +128,7 @@ int CSSInit( css_t * p_css ) ...@@ -127,7 +128,7 @@ int CSSInit( css_t * p_css )
intf_ErrMsg( "css error: AGID N/A, invalidating" ); intf_ErrMsg( "css error: AGID N/A, invalidating" );
p_css->i_agid = 0; p_css->i_agid = 0;
dvd_InvalidateAgid( p_css ); ioctl_InvalidateAgid( p_css );
} }
/* Unable to authenticate without AGID */ /* Unable to authenticate without AGID */
...@@ -149,14 +150,14 @@ int CSSInit( css_t * p_css ) ...@@ -149,14 +150,14 @@ int CSSInit( css_t * p_css )
} }
/* Send challenge to LU */ /* Send challenge to LU */
if( dvd_HostSendChallenge( p_css, p_buffer ) < 0 ) if( ioctl_HostSendChallenge( p_css, p_buffer ) < 0 )
{ {
intf_ErrMsg( "css error: failed sending challenge to LU" ); intf_ErrMsg( "css error: failed sending challenge to LU" );
return -1; return -1;
} }
/* Get key1 from LU */ /* Get key1 from LU */
if( dvd_LUSendKey1( p_css, p_buffer ) < 0) if( ioctl_LUSendKey1( p_css, p_buffer ) < 0)
{ {
intf_ErrMsg( "css error: failed getting key1 from LU" ); intf_ErrMsg( "css error: failed getting key1 from LU" );
return -1; return -1;
...@@ -189,7 +190,7 @@ int CSSInit( css_t * p_css ) ...@@ -189,7 +190,7 @@ int CSSInit( css_t * p_css )
} }
/* Get challenge from LU */ /* Get challenge from LU */
if( dvd_LUSendChallenge( p_css, p_buffer ) < 0 ) if( ioctl_LUSendChallenge( p_css, p_buffer ) < 0 )
{ {
intf_ErrMsg( "css error: failed getting challenge from LU" ); intf_ErrMsg( "css error: failed getting challenge from LU" );
return -1; return -1;
...@@ -211,7 +212,7 @@ int CSSInit( css_t * p_css ) ...@@ -211,7 +212,7 @@ int CSSInit( css_t * p_css )
} }
/* Send key2 to LU */ /* Send key2 to LU */
if( dvd_HostSendKey2( p_css, p_buffer ) < 0 ) if( ioctl_HostSendKey2( p_css, p_buffer ) < 0 )
{ {
intf_ErrMsg( "css error: failed sending key2 to LU" ); intf_ErrMsg( "css error: failed sending key2 to LU" );
return -1; return -1;
...@@ -238,14 +239,15 @@ int CSSInit( css_t * p_css ) ...@@ -238,14 +239,15 @@ int CSSInit( css_t * p_css )
return -1; return -1;
case 1: case 1:
intf_WarnMsg( 3, "css info: already authenticated" );
return 0; return 0;
case 0: case 0:
intf_WarnMsg( 3, "css info: getting disc key" ); intf_WarnMsg( 3, "css info: need to get disc key" );
} }
/* Get encrypted disc key */ /* Get encrypted disc key */
if( dvd_ReadKey( p_css, p_buffer ) < 0 ) if( ioctl_ReadKey( p_css, p_buffer ) < 0 )
{ {
intf_ErrMsg( "css error: could not read Disc Key" ); intf_ErrMsg( "css error: could not read Disc Key" );
return -1; return -1;
...@@ -262,21 +264,22 @@ int CSSInit( css_t * p_css ) ...@@ -262,21 +264,22 @@ int CSSInit( css_t * p_css )
switch( CSSGetASF( p_css ) ) switch( CSSGetASF( p_css ) )
{ {
case -1: case -1:
case 0:
return -1; return -1;
case 1: case 1:
intf_WarnMsg( 3, "css info: successfully authenticated" );
return 0; return 0;
}
return 0; case 0:
intf_WarnMsg( 3, "css info: no way to authenticate" );
}
#else /* HAVE_CSS */ #else /* HAVE_CSS */
intf_ErrMsg( "css error: CSS decryption is disabled in this module" ); intf_ErrMsg( "css error: CSS decryption is disabled in this module" );
#endif /* HAVE_CSS */
return -1; return -1;
#endif /* HAVE_CSS */
} }
/***************************************************************************** /*****************************************************************************
...@@ -475,8 +478,10 @@ int CSSGetKey( css_t * p_css ) ...@@ -475,8 +478,10 @@ int CSSGetKey( css_t * p_css )
p_title_key[i_highest].pi_key, KEY_SIZE ); p_title_key[i_highest].pi_key, KEY_SIZE );
return 0; return 0;
#else /* HAVE_CSS */ #else /* HAVE_CSS */
return 1; return 1;
#endif /* HAVE_CSS */ #endif /* HAVE_CSS */
} }
...@@ -522,15 +527,16 @@ int CSSDescrambleSector( dvd_key_t pi_key, u8* pi_sec ) ...@@ -522,15 +527,16 @@ int CSSDescrambleSector( dvd_key_t pi_key, u8* pi_sec )
} }
return 0; return 0;
#else /* HAVE_CSS */ #else /* HAVE_CSS */
return 1; return 1;
#endif /* HAVE_CSS */ #endif /* HAVE_CSS */
} }
#ifdef HAVE_CSS #ifdef HAVE_CSS
/*
* Following functions are local /* Following functions are local */
*/
/***************************************************************************** /*****************************************************************************
* CSSGetASF : Get Authentification success flag * CSSGetASF : Get Authentification success flag
...@@ -546,7 +552,7 @@ static int CSSGetASF( css_t *p_css ) ...@@ -546,7 +552,7 @@ static int CSSGetASF( css_t *p_css )
for( p_css->i_agid = 0 ; p_css->i_agid < 4 ; p_css->i_agid++ ) for( p_css->i_agid = 0 ; p_css->i_agid < 4 ; p_css->i_agid++ )
{ {
if( dvd_LUSendASF( p_css, &i_asf ) == 0 ) if( ioctl_LUSendASF( p_css, &i_asf ) == 0 )
{ {
intf_WarnMsg( 3, "css info: %sauthenticated", i_asf ? "":"not " ); intf_WarnMsg( 3, "css info: %sauthenticated", i_asf ? "":"not " );
...@@ -898,5 +904,6 @@ static int CSSCracker( int i_start, ...@@ -898,5 +904,6 @@ static int CSSCracker( int i_start,
return i_exit; return i_exit;
} }
#endif /* HAVE_CSS */ #endif /* HAVE_CSS */
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* dvd_ifo.h: Structures for ifo parsing * dvd_ifo.h: Structures for ifo parsing
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: dvd_ifo.h,v 1.9 2001/04/01 07:31:38 stef Exp $ * $Id: dvd_ifo.h,v 1.10 2001/04/04 02:49:18 sam Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -86,8 +86,8 @@ typedef struct command_desc_s ...@@ -86,8 +86,8 @@ typedef struct command_desc_s
u8 i_sub_cmd :4; u8 i_sub_cmd :4;
union union
{ {
u8 pi_8[6]; u8 pi_8[6];
u16 pi_16[3]; u16 pi_16[3];
} data;