dvd_ioctl.c 22 KB
Newer Older
Sam Hocevar's avatar
 
Sam Hocevar committed
1 2 3 4
/*****************************************************************************
 * dvd_ioctl.c: DVD ioctl replacement function
 *****************************************************************************
 * Copyright (C) 1999-2001 VideoLAN
Sam Hocevar's avatar
 
Sam Hocevar committed
5
 * $Id: dvd_ioctl.c,v 1.16 2001/05/31 03:12:49 sam Exp $
Sam Hocevar's avatar
 
Sam Hocevar committed
6 7 8
 *
 * Authors: Markus Kuespert <ltlBeBoy@beosmail.com>
 *          Samuel Hocevar <sam@zoy.org>
Sam Hocevar's avatar
 
Sam Hocevar committed
9
 *          Jon Lech Johansen <jon-vl@nanocrew.net>
Sam Hocevar's avatar
 
Sam Hocevar committed
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
#include "defs.h"

Sam Hocevar's avatar
 
Sam Hocevar committed
31
#include <string.h>                                    /* memcpy(), memset() */
Sam Hocevar's avatar
 
Sam Hocevar committed
32
#include <sys/types.h>
Sam Hocevar's avatar
 
Sam Hocevar committed
33

Sam Hocevar's avatar
 
Sam Hocevar committed
34 35 36 37 38 39
#if defined( WIN32 )
#   include <windows.h>
#   include <winioctl.h>
#else
#   include <netinet/in.h>
#   include <sys/ioctl.h>
Sam Hocevar's avatar
 
Sam Hocevar committed
40
#endif
Sam Hocevar's avatar
 
Sam Hocevar committed
41 42 43 44 45

#ifdef DVD_STRUCT_IN_SYS_CDIO_H
#   include <sys/cdio.h>
#endif
#ifdef DVD_STRUCT_IN_SYS_DVDIO_H
Sam Hocevar's avatar
 
Sam Hocevar committed
46 47
#   include <sys/dvdio.h>
#endif
Sam Hocevar's avatar
 
Sam Hocevar committed
48
#ifdef DVD_STRUCT_IN_LINUX_CDROM_H
Sam Hocevar's avatar
 
Sam Hocevar committed
49 50 51 52 53 54 55 56
#   include <linux/cdrom.h>
#endif
#ifdef SYS_BEOS
#   include <malloc.h>
#   include <scsi.h>
#endif

#include "common.h"
Sam Hocevar's avatar
 
Sam Hocevar committed
57

Sam Hocevar's avatar
 
Sam Hocevar committed
58 59
#include "intf_msg.h"

Sam Hocevar's avatar
 
Sam Hocevar committed
60 61 62 63
#ifdef SYS_DARWIN1_3
#   include "DVDioctl/DVDioctl.h"
#endif

Sam Hocevar's avatar
 
Sam Hocevar committed
64
#include "dvd_css.h"
Sam Hocevar's avatar
 
Sam Hocevar committed
65 66 67
#include "dvd_ioctl.h"

/*****************************************************************************
Sam Hocevar's avatar
 
Sam Hocevar committed
68
 * Local prototypes, BeOS specific
Sam Hocevar's avatar
 
Sam Hocevar committed
69 70
 *****************************************************************************/
#if defined( SYS_BEOS )
Sam Hocevar's avatar
 
Sam Hocevar committed
71
static void BeInitRDC ( raw_device_command *, int );
Sam Hocevar's avatar
 
Sam Hocevar committed
72 73 74
#endif

/*****************************************************************************
Sam Hocevar's avatar
 
Sam Hocevar committed
75
 * ioctl_ReadCopyright: check whether the disc is encrypted or not
Sam Hocevar's avatar
 
Sam Hocevar committed
76
 *****************************************************************************/
Sam Hocevar's avatar
 
Sam Hocevar committed
77
int ioctl_ReadCopyright( int i_fd, int i_layer, int *pi_copyright )
Sam Hocevar's avatar
 
