Diff of /src/ioctl.c [104348] .. [d040ac] Maximize Restore

  Switch to unified view

a/src/ioctl.c b/src/ioctl.c
1
/*****************************************************************************
1
/*****************************************************************************
2
 * ioctl.c: DVD ioctl replacement function
2
 * ioctl.c: DVD ioctl replacement function
3
 *****************************************************************************
3
 *****************************************************************************
4
 * Copyright (C) 1999-2001 VideoLAN
4
 * Copyright (C) 1999-2001 VideoLAN
5
 * $Id$
5
 * $Id: ioctl.c,v 1.1 2001/12/22 00:08:13 sam Exp $
6
 *
6
 *
7
 * Authors: Markus Kuespert <ltlBeBoy@beosmail.com>
7
 * Authors: Markus Kuespert <ltlBeBoy@beosmail.com>
8
 *          Sam Hocevar <sam@zoy.org>
8
 *          Samuel Hocevar <sam@zoy.org>
9
 *          Jon Lech Johansen <jon-vl@nanocrew.net>
9
 *          Jon Lech Johansen <jon-vl@nanocrew.net>
10
 *          HĂĽkan Hjort <d95hjort@dtek.chalmers.se>
10
 *          Hĺkan Hjort <d95hjort@dtek.chalmers.se>
11
 *          Eugenio Jarosiewicz <ej0@cise.ufl.edu>
11
 *          Eugenio Jarosiewicz <ej0@cise.ufl.edu>
12
 *          David SiebĂśrger <drs-videolan@rucus.ru.ac.za>
12
 *          David Siebörger <drs-videolan@rucus.ru.ac.za>
13
 *          Alex Strelnikov <lelik@os2.ru>
14
 *          Gildas Bazin <gbazin@netcourrier.com>
15
 *
13
 *
16
 * This program is free software; you can redistribute it and/or modify
14
 * This program is free software; you can redistribute it and/or modify
17
 * it under the terms of the GNU General Public License as published by
15
 * it under the terms of the GNU General Public License as published by
18
 * the Free Software Foundation; either version 2 of the License, or
16
 * the Free Software Foundation; either version 2 of the License, or
19
 * (at your option) any later version.
17
 * (at your option) any later version.
...
...
39
#include <sys/types.h>
37
#include <sys/types.h>
40
38
41
#if defined( WIN32 )
39
#if defined( WIN32 )
42
#   include <windows.h>
40
#   include <windows.h>
43
#   include <winioctl.h>
41
#   include <winioctl.h>
44
#elif defined ( SYS_OS2 )
45
#   define INCL_DOSFILEMGR
46
#   define INCL_DOSDEVICES
47
#   define INCL_DOSDEVIOCTL
48
#   define INCL_DOSERRORS
49
#   include <os2.h>
50
#   include <sys/ioctl.h>
51
#else
42
#else
52
#   include <netinet/in.h>
43
#   include <netinet/in.h>
53
#   include <sys/ioctl.h>
44
#   include <sys/ioctl.h>
54
#endif
45
#endif
55
46
...
...
74
#endif
65
#endif
75
#ifdef HPUX_SCTL_IO
66
#ifdef HPUX_SCTL_IO
76
#   include <sys/scsi.h>
67
#   include <sys/scsi.h>
77
#endif
68
#endif
78
#ifdef SOLARIS_USCSI
69
#ifdef SOLARIS_USCSI
79
#   include <dlfcn.h>
80
#   include <unistd.h>
70
#   include <unistd.h>
81
#   include <stropts.h>
71
#   include <stropts.h>
82
#   include <sys/scsi/scsi_types.h>
72
#   include <sys/scsi/scsi_types.h>
83
#   include <sys/scsi/impl/uscsi.h>
73
#   include <sys/scsi/impl/uscsi.h>
84
#endif
74
#endif
85
#ifdef DARWIN_DVD_IOCTL
75
76
#ifdef SYS_DARWIN
86
#   include <IOKit/storage/IODVDMediaBSDClient.h>
77
#   include <IOKit/storage/IODVDMediaBSDClient.h>
87
#endif
78
/* #   include "DVDioctl/DVDioctl.h" */
88
#ifdef __QNXNTO__
89
#   include <sys/mman.h>
90
#   include <sys/dcmd_cam.h>
91
#endif
79
#endif
92
80
93
#include "common.h"
81
#include "common.h"
94
82
95
#include "ioctl.h"
83
#include "ioctl.h"
...
...
111
/*****************************************************************************
99
/*****************************************************************************
112
 * Local prototypes, Solaris specific
100
 * Local prototypes, Solaris specific
113
 *****************************************************************************/
101
 *****************************************************************************/
114
#if defined( SOLARIS_USCSI )
102
#if defined( SOLARIS_USCSI )
115
static void SolarisInitUSCSI( struct uscsi_cmd *p_sc, int i_type );
103
static void SolarisInitUSCSI( struct uscsi_cmd *p_sc, int i_type );
116
static int SolarisSendUSCSI( int fd, struct uscsi_cmd *p_sc );
117
#endif
104
#endif
118
105
119
/*****************************************************************************
106
/*****************************************************************************
120
 * Local prototypes, win32 (aspi) specific
107
 * Local prototypes, win32 (aspi) specific
121
 *****************************************************************************/
108
 *****************************************************************************/
122
#if defined( WIN32 )
109
#if defined( WIN32 )
123
static void WinInitSPTD ( SCSI_PASS_THROUGH_DIRECT *, int );
124
static void WinInitSSC  ( struct SRB_ExecSCSICmd *, int );
110
static void WinInitSSC ( struct SRB_ExecSCSICmd *, int );
125
static int  WinSendSSC  ( int, struct SRB_ExecSCSICmd * );
111
static int  WinSendSSC ( int, struct SRB_ExecSCSICmd * );
126
#endif
127
128
/*****************************************************************************
129
 * Local prototypes, QNX specific
130
 *****************************************************************************/
131
#if defined( __QNXNTO__ )
132
static void QNXInitCPT ( CAM_PASS_THRU *, int );
133
#endif
134
135
/*****************************************************************************
136
 * Local prototypes, OS2 specific
137
 *****************************************************************************/
138
#if defined( SYS_OS2 )
139
static void OS2InitSDC( struct OS2_ExecSCSICmd *, int );
140
#endif
112
#endif
141
113
142
/*****************************************************************************
114
/*****************************************************************************
143
 * ioctl_ReadCopyright: check whether the disc is encrypted or not
115
 * ioctl_ReadCopyright: check whether the disc is encrypted or not
144
 *****************************************************************************/
116
 *****************************************************************************/
...
...
188
160
189
    *pi_copyright = p_buffer[ 4 ];
161
    *pi_copyright = p_buffer[ 4 ];
190
162
191
#elif defined( SOLARIS_USCSI )
163
#elif defined( SOLARIS_USCSI )
192
    INIT_USCSI( GPCMD_READ_DVD_STRUCTURE, 8 );
164
    INIT_USCSI( GPCMD_READ_DVD_STRUCTURE, 8 );
193
165
    
194
    rs_cdb.cdb_opaque[ 6 ] = i_layer;
166
    rs_cdb.cdb_opaque[ 6 ] = i_layer;
195
    rs_cdb.cdb_opaque[ 7 ] = DVD_STRUCT_COPYRIGHT;
167
    rs_cdb.cdb_opaque[ 7 ] = DVD_STRUCT_COPYRIGHT;
196
168
197
    i_ret = SolarisSendUSCSI(i_fd, &sc);
169
    i_ret = ioctl(i_fd, USCSICMD, &sc);
198
170
199
    if( i_ret < 0 || sc.uscsi_status ) {
171
    if( i_ret < 0 || sc.uscsi_status ) {
200
        i_ret = -1;
172
        i_ret = -1;
201
    }
173
    }
202
174
    
203
    *pi_copyright = p_buffer[ 4 ];
175
    *pi_copyright = p_buffer[ 4 ];
204
    /* s->copyright.rmi = p_buffer[ 5 ]; */
176
    /* s->copyright.rmi = p_buffer[ 5 ]; */
205
177
206
#elif defined( DARWIN_DVD_IOCTL )
178
#elif defined( SYS_DARWIN )
207
    INIT_DVDIOCTL( dk_dvd_read_structure_t, DVDCopyrightInfo,
179
    dk_dvd_read_structure_t dvd;
208
                   kDVDStructureFormatCopyrightInfo );
180
    DVDCopyrightInfo dvdcpi;
181
    
182
    memset(&dvd, 0, sizeof(dvd));
183
    memset(&dvdcpi, 0, sizeof(dvdcpi));
209
184
185
    dvd.buffer = &dvdcpi;
186
    dvd.bufferLength = sizeof(dvdcpi);
187
    dvd.format = kDVDStructureFormatCopyrightInfo;
210
    dvd.layer = i_layer;
188
    dvd.layer = i_layer;
211
189
190
    /* dvdcpi.dataLength[0] = 0x00; */ /* dataLength[0] is already memset to 0 */
191
    /* dvdcpi.dataLength[1] = 0x06; */
192
    
212
    i_ret = ioctl( i_fd, DKIOCDVDREADSTRUCTURE, &dvd );
193
    i_ret = ioctl( i_fd, DKIOCDVDREADSTRUCTURE, &dvd );
213
194
214
    *pi_copyright = dvdbs.copyrightProtectionSystemType;
195
    *pi_copyright = dvdcpi.copyrightProtectionSystemType;
215
196
216
#elif defined( WIN32 )
197
#elif defined( WIN32 )
217
    if( WIN2K ) /* NT/2k/XP */
198
    if( WIN2K ) /* NT/Win2000/Whistler */
199
    {
200
        DWORD tmp;
201
        u8 p_buffer[ 8 ];
202
        SCSI_PASS_THROUGH_DIRECT sptd;
203
204
        memset( &sptd, 0, sizeof( sptd ) );
205
        memset( &p_buffer, 0, sizeof( p_buffer ) );
218
    {
206
   
219
        INIT_SPTD( GPCMD_READ_DVD_STRUCTURE, 8 );
220
221
        /*  When using IOCTL_DVD_READ_STRUCTURE and
207
        /*  When using IOCTL_DVD_READ_STRUCTURE and 
222
            DVD_COPYRIGHT_DESCRIPTOR, CopyrightProtectionType
208
            DVD_COPYRIGHT_DESCRIPTOR, CopyrightProtectionType
223
            seems to be always 6 ???
209
            is always 6. So we send a raw scsi command instead. */
224
            To work around this MS bug we try to send a raw scsi command
225
            instead (if we've got enough privileges to do so). */
226
210
211
        sptd.Length             = sizeof( SCSI_PASS_THROUGH_DIRECT );
212
        sptd.CdbLength          = 12;
213
        sptd.DataIn             = SCSI_IOCTL_DATA_IN;
214
        sptd.DataTransferLength = 8;
215
        sptd.TimeOutValue       = 2;
216
        sptd.DataBuffer         = p_buffer;
217
        sptd.Cdb[ 0 ]           = GPCMD_READ_DVD_STRUCTURE;
227
        sptd.Cdb[ 6 ] = i_layer;
218
        sptd.Cdb[ 6 ]           = i_layer;
228
        sptd.Cdb[ 7 ] = DVD_STRUCT_COPYRIGHT;
219
        sptd.Cdb[ 7 ]           = DVD_STRUCT_COPYRIGHT;
220
        sptd.Cdb[ 8 ]           = (8 >> 8) & 0xff;
221
        sptd.Cdb[ 9 ]           =  8       & 0xff;
229
222
230
        i_ret = SEND_SPTD( i_fd, &sptd, &tmp );
223
        i_ret = DeviceIoControl( (HANDLE) i_fd,
224
                             IOCTL_SCSI_PASS_THROUGH_DIRECT,
225
                             &sptd, sizeof( SCSI_PASS_THROUGH_DIRECT ),
226
                             &sptd, sizeof( SCSI_PASS_THROUGH_DIRECT ),
227
                             &tmp, NULL ) ? 0 : -1;
231
228
232
        if( i_ret == 0 )
233
        {
234
            *pi_copyright = p_buffer[ 4 ];
229
        *pi_copyright = p_buffer[ 4 ];
235
        }
236
    }
230
    }
237
    else
231
    else
238
    {
232
    {
239
        INIT_SSC( GPCMD_READ_DVD_STRUCTURE, 8 );
233
        INIT_SSC( GPCMD_READ_DVD_STRUCTURE, 8 );
240
234
...
...
245
239
246
        *pi_copyright = p_buffer[ 4 ];
240
        *pi_copyright = p_buffer[ 4 ];
247
    }
241
    }
248
242
249
#elif defined( __QNXNTO__ )
243
#elif defined( __QNXNTO__ )
244
    /*
245
        QNX RTOS currently doesn't have a CAM
246
        interface (they're working on it though).
247
        Assume DVD is not encrypted.
248
    */
250
249
251
    INIT_CPT( GPCMD_READ_DVD_STRUCTURE, 8 );
252
253
    p_cpt->cam_cdb[ 6 ] = i_layer;
254
    p_cpt->cam_cdb[ 7 ] = DVD_STRUCT_COPYRIGHT;
255
256
    i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
257
258
    *pi_copyright = p_buffer[4];
250
    *pi_copyright = 0;
259
251
    i_ret = 0;
260
#elif defined( SYS_OS2 )
261
    INIT_SSC( GPCMD_READ_DVD_STRUCTURE, 8 );
262
263
    sdc.command[ 6 ] = i_layer;
264
    sdc.command[ 7 ] = DVD_STRUCT_COPYRIGHT;
265
266
    i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
267
                        &sdc, sizeof(sdc), &ulParamLen,
268
                        p_buffer, sizeof(p_buffer), &ulDataLen);
