* ioctl.c: DVD ioctl replacement function
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: ioctl.c,v 1.6 2001/08/06 13:28:00 sam Exp $
+ * $Id: ioctl.c,v 1.16 2001/12/11 14:43:38 sam Exp $
*
* Authors: Markus Kuespert <ltlBeBoy@beosmail.com>
* Samuel 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>
*
* 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
*****************************************************************************/
#include "defs.h"
+#include <stdio.h>
+
#include <string.h> /* memcpy(), memset() */
#include <sys/types.h>
#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_dvdioctl/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 <unistd.h>
+# include <stropts.h>
+# include <sys/scsi/scsi_types.h>
+# include <sys/scsi/impl/uscsi.h>
+#endif
-#include "config.h"
#include "common.h"
#ifdef SYS_DARWIN
-# include "DVDioctl/DVDioctl.h"
+# include <IOKit/storage/IODVDMediaBSDClient.h>
+/* # include "DVDioctl/DVDioctl.h" */
#endif
#include "ioctl.h"
+
/*****************************************************************************
* Local prototypes, BeOS specific
*****************************************************************************/
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 );
+#endif
+
/*****************************************************************************
* Local prototypes, win32 (aspi) specific
*****************************************************************************/
{
int i_ret;
-#if defined( DVD_STRUCT_IN_LINUX_CDROM_H )
+#if defined( HAVE_LINUX_DVD_STRUCT )
dvd_struct dvd;
dvd.type = DVD_STRUCT_COPYRIGHT;
*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 = ioctl(i_fd, USCSICMD, &sc);
+
+ if( i_ret < 0 || sc.uscsi_status ) {
+ i_ret = -1;
+ }
+
+ *pi_copyright = p_buffer[ 4 ];
+ /* s->copyright.rmi = p_buffer[ 5 ]; */
+
#elif defined( SYS_DARWIN )
- *pi_copyright = 1;
+ dk_dvd_read_structure_t dvd;
+ DVDCopyrightInfo dvdcpi;
+
+ memset(&dvd, 0, sizeof(dvd));
+ memset(&dvdcpi, 0, sizeof(dvdcpi));
- i_ret = 0;
+ dvd.buffer = &dvdcpi;
+ dvd.bufferLength = sizeof(dvdcpi);
+ dvd.format = kDVDStructureFormatCopyrightInfo;
+ dvd.layer = i_layer;
+
+ /* dvdcpi.dataLength[0] = 0x00; */ /* dataLength[0] is already memset to 0 */
+ /* dvdcpi.dataLength[1] = 0x06; */
+
+ i_ret = ioctl( i_fd, DKIOCDVDREADSTRUCTURE, &dvd );
+
+ *pi_copyright = dvdcpi.copyrightProtectionSystemType;
#elif defined( WIN32 )
if( WIN2K ) /* NT/Win2000/Whistler */
}
/*****************************************************************************
- * ioctl_ReadKey: get the disc key
+ * ioctl_ReadDiscKey: get the disc key
*****************************************************************************/
-int ioctl_ReadKey( int i_fd, int *pi_agid, u8 *p_key )
+int ioctl_ReadDiscKey( int i_fd, int *pi_agid, u8 *p_key )
{
int i_ret;
-#if defined( DVD_STRUCT_IN_LINUX_CDROM_H )
+#if defined( HAVE_LINUX_DVD_STRUCT )
dvd_struct dvd;
dvd.type = DVD_STRUCT_DISCKEY;
memcpy( p_key, p_buffer + 4, 2048 );
+#elif defined( HPUX_SCTL_IO )
+ INIT_SCTL_IO( GPCMD_READ_DVD_STRUCTURE, 2048 + 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, 2048 );
+
+#elif defined( SOLARIS_USCSI )
+ INIT_USCSI( GPCMD_READ_DVD_STRUCTURE, 2048 + 4 );
+
+ rs_cdb.cdb_opaque[ 7 ] = DVD_STRUCT_DISCKEY;
+ rs_cdb.cdb_opaque[ 10 ] = *pi_agid << 6;
+
+ i_ret = ioctl( i_fd, USCSICMD, &sc );
+
+ if( i_ret < 0 || sc.uscsi_status )
+ {
+ i_ret = -1;
+ return i_ret;
+ }
+
+ memcpy( p_key, p_buffer + 4, 2048 );
+
#elif defined( SYS_DARWIN )
- i_ret = 0;
+ dk_dvd_read_structure_t dvd;
+ DVDDiscKeyInfo dvddki;
+
+ memset(&dvd, 0, sizeof(dvd));
+ memset(&dvddki, 0, sizeof(dvddki));
+
+ dvd.buffer = &dvddki;
+ dvd.bufferLength = sizeof(dvddki);
+ dvd.format = kDVDStructureFormatDiscKeyInfo;
+ dvd.grantID = *pi_agid;
+
+ /* 2048+2 ; maybe we should do bit shifts to value of (sizeof(dvddki)-2) */
+ dvddki.dataLength[0] = 0x04;
+ dvddki.dataLength[1] = 0x02;
- memset( p_key, 0x00, 2048 );
+ i_ret = ioctl( i_fd, DKIOCDVDREADSTRUCTURE, &dvd );
+
+ memcpy( p_key, dvddki.discKeyStructures, sizeof(dvddki.discKeyStructures) );
#elif defined( WIN32 )
if( WIN2K ) /* NT/Win2000/Whistler */
return i_ret;
}
+/*****************************************************************************
+ * ioctl_ReadTitleKey: get the title key
+ *****************************************************************************/
+int ioctl_ReadTitleKey( int i_fd, int *pi_agid, int i_pos, u8 *p_key )
+{
+ int i_ret;
+
+#if defined( HAVE_LINUX_DVD_STRUCT )
+ dvd_authinfo dvd_ai;
+
+ memset( &dvd_ai, 0, sizeof(dvd_ai) );
+ dvd_ai.type = DVD_LU_SEND_TITLE_KEY;
+ dvd_ai.lstk.agid = *pi_agid;
+ dvd_ai.lstk.lba = i_pos;
+
+ i_ret = ioctl( i_fd, DVD_AUTH, &dvd_ai );
+
+ if( i_ret < 0 )
+ {
+ return i_ret;
+ }
+
+ memcpy( p_key, dvd_ai.lstk.title_key, 5 );
+
+#elif defined( HAVE_BSD_DVD_STRUCT )
+ i_ret = -1;
+
+#elif defined( SYS_BEOS )
+ i_ret = -1;
+
+#elif defined( HPUX_SCTL_IO )
+ i_ret = -1;
+
+#elif defined( SOLARIS_USCSI )
+ i_ret = -1;
+
+#elif defined( SYS_DARWIN )
+ dk_dvd_report_key_t dvd;
+ DVDTitleKeyInfo dvdtki;
+
+ memset(&dvd, 0, sizeof(dvd));
+ memset(&dvdtki, 0, sizeof(dvdtki));
+
+ dvd.buffer = &dvdtki;
+ dvd.bufferLength = sizeof(dvdtki);
+ dvd.format = kDVDKeyFormatTitleKey;
+ dvd.grantID = *pi_agid;
+ dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM; /* or this - this is memset 0x00 anyways */
+
+ /* dvdtki.dataLength[0] = 0x00; */ /* dataLength[0] is already memset to 0 */
+ dvdtki.dataLength[1] = 0x0a;
+
+ /* What are DVDTitleKeyInfo.{CP_MOD,CGMS,CP_SEC,CPM} and do they need to be set? */
+
+ i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
+
+ memcpy( p_key, dvdtki.titleKeyValue, sizeof(dvdtki.titleKeyValue) );
+
+#elif defined( WIN32 )
+ i_ret = -1;
+
+#else
+
+ i_ret = -1;
+
+#endif
+
+ return i_ret;
+}
+
+
/*****************************************************************************
* ioctl_ReportAgid: get AGID from the drive
*****************************************************************************/
{
int i_ret;
-#if defined( DVD_STRUCT_IN_LINUX_CDROM_H )
+#if defined( HAVE_LINUX_DVD_STRUCT )
dvd_authinfo auth_info;
auth_info.type = DVD_LU_SEND_AGID;
*pi_agid = p_buffer[ 7 ] >> 6;
-#elif defined( SYS_DARWIN )
- INIT_DVDIOCTL( 8 );
+#elif defined( HPUX_SCTL_IO )
+ INIT_SCTL_IO( GPCMD_REPORT_KEY, 8 );
- dvdioctl.i_keyformat = kCSSAGID;
- dvdioctl.i_agid = *pi_agid;
- dvdioctl.i_lba = 0;
+ sctl_io.cdb[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
- i_ret = ioctl( i_fd, IODVD_REPORT_KEY, &dvdioctl );
+ 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 = ioctl( i_fd, USCSICMD, &sc );
+
+ if( i_ret < 0 || sc.uscsi_status )
+ {
+ i_ret = -1;
+ }
+
+ *pi_agid = p_buffer[ 7 ] >> 6;
+
+#elif defined( SYS_DARWIN )
+ dk_dvd_report_key_t dvd;
+ DVDAuthenticationGrantIDInfo dvdagid;
+
+ memset(&dvd, 0, sizeof(dvd));
+ memset(&dvdagid, 0, sizeof(dvdagid));
+
+ dvd.buffer = &dvdagid;
+ dvd.bufferLength = sizeof(dvdagid);
+ dvd.format = kDVDKeyFormatAGID_CSS;
+ dvd.grantID = *pi_agid;
+ dvdagid.grantID = *pi_agid; /* do we need this? */
+ dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM; /* or this - this is memset 0x00 anyways */
+
+ /* dvdagid.dataLength[0] = 0x00; */ /* dataLength[0] is already memset to 0 */
+ /* dvdagid.dataLength[1] = 0x06; */
+
+ i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
+
+ *pi_agid = dvdagid.grantID;
+
#elif defined( WIN32 )
if( WIN2K ) /* NT/Win2000/Whistler */
{
{
int i_ret;
-#if defined( DVD_STRUCT_IN_LINUX_CDROM_H )
+#if defined( HAVE_LINUX_DVD_STRUCT )
dvd_authinfo auth_info;
auth_info.type = DVD_LU_SEND_CHALLENGE;
memcpy( p_challenge, p_buffer + 4, 12 );
-#elif defined( SYS_DARWIN )
- INIT_DVDIOCTL( 16 );
+#elif defined( HPUX_SCTL_IO )
+ INIT_SCTL_IO( GPCMD_REPORT_KEY, 16 );
- dvdioctl.i_keyformat = kChallengeKey;
- dvdioctl.i_agid = *pi_agid;
- dvdioctl.i_lba = 0;
+ sctl_io.cdb[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
- i_ret = ioctl( i_fd, IODVD_REPORT_KEY, &dvdioctl );
+ i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
memcpy( p_challenge, p_buffer + 4, 12 );
+#elif defined( SOLARIS_USCSI )
+ INIT_USCSI( GPCMD_REPORT_KEY, 16 );
+
+ rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
+
+ i_ret = ioctl( i_fd, USCSICMD, &sc );
+
+ if( i_ret < 0 || sc.uscsi_status )
+ {
+ i_ret = -1;
+ }
+
+ memcpy( p_challenge, p_buffer + 4, 12 );
+
+#elif defined( SYS_DARWIN )
+ dk_dvd_report_key_t dvd;
+ DVDChallengeKeyInfo dvdcki;
+
+ memset(&dvd, 0, sizeof(dvd));
+ memset(&dvdcki, 0, sizeof(dvdcki));
+
+ dvd.buffer = &dvdcki;
+ dvd.bufferLength = sizeof(dvdcki);
+ dvd.format = kDVDKeyFormatChallengeKey;
+ dvd.grantID = *pi_agid;
+
+ /* dvdcki.dataLength[0] = 0x00; */ /* dataLength[0] is already memset to 0 */
+ dvdcki.dataLength[1] = 0x0e;
+
+ i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
+
+ memcpy( p_challenge, dvdcki.challengeKeyValue, sizeof(dvdcki.challengeKeyValue) );
+
#elif defined( WIN32 )
if( WIN2K ) /* NT/Win2000/Whistler */
{
{
int i_ret;
-#if defined( DVD_STRUCT_IN_LINUX_CDROM_H )
+#if defined( HAVE_LINUX_DVD_STRUCT )
dvd_authinfo auth_info;
auth_info.type = DVD_LU_SEND_ASF;
*pi_asf = p_buffer[ 7 ] & 1;
-#elif defined( SYS_DARWIN )
- INIT_DVDIOCTL( 8 );
+#elif defined( HPUX_SCTL_IO )
+ INIT_SCTL_IO( GPCMD_REPORT_KEY, 8 );
+
+ sctl_io.cdb[ 10 ] = DVD_REPORT_ASF | (*pi_agid << 6);
+
+ i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
- dvdioctl.i_keyformat = kASF;
- dvdioctl.i_agid = *pi_agid;
- dvdioctl.i_lba = 0;
+ *pi_asf = p_buffer[ 7 ] & 1;
- i_ret = ioctl( i_fd, IODVD_REPORT_KEY, &dvdioctl );
+#elif defined( SOLARIS_USCSI )
+ INIT_USCSI( GPCMD_REPORT_KEY, 8 );
+
+ rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_ASF | (*pi_agid << 6);
+
+ i_ret = ioctl( i_fd, USCSICMD, &sc );
+
+ if( i_ret < 0 || sc.uscsi_status )
+ {
+ i_ret = -1;
+ }
*pi_asf = p_buffer[ 7 ] & 1;
+
+#elif defined( SYS_DARWIN )
+ dk_dvd_report_key_t dvd;
+ DVDAuthenticationSuccessFlagInfo dvdasfi;
+
+ memset(&dvd, 0, sizeof(dvd));
+ memset(&dvdasfi, 0, sizeof(dvdasfi));
+
+ dvd.buffer = &dvdasfi;
+ dvd.bufferLength = sizeof(dvdasfi);
+ dvd.format = kDVDKeyFormatASF;
+ dvd.grantID = *pi_agid;
+ dvdasfi.successFlag = *pi_asf;
+
+ /* dvdasfi.dataLength[0] = 0x00; */ /* dataLength[0] is already memset to 0 */
+ dvdasfi.dataLength[1] = 0x06;
+
+ i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
+
+ *pi_asf = dvdasfi.successFlag;
#elif defined( WIN32 )
if( WIN2K ) /* NT/Win2000/Whistler */
{
int i_ret;
-#if defined( DVD_STRUCT_IN_LINUX_CDROM_H )
+#if defined( HAVE_LINUX_DVD_STRUCT )
dvd_authinfo auth_info;
auth_info.type = DVD_LU_SEND_KEY1;
memcpy( p_key, p_buffer + 4, 8 );
-#elif defined( SYS_DARWIN )
- INIT_DVDIOCTL( 12 );
+#elif defined( HPUX_SCTL_IO )
+ INIT_SCTL_IO( GPCMD_REPORT_KEY, 12 );
- dvdioctl.i_keyformat = kKey1;
- dvdioctl.i_agid = *pi_agid;
+ sctl_io.cdb[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6);
- i_ret = ioctl( i_fd, IODVD_SEND_KEY, &dvdioctl );
+ i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
memcpy( p_key, p_buffer + 4, 8 );
+#elif defined( SOLARIS_USCSI )
+ INIT_USCSI( GPCMD_REPORT_KEY, 12 );
+
+ rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6);
+
+ i_ret = ioctl( i_fd, USCSICMD, &sc );
+
+ if( i_ret < 0 || sc.uscsi_status )
+ {
+ i_ret = -1;
+ }
+
+ memcpy( p_key, p_buffer + 4, 8 );;
+
+#elif defined( SYS_DARWIN )
+ dk_dvd_report_key_t dvd;
+ DVDKey1Info dvdk1i;
+
+ memset(&dvd, 0, sizeof(dvd));
+ memset(&dvdk1i, 0, sizeof(dvdk1i));
+
+ dvd.buffer = &dvdk1i;
+ dvd.bufferLength = sizeof(dvdk1i);
+ dvd.format = kDVDKeyFormatKey1;
+ dvd.grantID = *pi_agid;
+
+ /* dvdk1i.dataLength[0] = 0x00; */ /* dataLength[0] is already memset to 0 */
+ dvdk1i.dataLength[1] = 0x0a;
+
+ i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
+
+ memcpy( p_key, dvdk1i.key1Value, sizeof(dvdk1i.key1Value) );
+
#elif defined( WIN32 )
if( WIN2K ) /* NT/Win2000/Whistler */
{
{
int i_ret;
-#if defined( DVD_STRUCT_IN_LINUX_CDROM_H )
+#if defined( HAVE_LINUX_DVD_STRUCT )
dvd_authinfo auth_info;
auth_info.type = DVD_INVALIDATE_AGID;
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 = ioctl( i_fd, USCSICMD, &sc );
+
+ if( i_ret < 0 || sc.uscsi_status )
+ {
+ i_ret = -1;
+ }
+
#elif defined( SYS_DARWIN )
- INIT_DVDIOCTL( 0 );
+ dk_dvd_send_key_t dvd;
+ DVDAuthenticationGrantIDInfo dvdagid;
+
+ memset(&dvd, 0, sizeof(dvd));
+ memset(&dvdagid, 0, sizeof(dvdagid));
+
+ dvd.buffer = &dvdagid;
+ dvd.bufferLength = sizeof(dvdagid);
+ dvd.format = kDVDKeyFormatAGID_Invalidate;
+ dvd.grantID = *pi_agid;
+ dvdagid.grantID = *pi_agid; /* we need this? */
+
+ /* dvdagid.dataLength[0] = 0x00; */ /* dataLength[0] is already memset to 0 */
+ /* dvdagid.dataLength[1] = 0x06; */
- dvdioctl.i_keyformat = kInvalidateAGID;
- dvdioctl.i_agid = *pi_agid;
+ i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
- i_ret = ioctl( i_fd, IODVD_SEND_KEY, &dvdioctl );
+ *pi_agid = dvdagid.grantID;
#elif defined( WIN32 )
if( WIN2K ) /* NT/Win2000/Whistler */
*****************************************************************************/
int ioctl_SendChallenge( int i_fd, int *pi_agid, u8 *p_challenge )
{
-#if defined( DVD_STRUCT_IN_LINUX_CDROM_H )
+ int i_ret;
+
+#if defined( HAVE_LINUX_DVD_STRUCT )
dvd_authinfo auth_info;
auth_info.type = DVD_HOST_SEND_CHALLENGE;
return ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
-#elif defined( SYS_DARWIN )
- INIT_DVDIOCTL( 16 );
+#elif defined( HPUX_SCTL_IO )
+ INIT_SCTL_IO( GPCMD_SEND_KEY, 16 );
- dvdioctl.i_keyformat = kChallengeKey;
- dvdioctl.i_agid = *pi_agid;
+ sctl_io.cdb[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
p_buffer[ 1 ] = 0xe;
memcpy( p_buffer + 4, p_challenge, 12 );
- return ioctl( i_fd, IODVD_SEND_KEY, &dvdioctl );
+ return 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, 12 );
+
+ if( ioctl( i_fd, USCSICMD, &sc ) < 0 || sc.uscsi_status )
+ {
+ return -1;
+ }
+
+ return 0;
+
+#elif defined( SYS_DARWIN )
+ dk_dvd_send_key_t dvd;
+ DVDChallengeKeyInfo dvdcki;
+
+ memset(&dvd, 0, sizeof(dvd));
+ memset(&dvdcki, 0, sizeof(dvdcki));
+
+ dvd.buffer = &dvdcki;
+ dvd.bufferLength = sizeof(dvdcki);
+ dvd.format = kDVDKeyFormatChallengeKey;
+ dvd.grantID = *pi_agid;
+
+ /* dvdcki.dataLength[0] = 0x00; */ /* dataLength[0] is already memset to 0 */
+ dvdcki.dataLength[1] = 0x0e;
+
+ memcpy( dvdcki.challengeKeyValue, p_challenge, sizeof(dvdcki.challengeKeyValue) );
+
+ i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
#elif defined( WIN32 )
if( WIN2K ) /* NT/Win2000/Whistler */
return -1;
#endif
+ return i_ret;
}
/*****************************************************************************
*****************************************************************************/
int ioctl_SendKey2( int i_fd, int *pi_agid, u8 *p_key )
{
-#if defined( DVD_STRUCT_IN_LINUX_CDROM_H )
+ int i_ret;
+
+#if defined( HAVE_LINUX_DVD_STRUCT )
dvd_authinfo auth_info;
auth_info.type = DVD_HOST_SEND_KEY2;
return 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, 8 );
+
+ return 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, 8 );
+
+ if( ioctl( i_fd, USCSICMD, &sc ) < 0 || sc.uscsi_status )
+ {
+ return -1;
+ }
+
+ return 0;
+
+#elif defined( SYS_DARWIN )
+ dk_dvd_send_key_t dvd;
+ DVDKey2Info dvdk2i;
+
+ memset(&dvd, 0, sizeof(dvd));
+ memset(&dvdk2i, 0, sizeof(dvdk2i));
+
+ dvd.buffer = &dvdk2i;
+ dvd.bufferLength = sizeof(dvdk2i);
+ dvd.format = kDVDKeyFormatKey2;
+ dvd.grantID = *pi_agid;
+
+ /* dvdk2i.dataLength[0] = 0x00; */ /*dataLength[0] is already memset to 0 */
+ dvdk2i.dataLength[1] = 0x0a;
+
+ memcpy( dvdk2i.key2Value, p_key, sizeof(dvdk2i.key2Value) );
+
+ i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
+
#elif defined( WIN32 )
if( WIN2K ) /* NT/Win2000/Whistler */
{
return WinSendSSC( i_fd, &ssc );
}
-#elif defined( SYS_DARWIN )
- INIT_DVDIOCTL( 12 );
-
- dvdioctl.i_keyformat = kKey2;
- dvdioctl.i_agid = *pi_agid;
-
- p_buffer[ 1 ] = 0xa;
- memcpy( p_buffer + 4, p_key, 8 );
-
- return ioctl( i_fd, IODVD_SEND_KEY, &dvdioctl );
-
#else
/* DVD ioctls unavailable - do as if the ioctl failed */
return -1;
#endif
+ return i_ret;
}
/* Local prototypes */
}
#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 );
+}
+#endif
+
#if defined( WIN32 )
/*****************************************************************************
* WinInitSSC: initialize a ssc structure for the win32 aspi layer