Sam Hocevar committed
78
{
Sam Hocevar's avatar
 
Sam Hocevar committed
79
    int i_ret;
Sam Hocevar's avatar
 
Sam Hocevar committed
80

Sam Hocevar's avatar
 
Sam Hocevar committed
81
#if defined( DVD_STRUCT_IN_LINUX_CDROM_H )
Sam Hocevar's avatar
 
Sam Hocevar committed
82
    dvd_struct dvd;
Sam Hocevar's avatar
 
Sam Hocevar committed
83

Sam Hocevar's avatar
 
Sam Hocevar committed
84 85
    dvd.type = DVD_STRUCT_COPYRIGHT;
    dvd.copyright.layer_num = i_layer;
Sam Hocevar's avatar
 
Sam Hocevar committed
86

Sam Hocevar's avatar
 
Sam Hocevar committed
87
    i_ret = ioctl( i_fd, DVD_READ_STRUCT, &dvd );
Sam Hocevar's avatar
 
Sam Hocevar committed
88

Sam Hocevar's avatar
 
Sam Hocevar committed
89
    *pi_copyright = dvd.copyright.cpst;
Sam Hocevar's avatar
 
Sam Hocevar committed
90

Sam Hocevar's avatar
 
Sam Hocevar committed
91 92 93 94 95 96 97 98 99 100
#elif defined( HAVE_BSD_DVD_STRUCT )
    struct dvd_struct dvd;

    dvd.format = DVD_STRUCT_COPYRIGHT;
    dvd.layer_num = i_layer;

    i_ret = ioctl( i_fd, DVDIOCREADSTRUCTURE, &dvd );

    *pi_copyright = dvd.cpst;

Sam Hocevar's avatar
 
Sam Hocevar committed
101
#elif defined( SYS_BEOS )
Sam Hocevar's avatar
 
Sam Hocevar committed
102
    INIT_RDC( GPCMD_READ_DVD_STRUCTURE, 8 );
Sam Hocevar's avatar
 
Sam Hocevar committed
103

Sam Hocevar's avatar
 
Sam Hocevar committed
104 105
    rdc.command[ 6 ] = i_layer;
    rdc.command[ 7 ] = DVD_STRUCT_COPYRIGHT;
Sam Hocevar's avatar
 
Sam Hocevar committed
106

Sam Hocevar's avatar
 
Sam Hocevar committed
107
    i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
Sam Hocevar's avatar
 
Sam Hocevar committed
108

Sam Hocevar's avatar
 
Sam Hocevar committed
109
    *pi_copyright = p_buffer[ 4 ];
Sam Hocevar's avatar
 
Sam Hocevar committed
110

Sam Hocevar's avatar
 
Sam Hocevar committed
111 112
#elif defined( SYS_DARWIN1_3 )
    intf_ErrMsg( "css error: DVD ioctls not fully functional yet" );
Sam Hocevar's avatar
 
Sam Hocevar committed
113
    intf_ErrMsg( "css error: assuming disc is encrypted" );
Sam Hocevar's avatar
 
Sam Hocevar committed
114

Sam Hocevar's avatar
 
Sam Hocevar committed
115
    *pi_copyright = 1;
Sam Hocevar's avatar
 
Sam Hocevar committed
116

Sam Hocevar's avatar
 
Sam Hocevar committed
117
    i_ret = 0;
Sam Hocevar's avatar
 
Sam Hocevar committed
118

Sam Hocevar's avatar
 
Sam Hocevar committed
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
#elif defined( WIN32 )
    if( GetVersion() < 0x80000000 ) /* NT/Win2000/Whistler */
    {
        DWORD tmp;
        u8 p_buffer[ 8 ];
        SCSI_PASS_THROUGH_DIRECT sptd;

        memset( &sptd, 0, sizeof( sptd ) );
        memset( &p_buffer, 0, sizeof( p_buffer ) );
   
        /*  When using IOCTL_DVD_READ_STRUCTURE and 
            DVD_COPYRIGHT_DESCRIPTOR, CopyrightProtectionType
            is always 6. So we send a raw scsi command instead. */

        sptd.Length             = sizeof( SCSI_PASS_THROUGH_DIRECT );
        sptd.CdbLength          = 12;
        sptd.DataIn             = SCSI_IOCTL_DATA_IN;
        sptd.DataTransferLength = 8;
        sptd.TimeOutValue       = 2;
        sptd.DataBuffer         = p_buffer;
        sptd.Cdb[ 0 ]           = GPCMD_READ_DVD_STRUCTURE;
        sptd.Cdb[ 6 ]           = i_layer;
        sptd.Cdb[ 7 ]           = DVD_STRUCT_COPYRIGHT;
        sptd.Cdb[ 8 ]           = (8 >> 8) & 0xff;
        sptd.Cdb[ 9 ]           =  8       & 0xff;

        i_ret = DeviceIoControl( (HANDLE) i_fd,
                             IOCTL_SCSI_PASS_THROUGH_DIRECT,
                             &sptd, sizeof( SCSI_PASS_THROUGH_DIRECT ),
                             &sptd, sizeof( SCSI_PASS_THROUGH_DIRECT ),
                             &tmp, NULL ) ? 0 : -1;

        *pi_copyright = p_buffer[4];
    }
    else
    {
        /* TODO: add WNASPI support for Win9x */
        intf_ErrMsg( "css error: DVD ioctls not functional yet" );
        intf_ErrMsg( "css error: assuming disc is unencrypted" );
        *pi_copyright = 0;
        i_ret = 0;
    }

Sam Hocevar's avatar
 
Sam Hocevar committed
162
#else
Sam Hocevar's avatar
 
Sam Hocevar committed
163 164
    /* DVD ioctls unavailable - do as if the ioctl failed */
    i_ret = -1;
Sam Hocevar's avatar
 
Sam Hocevar committed
165

Sam Hocevar's avatar
 
Sam Hocevar committed
166
#endif
Sam Hocevar's avatar
 
Sam Hocevar committed
167
    return i_ret;
Sam Hocevar's avatar
 
Sam Hocevar committed
168
}
Sam Hocevar's avatar
 
Sam Hocevar committed
169

Sam Hocevar's avatar
 
Sam Hocevar committed
170
/*****************************************************************************
Sam Hocevar's avatar
 
Sam Hocevar committed
171
 * ioctl_ReadKey: get the disc key
Sam Hocevar's avatar
 
Sam Hocevar committed
172
 *****************************************************************************/
Sam Hocevar's avatar
 
Sam Hocevar committed
173
int ioctl_ReadKey( int i_fd, int *pi_agid, u8 *p_key )
Sam Hocevar's avatar
 