269
270
    *pi_copyright = p_buffer[ 4 ];
271
252
272
#else
253
#else
273
#   error "DVD ioctls are unavailable on this system"
254
    /* DVD ioctls unavailable - do as if the ioctl failed */
255
    i_ret = -1;
274
256
275
#endif
257
#endif
276
    return i_ret;
258
    return i_ret;
277
}
259
}
278
260
279
/*****************************************************************************
261
/*****************************************************************************
280
 * ioctl_ReadDiscKey: get the disc key
262
 * ioctl_ReadDiscKey: get the disc key
281
 *****************************************************************************/
263
 *****************************************************************************/
282
int ioctl_ReadDiscKey( int i_fd, int *pi_agid, uint8_t *p_key )
264
int ioctl_ReadDiscKey( int i_fd, int *pi_agid, u8 *p_key )
283
{
265
{
284
    int i_ret;
266
    int i_ret;
285
267
286
#if defined( HAVE_LINUX_DVD_STRUCT )
268
#if defined( HAVE_LINUX_DVD_STRUCT )
287
    dvd_struct dvd;
269
    dvd_struct dvd;
...
...
320
#elif defined( SYS_BEOS )
302
#elif defined( SYS_BEOS )
321
    INIT_RDC( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
303
    INIT_RDC( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
322
304
323
    rdc.command[ 7 ]  = DVD_STRUCT_DISCKEY;
305
    rdc.command[ 7 ]  = DVD_STRUCT_DISCKEY;
324
    rdc.command[ 10 ] = *pi_agid << 6;
306
    rdc.command[ 10 ] = *pi_agid << 6;
325
307
    
326
    i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
308
    i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
327
309
328
    if( i_ret < 0 )
310
    if( i_ret < 0 )
329
    {
311
    {
330
        return i_ret;
312
        return i_ret;
...
...
335
#elif defined( HPUX_SCTL_IO )
317
#elif defined( HPUX_SCTL_IO )
336
    INIT_SCTL_IO( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
318
    INIT_SCTL_IO( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
337
319
338
    sctl_io.cdb[ 7 ]  = DVD_STRUCT_DISCKEY;
320
    sctl_io.cdb[ 7 ]  = DVD_STRUCT_DISCKEY;
339
    sctl_io.cdb[ 10 ] = *pi_agid << 6;
321
    sctl_io.cdb[ 10 ] = *pi_agid << 6;
340
322
    
341
    i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
323
    i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
342
324
343
    if( i_ret < 0 )
325
    if( i_ret < 0 )
344
    {
326
    {
345
        return i_ret;
327
        return i_ret;
...
...
347
329
348
    memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );
330
    memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );
349
331
350
#elif defined( SOLARIS_USCSI )
332
#elif defined( SOLARIS_USCSI )
351
    INIT_USCSI( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
333
    INIT_USCSI( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
352
334
    
353
    rs_cdb.cdb_opaque[ 7 ] = DVD_STRUCT_DISCKEY;
335
    rs_cdb.cdb_opaque[ 7 ] = DVD_STRUCT_DISCKEY;
354
    rs_cdb.cdb_opaque[ 10 ] = *pi_agid << 6;
336
    rs_cdb.cdb_opaque[ 10 ] = *pi_agid << 6;
355
337
    
356
    i_ret = SolarisSendUSCSI( i_fd, &sc );
338
    i_ret = ioctl( i_fd, USCSICMD, &sc );
357
339
    
358
    if( i_ret < 0 || sc.uscsi_status )
340
    if( i_ret < 0 || sc.uscsi_status )
359
    {
341
    {
360
        i_ret = -1;
342
        i_ret = -1;
361
        return i_ret;
343
        return i_ret;
362
    }
344
    }
363
345
364
    memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );
346
    memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );
365
347
366
#elif defined( DARWIN_DVD_IOCTL )
348
#elif defined( SYS_DARWIN )
367
    INIT_DVDIOCTL( dk_dvd_read_structure_t, DVDDiscKeyInfo,
349
    dk_dvd_read_structure_t dvd;
368
                   kDVDStructureFormatDiscKeyInfo );
350
    DVDDiscKeyInfo dvddki;
351
    
352
    memset(&dvd, 0, sizeof(dvd));
353
    memset(&dvddki, 0, sizeof(dvddki));
369
354
355
    dvd.buffer = &dvddki;
356
    dvd.bufferLength = sizeof(dvddki);
357
    dvd.format = kDVDStructureFormatDiscKeyInfo;
370
    dvd.grantID = *pi_agid;
358
    dvd.grantID = *pi_agid;
371
359
360
    /* 2048+2 ; maybe we should do bit shifts to value of (sizeof(dvddki)-2) */
361
    dvddki.dataLength[ 0 ] = 0x04;
362
    dvddki.dataLength[ 1 ] = 0x02;
363
372
    i_ret = ioctl( i_fd, DKIOCDVDREADSTRUCTURE, &dvd );
364
    i_ret = ioctl( i_fd, DKIOCDVDREADSTRUCTURE, &dvd );
373
365
374
    memcpy( p_key, dvdbs.discKeyStructures, DVD_DISCKEY_SIZE );
366
    memcpy( p_key, dvddki.discKeyStructures, DVD_DISCKEY_SIZE );
375
367
376
#elif defined( WIN32 )
368
#elif defined( WIN32 )
377
    if( WIN2K ) /* NT/2k/XP */
369
    if( WIN2K ) /* NT/Win2000/Whistler */
378
    {
370
    {
379
        DWORD tmp;
371
        DWORD tmp;
380
        uint8_t buffer[DVD_DISK_KEY_LENGTH];
372
        u8 buffer[DVD_DISK_KEY_LENGTH];
381
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
373
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
382
374
383
        memset( &buffer, 0, sizeof( buffer ) );
375
        memset( &buffer, 0, sizeof( buffer ) );
384
376
385
        key->KeyLength  = DVD_DISK_KEY_LENGTH;
377
        key->KeyLength  = DVD_DISK_KEY_LENGTH;
386
        key->SessionId  = *pi_agid;
378
        key->SessionId  = *pi_agid;
387
        key->KeyType    = DvdDiskKey;
379
        key->KeyType    = DvdDiskKey;
388
        key->KeyFlags   = 0;
380
        key->KeyFlags   = 0;
389
381
390
        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
382
        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key, 
391
                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
383
                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
384
385
        if( i_ret < 0 )
386
        {   
387
            return i_ret;
388
        }
389
390
        memcpy( p_key, key->KeyData, DVD_DISCKEY_SIZE );
391
    }
392
    else
393
    {
394
        INIT_SSC( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
395
396
        ssc.CDBByte[ 7 ]  = DVD_STRUCT_DISCKEY;
397
        ssc.CDBByte[ 10 ] = *pi_agid << 6;
398
    
399
        i_ret = WinSendSSC( i_fd, &ssc );
392
400
393
        if( i_ret < 0 )
401
        if( i_ret < 0 )
394
        {
402
        {
395
            return i_ret;
403
            return i_ret;
396
        }
404
        }
397
405
398
        memcpy( p_key, key->KeyData, DVD_DISCKEY_SIZE );
399
    }
400
    else
401
    {
402
        INIT_SSC( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
403
404
        ssc.CDBByte[ 7 ]  = DVD_STRUCT_DISCKEY;
405
        ssc.CDBByte[ 10 ] = *pi_agid << 6;
406
407
        i_ret = WinSendSSC( i_fd, &ssc );
408
409
        if( i_ret < 0 )
410
        {
411
            return i_ret;
412
        }
413
414
        memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );
406
        memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );
415
    }
407
    }
416
408
417
#elif defined( __QNXNTO__ )
418
419
    INIT_CPT( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
420
421
    p_cpt->cam_cdb[ 7 ] = DVD_STRUCT_DISCKEY;
422
    p_cpt->cam_cdb[ 10 ] = *pi_agid << 6;
423
424
    i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
425
426
    memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );
427
428
#elif defined ( SYS_OS2 )
429
    INIT_SSC( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
430
431
    sdc.command[ 7 ]  = DVD_STRUCT_DISCKEY;
432
    sdc.command[ 10 ] = *pi_agid << 6;
433
434
    i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
435
                        &sdc, sizeof(sdc), &ulParamLen,
436
                        p_buffer, sizeof(p_buffer), &ulDataLen);
437
438
    if( i_ret < 0 )
439
    {
440
        return i_ret;
441
    }
442
443
    memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );
444
445
#else
409
#else
446
#   error "DVD ioctls are unavailable on this system"
410
    /* DVD ioctls unavailable - do as if the ioctl failed */
411
    i_ret = -1;
447
412
448
#endif
413
#endif
449
    return i_ret;
414
    return i_ret;
450
}
415
}
451
416
452
/*****************************************************************************
417
/*****************************************************************************
453
 * ioctl_ReadTitleKey: get the title key
418
 * ioctl_ReadTitleKey: get the title key
454
 *****************************************************************************/
419
 *****************************************************************************/
455
int ioctl_ReadTitleKey( int i_fd, int *pi_agid, int i_pos, uint8_t *p_key )
420
int ioctl_ReadTitleKey( int i_fd, int *pi_agid, int i_pos, u8 *p_key )
456
{
421
{
457
    int i_ret;
422
    int i_ret;
458
423
459
#if defined( HAVE_LINUX_DVD_STRUCT )
424
#if defined( HAVE_LINUX_DVD_STRUCT )
460
    dvd_authinfo auth_info;
425
    dvd_authinfo auth_info;
...
...
506
471
507
    memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
472
    memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
508
473
509
#elif defined( SOLARIS_USCSI )
474
#elif defined( SOLARIS_USCSI )
510
    INIT_USCSI( GPCMD_REPORT_KEY, 12 );
475
    INIT_USCSI( GPCMD_REPORT_KEY, 12 );
511
476
    
512
    rs_cdb.cdb_opaque[ 2 ] = ( i_pos >> 24 ) & 0xff;
477
    rs_cdb.cdb_opaque[ 2 ] = ( i_pos >> 24 ) & 0xff;
513
    rs_cdb.cdb_opaque[ 3 ] = ( i_pos >> 16 ) & 0xff;
478
    rs_cdb.cdb_opaque[ 3 ] = ( i_pos >> 16 ) & 0xff;
514
    rs_cdb.cdb_opaque[ 4 ] = ( i_pos >>  8 ) & 0xff;
479
    rs_cdb.cdb_opaque[ 4 ] = ( i_pos >>  8 ) & 0xff;
515
    rs_cdb.cdb_opaque[ 5 ] = ( i_pos       ) & 0xff;
480
    rs_cdb.cdb_opaque[ 5 ] = ( i_pos       ) & 0xff;
516
    rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);
481
    rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);
517
482
    
518
    i_ret = SolarisSendUSCSI( i_fd, &sc );
483
    i_ret = ioctl( i_fd, USCSICMD, &sc );
519
484
    
520
    if( i_ret < 0 || sc.uscsi_status )
485
    if( i_ret < 0 || sc.uscsi_status )
521
    {
486
    {
522
        i_ret = -1;
487
        i_ret = -1;
523
    }
488
    }
524
489
525
    /* Do we want to return the cp_sec flag perhaps? */
490
    /* Do we want to return the cp_sec flag perhaps? */
526
    /* a->lstk.cpm    = (buf[ 4 ] >> 7) & 1; */
491
    /* a->lstk.cpm    = (buf[ 4 ] >> 7) & 1; */
527
    /* a->lstk.cp_sec = (buf[ 4 ] >> 6) & 1; */
492
    /* a->lstk.cp_sec = (buf[ 4 ] >> 6) & 1; */
528
    /* a->lstk.cgms   = (buf[ 4 ] >> 4) & 3; */
493
    /* a->lstk.cgms   = (buf[ 4 ] >> 4) & 3; */
529
494
 
530
    memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
495
    memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE ); 
531
496
    
532
#elif defined( DARWIN_DVD_IOCTL )
497
#elif defined( SYS_DARWIN )
533
    INIT_DVDIOCTL( dk_dvd_report_key_t, DVDTitleKeyInfo,
498
    dk_dvd_report_key_t dvd;
534
                   kDVDKeyFormatTitleKey );
499
    DVDTitleKeyInfo dvdtki;
500
    
501
    memset(&dvd, 0, sizeof(dvd));
502
    memset(&dvdtki, 0, sizeof(dvdtki));
535
503
536
    dvd.address = i_pos;
504
    dvd.buffer = &dvdtki;
505
    dvd.bufferLength = sizeof(dvdtki);
506
    dvd.format = kDVDKeyFormatTitleKey;
537
    dvd.grantID = *pi_agid;
507
    dvd.grantID = *pi_agid;
538
    dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
508
    dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM; /* or this - this is memset 0x00 anyways */
509
510
    /* dvdtki.dataLength[0] = 0x00; */ /* dataLength[0] is already memset to 0 */
511
    dvdtki.dataLength[ 1 ] = 0x0a;
512
    
513
    /* What are DVDTitleKeyInfo.{CP_MOD,CGMS,CP_SEC,CPM} and do they need to be set? */
514
#warning "Correct title key reading for MacOSX / Darwin!"
515
    /* hh: No that should be part of the result I belive.
516
     * You do need to set the sector/lba/position somehow though! */
539
517
540
    i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
518
    i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
541
519
542
    memcpy( p_key, dvdbs.titleKeyValue, DVD_KEY_SIZE );
520
    memcpy( p_key, dvdtki.titleKeyValue, DVD_KEY_SIZE );
543
521
544
#elif defined( WIN32 )
522
#elif defined( WIN32 )
545
    if( WIN2K ) /* NT/2k/XP */
523
    if( WIN2K ) /* NT/Win2000/Whistler */
546
    {
524
    {
547
        DWORD tmp;
525
        DWORD tmp;
548
        uint8_t buffer[DVD_TITLE_KEY_LENGTH];
526
        u8 buffer[DVD_BUS_KEY_LENGTH];
549
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
527
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
550
528
551
        memset( &buffer, 0, sizeof( buffer ) );
529
        memset( &buffer, 0, sizeof( buffer ) );
552
530
553
        key->KeyLength  = DVD_TITLE_KEY_LENGTH;
531
        key->KeyLength  = DVD_BUS_KEY_LENGTH;
554
        key->SessionId  = *pi_agid;
532
        key->SessionId  = *pi_agid;
555
        key->KeyType    = DvdTitleKey;
533
        key->KeyType    = DvdTitleKey;
556
        key->KeyFlags   = 0;
534
        key->KeyFlags   = 0;
557
        key->Parameters.TitleOffset.QuadPart = (LONGLONG) i_pos *
535
#warning "Fix ReadTitleKey for WIN32!"
558
                                                   2048 /*DVDCSS_BLOCK_SIZE*/;
536
        //key->Parameters.TitleOffset = i_pos; // is this ok?
559
537
560
        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
538
        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key, 
561
                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
539
                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
562
540
563
        memcpy( p_key, key->KeyData, DVD_KEY_SIZE );
541
        memcpy( p_key, key->KeyData, DVD_KEY_SIZE );
564
    }
542
    }
565
    else
543
    else
...
...
575
        i_ret = WinSendSSC( i_fd, &ssc );
553
        i_ret = WinSendSSC( i_fd, &ssc );
576
554
577
        memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
555
        memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
578
    }
556
    }
579
557
580
#elif defined( __QNXNTO__ )
581
582
    INIT_CPT( GPCMD_REPORT_KEY, 12 );
583
584
    p_cpt->cam_cdb[ 2 ] = ( i_pos >> 24 ) & 0xff;
585
    p_cpt->cam_cdb[ 3 ] = ( i_pos >> 16 ) & 0xff;
586
    p_cpt->cam_cdb[ 4 ] = ( i_pos >>  8 ) & 0xff;
587
    p_cpt->cam_cdb[ 5 ] = ( i_pos       ) & 0xff;
588
    p_cpt->cam_cdb[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);
589
590
    i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
591
592
    memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
593
594
#elif defined( SYS_OS2 )
595
    INIT_SSC( GPCMD_REPORT_KEY, 12 );
596
597
    sdc.command[ 2 ] = ( i_pos >> 24 ) & 0xff;
598
    sdc.command[ 3 ] = ( i_pos >> 16 ) & 0xff;
599
    sdc.command[ 4 ] = ( i_pos >>  8 ) & 0xff;
600
    sdc.command[ 5 ] = ( i_pos       ) & 0xff;
601
    sdc.command[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);
602
603
    i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
604
                        &sdc, sizeof(sdc), &ulParamLen,
605
                        p_buffer, sizeof(p_buffer), &ulDataLen);
606
607
    memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
608
609
#else
558
#else
610
#   error "DVD ioctls are unavailable on this system"
559
    /* DVD ioctls unavailable - do as if the ioctl failed */
560
    i_ret = -1;
611
561
612
#endif
562
#endif
613
563
614
    return i_ret;
564
    return i_ret;
615
}
565
}
...
...
662
612
663
    *pi_agid = p_buffer[ 7 ] >> 6;