Sam Hocevar committed
174 175
{
    int i_ret;
Sam Hocevar's avatar
 
Sam Hocevar committed
176

Sam Hocevar's avatar
 
Sam Hocevar committed
177
#if defined( DVD_STRUCT_IN_LINUX_CDROM_H )
Sam Hocevar's avatar
 
Sam Hocevar committed
178
    dvd_struct dvd;
Sam Hocevar's avatar
 
Sam Hocevar committed
179

Sam Hocevar's avatar
 
Sam Hocevar committed
180
    dvd.type = DVD_STRUCT_DISCKEY;
Sam Hocevar's avatar
 
Sam Hocevar committed
181
    dvd.disckey.agid = *pi_agid;
Sam Hocevar's avatar
 
Sam Hocevar committed
182
    memset( dvd.disckey.value, 0, 2048 );
Sam Hocevar's avatar
 
Sam Hocevar committed
183

Sam Hocevar's avatar
 
Sam Hocevar committed
184
    i_ret = ioctl( i_fd, DVD_READ_STRUCT, &dvd );
Sam Hocevar's avatar
 
Sam Hocevar committed
185

Sam Hocevar's avatar
 
Sam Hocevar committed
186 187 188 189
    if( i_ret < 0 )
    {
        return i_ret;
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
190

Sam Hocevar's avatar
 
Sam Hocevar committed
191
    memcpy( p_key, dvd.disckey.value, 2048 );
Sam Hocevar's avatar
 
Sam Hocevar committed
192

Sam Hocevar's avatar
 
Sam Hocevar committed
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
#elif defined( HAVE_BSD_DVD_STRUCT )
    struct dvd_struct dvd;

    dvd.format = DVD_STRUCT_DISCKEY;
    dvd.agid = *pi_agid;
    memset( dvd.data, 0, 2048 );

    i_ret = ioctl( i_fd, DVDIOCREADSTRUCTURE, &dvd );

    if( i_ret < 0 )
    {
        return i_ret;
    }

    memcpy( p_key, dvd.data, 2048 );

Sam Hocevar's avatar
 
Sam Hocevar committed
209
#elif defined( SYS_BEOS )
Sam Hocevar's avatar
 
Sam Hocevar committed
210
    INIT_RDC( GPCMD_READ_DVD_STRUCTURE, 2048 + 4 );
Sam Hocevar's avatar
 
Sam Hocevar committed
211

Sam Hocevar's avatar
 
Sam Hocevar committed
212
    rdc.command[ 7 ]  = DVD_STRUCT_DISCKEY;
Sam Hocevar's avatar
 
Sam Hocevar committed
213
    rdc.command[ 10 ] = *pi_agid << 6;
Sam Hocevar's avatar
 
Sam Hocevar committed
214
    
Sam Hocevar's avatar
 
Sam Hocevar committed
215
    i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
Sam Hocevar's avatar
 
Sam Hocevar committed
216

Sam Hocevar's avatar
 
Sam Hocevar committed
217 218 219 220
    if( i_ret < 0 )
    {
        return i_ret;
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
221

Sam Hocevar's avatar
 
Sam Hocevar committed
222
    memcpy( p_key, p_buffer + 4, 2048 );
Sam Hocevar's avatar
 
Sam Hocevar committed
223

Sam Hocevar's avatar
 
Sam Hocevar committed
224 225 226 227 228 229 230 231
#elif defined( SYS_DARWIN1_3 )
    intf_ErrMsg( "css error: DVD ioctls not fully functional yet" );
    intf_ErrMsg( "css error: sending an empty key" );

    i_ret = 0;

    memset( p_key, 0x00, 2048 );

Sam Hocevar's avatar
 
Sam Hocevar committed
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
#elif defined( WIN32 )
    if( GetVersion() < 0x80000000 ) /* NT/Win2000/Whistler */
    {
        DWORD tmp;
        u8 buffer[DVD_DISK_KEY_LENGTH];
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;

        memset( &buffer, 0, sizeof( buffer ) );

        key->KeyLength  = DVD_DISK_KEY_LENGTH;
        key->SessionId  = *pi_agid;
        key->KeyType    = DvdDiskKey;
        key->KeyFlags   = 0;

        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key, 
                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;

        if( i_ret < 0 )
        {   
            return i_ret;
        }

        memcpy( p_key, key->KeyData, 2048 );
    }
    else
    {
        i_ret = -1;
    }

Sam Hocevar's avatar
 
Sam Hocevar committed
261
#else
Sam Hocevar's avatar
 
Sam Hocevar committed
262 263
    /* DVD ioctls unavailable - do as if the ioctl failed */
    i_ret = -1;
Sam Hocevar's avatar
 
Sam Hocevar committed
264

Sam Hocevar's avatar
 
Sam Hocevar committed
265
#endif
Sam Hocevar's avatar
 
Sam Hocevar committed
266
    return i_ret;
Sam Hocevar's avatar
 
Sam Hocevar committed
267
}
Sam Hocevar's avatar
 
Sam Hocevar committed
268

Sam Hocevar's avatar
 
Sam Hocevar committed
269
/*****************************************************************************
Sam Hocevar's avatar
 
Sam Hocevar committed
270
 * ioctl_ReportAgid: get AGID from the drive
Sam Hocevar's avatar
 
Sam Hocevar committed
271
 *****************************************************************************/
Sam Hocevar's avatar
 
Sam Hocevar committed
272
int ioctl_ReportAgid( int i_fd, int *pi_agid )
Sam Hocevar's avatar
 
Sam Hocevar committed
273 274
{
    int i_ret;
Sam Hocevar's avatar
 
Sam Hocevar committed
275

Sam Hocevar's avatar
 
Sam Hocevar committed
276
#if defined( DVD_STRUCT_IN_LINUX_CDROM_H )
Sam Hocevar's avatar
 
Sam Hocevar committed
277
    dvd_authinfo auth_info;
Sam Hocevar's avatar
 
Sam Hocevar committed
278

Sam Hocevar's avatar
 
Sam Hocevar committed
279
    auth_info.type = DVD_LU_SEND_AGID;
Sam Hocevar's avatar
 
Sam Hocevar committed
280
    auth_info.lsa.agid = *pi_agid;
Sam Hocevar's avatar
 
Sam Hocevar committed
281

Sam Hocevar's avatar
 
Sam Hocevar committed
282
    i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
Sam Hocevar's avatar
 
Sam Hocevar committed
283

Sam Hocevar's avatar
 
Sam Hocevar committed
284
    *pi_agid = auth_info.lsa.agid;
Sam Hocevar's avatar
 
Sam Hocevar committed
285

Sam Hocevar's avatar
 
Sam Hocevar committed
286 287 288 289 290 291 292 293 294 295
#elif defined( HAVE_BSD_DVD_STRUCT )
    struct dvd_authinfo auth_info;

    auth_info.format = DVD_REPORT_AGID;
    auth_info.agid = *pi_agid;

    i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );

    *pi_agid = auth_info.agid;

Sam Hocevar's avatar
 
Sam Hocevar committed
296
#elif defined( SYS_BEOS )
Sam Hocevar's avatar
 
Sam Hocevar committed
297
    INIT_RDC( GPCMD_REPORT_KEY, 8 );
Sam Hocevar's avatar
 
Sam Hocevar committed
298

Sam Hocevar's avatar
 
Sam Hocevar committed
299
    rdc.command[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
Sam Hocevar's avatar
 
Sam Hocevar committed
300

Sam Hocevar's avatar
 
Sam Hocevar committed
301
    i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
Sam Hocevar's avatar
 
Sam Hocevar committed
302

Sam Hocevar's avatar
 
Sam Hocevar committed
303
    *pi_agid = p_buffer[ 7 ] >> 6;
Sam Hocevar's avatar
 
Sam Hocevar committed
304

Sam Hocevar's avatar
 
Sam Hocevar committed
305 306 307 308 309 310 311 312 313
#elif defined( SYS_DARWIN1_3 )
    INIT_DVDIOCTL( 8 );

    dvdioctl.i_keyformat = kCSSAGID;
    dvdioctl.i_agid = *pi_agid;
    dvdioctl.i_lba = 0;

    i_ret = ioctl( i_fd, IODVD_REPORT_KEY, &dvdioctl );

Sam Hocevar's avatar
 
Sam Hocevar committed
314
    *pi_agid = p_buffer[ 7 ] >> 6;
Sam Hocevar's avatar
 
Sam Hocevar committed
315

Sam Hocevar's avatar
 
Sam Hocevar committed
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
#elif defined( WIN32 )
    if( GetVersion() < 0x80000000 ) /* NT/Win2000/Whistler */
    {
        ULONG id;
        DWORD tmp;

        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_START_SESSION, 
                        &tmp, 4, &id, sizeof( id ), &tmp, NULL ) ? 0 : -1;

        *pi_agid = id;
    }
    else
    {
        i_ret = -1;
    }

Sam Hocevar's avatar
 
Sam Hocevar committed
332
#else
Sam Hocevar's avatar
 
Sam Hocevar committed
333 334
    /* DVD ioctls unavailable - do as if the ioctl failed */
    i_ret = -1;
Sam Hocevar's avatar
 
Sam Hocevar committed
335

Sam Hocevar's avatar
 
Sam Hocevar committed
336
#endif
Sam Hocevar's avatar
 
Sam Hocevar committed
337
    return i_ret;
Sam Hocevar's avatar
 
Sam Hocevar committed
338
}
Sam Hocevar's avatar
 
Sam Hocevar committed
339

Sam Hocevar's avatar
 
Sam Hocevar committed
340
/*****************************************************************************
Sam Hocevar's avatar
 
Sam Hocevar committed
341
 * ioctl_ReportChallenge: get challenge from the drive
Sam Hocevar's avatar
 
Sam Hocevar committed
342
 *****************************************************************************/
Sam Hocevar's avatar
 
Sam Hocevar committed
343
int ioctl_ReportChallenge( int i_fd, int *pi_agid, u8 *p_challenge )
Sam Hocevar's avatar
 
Sam Hocevar committed
344 345
{
    int i_ret;
Sam Hocevar's avatar
 
Sam Hocevar committed
346

Sam Hocevar's avatar
 
Sam Hocevar committed
347
#if defined( DVD_STRUCT_IN_LINUX_CDROM_H )
Sam Hocevar's avatar
 
Sam Hocevar committed
348
    dvd_authinfo auth_info;
Sam Hocevar's avatar
 
Sam Hocevar committed
349

Sam Hocevar's avatar
 
Sam Hocevar committed
350
    auth_info.type = DVD_LU_SEND_CHALLENGE;
Sam Hocevar's avatar
 
Sam Hocevar committed
351
    auth_info.lsc.agid = *pi_agid;
Sam Hocevar's avatar
 
Sam Hocevar committed
352

Sam Hocevar's avatar
 
Sam Hocevar committed
353
    i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
Sam Hocevar's avatar
 
Sam Hocevar committed
354

Sam Hocevar's avatar
 
Sam Hocevar committed
355
    memcpy( p_challenge, auth_info.lsc.chal, sizeof(dvd_challenge) );
Sam Hocevar's avatar
 
Sam Hocevar committed
356

Sam Hocevar's avatar
 
Sam Hocevar committed
357 358 359 360 361 362 363 364 365 366
#elif defined( HAVE_BSD_DVD_STRUCT )
    struct dvd_authinfo auth_info;

    auth_info.format = DVD_REPORT_CHALLENGE;
    auth_info.agid = *pi_agid;

    i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );

    memcpy( p_challenge, auth_info.keychal, 10 );

Sam Hocevar's avatar
 
Sam Hocevar committed
367
#elif defined( SYS_BEOS )
Sam Hocevar's avatar
 
Sam Hocevar committed
368
    INIT_RDC( GPCMD_REPORT_KEY, 16 );
Sam Hocevar's avatar
 
Sam Hocevar committed
369

Sam Hocevar's avatar
 
Sam Hocevar committed
370
    rdc.command[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
Sam Hocevar's avatar
 
Sam Hocevar committed
371

Sam Hocevar's avatar
 
Sam Hocevar committed
372
    i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
Sam Hocevar's avatar
 
Sam Hocevar committed
373

Sam Hocevar's avatar
 
Sam Hocevar committed
374
    memcpy( p_challenge, p_buffer + 4, 12 );
Sam Hocevar's avatar
 
Sam Hocevar committed
375

Sam Hocevar's avatar
 
Sam Hocevar committed
376 377 378 379 380 381 382 383 384 385 386
#elif defined( SYS_DARWIN1_3 )
    INIT_DVDIOCTL( 16 );

    dvdioctl.i_keyformat = kChallengeKey;
    dvdioctl.i_agid = *pi_agid;
    dvdioctl.i_lba = 0;

    i_ret = ioctl( i_fd, IODVD_REPORT_KEY, &dvdioctl );

    memcpy( p_challenge, p_buffer + 4, 12 );

Sam Hocevar's avatar
 
Sam Hocevar committed
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
#elif defined( WIN32 )
    if( GetVersion() < 0x80000000 ) /* NT/Win2000/Whistler */
    {
        DWORD tmp;
        u8 buffer[DVD_CHALLENGE_KEY_LENGTH];
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;

        memset( &buffer, 0, sizeof( buffer ) );

        key->KeyLength  = DVD_CHALLENGE_KEY_LENGTH;
        key->SessionId  = *pi_agid;
        key->KeyType    = DvdChallengeKey;
        key->KeyFlags   = 0;

        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key, 
                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;

        if( i_ret < 0 )
        {
            return i_ret;
        }

        memcpy( p_challenge, key->KeyData, 10 );
    }
    else
    {
        i_ret = -1;
    }

Sam Hocevar's avatar
 
Sam Hocevar committed
416
#else
Sam Hocevar's avatar
 
Sam Hocevar committed
417 418
    /* DVD ioctls unavailable - do as if the ioctl failed */
    i_ret = -1;
Sam Hocevar's avatar
 
Sam Hocevar committed
419

Sam Hocevar's avatar
 
Sam Hocevar committed
420
#endif
Sam Hocevar's avatar
 
Sam Hocevar committed
421
    return i_ret;
Sam Hocevar's avatar
 
Sam Hocevar committed
422
}
Sam Hocevar's avatar
 
Sam Hocevar committed
423

Sam Hocevar's avatar
 
Sam Hocevar committed
424
/*****************************************************************************
Sam Hocevar's avatar
 
Sam Hocevar committed
425
 * ioctl_ReportASF: get ASF from the drive
Sam Hocevar's avatar
 
Sam Hocevar committed
426
 *****************************************************************************/
Sam Hocevar's avatar
 
Sam Hocevar committed
427
int ioctl_ReportASF( int i_fd, int *pi_agid, int *pi_asf )
Sam Hocevar's avatar
 
Sam Hocevar committed
428
{
Sam Hocevar's avatar
 
Sam Hocevar committed
429 430
    int i_ret;

Sam Hocevar's avatar
 
Sam Hocevar committed
431
#if defined( DVD_STRUCT_IN_LINUX_CDROM_H )
Sam Hocevar's avatar
 
Sam Hocevar committed
432
    dvd_authinfo auth_info;
Sam Hocevar's avatar
 
Sam Hocevar committed
433

Sam Hocevar's avatar
 
Sam Hocevar committed
434
    auth_info.type = DVD_LU_SEND_ASF;
Sam Hocevar's avatar
 
Sam Hocevar committed
435
    auth_info.lsasf.agid = *pi_agid;
Sam Hocevar's avatar
 
Sam Hocevar committed
436
    auth_info.lsasf.asf = *pi_asf;
Sam Hocevar's avatar
 
Sam Hocevar committed
437

Sam Hocevar's avatar
 
Sam Hocevar committed
438
    i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
Sam Hocevar's avatar
 
Sam Hocevar committed
439

Sam Hocevar's avatar
 
Sam Hocevar committed
440
    *pi_asf = auth_info.lsasf.asf;
Sam Hocevar's avatar
 
Sam Hocevar committed
441

Sam Hocevar's avatar
 
Sam Hocevar committed
442 443 444 445 446 447 448 449 450 451 452
#elif defined( HAVE_BSD_DVD_STRUCT )
    struct dvd_authinfo auth_info;

    auth_info.format = DVD_REPORT_ASF;
    auth_info.agid = *pi_agid;
    auth_info.asf = *pi_asf;

    i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );

    *pi_asf = auth_info.asf;

Sam Hocevar's avatar
 
Sam Hocevar committed
453
#elif defined( SYS_BEOS )
Sam Hocevar's avatar
 
Sam Hocevar committed
454
    INIT_RDC( GPCMD_REPORT_KEY, 8 );
Sam Hocevar's avatar
 
Sam Hocevar committed
455

Sam Hocevar's avatar
 
Sam Hocevar committed
456
    rdc.command[ 10 ] = DVD_REPORT_ASF | (*pi_agid << 6);
Sam Hocevar's avatar
 
Sam Hocevar committed
457

Sam Hocevar's avatar
 
Sam Hocevar committed
458
    i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
Sam Hocevar's avatar
 
Sam Hocevar committed
459 460 461 462

    *pi_asf = p_buffer[ 7 ] & 1;

#elif defined( SYS_DARWIN1_3 )
Sam Hocevar's avatar
 
Sam Hocevar committed
463
    INIT_DVDIOCTL( 8 );
Sam Hocevar's avatar
 
Sam Hocevar committed
464

Sam Hocevar's avatar
 
Sam Hocevar committed
465 466 467
    dvdioctl.i_keyformat = kASF;
    dvdioctl.i_agid = *pi_agid;
    dvdioctl.i_lba = 0;
Sam Hocevar's avatar
 
Sam Hocevar committed
468

Sam Hocevar's avatar
 
Sam Hocevar committed
469
    i_ret = ioctl( i_fd, IODVD_REPORT_KEY, &dvdioctl );
Sam Hocevar's avatar
 
Sam Hocevar committed
470 471

    *pi_asf = p_buffer[ 7 ] & 1;
Sam Hocevar's avatar
 
Sam Hocevar committed
472

Sam Hocevar's avatar
 
Sam Hocevar committed
473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503
#elif defined( WIN32 )
    if( GetVersion() < 0x80000000 ) /* NT/Win2000/Whistler */
    {
        DWORD tmp;
        u8 buffer[DVD_ASF_LENGTH];
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;

        memset( &buffer, 0, sizeof( buffer ) );

        key->KeyLength  = DVD_ASF_LENGTH;
        key->SessionId  = *pi_agid;
        key->KeyType    = DvdAsf;
        key->KeyFlags   = 0;

        ((PDVD_ASF)key->KeyData)->SuccessFlag = *pi_asf;

        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key, 
                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;

        if( i_ret < 0 )
        {
            return i_ret;
        }

        *pi_asf = ((PDVD_ASF)key->KeyData)->SuccessFlag;
    }
    else
    {
        i_ret = -1;
    }

Sam Hocevar's avatar
 
Sam Hocevar committed
504
#else
Sam Hocevar's avatar
 
Sam Hocevar committed
505 506
    /* DVD ioctls unavailable - do as if the ioctl failed */
    i_ret = -1;
Sam Hocevar's avatar
 
Sam Hocevar committed
507

Sam Hocevar's avatar
 
Sam Hocevar committed
508
#endif
Sam Hocevar's avatar
 
Sam Hocevar committed
509
    return i_ret;
Sam Hocevar's avatar
 
Sam Hocevar committed
510
}
Sam Hocevar's avatar
 
Sam Hocevar committed
511

Sam Hocevar's avatar
 
Sam Hocevar committed
512
/*****************************************************************************
Sam Hocevar's avatar
 
Sam Hocevar committed
513
 * ioctl_ReportKey1: get the first key from the drive
Sam Hocevar's avatar
 
Sam Hocevar committed
514
 *****************************************************************************/
Sam Hocevar's avatar
 
Sam Hocevar committed
515
int ioctl_ReportKey1( int i_fd, int *pi_agid, u8 *p_key )
Sam Hocevar's avatar
 
Sam Hocevar committed
516 517
{
    int i_ret;
Sam Hocevar's avatar
 
Sam Hocevar committed
518

Sam Hocevar's avatar
 
Sam Hocevar committed
519
#if defined( DVD_STRUCT_IN_LINUX_CDROM_H )
Sam Hocevar's avatar
 
Sam Hocevar committed
520
    dvd_authinfo auth_info;
Sam Hocevar's avatar
 
Sam Hocevar committed
521

Sam Hocevar's avatar
 
Sam Hocevar committed
522
    auth_info.type = DVD_LU_SEND_KEY1;
Sam Hocevar's avatar
 
Sam Hocevar committed
523
    auth_info.lsk.agid = *pi_agid;
Sam Hocevar's avatar
 
Sam Hocevar committed
524

Sam Hocevar's avatar
 
Sam Hocevar committed
525
    i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
Sam Hocevar's avatar
 
Sam Hocevar committed
526

Sam Hocevar's avatar
 
Sam Hocevar committed
527
    memcpy( p_key, auth_info.lsk.key, sizeof(dvd_key) );
Sam Hocevar's avatar
 
Sam Hocevar committed
528

Sam Hocevar's avatar
 
Sam Hocevar committed
529 530 531 532 533 534 535 536 537 538
#elif defined( HAVE_BSD_DVD_STRUCT )
    struct dvd_authinfo auth_info;

    auth_info.format = DVD_REPORT_KEY1;
    auth_info.agid = *pi_agid;

    i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );

    memcpy( p_key, auth_info.keychal, 8 );