613
    *pi_agid = p_buffer[ 7 ] >> 6;
664
614
665
#elif defined( SOLARIS_USCSI )
615
#elif defined( SOLARIS_USCSI )
666
    INIT_USCSI( GPCMD_REPORT_KEY, 8 );
616
    INIT_USCSI( GPCMD_REPORT_KEY, 8 );
667
617
    
668
    rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
618
    rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
669
619
    
670
    i_ret = SolarisSendUSCSI( i_fd, &sc );
620
    i_ret = ioctl( i_fd, USCSICMD, &sc );
671
621
    
672
    if( i_ret < 0 || sc.uscsi_status )
622
    if( i_ret < 0 || sc.uscsi_status )
673
    {
623
    {
674
        i_ret = -1;
624
        i_ret = -1;
675
    }
625
    }
676
626
677
    *pi_agid = p_buffer[ 7 ] >> 6;
627
    *pi_agid = p_buffer[ 7 ] >> 6;
678
628
    
679
#elif defined( DARWIN_DVD_IOCTL )
629
#elif defined( SYS_DARWIN )
680
    INIT_DVDIOCTL( dk_dvd_report_key_t, DVDAuthenticationGrantIDInfo,
630
    dk_dvd_report_key_t dvd;
681
                   kDVDKeyFormatAGID_CSS );
631
    DVDAuthenticationGrantIDInfo dvdagid;
632
    
633
    memset(&dvd, 0, sizeof(dvd));
634
    memset(&dvdagid, 0, sizeof(dvdagid));
682
635
636
    dvd.buffer = &dvdagid;
637
    dvd.bufferLength = sizeof(dvdagid);
638
    dvd.format = kDVDKeyFormatAGID_CSS;
683
    dvd.grantID = *pi_agid;
639
    dvd.grantID = *pi_agid;
684
    dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
640
    dvdagid.grantID = *pi_agid; /* do we need this? */
641
    dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM; /* or this - this is memset 0x00 anyways */
642
643
    /* dvdagid.dataLength[0] = 0x00; */ /* dataLength[0] is already memset to 0 */
644
    /* dvdagid.dataLength[1] = 0x06; */
685
645
686
    i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
646
    i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
687
647
688
    *pi_agid = dvdbs.grantID;
648
    *pi_agid = dvdagid.grantID;
689
649
690
#elif defined( WIN32 )
650
#elif defined( WIN32 )
691
    if( WIN2K ) /* NT/2k/XP */
651
    if( WIN2K ) /* NT/Win2000/Whistler */
692
    {
652
    {
693
        ULONG id;
653
        ULONG id;
694
        DWORD tmp;
654
        DWORD tmp;
695
655
696
        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_START_SESSION,
656
        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_START_SESSION, 
697
                        &tmp, 4, &id, sizeof( id ), &tmp, NULL ) ? 0 : -1;
657
                        &tmp, 4, &id, sizeof( id ), &tmp, NULL ) ? 0 : -1;
698
658
699
        *pi_agid = id;
659
        *pi_agid = id;
700
    }
660
    }
701
    else
661
    else
...
...
707
        i_ret = WinSendSSC( i_fd, &ssc );
667
        i_ret = WinSendSSC( i_fd, &ssc );
708
668
709
        *pi_agid = p_buffer[ 7 ] >> 6;
669
        *pi_agid = p_buffer[ 7 ] >> 6;
710
    }
670
    }
711
671
712
#elif defined( __QNXNTO__ )
713
714
    INIT_CPT( GPCMD_REPORT_KEY, 8 );
715
716
    p_cpt->cam_cdb[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
717
718
    i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
719
720
    *pi_agid = p_buffer[ 7 ] >> 6;
721
722
#elif defined( SYS_OS2 )
723
    INIT_SSC( GPCMD_REPORT_KEY, 8 );
724
725
    sdc.command[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
726
727
    i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
728
                        &sdc, sizeof(sdc), &ulParamLen,
729
                        p_buffer, sizeof(p_buffer), &ulDataLen);
730
731
    *pi_agid = p_buffer[ 7 ] >> 6;
732
733
#else
672
#else
734
#   error "DVD ioctls are unavailable on this system"
673
    /* DVD ioctls unavailable - do as if the ioctl failed */
674
    i_ret = -1;
735
675
736
#endif
676
#endif
737
    return i_ret;
677
    return i_ret;
738
}
678
}
739
679
740
/*****************************************************************************
680
/*****************************************************************************
741
 * ioctl_ReportChallenge: get challenge from the drive
681
 * ioctl_ReportChallenge: get challenge from the drive
742
 *****************************************************************************/
682
 *****************************************************************************/