Sam Hocevar's avatar
 
Sam Hocevar committed
539
#elif defined( SYS_BEOS )
Sam Hocevar's avatar
 
Sam Hocevar committed
540
    INIT_RDC( GPCMD_REPORT_KEY, 12 );
Sam Hocevar's avatar
 
Sam Hocevar committed
541

Sam Hocevar's avatar
 
Sam Hocevar committed
542
    rdc.command[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6);
Sam Hocevar's avatar
 
Sam Hocevar committed
543

Sam Hocevar's avatar
 
Sam Hocevar committed
544
    i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
Sam Hocevar's avatar
 
Sam Hocevar committed
545

Sam Hocevar's avatar
 
Sam Hocevar committed
546
    memcpy( p_key, p_buffer + 4, 8 );
Sam Hocevar's avatar
 
Sam Hocevar committed
547

Sam Hocevar's avatar
 
Sam Hocevar committed
548 549 550 551 552 553 554 555 556 557
#elif defined( SYS_DARWIN1_3 )
    INIT_DVDIOCTL( 12 );

    dvdioctl.i_keyformat = kKey1;
    dvdioctl.i_agid = *pi_agid;

    i_ret = ioctl( i_fd, IODVD_SEND_KEY, &dvdioctl );

    memcpy( p_key, p_buffer + 4, 8 );

Sam Hocevar's avatar
 
Sam Hocevar committed
558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
#elif defined( WIN32 )
    if( GetVersion() < 0x80000000 ) /* NT/Win2000/Whistler */
    {
        DWORD tmp;
        u8 buffer[DVD_BUS_KEY_LENGTH];
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;

        memset( &buffer, 0, sizeof( buffer ) );

        key->KeyLength  = DVD_BUS_KEY_LENGTH;
        key->SessionId  = *pi_agid;
        key->KeyType    = DvdBusKey1;
        key->KeyFlags   = 0;

        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key, 
                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;

        memcpy( p_key, key->KeyData, 8 );
    }
    else
    {
        i_ret = -1;
    }

Sam Hocevar's avatar
 
Sam Hocevar committed
582
#else
Sam Hocevar's avatar
 
Sam Hocevar committed
583 584
    /* DVD ioctls unavailable - do as if the ioctl failed */
    i_ret = -1;
Sam Hocevar's avatar
 
Sam Hocevar committed
585

Sam Hocevar's avatar
 
Sam Hocevar committed
586
#endif
Sam Hocevar's avatar
 
Sam Hocevar committed
587
    return i_ret;
Sam Hocevar's avatar
 
Sam Hocevar committed
588 589 590
}

/*****************************************************************************
Sam Hocevar's avatar
 
Sam Hocevar committed
591
 * ioctl_InvalidateAgid: invalidate the current AGID
Sam Hocevar's avatar
 
Sam Hocevar committed
592
 *****************************************************************************/
Sam Hocevar's avatar
 
Sam Hocevar committed
593
int ioctl_InvalidateAgid( int i_fd, int *pi_agid )
Sam Hocevar's avatar
 
Sam Hocevar committed
594
{
Sam Hocevar's avatar
 
Sam Hocevar committed
595
    int i_ret;
Sam Hocevar's avatar
 
Sam Hocevar committed
596

Sam Hocevar's avatar
 
Sam Hocevar committed
597
#if defined( DVD_STRUCT_IN_LINUX_CDROM_H )
Sam Hocevar's avatar
 
Sam Hocevar committed
598
    dvd_authinfo auth_info;
Sam Hocevar's avatar
 
Sam Hocevar committed
599

Sam Hocevar's avatar
 
Sam Hocevar committed
600
    auth_info.type = DVD_INVALIDATE_AGID;
Sam Hocevar's avatar
 
Sam Hocevar committed
601
    auth_info.lsa.agid = *pi_agid;
Sam Hocevar's avatar
 
Sam Hocevar committed
602

Sam Hocevar's avatar
 
Sam Hocevar committed
603
    i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
Sam Hocevar's avatar
 
Sam Hocevar committed
604

Sam Hocevar's avatar
 
Sam Hocevar committed
605
    *pi_agid = auth_info.lsa.agid;
Sam Hocevar's avatar
 
Sam Hocevar committed
606

Sam Hocevar's avatar
 
Sam Hocevar committed
607 608 609 610 611 612 613 614 615 616
#elif defined( HAVE_BSD_DVD_STRUCT )
    struct dvd_authinfo auth_info;

    auth_info.format = DVD_INVALIDATE_AGID;
    auth_info.agid = *pi_agid;

    i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );

    *pi_agid = auth_info.agid;

Sam Hocevar's avatar
 
Sam Hocevar committed
617
#elif defined( SYS_BEOS )
Sam Hocevar's avatar
 
Sam Hocevar committed
618
    INIT_RDC( GPCMD_REPORT_KEY, 0 );
Sam Hocevar's avatar
 
Sam Hocevar committed
619

Sam Hocevar's avatar
 
Sam Hocevar committed
620
    rdc.command[ 10 ] = DVD_INVALIDATE_AGID | (*pi_agid << 6);
Sam Hocevar's avatar
 
Sam Hocevar committed
621

Sam Hocevar's avatar
 
Sam Hocevar committed
622
    i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
Sam Hocevar's avatar
 
Sam Hocevar committed
623

Sam Hocevar's avatar
 
Sam Hocevar committed
624 625 626 627 628 629 630 631
#elif defined( SYS_DARWIN1_3 )
    INIT_DVDIOCTL( 0 );

    dvdioctl.i_keyformat = kInvalidateAGID;
    dvdioctl.i_agid = *pi_agid;

    i_ret = ioctl( i_fd, IODVD_SEND_KEY, &dvdioctl );