743
int ioctl_ReportChallenge( int i_fd, int *pi_agid, uint8_t *p_challenge )
683
int ioctl_ReportChallenge( int i_fd, int *pi_agid, u8 *p_challenge )
744
{
684
{
745
    int i_ret;
685
    int i_ret;
746
686
747
#if defined( HAVE_LINUX_DVD_STRUCT )
687
#if defined( HAVE_LINUX_DVD_STRUCT )
748
    dvd_authinfo auth_info;
688
    dvd_authinfo auth_info;
...
...
784
724
785
    memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
725
    memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
786
726
787
#elif defined( SOLARIS_USCSI )
727
#elif defined( SOLARIS_USCSI )
788
    INIT_USCSI( GPCMD_REPORT_KEY, 16 );
728
    INIT_USCSI( GPCMD_REPORT_KEY, 16 );
789
729
    
790
    rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
730
    rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
791
731
    
792
    i_ret = SolarisSendUSCSI( i_fd, &sc );
732
    i_ret = ioctl( i_fd, USCSICMD, &sc );
793
733
    
794
    if( i_ret < 0 || sc.uscsi_status )
734
    if( i_ret < 0 || sc.uscsi_status )
795
    {
735
    {
796
        i_ret = -1;
736
        i_ret = -1;
797
    }
737
    }
798
738
799
    memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
739
    memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
800
740
    
801
#elif defined( DARWIN_DVD_IOCTL )
741
#elif defined( SYS_DARWIN )
802
    INIT_DVDIOCTL( dk_dvd_report_key_t, DVDChallengeKeyInfo,
742
    dk_dvd_report_key_t dvd;
803
                   kDVDKeyFormatChallengeKey );
743
    DVDChallengeKeyInfo dvdcki;
744
    
745
    memset(&dvd, 0, sizeof(dvd));
746
    memset(&dvdcki, 0, sizeof(dvdcki));
804
747
748
    dvd.buffer = &dvdcki;
749
    dvd.bufferLength = sizeof(dvdcki);
750
    dvd.format = kDVDKeyFormatChallengeKey;
805
    dvd.grantID = *pi_agid;
751
    dvd.grantID = *pi_agid;
806
752
753
    /* dvdcki.dataLength[0] = 0x00; */ /* dataLength[0] is already memset to 0 */
754
    dvdcki.dataLength[ 1 ] = 0x0e;
755
807
    i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
756
    i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
808
757
809
    memcpy( p_challenge, dvdbs.challengeKeyValue, DVD_CHALLENGE_SIZE );
758
    memcpy( p_challenge, dvdcki.challengeKeyValue, DVD_CHALLENGE_SIZE );
810
759
811
#elif defined( WIN32 )
760
#elif defined( WIN32 )
812
    if( WIN2K ) /* NT/2k/XP */
761
    if( WIN2K ) /* NT/Win2000/Whistler */
813
    {
762
    {
814
        DWORD tmp;
763
        DWORD tmp;
815
        uint8_t buffer[DVD_CHALLENGE_KEY_LENGTH];
764
        u8 buffer[DVD_CHALLENGE_KEY_LENGTH];
816
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
765
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
817
766
818
        memset( &buffer, 0, sizeof( buffer ) );
767
        memset( &buffer, 0, sizeof( buffer ) );
819
768
820
        key->KeyLength  = DVD_CHALLENGE_KEY_LENGTH;
769
        key->KeyLength  = DVD_CHALLENGE_KEY_LENGTH;
821
        key->SessionId  = *pi_agid;
770
        key->SessionId  = *pi_agid;
822
        key->KeyType    = DvdChallengeKey;
771
        key->KeyType    = DvdChallengeKey;
823
        key->KeyFlags   = 0;
772
        key->KeyFlags   = 0;
824
773
825
        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
774
        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key, 
826
                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
775
                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
827
776
828
        if( i_ret < 0 )
777
        if( i_ret < 0 )
829
        {
778
        {
830
            return i_ret;
779
            return i_ret;
...
...
841
        i_ret = WinSendSSC( i_fd, &ssc );
790
        i_ret = WinSendSSC( i_fd, &ssc );
842
791
843
        memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
792
        memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
844
    }
793
    }
845
794
846
#elif defined( __QNXNTO__ )
847
848
    INIT_CPT( GPCMD_REPORT_KEY, 16 );
849
850
    p_cpt->cam_cdb[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
851
852
    i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
853
854
    memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
855
856
#elif defined( SYS_OS2 )
857
    INIT_SSC( GPCMD_REPORT_KEY, 16 );
858
859
    sdc.command[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
860
861
    i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
862
                        &sdc, sizeof(sdc), &ulParamLen,
863
                        p_buffer, sizeof(p_buffer), &ulDataLen);
864
865
    memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
866
867
#else
795
#else
868
#   error "DVD ioctls are unavailable on this system"
796
    /* DVD ioctls unavailable - do as if the ioctl failed */
797
    i_ret = -1;
869
798
870
#endif
799
#endif
871
    return i_ret;
800
    return i_ret;
872
}
801
}
873
802
...
...
918
847
919
    *pi_asf = p_buffer[ 7 ] & 1;
848
    *pi_asf = p_buffer[ 7 ] & 1;
920
849
921
#elif defined( SOLARIS_USCSI )
850
#elif defined( SOLARIS_USCSI )
922
    INIT_USCSI( GPCMD_REPORT_KEY, 8 );
851
    INIT_USCSI( GPCMD_REPORT_KEY, 8 );
923
852
    
924
    rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_ASF;
853
    rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_ASF;
925
854
    
926
    i_ret = SolarisSendUSCSI( i_fd, &sc );
855
    i_ret = ioctl( i_fd, USCSICMD, &sc );
927
856
    
928
    if( i_ret < 0 || sc.uscsi_status )
857
    if( i_ret < 0 || sc.uscsi_status )
929
    {
858
    {
930
        i_ret = -1;
859
        i_ret = -1;
931
    }
860
    }
932
861
933
    *pi_asf = p_buffer[ 7 ] & 1;
862
    *pi_asf = p_buffer[ 7 ] & 1;
934
863
    
935
#elif defined( DARWIN_DVD_IOCTL )
864
#elif defined( SYS_DARWIN )
936
    INIT_DVDIOCTL( dk_dvd_report_key_t, DVDAuthenticationSuccessFlagInfo,
865
    dk_dvd_report_key_t dvd;
937
                   kDVDKeyFormatASF );
866
    DVDAuthenticationSuccessFlagInfo dvdasfi;
867
    
868
    memset(&dvd, 0, sizeof(dvd));
869
    memset(&dvdasfi, 0, sizeof(dvdasfi));
938
870
871
    dvd.buffer = &dvdasfi;
872
    dvd.bufferLength = sizeof(dvdasfi);
873
    dvd.format = kDVDKeyFormatASF;
874
    dvdasfi.successFlag = *pi_asf;
875
876
    /* dvdasfi.dataLength[0] = 0x00; */ /* dataLength[0] is already memset to 0 */
877
    dvdasfi.dataLength[ 1 ] = 0x06;
878
    
939
    i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
879
    i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
940
880
941
    *pi_asf = dvdbs.successFlag;
881
    *pi_asf = dvdasfi.successFlag;
942
882
943
#elif defined( WIN32 )
883
#elif defined( WIN32 )
944
    if( WIN2K ) /* NT/2k/XP */
884
    if( WIN2K ) /* NT/Win2000/Whistler */
945
    {
885
    {
946
        DWORD tmp;
886
        DWORD tmp;
947
        uint8_t buffer[DVD_ASF_LENGTH];
887
        u8 buffer[DVD_ASF_LENGTH];
948
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
888
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
949
889
950
        memset( &buffer, 0, sizeof( buffer ) );
890
        memset( &buffer, 0, sizeof( buffer ) );
951
891
952
        key->KeyLength  = DVD_ASF_LENGTH;
892
        key->KeyLength  = DVD_ASF_LENGTH;
953
        key->KeyType    = DvdAsf;
893
        key->KeyType    = DvdAsf;
954
        key->KeyFlags   = 0;
894
        key->KeyFlags   = 0;
955
895
956
        ((PDVD_ASF)key->KeyData)->SuccessFlag = *pi_asf;
896
        ((PDVD_ASF)key->KeyData)->SuccessFlag = *pi_asf;
957
897
958
        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
898
        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key, 
959
                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
899
                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
960
900
961
        if( i_ret < 0 )
901
        if( i_ret < 0 )
962
        {
902
        {
963
            return i_ret;
903
            return i_ret;
...
...
974
        i_ret = WinSendSSC( i_fd, &ssc );
914
        i_ret = WinSendSSC( i_fd, &ssc );
975
915
976
        *pi_asf = p_buffer[ 7 ] & 1;
916
        *pi_asf = p_buffer[ 7 ] & 1;
977
    }
917
    }
978
918
979
#elif defined( __QNXNTO__ )
980
981
    INIT_CPT( GPCMD_REPORT_KEY, 8 );
982
983
    p_cpt->cam_cdb[ 10 ] = DVD_REPORT_ASF;
984
985
    i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
986
987
    *pi_asf = p_buffer[ 7 ] & 1;
988
989
#elif defined( SYS_OS2 )
990
    INIT_SSC( GPCMD_REPORT_KEY, 8 );
991
992
    sdc.command[ 10 ] = DVD_REPORT_ASF;
993
994
    i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
995
                        &sdc, sizeof(sdc), &ulParamLen,
996
                        p_buffer, sizeof(p_buffer), &ulDataLen);
997
998
    *pi_asf = p_buffer[ 7 ] & 1;
999
1000
#else
919
#else
1001
#   error "DVD ioctls are unavailable on this system"
920
    /* DVD ioctls unavailable - do as if the ioctl failed */
921
    i_ret = -1;
1002
922
1003
#endif
923
#endif
1004
    return i_ret;
924
    return i_ret;
1005
}
925
}
1006
926
1007
/*****************************************************************************
927
/*****************************************************************************
1008
 * ioctl_ReportKey1: get the first key from the drive
928
 * ioctl_ReportKey1: get the first key from the drive
1009
 *****************************************************************************/
929
 *****************************************************************************/
1010
int ioctl_ReportKey1( int i_fd, int *pi_agid, uint8_t *p_key )
930
int ioctl_ReportKey1( int i_fd, int *pi_agid, u8 *p_key )
1011
{
931
{
1012
    int i_ret;
932
    int i_ret;
1013
933
1014
#if defined( HAVE_LINUX_DVD_STRUCT )
934
#if defined( HAVE_LINUX_DVD_STRUCT )
1015
    dvd_authinfo auth_info;
935
    dvd_authinfo auth_info;
...
...
1051
971
1052
    memcpy( p_key, p_buffer + 4, DVD_KEY_SIZE );
972
    memcpy( p_key, p_buffer + 4, DVD_KEY_SIZE );
1053
973
1054
#elif defined( SOLARIS_USCSI )
974
#elif defined( SOLARIS_USCSI )
1055
    INIT_USCSI( GPCMD_REPORT_KEY, 12 );
975
    INIT_USCSI( GPCMD_REPORT_KEY, 12 );
1056
976
    
1057
    rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6);
977
    rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6);
1058
978
    
1059
    i_ret = SolarisSendUSCSI( i_fd, &sc );
979
    i_ret = ioctl( i_fd, USCSICMD, &sc );
1060
980
    
1061
    if( i_ret < 0 || sc.uscsi_status )
981
    if( i_ret < 0 || sc.uscsi_status )
1062
    {
982
    {
1063
        i_ret = -1;
983
        i_ret = -1;
1064
    }
984
    }
1065
985
1066
    memcpy( p_key, p_buffer + 4, DVD_KEY_SIZE );
986
    memcpy( p_key, p_buffer + 4, DVD_KEY_SIZE );
1067
987
    
1068
#elif defined( DARWIN_DVD_IOCTL )
988
#elif defined( SYS_DARWIN )
1069
    INIT_DVDIOCTL( dk_dvd_report_key_t, DVDKey1Info,
989
    dk_dvd_report_key_t dvd;
1070
                   kDVDKeyFormatKey1 );
990
    DVDKey1Info dvdk1i;
991
    
992
    memset(&dvd, 0, sizeof(dvd));
993
    memset(&dvdk1i, 0, sizeof(dvdk1i));
1071
994
995
    dvd.buffer = &dvdk1i;
996
    dvd.bufferLength = sizeof(dvdk1i);
997
    dvd.format = kDVDKeyFormatKey1;
1072
    dvd.grantID = *pi_agid;
998
    dvd.grantID = *pi_agid;
999
    
1000
    /* dvdk1i.dataLength[0] = 0x00; */ /* dataLength[0] is already memset to 0 */
1001
    dvdk1i.dataLength[ 1 ] = 0x0a;
1073
1002
1074
    i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
1003
    i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
1075
1004
1076
    memcpy( p_key, dvdbs.key1Value, DVD_KEY_SIZE );
1005
    memcpy( p_key, dvdk1i.key1Value, DVD_KEY_SIZE );
1077
1006
1078
#elif defined( WIN32 )
1007
#elif defined( WIN32 )
1079
    if( WIN2K ) /* NT/2k/XP */
1008
    if( WIN2K ) /* NT/Win2000/Whistler */
1080
    {
1009
    {
1081
        DWORD tmp;
1010
        DWORD tmp;
1082
        uint8_t buffer[DVD_BUS_KEY_LENGTH];
1011
        u8 buffer[DVD_BUS_KEY_LENGTH];
1083
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
1012
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
1084
1013
1085
        memset( &buffer, 0, sizeof( buffer ) );
1014
        memset( &buffer, 0, sizeof( buffer ) );
1086
1015
1087
        key->KeyLength  = DVD_BUS_KEY_LENGTH;
1016
        key->KeyLength  = DVD_BUS_KEY_LENGTH;
1088
        key->SessionId  = *pi_agid;
1017
        key->SessionId  = *pi_agid;
1089
        key->KeyType    = DvdBusKey1;
1018
        key->KeyType    = DvdBusKey1;
1090
        key->KeyFlags   = 0;
1019
        key->KeyFlags   = 0;
1091
1020
1092
        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
1021
        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key, 
1093
                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
1022
                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
1094
1023
1095
        memcpy( p_key, key->KeyData, DVD_KEY_SIZE );
1024
        memcpy( p_key, key->KeyData, DVD_KEY_SIZE );
1096
    }
1025
    }
1097
    else
1026
    else
...
...
1103
        i_ret = WinSendSSC( i_fd, &ssc );
1032
        i_ret = WinSendSSC( i_fd, &ssc );
1104
1033
1105
        memcpy( p_key, p_buffer + 4, DVD_KEY_SIZE );
1034
        memcpy( p_key, p_buffer + 4, DVD_KEY_SIZE );
1106
    }
1035
    }
1107
1036
1108
#elif defined( __QNXNTO__ )
1109
1110
    INIT_CPT( GPCMD_REPORT_KEY, 12 );
1111
1112
    p_cpt->cam_cdb[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6);
1113
1114
    i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
1115
1116
    memcpy( p_key, p_buffer + 4, DVD_KEY_SIZE );
1117
1118
#elif defined( SYS_OS2 )
1119
    INIT_SSC( GPCMD_REPORT_KEY, 12 );
1120
1121
    sdc.command[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6);
1122
1123
    i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
1124
                        &sdc, sizeof(sdc), &ulParamLen,
1125
                        p_buffer, sizeof(p_buffer), &ulDataLen);
1126
1127
    memcpy( p_key, p_buffer + 4, DVD_KEY_SIZE );