Sam Hocevar's avatar
 
Sam Hocevar committed
632 633 634 635 636 637 638 639 640 641 642 643 644
#elif defined( WIN32 )
    if( GetVersion() < 0x80000000 ) /* NT/Win2000/Whistler */
    {
        DWORD tmp;

        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_END_SESSION, 
                    pi_agid, sizeof( *pi_agid ), NULL, 0, &tmp, NULL ) ? 0 : -1;
    }
    else
    {
        i_ret = -1;
    }

Sam Hocevar's avatar
 
Sam Hocevar committed
645
#else
Sam Hocevar's avatar
 
Sam Hocevar committed
646 647
    /* DVD ioctls unavailable - do as if the ioctl failed */
    i_ret = -1;
Sam Hocevar's avatar
 
Sam Hocevar committed
648 649

#endif
Sam Hocevar's avatar
 
Sam Hocevar committed
650
    return i_ret;
Sam Hocevar's avatar
 
Sam Hocevar committed
651 652 653
}

/*****************************************************************************
Sam Hocevar's avatar
 
Sam Hocevar committed
654
 * ioctl_SendChallenge: send challenge to the drive
Sam Hocevar's avatar
 
Sam Hocevar committed
655
 *****************************************************************************/
Sam Hocevar's avatar
 
Sam Hocevar committed
656
int ioctl_SendChallenge( int i_fd, int *pi_agid, u8 *p_challenge )
Sam Hocevar's avatar
 