1128
1129
#else
1037
#else
1130
#   error "DVD ioctls are unavailable on this system"
1038
    /* DVD ioctls unavailable - do as if the ioctl failed */
1039
    i_ret = -1;
1131
1040
1132
#endif
1041
#endif
1133
    return i_ret;
1042
    return i_ret;
1134
}
1043
}
1135
1044
...
...
1172
1081
1173
    i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
1082
    i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
1174
1083
1175
#elif defined( SOLARIS_USCSI )
1084
#elif defined( SOLARIS_USCSI )
1176
    INIT_USCSI( GPCMD_REPORT_KEY, 0 );
1085
    INIT_USCSI( GPCMD_REPORT_KEY, 0 );
1177
1086
    
1178
    rs_cdb.cdb_opaque[ 10 ] = DVD_INVALIDATE_AGID | (*pi_agid << 6);
1087
    rs_cdb.cdb_opaque[ 10 ] = DVD_INVALIDATE_AGID | (*pi_agid << 6);
1179
1088
    
1180
    i_ret = SolarisSendUSCSI( i_fd, &sc );
1089
    i_ret = ioctl( i_fd, USCSICMD, &sc );
1181
1090
    
1182
    if( i_ret < 0 || sc.uscsi_status )
1091
    if( i_ret < 0 || sc.uscsi_status )
1183
    {
1092
    {
1184
        i_ret = -1;
1093
        i_ret = -1;
1185
    }
1094
    }
1186
1095
1187
#elif defined( DARWIN_DVD_IOCTL )
1096
#elif defined( SYS_DARWIN )
1188
    INIT_DVDIOCTL( dk_dvd_send_key_t, DVDAuthenticationGrantIDInfo,
1097
    dk_dvd_send_key_t dvd;
1189
                   kDVDKeyFormatAGID_Invalidate );
1098
    DVDAuthenticationGrantIDInfo dvdagid;
1099
    
1100
    memset(&dvd, 0, sizeof(dvd));
1101
    memset(&dvdagid, 0, sizeof(dvdagid));
1190
1102
1103
    dvd.buffer = &dvdagid;
1104
    dvd.bufferLength = sizeof(dvdagid);
1105
    dvd.format = kDVDKeyFormatAGID_Invalidate;
1191
    dvd.grantID = *pi_agid;
1106
    dvd.grantID = *pi_agid;
1107
    dvdagid.grantID = *pi_agid; /* we need this? */
1108
    
1109
    /* dvdagid.dataLength[0] = 0x00; */ /* dataLength[0] is already memset to 0 */
1110
    /* dvdagid.dataLength[1] = 0x06; */
1192
1111
1193
    i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
1112
    i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
1194
1113
1195
#elif defined( WIN32 )
1114
#elif defined( WIN32 )
1196
    if( WIN2K ) /* NT/2k/XP */
1115
    if( WIN2K ) /* NT/Win2000/Whistler */
1197
    {
1116
    {
1198
        DWORD tmp;
1117
        DWORD tmp;
1199
1118
1200
        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_END_SESSION,
1119
        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_END_SESSION, 
1201
                    pi_agid, sizeof( *pi_agid ), NULL, 0, &tmp, NULL ) ? 0 : -1;
1120
                    pi_agid, sizeof( *pi_agid ), NULL, 0, &tmp, NULL ) ? 0 : -1;
1202
    }
1121
    }
1203
    else
1122
    else
1204
    {
1123
    {
1205
#if defined( __MINGW32__ )
1124
#if defined( __MINGW32__ )
...
...
1215
        ssc.CDBByte[ 10 ] = DVD_INVALIDATE_AGID | (*pi_agid << 6);
1134
        ssc.CDBByte[ 10 ] = DVD_INVALIDATE_AGID | (*pi_agid << 6);
1216
1135
1217
        i_ret = WinSendSSC( i_fd, &ssc );
1136
        i_ret = WinSendSSC( i_fd, &ssc );
1218
    }
1137
    }
1219
1138
1220
#elif defined( __QNXNTO__ )
1221
1222
    INIT_CPT( GPCMD_REPORT_KEY, 0 );
1223
1224
    p_cpt->cam_cdb[ 10 ] = DVD_INVALIDATE_AGID | (*pi_agid << 6);
1225
1226
    i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
1227
1228
#elif defined( SYS_OS2 )
1229
    INIT_SSC( GPCMD_REPORT_KEY, 1 );
1230
1231
    sdc.data_length = 0;
1232
    sdc.command[ 8 ] = 0;
1233
    sdc.command[ 9 ] = 0;
1234
1235
    sdc.command[ 10 ] = DVD_INVALIDATE_AGID | (*pi_agid << 6);
1236
1237
    i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
1238
                        &sdc, sizeof(sdc), &ulParamLen,
1239
                        NULL, 0, &ulDataLen);
1240
#else
1139
#else
1241
#   error "DVD ioctls are unavailable on this system"
1140
    /* DVD ioctls unavailable - do as if the ioctl failed */
1141
    i_ret = -1;
1242
1142
1243
#endif
1143
#endif
1244
    return i_ret;
1144
    return i_ret;
1245
}
1145
}
1246
1146
1247
/*****************************************************************************
1147
/*****************************************************************************
1248
 * ioctl_SendChallenge: send challenge to the drive
1148
 * ioctl_SendChallenge: send challenge to the drive
1249
 *****************************************************************************/
1149
 *****************************************************************************/
1250
int ioctl_SendChallenge( int i_fd, int *pi_agid, uint8_t *p_challenge )
1150
int ioctl_SendChallenge( int i_fd, int *pi_agid, u8 *p_challenge )
1251
{
1151
{
1252
    int i_ret;
1152
    int i_ret;
1253
1153
1254
#if defined( HAVE_LINUX_DVD_STRUCT )
1154
#if defined( HAVE_LINUX_DVD_STRUCT )
1255
    dvd_authinfo auth_info;
1155
    dvd_authinfo auth_info;
...
...
1258
    auth_info.type = DVD_HOST_SEND_CHALLENGE;
1158
    auth_info.type = DVD_HOST_SEND_CHALLENGE;
1259
    auth_info.hsc.agid = *pi_agid;
1159
    auth_info.hsc.agid = *pi_agid;
1260
1160
1261
    memcpy( auth_info.hsc.chal, p_challenge, DVD_CHALLENGE_SIZE );
1161
    memcpy( auth_info.hsc.chal, p_challenge, DVD_CHALLENGE_SIZE );
1262
1162
1263
    i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
1163
    return ioctl( i_fd, DVD_AUTH, &auth_info );
1264
1164
1265
#elif defined( HAVE_BSD_DVD_STRUCT )
1165
#elif defined( HAVE_BSD_DVD_STRUCT )
1266
    struct dvd_authinfo auth_info;
1166
    struct dvd_authinfo auth_info;
1267
1167
1268
    memset( &auth_info, 0, sizeof( auth_info ) );
1168
    memset( &auth_info, 0, sizeof( auth_info ) );
1269
    auth_info.format = DVD_SEND_CHALLENGE;
1169
    auth_info.format = DVD_SEND_CHALLENGE;
1270
    auth_info.agid = *pi_agid;
1170
    auth_info.agid = *pi_agid;
1271
1171
1272
    memcpy( auth_info.keychal, p_challenge, DVD_CHALLENGE_SIZE );
1172
    memcpy( auth_info.keychal, p_challenge, DVD_CHALLENGE_SIZE );
1273
1173
1274
    i_ret = ioctl( i_fd, DVDIOCSENDKEY, &auth_info );
1174
    return ioctl( i_fd, DVDIOCSENDKEY, &auth_info );
1275
1175
1276
#elif defined( SYS_BEOS )
1176
#elif defined( SYS_BEOS )
1277
    INIT_RDC( GPCMD_SEND_KEY, 16 );
1177
    INIT_RDC( GPCMD_SEND_KEY, 16 );
1278
1178
1279
    rdc.command[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
1179
    rdc.command[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
1280
1180
1281
    p_buffer[ 1 ] = 0xe;
1181
    p_buffer[ 1 ] = 0xe;
1282
    memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
1182
    memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
1283
1183
1284
    i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
1184
    return ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
1285
1185
1286
#elif defined( HPUX_SCTL_IO )
1186
#elif defined( HPUX_SCTL_IO )
1287
    INIT_SCTL_IO( GPCMD_SEND_KEY, 16 );
1187
    INIT_SCTL_IO( GPCMD_SEND_KEY, 16 );
1288
1188
1289
    sctl_io.cdb[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
1189
    sctl_io.cdb[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
1290
1190
1291
    p_buffer[ 1 ] = 0xe;
1191
    p_buffer[ 1 ] = 0xe;
1292
    memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
1192
    memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
1293
1193
1294
    i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
1194
    return ioctl( i_fd, SIOC_IO, &sctl_io );
1295
1195
1296
#elif defined( SOLARIS_USCSI )
1196
#elif defined( SOLARIS_USCSI )
1297
    INIT_USCSI( GPCMD_SEND_KEY, 16 );
1197
    INIT_USCSI( GPCMD_SEND_KEY, 16 );
1298
1198
    
1299
    rs_cdb.cdb_opaque[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
1199
    rs_cdb.cdb_opaque[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
1300
1200
    
1301
    p_buffer[ 1 ] = 0xe;
1201
    p_buffer[ 1 ] = 0xe;
1302
    memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
1202
    memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
1303
1203
    
1304
    if( SolarisSendUSCSI( i_fd, &sc ) < 0 || sc.uscsi_status )
1204
    if( ioctl( i_fd, USCSICMD, &sc ) < 0 || sc.uscsi_status )
1305
    {
1205
    {
1306
        return -1;
1206
        return -1;
1307
    }
1207
    }
1308
1208
1309
    i_ret = 0;
1209
    return 0;
1310
1210
    
1311
#elif defined( DARWIN_DVD_IOCTL )
1211
#elif defined( SYS_DARWIN )
1312
    INIT_DVDIOCTL( dk_dvd_send_key_t, DVDChallengeKeyInfo,
1212
    dk_dvd_send_key_t dvd;
1313
                   kDVDKeyFormatChallengeKey );
1213
    DVDChallengeKeyInfo dvdcki;
1214
    
1215
    memset(&dvd, 0, sizeof(dvd));
1216
    memset(&dvdcki, 0, sizeof(dvdcki));
1314
1217
1218
    dvd.buffer = &dvdcki;
1219
    dvd.bufferLength = sizeof(dvdcki);
1220
    dvd.format = kDVDKeyFormatChallengeKey;
1315
    dvd.grantID = *pi_agid;
1221
    dvd.grantID = *pi_agid;
1316
    dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
1317
1222
1223
    /* dvdcki.dataLength[0] = 0x00; */ /* dataLength[0] is already memset to 0 */
1318
    dvdbs.dataLength[ 1 ] = 0xe;
1224
    dvdcki.dataLength[ 1 ] = 0x0e;
1225
1319
    memcpy( dvdbs.challengeKeyValue, p_challenge, DVD_CHALLENGE_SIZE );
1226
    memcpy( dvdcki.challengeKeyValue, p_challenge, DVD_CHALLENGE_SIZE );
1320
1227
1321
    i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
1228
    i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
1322
1229
1323
#elif defined( WIN32 )
1230
#elif defined( WIN32 )
1324
    if( WIN2K ) /* NT/2k/XP */
1231
    if( WIN2K ) /* NT/Win2000/Whistler */
1325
    {
1232
    {
1326
        DWORD tmp;
1233
        DWORD tmp;
1327
        uint8_t buffer[DVD_CHALLENGE_KEY_LENGTH];
1234
        u8 buffer[DVD_CHALLENGE_KEY_LENGTH];
1328
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
1235
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
1329
1236
1330
        memset( &buffer, 0, sizeof( buffer ) );
1237
        memset( &buffer, 0, sizeof( buffer ) );
1331
1238
1332
        key->KeyLength  = DVD_CHALLENGE_KEY_LENGTH;
1239
        key->KeyLength  = DVD_CHALLENGE_KEY_LENGTH;
...
...
1334
        key->KeyType    = DvdChallengeKey;
1241
        key->KeyType    = DvdChallengeKey;
1335
        key->KeyFlags   = 0;
1242
        key->KeyFlags   = 0;
1336
1243
1337
        memcpy( key->KeyData, p_challenge, DVD_CHALLENGE_SIZE );
1244
        memcpy( key->KeyData, p_challenge, DVD_CHALLENGE_SIZE );
1338
1245
1339
        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_SEND_KEY, key,
1246
        return DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_SEND_KEY, key, 
1340
                 key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
1247
                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
1341
    }
1248
    }
1342
    else
1249
    else
1343
    {
1250
    {
1344
        INIT_SSC( GPCMD_SEND_KEY, 16 );
1251
        INIT_SSC( GPCMD_SEND_KEY, 16 );
1345
1252
1346
        ssc.CDBByte[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
1253
        ssc.CDBByte[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
1347
1254
1348
        p_buffer[ 1 ] = 0xe;
1255
        p_buffer[ 1 ] = 0xe;
1349
        memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
1256
        memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
1350
1257
1351
        i_ret = WinSendSSC( i_fd, &ssc );
1258
        return WinSendSSC( i_fd, &ssc );
1352
    }
1259
    }
1353
1354
#elif defined( __QNXNTO__ )
1355
1356
    INIT_CPT( GPCMD_SEND_KEY, 16 );
1357
1358
    p_cpt->cam_cdb[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
1359
1360
    p_buffer[ 1 ] = 0xe;
1361
    memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
1362
1363
    i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
1364
1365
#elif defined( SYS_OS2 )
1366
    INIT_SSC( GPCMD_SEND_KEY, 16 );
1367
1368
    sdc.command[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
1369
1370
    p_buffer[ 1 ] = 0xe;
1371
    memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
1372
1373
    i_ret = DosDevIOCtl( i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
1374
                         &sdc, sizeof(sdc), &ulParamLen,
1375
                         p_buffer, sizeof(p_buffer), &ulDataLen );
1376
1260
1377
#else
1261
#else
1378
#   error "DVD ioctls are unavailable on this system"
1262
    /* DVD ioctls unavailable - do as if the ioctl failed */
1263
    return -1;
1379
1264
1380
#endif
1265
#endif
1381
    return i_ret;
1266
    return i_ret;
1382
}
1267
}
1383
1268
1384
/*****************************************************************************
1269
/*****************************************************************************
1385
 * ioctl_SendKey2: send the second key to the drive
1270
 * ioctl_SendKey2: send the second key to the drive
1386
 *****************************************************************************/
1271
 *****************************************************************************/
1387
int ioctl_SendKey2( int i_fd, int *pi_agid, uint8_t *p_key )
1272
int ioctl_SendKey2( int i_fd, int *pi_agid, u8 *p_key )
1388
{
1273
{
1389
    int i_ret;
1274
    int i_ret;
1390
1275
1391
#if defined( HAVE_LINUX_DVD_STRUCT )
1276
#if defined( HAVE_LINUX_DVD_STRUCT )
1392
    dvd_authinfo auth_info;
1277
    dvd_authinfo auth_info;
...
...
1395
    auth_info.type = DVD_HOST_SEND_KEY2;
1280
    auth_info.type = DVD_HOST_SEND_KEY2;
1396
    auth_info.hsk.agid = *pi_agid;
1281
    auth_info.hsk.agid = *pi_agid;
1397
1282
1398
    memcpy( auth_info.hsk.key, p_key, DVD_KEY_SIZE );
1283
    memcpy( auth_info.hsk.key, p_key, DVD_KEY_SIZE );
1399
1284
1400
    i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
1285
    return ioctl( i_fd, DVD_AUTH, &auth_info );
1401
1286
1402
#elif defined( HAVE_BSD_DVD_STRUCT )
1287
#elif defined( HAVE_BSD_DVD_STRUCT )
1403
    struct dvd_authinfo auth_info;
1288
    struct dvd_authinfo auth_info;
1404
1289
1405
    memset( &auth_info, 0, sizeof( auth_info ) );
1290
    memset( &auth_info, 0, sizeof( auth_info ) );
1406
    auth_info.format = DVD_SEND_KEY2;
1291
    auth_info.format = DVD_SEND_KEY2;
1407
    auth_info.agid = *pi_agid;
1292
    auth_info.agid = *pi_agid;
1408
1293
1409
    memcpy( auth_info.keychal, p_key, DVD_KEY_SIZE );
1294
    memcpy( auth_info.keychal, p_key, DVD_KEY_SIZE );
1410
1295
1411
    i_ret = ioctl( i_fd, DVDIOCSENDKEY, &auth_info );
1296
    return ioctl( i_fd, DVDIOCSENDKEY, &auth_info );
1412
1297
1413
#elif defined( SYS_BEOS )
1298
#elif defined( SYS_BEOS )
1414
    INIT_RDC( GPCMD_SEND_KEY, 12 );
1299
    INIT_RDC( GPCMD_SEND_KEY, 12 );
1415
1300
1416
    rdc.command[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
1301
    rdc.command[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
1417
1302
1418
    p_buffer[ 1 ] = 0xa;
1303
    p_buffer[ 1 ] = 0xa;
1419
    memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
1304
    memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
1420
1305
1421
    i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
1306
    return ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
1422
1307
1423
#elif defined( HPUX_SCTL_IO )
1308
#elif defined( HPUX_SCTL_IO )
1424
    INIT_SCTL_IO( GPCMD_SEND_KEY, 12 );
1309
    INIT_SCTL_IO( GPCMD_SEND_KEY, 12 );
1425
1310
1426
    sctl_io.cdb[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
1311
    sctl_io.cdb[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
1427
1312
1428
    p_buffer[ 1 ] = 0xa;
1313
    p_buffer[ 1 ] = 0xa;
1429
    memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
1314
    memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
1430
1315
1431
    i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
1316
    return ioctl( i_fd, SIOC_IO, &sctl_io );
1432
1317
1433
#elif defined( SOLARIS_USCSI )
1318
#elif defined( SOLARIS_USCSI )
1434
    INIT_USCSI( GPCMD_SEND_KEY, 12 );
1319
    INIT_USCSI( GPCMD_SEND_KEY, 12 );
1435
1320
    
1436
    rs_cdb.cdb_opaque[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
1321
    rs_cdb.cdb_opaque[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
1437
1322
    
1438
    p_buffer[ 1 ] = 0xa;
1323
    p_buffer[ 1 ] = 0xa;
1439
    memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
1324
    memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
1440
1325
    
1441
    if( SolarisSendUSCSI( i_fd, &sc ) < 0 || sc.uscsi_status )
1326
    if( ioctl( i_fd, USCSICMD, &sc ) < 0 || sc.uscsi_status )
1442
    {
1327
    {
1443
        return -1;
1328
        return -1;
1444
    }
1329
    }
1445
1330
1446
    i_ret = 0;
1331
    return 0;
1447
1332
    
1448
#elif defined( DARWIN_DVD_IOCTL )
1333
#elif defined( SYS_DARWIN )
1449
    INIT_DVDIOCTL( dk_dvd_send_key_t, DVDKey2Info,
1334
    dk_dvd_send_key_t dvd;
1450
                   kDVDKeyFormatKey2 );
1335
    DVDKey2Info dvdk2i;
1336
    
1337
    memset(&dvd, 0, sizeof(dvd));
1338
    memset(&dvdk2i, 0, sizeof(dvdk2i));
1451
1339
1340
    dvd.buffer = &dvdk2i;
1341
    dvd.bufferLength = sizeof(dvdk2i);
1342
    dvd.format = kDVDKeyFormatKey2;
1452
    dvd.grantID = *pi_agid;
1343
    dvd.grantID = *pi_agid;
1453
    dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
1454
1344
1345
    /* dvdk2i.dataLength[0] = 0x00; */ /*dataLength[0] is already memset to 0 */
1455
    dvdbs.dataLength[ 1 ] = 0xa;
1346
    dvdk2i.dataLength[ 1 ] = 0x0a;
1347
    
1456
    memcpy( dvdbs.key2Value, p_key, DVD_KEY_SIZE );
1348
    memcpy( dvdk2i.key2Value, p_key, DVD_KEY_SIZE );
1457
1349
1458
    i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
1350
    i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
1459
1351
1460
#elif defined( WIN32 )
1352
#elif defined( WIN32 )
1461
    if( WIN2K ) /* NT/2k/XP */
1353
    if( WIN2K ) /* NT/Win2000/Whistler */
1462
    {
1354
    {
1463
        DWORD tmp;
1355
        DWORD tmp;
1464
        uint8_t buffer[DVD_BUS_KEY_LENGTH];
1356
        u8 buffer[DVD_BUS_KEY_LENGTH];
1465
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
1357
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
1466
1358
1467
        memset( &buffer, 0, sizeof( buffer ) );
1359
        memset( &buffer, 0, sizeof( buffer ) );
1468
1360
1469
        key->KeyLength  = DVD_BUS_KEY_LENGTH;
1361
        key->KeyLength  = DVD_BUS_KEY_LENGTH;
...
...
1471
        key->KeyType    = DvdBusKey2;
1363
        key->KeyType    = DvdBusKey2;
1472
        key->KeyFlags   = 0;
1364
        key->KeyFlags   = 0;
1473
1365
1474
        memcpy( key->KeyData, p_key, DVD_KEY_SIZE );
1366
        memcpy( key->KeyData, p_key, DVD_KEY_SIZE );
1475
1367
1476
        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_SEND_KEY, key,
1368
        return DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_SEND_KEY, key, 
1477
                 key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
1369
                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
1478
    }
1370
    }
1479
    else
1371
    else
1480
    {
1372
    {
1481
        INIT_SSC( GPCMD_SEND_KEY, 12 );
1373
        INIT_SSC( GPCMD_SEND_KEY, 12 );
1482
1374
1483
        ssc.CDBByte[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
1375
        ssc.CDBByte[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
1484
1376
1485
        p_buffer[ 1 ] = 0xa;
1377
        p_buffer[ 1 ] = 0xa;
1486
        memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
1378
        memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
1487
1379
1488
        i_ret = WinSendSSC( i_fd, &ssc );
1380
        return WinSendSSC( i_fd, &ssc );
1489
    }
1381
    }
1490
1491
#elif defined( __QNXNTO__ )
1492
1493
    INIT_CPT( GPCMD_SEND_KEY, 12 );
1494
1495
    p_cpt->cam_cdb[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
1496
1497
    p_buffer[ 1 ] = 0xa;
1498
    memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
1499
1500
    i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
1501
1502
#elif defined( SYS_OS2 )
1503
    INIT_SSC( GPCMD_SEND_KEY, 12 );
1504
1505
    sdc.command[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
1506
1507
    p_buffer[ 1 ] = 0xa;
1508
    memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
1509
1510
    i_ret = DosDevIOCtl( i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
1511
                         &sdc, sizeof(sdc), &ulParamLen,
1512
                         p_buffer, sizeof(p_buffer), &ulDataLen );
1513
1382
1514
#else
1383
#else
1515
#   error "DVD ioctls are unavailable on this system"
1384
    /* DVD ioctls unavailable - do as if the ioctl failed */
1385
    i_ret = -1;
1516
1386
1517
#endif
1387
#endif
1518
    return i_ret;
1388
    return i_ret;
1519
}
1389
}
1520
1390
...
...
1523
 *****************************************************************************/
1393
 *****************************************************************************/
1524
int ioctl_ReportRPC( int i_fd, int *p_type, int *p_mask, int *p_scheme )
1394
int ioctl_ReportRPC( int i_fd, int *p_type, int *p_mask, int *p_scheme )
1525
{
1395
{
1526
    int i_ret;
1396
    int i_ret;
1527
1397
1528
#if defined( HAVE_LINUX_DVD_STRUCT ) && defined( DVD_LU_SEND_RPC_STATE )
1398
#if defined( HAVE_LINUX_DVD_STRUCT ) && !defined(__OpenBSD__)
1529
    dvd_authinfo auth_info;
1399
    dvd_authinfo auth_info;
1530
1400
1531
    memset( &auth_info, 0, sizeof( auth_info ) );
1401
    memset( &auth_info, 0, sizeof( auth_info ) );
1532
    auth_info.type = DVD_LU_SEND_RPC_STATE;
1402
    auth_info.type = DVD_LU_SEND_RPC_STATE;
1533
1403
...
...
1535
1405
1536
    *p_type = auth_info.lrpcs.type;
1406
    *p_type = auth_info.lrpcs.type;
1537
    *p_mask = auth_info.lrpcs.region_mask;
1407
    *p_mask = auth_info.lrpcs.region_mask;
1538
    *p_scheme = auth_info.lrpcs.rpc_scheme;
1408
    *p_scheme = auth_info.lrpcs.rpc_scheme;
1539
1409
1540
#elif defined( HAVE_LINUX_DVD_STRUCT )
1541
    /* FIXME: OpenBSD doesn't know this */
1542
    i_ret = -1;
1543
1544
#elif defined( HAVE_BSD_DVD_STRUCT )
1410
#elif defined( HAVE_BSD_DVD_STRUCT )
1545
    struct dvd_authinfo auth_info;
1411
    struct dvd_authinfo auth_info;
1546
1412
1547
    memset( &auth_info, 0, sizeof( auth_info ) );
1413
    memset( &auth_info, 0, sizeof( auth_info ) );
1548
    auth_info.format = DVD_REPORT_RPC;
1414
    auth_info.format = DVD_REPORT_RPC;
...
...
1562
1428
1563
    *p_type = p_buffer[ 4 ] >> 6;
1429
    *p_type = p_buffer[ 4 ] >> 6;
1564
    *p_mask = p_buffer[ 5 ];
1430
    *p_mask = p_buffer[ 5 ];
1565
    *p_scheme = p_buffer[ 6 ];
1431
    *p_scheme = p_buffer[ 6 ];
1566
1432
1567
#elif defined( HPUX_SCTL_IO )
1433
#elif defined( SOLARIS_USCSI )
1568
    INIT_SCTL_IO( GPCMD_REPORT_KEY, 8 );
1434
    INIT_USCSI( GPCMD_REPORT_KEY, 8 );
1569
1435
    
1570
    sctl_io.cdb[ 10 ] = DVD_REPORT_RPC;
1436
    rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_RPC;
1571
1437
    
1572
    i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
1438
    i_ret = ioctl( i_fd, USCSICMD, &sc );
1573
1439
    
1440
    if( i_ret < 0 || sc.uscsi_status )
1441
    {
1442
        i_ret = -1;
1443
    }
1444
    
1574
    *p_type = p_buffer[ 4 ] >> 6;
1445
    *p_type = p_buffer[ 4 ] >> 6;
1575
    *p_mask = p_buffer[ 5 ];
1446
    *p_mask = p_buffer[ 5 ];
1576
    *p_scheme = p_buffer[ 6 ];
1447
    *p_scheme = p_buffer[ 6 ];
1577
1578
#elif defined( SOLARIS_USCSI )
1579
    INIT_USCSI( GPCMD_REPORT_KEY, 8 );
1580
1581
    rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_RPC;
1582
1583
    i_ret = SolarisSendUSCSI( i_fd, &sc );
1584
1585
    if( i_ret < 0 || sc.uscsi_status )
1586
    {
1448
    
1449
#elif defined( SYS_DARWIN )
1450
    /* The headers for Darwin / MacOSX are unavaialbe. */
1451
    /* Someone who has them should have no problem implementing this. */
1587
        i_ret = -1;
1452
    i_ret = -1;
1588
    }
1453
    
1589
1590
    *p_type = p_buffer[ 4 ] >> 6;
1591
    *p_mask = p_buffer[ 5 ];
1592
    *p_scheme = p_buffer[ 6 ];
1593
1594
#elif defined( DARWIN_DVD_IOCTL )
1595
    INIT_DVDIOCTL( dk_dvd_report_key_t, DVDRegionPlaybackControlInfo,
1596
                   kDVDKeyFormatRegionState );
1597
1598
    dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
1599
1600
    i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
1601
1602
    *p_type = dvdbs.typeCode;
1603
    *p_mask = dvdbs.driveRegion;
1604
    *p_scheme = dvdbs.rpcScheme;
1605
1606
#elif defined( WIN32 )
1454
#elif defined( WIN32 )
1607
    if( WIN2K ) /* NT/2k/XP */
1455
    if( WIN2K ) /* NT/Win2000/Whistler */
1608
    {
1456
    {
1609
        DWORD tmp;
1457
        DWORD tmp;
1610
        uint8_t buffer[DVD_RPC_KEY_LENGTH];
1458
        u8 buffer[ DVD_ASF_LENGTH ]; /* correct this */
1611
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
1459
        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
1612
1460
1613
        memset( &buffer, 0, sizeof( buffer ) );
1461
        memset( &buffer, 0, sizeof( buffer ) );
1614
1462
1615
        key->KeyLength  = DVD_RPC_KEY_LENGTH;
1463
        key->KeyLength  = DVD_ASF_LENGTH; /* correct this */
1616
        key->KeyType    = DvdGetRpcKey;
1464
        key->KeyType    = DvdGetRpcKey;
1617
        key->KeyFlags   = 0;
1465
        key->KeyFlags   = 0;
1618
1466
1467
#warning "Fix ReportRPC for WIN32!"
1468
        /* The IOCTL_DVD_READ_KEY might be the right IOCTL */
1619
        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
1469
        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key, 
1620
                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
1470
                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
1621
1471
1622
        if( i_ret < 0 )
1472
        /* Someone who has the headers should correct all this. */
1623
        {
1473
        *p_type = 0;
1624
            return i_ret;
1474
        *p_mask = 0;
1625
        }
1475
        *p_scheme = 0;
1476
        i_ret = -1; /* Remove this line when implemented. */
1626
1477
1627
        *p_type = ((PDVD_RPC_KEY)key->KeyData)->TypeCode;
1628
        *p_mask = ((PDVD_RPC_KEY)key->KeyData)->RegionMask;
1629
        *p_scheme = ((PDVD_RPC_KEY)key->KeyData)->RpcScheme;
1630
    }
1478
    }
1631
    else
1479
    else
1632
    {
1480
    {
1633
        INIT_SSC( GPCMD_REPORT_KEY, 8 );
1481
        INIT_SSC( GPCMD_REPORT_KEY, 8 );
1634
1482
...
...
1639
        *p_type = p_buffer[ 4 ] >> 6;
1487
        *p_type = p_buffer[ 4 ] >> 6;
1640
        *p_mask = p_buffer[ 5 ];
1488
        *p_mask = p_buffer[ 5 ];
1641
        *p_scheme = p_buffer[ 6 ];
1489
        *p_scheme = p_buffer[ 6 ];
1642
    }
1490
    }
1643
1491
1644
#elif defined( __QNXNTO__ )
1645
1646
    INIT_CPT( GPCMD_REPORT_KEY, 8 );
1647
1648
    p_cpt->cam_cdb[ 10 ] = DVD_REPORT_RPC;
1649
1650
    i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
1651
1652
    *p_type = p_buffer[ 4 ] >> 6;
1653
    *p_mask = p_buffer[ 5 ];
1654
    *p_scheme = p_buffer[ 6 ];
1655
1656
#elif defined( SYS_OS2 )
1657
    INIT_SSC( GPCMD_REPORT_KEY, 8 );
1658
1659
    sdc.command[ 10 ] = DVD_REPORT_RPC;
1660
1661
    i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
1662
                        &sdc, sizeof(sdc), &ulParamLen,
1663
                        p_buffer, sizeof(p_buffer), &ulDataLen);
1664
1665
    *p_type = p_buffer[ 4 ] >> 6;
1666
    *p_mask = p_buffer[ 5 ];
1667
    *p_scheme = p_buffer[ 6 ];
1668
1669
#else
1492
#else
1670
#   error "DVD ioctls are unavailable on this system"
1493
    /* DVD ioctls unavailable - do as if the ioctl failed */
1671
1672
#endif
1673
    return i_ret;
1674
}
1675
1676
/*****************************************************************************
1677
 * ioctl_SendRPC: set RPC status for the drive
1678
 *****************************************************************************/
1679
int ioctl_SendRPC( int i_fd, int i_pdrc )
1680
{
1681
    int i_ret;
1682
1683
#if defined( HAVE_LINUX_DVD_STRUCT ) && defined( DVD_HOST_SEND_RPC_STATE )
1684
    dvd_authinfo auth_info;
1685
1686
    memset( &auth_info, 0, sizeof( auth_info ) );
1687
    auth_info.type = DVD_HOST_SEND_RPC_STATE;
1688
    auth_info.hrpcs.pdrc = i_pdrc;
1689
1690
    i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
1691
1692
#elif defined( HAVE_LINUX_DVD_STRUCT )
1693
    /* FIXME: OpenBSD doesn't know this */
1694
    i_ret = -1;
1494
    i_ret = -1;
1695
1696
#elif defined( HAVE_BSD_DVD_STRUCT )
1697
    struct dvd_authinfo auth_info;
1698
1699
    memset( &auth_info, 0, sizeof( auth_info ) );
1700
    auth_info.format = DVD_SEND_RPC;
1701
    auth_info.region = i_pdrc;
1702
1703
    i_ret = ioctl( i_fd, DVDIOCSENDKEY, &auth_info );
1704
1705
#elif defined( SYS_BEOS )
1706
    INIT_RDC( GPCMD_SEND_KEY, 8 );
1707
1708
    rdc.command[ 10 ] = DVD_SEND_RPC;
1709
1710
    p_buffer[ 1 ] = 6;
1711
    p_buffer[ 4 ] = i_pdrc;
1712
1713
    i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
1714
1715
#elif defined( HPUX_SCTL_IO )
1716
    INIT_SCTL_IO( GPCMD_SEND_KEY, 8 );
1717
1718
    sctl_io.cdb[ 10 ] = DVD_SEND_RPC;
1719
1720
    p_buffer[ 1 ] = 6;
1721
    p_buffer[ 4 ] = i_pdrc;
1722
1723
    i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
1724
1725
#elif defined( SOLARIS_USCSI )
1726
    INIT_USCSI( GPCMD_SEND_KEY, 8 );
1727
1728
    rs_cdb.cdb_opaque[ 10 ] = DVD_SEND_RPC;
1729
1730
    p_buffer[ 1 ] = 6;
1731
    p_buffer[ 4 ] = i_pdrc;
1732
1733
    i_ret = SolarisSendUSCSI( i_fd, &sc );
1734
1735
    if( i_ret < 0 || sc.uscsi_status )
1736
    {
1737
        i_ret = -1;
1738
    }
1739
1740
#elif defined( DARWIN_DVD_IOCTL )
1741
    INIT_DVDIOCTL( dk_dvd_send_key_t, DVDRegionPlaybackControlInfo,
1742
                   kDVDKeyFormatSetRegion );
1743
1744
    dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
1745
    dvdbs.driveRegion = i_pdrc;
1746
1747
    i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
1748
1749
#elif defined( WIN32 )
1750
    if( WIN2K ) /* NT/2k/XP */
1751
    {
1752
        INIT_SPTD( GPCMD_SEND_KEY, 8 );
1753
1754
        sptd.Cdb[ 10 ] = DVD_SEND_RPC;
1755
1756
        p_buffer[ 1 ] = 6;
1757
        p_buffer[ 4 ] = i_pdrc;
1758
1759
        i_ret = SEND_SPTD( i_fd, &sptd, &tmp );
1760
    }
1761
    else
1762
    {
1763
        INIT_SSC( GPCMD_SEND_KEY, 8 );
1764
1765
        ssc.CDBByte[ 10 ] = DVD_SEND_RPC;
1766
1767
        p_buffer[ 1 ] = 6;
1768
        p_buffer[ 4 ] = i_pdrc;
1769
1770
        i_ret = WinSendSSC( i_fd, &ssc );
1771
    }
1772
1773
#elif defined( __QNXNTO__ )
1774
1775
    INIT_CPT( GPCMD_SEND_KEY, 8 );
1776
1777
    p_cpt->cam_cdb[ 10 ] = DVD_SEND_RPC;
1778
1779
    p_buffer[ 1 ] = 6;
1780
    p_buffer[ 4 ] = i_pdrc;
1781
1782
    i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
1783
1784
#elif defined( SYS_OS2 )
1785
    INIT_SSC( GPCMD_SEND_KEY, 8 );
1786
1787
    sdc.command[ 10 ] = DVD_SEND_RPC;
1788
1789
    p_buffer[ 1 ] = 6;
1790
    p_buffer[ 4 ] = i_pdrc;
1791
1792
    i_ret = DosDevIOCtl( i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
1793
                         &sdc, sizeof(sdc), &ulParamLen,
1794
                         p_buffer, sizeof(p_buffer), &ulDataLen );
1795
1796
#else
1797
#   error "DVD ioctls are unavailable on this system"
1798
1495
1799
#endif
1496
#endif
1800
    return i_ret;
1497
    return i_ret;
1801
}
1498
}
1802
1499
...
...
1817
    {
1514
    {
1818
        case GPCMD_SEND_KEY:
1515
        case GPCMD_SEND_KEY:
1819
            /* leave the flags to 0 */
1516
            /* leave the flags to 0 */
1820
            break;
1517
            break;
1821
1518
1822
        case GPCMD_READ_DVD_STRUCTURE: case GPCMD_REPORT_KEY:
1519
        case GPCMD_READ_DVD_STRUCTURE:
1520
        case GPCMD_REPORT_KEY:
1823
    p_rdc->flags = B_RAW_DEVICE_DATA_IN; break; }
1521
            p_rdc->flags = B_RAW_DEVICE_DATA_IN;
1522
            break;
1523
    }
1824
1524
1825
    p_rdc->command[ 0 ]      = i_type;
1525
    p_rdc->command[ 0 ]      = i_type;
1826
1526
1827
    p_rdc->command[ 8 ]      = (p_rdc->data_length >> 8) & 0xff;
1527
    p_rdc->command[ 8 ]      = (p_rdc->data_length >> 8) & 0xff;
1828
    p_rdc->command[ 9 ]      =  p_rdc->data_length       & 0xff;
1528
    p_rdc->command[ 9 ]      =  p_rdc->data_length       & 0xff;
...
...
1870
1570
1871
#if defined( SOLARIS_USCSI )
1571
#if defined( SOLARIS_USCSI )
1872
/*****************************************************************************
1572
/*****************************************************************************
1873
 * SolarisInitUSCSI: initialize a USCSICMD structure for the Solaris kernel
1573
 * SolarisInitUSCSI: initialize a USCSICMD structure for the Solaris kernel
1874
 *****************************************************************************
1574
 *****************************************************************************
1875
 * This function initializes a Solaris userspace scsi command structure for
1575
 * This function initializes a Solaris userspace scsi command structure for 
1876
 * future use, either a read command or a write command.
1576
 * future use, either a read command or a write command.
1877
 *****************************************************************************/
1577
 *****************************************************************************/
1878
static void SolarisInitUSCSI( struct uscsi_cmd *p_sc, int i_type )
1578
static void SolarisInitUSCSI( struct uscsi_cmd *p_sc, int i_type )
1879
{
1579
{   
1880
    union scsi_cdb *rs_cdb;
1580
    union scsi_cdb *rs_cdb;
1881
    memset( p_sc->uscsi_cdb, 0, sizeof( union scsi_cdb ) );
1581
    memset( p_sc->uscsi_cdb, 0, sizeof( union scsi_cdb ) );
1882
    memset( p_sc->uscsi_bufaddr, 0, p_sc->uscsi_buflen );
1582
    memset( p_sc->uscsi_bufaddr, 0, p_sc->uscsi_buflen );
1883
1583
    
1884
    switch( i_type )
1584
    switch( i_type )
1885
    {
1585
    {
1886
        case GPCMD_SEND_KEY:
1586
        case GPCMD_SEND_KEY:
1887
            p_sc->uscsi_flags = USCSI_ISOLATE | USCSI_WRITE;
1587
            p_sc->uscsi_flags = USCSI_ISOLATE | USCSI_WRITE;
1888
            break;
1588
            break;
...
...
1890
        case GPCMD_READ_DVD_STRUCTURE:
1590
        case GPCMD_READ_DVD_STRUCTURE:
1891
        case GPCMD_REPORT_KEY:
1591
        case GPCMD_REPORT_KEY:
1892
            p_sc->uscsi_flags = USCSI_ISOLATE | USCSI_READ;
1592
            p_sc->uscsi_flags = USCSI_ISOLATE | USCSI_READ;
1893
            break;
1593
            break;
1894
    }
1594
    }
1895
1595
    
1896
    rs_cdb = (union scsi_cdb *)p_sc->uscsi_cdb;
1596
    rs_cdb = (union scsi_cdb *)p_sc->uscsi_cdb;
1897
1597
    
1898
    rs_cdb->scc_cmd = i_type;
1598
    rs_cdb->scc_cmd = i_type;
1899
1599
1900
    rs_cdb->cdb_opaque[ 8 ] = (p_sc->uscsi_buflen >> 8) & 0xff;
1600
    rs_cdb->cdb_opaque[ 8 ] = (p_sc->uscsi_buflen >> 8) & 0xff;
1901
    rs_cdb->cdb_opaque[ 9 ] =  p_sc->uscsi_buflen       & 0xff;
1601
    rs_cdb->cdb_opaque[ 9 ] =  p_sc->uscsi_buflen       & 0xff;
1902
    p_sc->uscsi_cdblen = 12;
1602
    p_sc->uscsi_cdblen = 12;
1903
1603
1904
    USCSI_TIMEOUT( p_sc, 15 );
1604
    USCSI_TIMEOUT( p_sc, 15 );
1905
}
1605
}
1906
1907
/*****************************************************************************
1908
 * SolarisSendUSCSI: send a USCSICMD structure to the Solaris kernel
1909
 * for execution
1910
 *****************************************************************************
1911
 * When available, this function uses the function smedia_uscsi_cmd()
1912
 * from Solaris' libsmedia library (Solaris 9 or newer) to execute the
1913
 * USCSI command.  smedia_uscsi_cmd() allows USCSI commands for
1914
 * non-root users on removable media devices on Solaris 9; sending the
1915
 * USCSI command directly to the device using the USCSICMD ioctl fails
1916
 * with an EPERM error on Solaris 9.
1917
 *
1918
 * The code will fall back to the USCSICMD ioctl method, when
1919
 * libsmedia.so is not available or does not export the
1920
 * smedia_uscsi_cmd() function (on Solaris releases upto and including
1921
 * Solaris 8). Fortunatelly, on these old releases non-root users are
1922
 * allowed to perform USCSICMD ioctls on removable media devices.
1923
 *****************************************************************************/
1924
static int SolarisSendUSCSI( int i_fd, struct uscsi_cmd *p_sc )
1925
{
1926
    void *p_handle;
1927
1928
    /* We use static variables to keep track of the libsmedia symbols, which
1929
     * is harmless even in a multithreaded program because the library and
1930
     * its symbols will always be mapped at the same address. */
1931
    static int b_tried = 0;
1932
    static int b_have_sm = 0;
1933
    static void * (*p_get_handle) ( int32_t );
1934
    static int (*p_uscsi_cmd) ( void *, struct uscsi_cmd * );
1935
    static int (*p_release_handle) ( void * );
1936
1937
    if( !b_tried )
1938
    {
1939
        void *p_lib;
1940
1941
        p_lib = dlopen( "libsmedia.so", RTLD_NOW );
1942
        if( p_lib )
1943
        {
1944
            p_get_handle = dlsym( p_lib, "smedia_get_handle" );
1945
            p_uscsi_cmd = dlsym( p_lib, "smedia_uscsi_cmd" );
1946
            p_release_handle = dlsym( p_lib, "smedia_release_handle" );
1947
1948
            if( p_get_handle && p_uscsi_cmd && p_release_handle )
1949
            {
1950
                b_have_sm = 1;
1951
            }
1952
            else
1953
            {
1954
                dlclose( p_lib );
1955
            }
1956
        }
1957
1958
        b_tried = 1;
1959
    }
1960
1961
    if( b_have_sm && (p_handle = p_get_handle(i_fd)) )
1962
    {
1963
        int i_ret = p_uscsi_cmd( p_handle, p_sc );
1964
        p_release_handle( p_handle );
1965
        return i_ret;
1966
    }
1967
1968
    return ioctl( i_fd, USCSICMD, p_sc );
1969
}
1970
#endif
1606
#endif
1971
1607
1972
#if defined( WIN32 )
1608
#if defined( WIN32 )
1973
/*****************************************************************************
1974
 * WinInitSPTD: initialize a sptd structure
1975
 *****************************************************************************
1976
 * This function initializes a SCSI pass through command structure for future
1977
 * use, either a read command or a write command.
1978
 *****************************************************************************/
1979
static void WinInitSPTD( SCSI_PASS_THROUGH_DIRECT *p_sptd, int i_type )
1980
{
1981
    memset( p_sptd->DataBuffer, 0, p_sptd->DataTransferLength );
1982
1983
    switch( i_type )
1984
    {
1985
        case GPCMD_SEND_KEY:
1986
            p_sptd->DataIn = SCSI_IOCTL_DATA_OUT;
1987
            break;
1988
1989
        case GPCMD_READ_DVD_STRUCTURE:
1990
        case GPCMD_REPORT_KEY:
1991
            p_sptd->DataIn = SCSI_IOCTL_DATA_IN;
1992
            break;
1993
    }
1994
1995
    p_sptd->Cdb[ 0 ] = i_type;
1996
    p_sptd->Cdb[ 8 ] = (uint8_t)(p_sptd->DataTransferLength >> 8) & 0xff;
1997
    p_sptd->Cdb[ 9 ] = (uint8_t) p_sptd->DataTransferLength       & 0xff;
1998
    p_sptd->CdbLength = 12;
1999
2000
    p_sptd->TimeOutValue = 2;
2001
}
2002
2003
/*****************************************************************************
1609
/*****************************************************************************
2004
 * WinInitSSC: initialize a ssc structure for the win32 aspi layer
1610
 * WinInitSSC: initialize a ssc structure for the win32 aspi layer
2005
 *****************************************************************************
1611
 *****************************************************************************
2006
 * This function initializes a ssc raw device command structure for future
1612
 * This function initializes a ssc raw device command structure for future
2007
 * use, either a read command or a write command.
1613
 * use, either a read command or a write command.
...
...
2025
    p_ssc->SRB_Cmd      = SC_EXEC_SCSI_CMD;
1631
    p_ssc->SRB_Cmd      = SC_EXEC_SCSI_CMD;
2026
    p_ssc->SRB_Flags    |= SRB_EVENT_NOTIFY;
1632
    p_ssc->SRB_Flags    |= SRB_EVENT_NOTIFY;
2027
1633
2028
    p_ssc->CDBByte[ 0 ] = i_type;
1634
    p_ssc->CDBByte[ 0 ] = i_type;
2029
1635
2030
    p_ssc->CDBByte[ 8 ] = (uint8_t)(p_ssc->SRB_BufLen >> 8) & 0xff;
1636
    p_ssc->CDBByte[ 8 ] = (u8)(p_ssc->SRB_BufLen >> 8) & 0xff;
2031
    p_ssc->CDBByte[ 9 ] = (uint8_t) p_ssc->SRB_BufLen       & 0xff;
1637
    p_ssc->CDBByte[ 9 ] = (u8) p_ssc->SRB_BufLen       & 0xff;
2032
    p_ssc->SRB_CDBLen   = 12;
1638
    p_ssc->SRB_CDBLen   = 12;
2033
1639
2034
    p_ssc->SRB_SenseLen = SENSE_LEN;
1640
    p_ssc->SRB_SenseLen = SENSE_LEN;
2035
}
1641
}
2036
1642
...
...
2060
1666
2061
    return p_ssc->SRB_Status == SS_COMP ? 0 : -1;
1667
    return p_ssc->SRB_Status == SS_COMP ? 0 : -1;
2062
}
1668
}
2063
#endif
1669
#endif
2064
1670
2065
#if defined( __QNXNTO__ )
2066
/*****************************************************************************
2067
 * QNXInitCPT: initialize a CPT structure for QNX Neutrino
2068
 *****************************************************************************
2069
 * This function initializes a cpt command structure for future use,
2070
 * either a read command or a write command.
2071
 *****************************************************************************/
2072
static void QNXInitCPT( CAM_PASS_THRU * p_cpt, int i_type )
2073
{
2074
    switch( i_type )
2075
    {
2076
        case GPCMD_SEND_KEY:
2077
            p_cpt->cam_flags = CAM_DIR_OUT;
2078
            break;
2079
2080
        case GPCMD_READ_DVD_STRUCTURE:
2081
        case GPCMD_REPORT_KEY:
2082
            p_cpt->cam_flags = CAM_DIR_IN;
2083
            break;
2084
    }
2085
2086
    p_cpt->cam_cdb[0] = i_type;
2087
2088
    p_cpt->cam_cdb[ 8 ] = (p_cpt->cam_dxfer_len >> 8) & 0xff;
2089
    p_cpt->cam_cdb[ 9 ] =  p_cpt->cam_dxfer_len       & 0xff;
2090
    p_cpt->cam_cdb_len = 12;
2091
2092
    p_cpt->cam_timeout = CAM_TIME_DEFAULT;
2093
}
2094
#endif
2095
2096
#if defined( SYS_OS2 )
2097
/*****************************************************************************
2098
 * OS2InitSDC: initialize a SDC structure for the Execute SCSI-command
2099
 *****************************************************************************
2100
 * This function initializes a OS2 'execute SCSI command' structure for
2101
 * future use, either a read command or a write command.
2102
 *****************************************************************************/
2103
static void OS2InitSDC( struct OS2_ExecSCSICmd *p_sdc, int i_type )
2104
{
2105
    switch( i_type )
2106
    {
2107
        case GPCMD_SEND_KEY:
2108
            p_sdc->flags = 0;
2109
            break;
2110
2111
        case GPCMD_READ_DVD_STRUCTURE:
2112
        case GPCMD_REPORT_KEY:
2113
            p_sdc->flags = EX_DIRECTION_IN;
2114
            break;
2115
    }
2116
2117
    p_sdc->command[ 0 ] = i_type;
2118
    p_sdc->command[ 8 ] = (p_sdc->data_length >> 8) & 0xff;
2119
    p_sdc->command[ 9 ] = p_sdc->data_length        & 0xff;
2120
    p_sdc->id_code      = 0x31304443;    // 'CD01'
2121
    p_sdc->cmd_length   = 12;
2122
}
2123
#endif