Sam Hocevar committed
657
{
Sam Hocevar's avatar
 
Sam Hocevar committed
658
#if defined( DVD_STRUCT_IN_LINUX_CDROM_H )
Sam Hocevar's avatar
 
Sam Hocevar committed
659
    dvd_authinfo auth_info;
Sam Hocevar's avatar
 
Sam Hocevar committed
660

Sam Hocevar's avatar
 
Sam Hocevar committed
661
    auth_info.type = DVD_HOST_SEND_CHALLENGE;
Sam Hocevar's avatar
 
Sam Hocevar committed
662
    auth_info.hsc.agid = *pi_agid;
Sam Hocevar's avatar
 
Sam Hocevar committed
663

Sam Hocevar's avatar
 
Sam Hocevar committed
664
    memcpy( auth_info.hsc.chal, p_challenge, sizeof(dvd_challenge) );
Sam Hocevar's avatar
 
Sam Hocevar committed
665

Sam Hocevar's avatar
 
Sam Hocevar committed
666
    return ioctl( i_fd, DVD_AUTH, &auth_info );
Sam Hocevar's avatar
 
Sam Hocevar committed
667

Sam Hocevar's avatar
 
Sam Hocevar committed
668 669 670 671 672 673 674 675 676 677
#elif defined( HAVE_BSD_DVD_STRUCT )
    struct dvd_authinfo auth_info;

    auth_info.format = DVD_SEND_CHALLENGE;
    auth_info.agid = *pi_agid;

    memcpy( auth_info.keychal, p_challenge, 12 );

    return ioctl( i_fd, DVDIOCSENDKEY, &auth_info );

Sam Hocevar's avatar
 
Sam Hocevar committed
678
#elif defined( SYS_BEOS )
Sam Hocevar's avatar
 
Sam Hocevar committed
679
    INIT_RDC( GPCMD_SEND_KEY, 16 );
Sam Hocevar's avatar
 
Sam Hocevar committed
680

Sam Hocevar's avatar
 
Sam Hocevar committed
681
    rdc.command[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
Sam Hocevar's avatar
 
Sam Hocevar committed
682

Sam Hocevar's avatar
 
Sam Hocevar committed
683
    p_buffer[ 1 ] = 0xe;
Sam Hocevar's avatar
 
Sam Hocevar committed
684
    memcpy( p_buffer + 4, p_challenge, 12 );
Sam Hocevar's avatar
 
Sam Hocevar committed
685

Sam Hocevar's avatar
 
Sam Hocevar committed
686
    return ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
Sam Hocevar's avatar
 
Sam Hocevar committed
687

Sam Hocevar's avatar
 
Sam Hocevar committed
688 689 690 691 692 693 694 695 696 697 698
#elif defined( SYS_DARWIN1_3 )
    INIT_DVDIOCTL( 16 );

    dvdioctl.i_keyformat = kChallengeKey;
    dvdioctl.i_agid = *pi_agid;

    p_buffer[ 1 ] = 0xe;
    memcpy( p_buffer + 4, p_challenge, 12 );

    return ioctl( i_fd, IODVD_SEND_KEY, &dvdioctl );

Sam Hocevar's avatar
 
Sam Hocevar committed
699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722
#elif defined( WIN32 )
    if( GetVersion() < 0x80000000 ) /* NT/Win2000/Whistler */
    {
        DWORD tmp;
        u8 buffer[DVD_CHALLENGE_KEY_LENGTH];
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;

        memset( &buffer, 0, sizeof( buffer ) );

        key->KeyLength  = DVD_CHALLENGE_KEY_LENGTH;
        key->SessionId  = *pi_agid;
        key->KeyType    = DvdChallengeKey;
        key->KeyFlags   = 0;

        memcpy( key->KeyData, p_challenge, 10 );

        return DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_SEND_KEY, key, 
                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
    }
    else
    {
        return -1;
    }

Sam Hocevar's avatar
 
Sam Hocevar committed
723
#else
Sam Hocevar's avatar
 
Sam Hocevar committed
724
    /* DVD ioctls unavailable - do as if the ioctl failed */
Sam Hocevar's avatar
 
Sam Hocevar committed
725 726 727
    return -1;

#endif
Sam Hocevar's avatar
 
Sam Hocevar committed
728 729 730
}

/*****************************************************************************
Sam Hocevar's avatar
 
Sam Hocevar committed
731
 * ioctl_SendKey2: send the second key to the drive
Sam Hocevar's avatar
 
Sam Hocevar committed
732
 *****************************************************************************/
Sam Hocevar's avatar
 
Sam Hocevar committed
733
int ioctl_SendKey2( int i_fd, int *pi_agid, u8 *p_key )
Sam Hocevar's avatar
 
Sam Hocevar committed
734
{
Sam Hocevar's avatar
 
Sam Hocevar committed
735
#if defined( DVD_STRUCT_IN_LINUX_CDROM_H )
Sam Hocevar's avatar
 
Sam Hocevar committed
736 737 738
    dvd_authinfo auth_info;

    auth_info.type = DVD_HOST_SEND_KEY2;
Sam Hocevar's avatar
 
Sam Hocevar committed
739
    auth_info.hsk.agid = *pi_agid;
Sam Hocevar's avatar
 
Sam Hocevar committed
740 741 742

    memcpy( auth_info.hsk.key, p_key, sizeof(dvd_key) );

Sam Hocevar's avatar
 
Sam Hocevar committed
743
    return ioctl( i_fd, DVD_AUTH, &auth_info );
Sam Hocevar's avatar
 
Sam Hocevar committed
744

Sam Hocevar's avatar
 
Sam Hocevar committed
745 746 747 748 749 750 751 752 753 754
#elif defined( HAVE_BSD_DVD_STRUCT )
    struct dvd_authinfo auth_info;

    auth_info.format = DVD_SEND_KEY2;
    auth_info.agid = *pi_agid;

    memcpy( auth_info.keychal, p_key, 8 );

    return ioctl( i_fd, DVDIOCSENDKEY, &auth_info );

Sam Hocevar's avatar
 
Sam Hocevar committed
755
#elif defined( SYS_BEOS )
Sam Hocevar's avatar
 
Sam Hocevar committed
756
    INIT_RDC( GPCMD_SEND_KEY, 12 );
Sam Hocevar's avatar
 
Sam Hocevar committed
757

Sam Hocevar's avatar
 
Sam Hocevar committed
758
    rdc.command[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
Sam Hocevar's avatar
 
Sam Hocevar committed
759

Sam Hocevar's avatar
 
Sam Hocevar committed
760
    p_buffer[ 1 ] = 0xa;
Sam Hocevar's avatar
 
Sam Hocevar committed
761
    memcpy( p_buffer + 4, p_key, 8 );
Sam Hocevar's avatar
 
Sam Hocevar committed
762

Sam Hocevar's avatar
 
Sam Hocevar committed
763
    return ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
Sam Hocevar's avatar
 
Sam Hocevar committed
764

Sam Hocevar's avatar
 
Sam Hocevar committed
765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788
#elif defined( WIN32 )
    if( GetVersion() < 0x80000000 ) /* NT/Win2000/Whistler */
    {
        DWORD tmp;
        u8 buffer[DVD_BUS_KEY_LENGTH];
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;

        memset( &buffer, 0, sizeof( buffer ) );

        key->KeyLength  = DVD_BUS_KEY_LENGTH;
        key->SessionId  = *pi_agid;
        key->KeyType    = DvdBusKey2;
        key->KeyFlags   = 0;

        memcpy( key->KeyData, p_key, 8 );

        return DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_SEND_KEY, key, 
                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
    }
    else
    {
        return -1;
    }

Sam Hocevar's avatar
 
Sam Hocevar committed
789 790 791 792 793 794 795 796 797 798 799
#elif defined( SYS_DARWIN1_3 )
    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 );

Sam Hocevar's avatar
 
Sam Hocevar committed
800
#else
Sam Hocevar's avatar
 
Sam Hocevar committed
801
    /* DVD ioctls unavailable - do as if the ioctl failed */
Sam Hocevar's avatar
 
Sam Hocevar committed
802
    return -1;
Sam Hocevar's avatar
 
Sam Hocevar committed
803

Sam Hocevar's avatar
 
Sam Hocevar committed
804
#endif
Sam Hocevar's avatar
 
Sam Hocevar committed
805 806
}

Sam Hocevar's avatar
 
Sam Hocevar committed
807 808 809
/* Local prototypes */

#if defined( SYS_BEOS )
Sam Hocevar's avatar
 
Sam Hocevar committed
810
/*****************************************************************************
Sam Hocevar's avatar
 
Sam Hocevar committed
811
 * BeInitRDC: initialize a RDC structure for the BeOS kernel
Sam Hocevar's avatar
 
Sam Hocevar committed
812
 *****************************************************************************
Sam Hocevar's avatar
 
Sam Hocevar committed
813 814
 * This function initializes a BeOS raw device command structure for future
 * use, either a read command or a write command.
Sam Hocevar's avatar
 
Sam Hocevar committed
815
 *****************************************************************************/
Sam Hocevar's avatar
 
Sam Hocevar committed
816
static void BeInitRDC( raw_device_command *p_rdc, int i_type )
Sam Hocevar's avatar
 
Sam Hocevar committed
817
{
Sam Hocevar's avatar
 
Sam Hocevar committed
818
    memset( p_rdc->data, 0, p_rdc->data_length );
Sam Hocevar's avatar
 
Sam Hocevar committed
819

Sam Hocevar's avatar
 
Sam Hocevar committed
820 821 822 823 824 825 826 827
    switch( i_type )
    {
        case GPCMD_SEND_KEY:
            /* leave the flags to 0 */
            break;

        case GPCMD_READ_DVD_STRUCTURE:
        case GPCMD_REPORT_KEY:
Sam Hocevar's avatar
 
Sam Hocevar committed
828
            p_rdc->flags = B_RAW_DEVICE_DATA_IN;
Sam Hocevar's avatar
 
Sam Hocevar committed
829 830 831 832 833
            break;
    }

    p_rdc->command[ 0 ]      = i_type;

Sam Hocevar's avatar
 
Sam Hocevar committed
834 835
    p_rdc->command[ 8 ]      = (p_rdc->data_length >> 8) & 0xff;
    p_rdc->command[ 9 ]      =  p_rdc->data_length       & 0xff;
Sam Hocevar's avatar
 
Sam Hocevar committed
836
    p_rdc->command_length    = 12;
Sam Hocevar's avatar
 
Sam Hocevar committed
837

Sam Hocevar's avatar
 
Sam Hocevar committed
838 839
    p_rdc->sense_data        = NULL;
    p_rdc->sense_data_length = 0;
Sam Hocevar's avatar
 
Sam Hocevar committed
840

Sam Hocevar's avatar
 
Sam Hocevar committed
841
    p_rdc->timeout           = 1000000;
Sam Hocevar's avatar
 
Sam Hocevar committed
842 843 844
}
#endif