7027
|
1 /*****************************************************************************
|
|
2 * ioctl.c: DVD ioctl replacement function
|
|
3 *****************************************************************************
|
|
4 * Copyright (C) 1999-2001 VideoLAN
|
|
5 * $Id$
|
|
6 *
|
|
7 * Authors: Markus Kuespert <ltlBeBoy@beosmail.com>
|
|
8 * Samuel Hocevar <sam@zoy.org>
|
|
9 * Jon Lech Johansen <jon-vl@nanocrew.net>
|
|
10 * Håkan Hjort <d95hjort@dtek.chalmers.se>
|
|
11 * Eugenio Jarosiewicz <ej0@cise.ufl.edu>
|
|
12 * David Siebörger <drs-videolan@rucus.ru.ac.za>
|
|
13 * Alex Strelnikov <lelik@os2.ru>
|
|
14 *
|
|
15 * This program is free software; you can redistribute it and/or modify
|
|
16 * it under the terms of the GNU General Public License as published by
|
|
17 * the Free Software Foundation; either version 2 of the License, or
|
|
18 * (at your option) any later version.
|
|
19 *
|
|
20 * This program is distributed in the hope that it will be useful,
|
|
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
23 * GNU General Public License for more details.
|
|
24 *
|
|
25 * You should have received a copy of the GNU General Public License
|
|
26 * along with this program; if not, write to the Free Software
|
|
27 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
|
|
28 *****************************************************************************/
|
|
29
|
|
30 /*****************************************************************************
|
|
31 * Preamble
|
|
32 *****************************************************************************/
|
|
33 #include "config.h"
|
|
34
|
|
35 #include <stdio.h>
|
|
36
|
|
37 #include <string.h> /* memcpy(), memset() */
|
|
38 #include <sys/types.h>
|
|
39
|
|
40 #if defined( WIN32 )
|
8142
|
41 # undef DATADIR /* clashes with /usr/include/w32api/objidl.h */
|
7027
|
42 # include <windows.h>
|
|
43 # 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
|
|
52 # include <netinet/in.h>
|
|
53 # include <sys/ioctl.h>
|
|
54 #endif
|
|
55
|
|
56 #ifdef DVD_STRUCT_IN_SYS_CDIO_H
|
|
57 # include <sys/cdio.h>
|
|
58 #endif
|
|
59 #ifdef DVD_STRUCT_IN_SYS_DVDIO_H
|
|
60 # include <sys/dvdio.h>
|
|
61 #endif
|
|
62 #ifdef DVD_STRUCT_IN_LINUX_CDROM_H
|
|
63 # include <linux/cdrom.h>
|
|
64 #endif
|
|
65 #ifdef DVD_STRUCT_IN_DVD_H
|
|
66 # include <dvd.h>
|
|
67 #endif
|
|
68 #ifdef DVD_STRUCT_IN_BSDI_DVDIOCTL_DVD_H
|
|
69 # include "bsdi_dvd.h"
|
|
70 #endif
|
|
71 #ifdef SYS_BEOS
|
|
72 # include <malloc.h>
|
|
73 # include <scsi.h>
|
|
74 #endif
|
|
75 #ifdef HPUX_SCTL_IO
|
|
76 # include <sys/scsi.h>
|
|
77 #endif
|
|
78 #ifdef SOLARIS_USCSI
|
|
79 # include <unistd.h>
|
|
80 # include <stropts.h>
|
|
81 # include <sys/scsi/scsi_types.h>
|
|
82 # include <sys/scsi/impl/uscsi.h>
|
|
83 #endif
|
|
84 #ifdef DARWIN_DVD_IOCTL
|
|
85 # include <IOKit/storage/IODVDMediaBSDClient.h>
|
|
86 #endif
|
|
87 #ifdef __QNXNTO__
|
|
88 # include <sys/mman.h>
|
|
89 # include <sys/dcmd_cam.h>
|
|
90 #endif
|
|
91
|
|
92 #include "common.h"
|
|
93
|
|
94 #include "ioctl.h"
|
|
95
|
|
96 /*****************************************************************************
|
|
97 * Local prototypes, BeOS specific
|
|
98 *****************************************************************************/
|
|
99 #if defined( SYS_BEOS )
|
|
100 static void BeInitRDC ( raw_device_command *, int );
|
|
101 #endif
|
|
102
|
|
103 /*****************************************************************************
|
|
104 * Local prototypes, HP-UX specific
|
|
105 *****************************************************************************/
|
|
106 #if defined( HPUX_SCTL_IO )
|
|
107 static void HPUXInitSCTL ( struct sctl_io *sctl_io, int i_type );
|
|
108 #endif
|
|
109
|
|
110 /*****************************************************************************
|
|
111 * Local prototypes, Solaris specific
|
|
112 *****************************************************************************/
|
|
113 #if defined( SOLARIS_USCSI )
|
|
114 static void SolarisInitUSCSI( struct uscsi_cmd *p_sc, int i_type );
|
|
115 #endif
|
|
116
|
|
117 /*****************************************************************************
|
|
118 * Local prototypes, win32 (aspi) specific
|
|
119 *****************************************************************************/
|
|
120 #if defined( WIN32 )
|
|
121 static void WinInitSSC ( struct SRB_ExecSCSICmd *, int );
|
|
122 static int WinSendSSC ( int, struct SRB_ExecSCSICmd * );
|
|
123 #endif
|
|
124
|
|
125 /*****************************************************************************
|
|
126 * Local prototypes, QNX specific
|
|
127 *****************************************************************************/
|
|
128 #if defined( __QNXNTO__ )
|
|
129 static void QNXInitCPT ( CAM_PASS_THRU *, int );
|
|
130 #endif
|
|
131
|
|
132 /*****************************************************************************
|
|
133 * Local prototypes, OS2 specific
|
|
134 *****************************************************************************/
|
|
135 #if defined( SYS_OS2 )
|
|
136 static void OS2InitSDC( struct OS2_ExecSCSICmd *, int );
|
|
137 #endif
|
|
138
|
|
139 /*****************************************************************************
|
|
140 * ioctl_ReadCopyright: check whether the disc is encrypted or not
|
|
141 *****************************************************************************/
|
|
142 int ioctl_ReadCopyright( int i_fd, int i_layer, int *pi_copyright )
|
|
143 {
|
|
144 int i_ret;
|
|
145
|
|
146 #if defined( HAVE_LINUX_DVD_STRUCT )
|
|
147 dvd_struct dvd;
|
|
148
|
|
149 memset( &dvd, 0, sizeof( dvd ) );
|
|
150 dvd.type = DVD_STRUCT_COPYRIGHT;
|
|
151 dvd.copyright.layer_num = i_layer;
|
|
152
|
|
153 i_ret = ioctl( i_fd, DVD_READ_STRUCT, &dvd );
|
|
154
|
|
155 *pi_copyright = dvd.copyright.cpst;
|
|
156
|
|
157 #elif defined( HAVE_BSD_DVD_STRUCT )
|
|
158 struct dvd_struct dvd;
|
|
159
|
|
160 memset( &dvd, 0, sizeof( dvd ) );
|
|
161 dvd.format = DVD_STRUCT_COPYRIGHT;
|
|
162 dvd.layer_num = i_layer;
|
|
163
|
|
164 i_ret = ioctl( i_fd, DVDIOCREADSTRUCTURE, &dvd );
|
|
165
|
|
166 *pi_copyright = dvd.cpst;
|
|
167
|
|
168 #elif defined( SYS_BEOS )
|
|
169 INIT_RDC( GPCMD_READ_DVD_STRUCTURE, 8 );
|
|
170
|
|
171 rdc.command[ 6 ] = i_layer;
|
|
172 rdc.command[ 7 ] = DVD_STRUCT_COPYRIGHT;
|
|
173
|
|
174 i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
|
|
175
|
|
176 *pi_copyright = p_buffer[ 4 ];
|
|
177
|
|
178 #elif defined( HPUX_SCTL_IO )
|
|
179 INIT_SCTL_IO( GPCMD_READ_DVD_STRUCTURE, 8 );
|
|
180
|
|
181 sctl_io.cdb[ 6 ] = i_layer;
|
|
182 sctl_io.cdb[ 7 ] = DVD_STRUCT_COPYRIGHT;
|
|
183
|
|
184 i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
|
|
185
|
|
186 *pi_copyright = p_buffer[ 4 ];
|
|
187
|
|
188 #elif defined( SOLARIS_USCSI )
|
|
189 INIT_USCSI( GPCMD_READ_DVD_STRUCTURE, 8 );
|
|
190
|
|
191 rs_cdb.cdb_opaque[ 6 ] = i_layer;
|
|
192 rs_cdb.cdb_opaque[ 7 ] = DVD_STRUCT_COPYRIGHT;
|
|
193
|
|
194 i_ret = ioctl(i_fd, USCSICMD, &sc);
|
|
195
|
|
196 if( i_ret < 0 || sc.uscsi_status ) {
|
|
197 i_ret = -1;
|
|
198 }
|
|
199
|
|
200 *pi_copyright = p_buffer[ 4 ];
|
|
201 /* s->copyright.rmi = p_buffer[ 5 ]; */
|
|
202
|
|
203 #elif defined( DARWIN_DVD_IOCTL )
|
|
204 INIT_DVDIOCTL( dk_dvd_read_structure_t, DVDCopyrightInfo,
|
|
205 kDVDStructureFormatCopyrightInfo );
|
|
206
|
|
207 dvd.layer = i_layer;
|
|
208
|
|
209 i_ret = ioctl( i_fd, DKIOCDVDREADSTRUCTURE, &dvd );
|
|
210
|
|
211 *pi_copyright = dvdbs.copyrightProtectionSystemType;
|
|
212
|
|
213 #elif defined( WIN32 )
|
|
214 if( WIN2K ) /* NT/Win2000/Whistler */
|
|
215 {
|
|
216 DWORD tmp;
|
|
217 u8 p_buffer[ 8 ];
|
|
218 SCSI_PASS_THROUGH_DIRECT sptd;
|
|
219
|
|
220 memset( &sptd, 0, sizeof( sptd ) );
|
|
221 memset( &p_buffer, 0, sizeof( p_buffer ) );
|
|
222
|
|
223 /* When using IOCTL_DVD_READ_STRUCTURE and
|
|
224 DVD_COPYRIGHT_DESCRIPTOR, CopyrightProtectionType
|
|
225 is always 6. So we send a raw scsi command instead. */
|
|
226
|
|
227 sptd.Length = sizeof( SCSI_PASS_THROUGH_DIRECT );
|
|
228 sptd.CdbLength = 12;
|
|
229 sptd.DataIn = SCSI_IOCTL_DATA_IN;
|
|
230 sptd.DataTransferLength = 8;
|
|
231 sptd.TimeOutValue = 2;
|
|
232 sptd.DataBuffer = p_buffer;
|
|
233 sptd.Cdb[ 0 ] = GPCMD_READ_DVD_STRUCTURE;
|
|
234 sptd.Cdb[ 6 ] = i_layer;
|
|
235 sptd.Cdb[ 7 ] = DVD_STRUCT_COPYRIGHT;
|
|
236 sptd.Cdb[ 8 ] = (8 >> 8) & 0xff;
|
|
237 sptd.Cdb[ 9 ] = 8 & 0xff;
|
|
238
|
|
239 i_ret = DeviceIoControl( (HANDLE) i_fd,
|
|
240 IOCTL_SCSI_PASS_THROUGH_DIRECT,
|
|
241 &sptd, sizeof( SCSI_PASS_THROUGH_DIRECT ),
|
|
242 &sptd, sizeof( SCSI_PASS_THROUGH_DIRECT ),
|
|
243 &tmp, NULL ) ? 0 : -1;
|
|
244
|
|
245 *pi_copyright = p_buffer[ 4 ];
|
|
246 }
|
|
247 else
|
|
248 {
|
|
249 INIT_SSC( GPCMD_READ_DVD_STRUCTURE, 8 );
|
|
250
|
|
251 ssc.CDBByte[ 6 ] = i_layer;
|
|
252 ssc.CDBByte[ 7 ] = DVD_STRUCT_COPYRIGHT;
|
|
253
|
|
254 i_ret = WinSendSSC( i_fd, &ssc );
|
|
255
|
|
256 *pi_copyright = p_buffer[ 4 ];
|
|
257 }
|
|
258
|
|
259 #elif defined( __QNXNTO__ )
|
|
260
|
|
261 INIT_CPT( GPCMD_READ_DVD_STRUCTURE, 8 );
|
|
262
|
|
263 p_cpt->cam_cdb[ 6 ] = i_layer;
|
|
264 p_cpt->cam_cdb[ 7 ] = DVD_STRUCT_COPYRIGHT;
|
|
265
|
|
266 i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
|
|
267
|
|
268 *pi_copyright = p_buffer[4];
|
|
269
|
|
270 #elif defined( SYS_OS2 )
|
|
271 INIT_SSC( GPCMD_READ_DVD_STRUCTURE, 8 );
|
|
272
|
|
273 sdc.command[ 6 ] = i_layer;
|
|
274 sdc.command[ 7 ] = DVD_STRUCT_COPYRIGHT;
|
|
275
|
|
276 i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
|
|
277 &sdc, sizeof(sdc), &ulParamLen,
|
|
278 p_buffer, sizeof(p_buffer), &ulDataLen);
|
|
279
|
|
280 *pi_copyright = p_buffer[ 4 ];
|
|
281
|
|
282 #else
|
|
283 # error "DVD ioctls are unavailable on this system"
|
|
284
|
|
285 #endif
|
|
286 return i_ret;
|
|
287 }
|
|
288
|
|
289 /*****************************************************************************
|
|
290 * ioctl_ReadDiscKey: get the disc key
|
|
291 *****************************************************************************/
|
|
292 int ioctl_ReadDiscKey( int i_fd, int *pi_agid, u8 *p_key )
|
|
293 {
|
|
294 int i_ret;
|
|
295
|
|
296 #if defined( HAVE_LINUX_DVD_STRUCT )
|
|
297 dvd_struct dvd;
|
|
298
|
|
299 memset( &dvd, 0, sizeof( dvd ) );
|
|
300 dvd.type = DVD_STRUCT_DISCKEY;
|
|
301 dvd.disckey.agid = *pi_agid;
|
|
302 memset( dvd.disckey.value, 0, DVD_DISCKEY_SIZE );
|
|
303
|
|
304 i_ret = ioctl( i_fd, DVD_READ_STRUCT, &dvd );
|
|
305
|
|
306 if( i_ret < 0 )
|
|
307 {
|
|
308 return i_ret;
|
|
309 }
|
|
310
|
|
311 memcpy( p_key, dvd.disckey.value, DVD_DISCKEY_SIZE );
|
|
312
|
|
313 #elif defined( HAVE_BSD_DVD_STRUCT )
|
|
314 struct dvd_struct dvd;
|
|
315
|
|
316 memset( &dvd, 0, sizeof( dvd ) );
|
|
317 dvd.format = DVD_STRUCT_DISCKEY;
|
|
318 dvd.agid = *pi_agid;
|
|
319 memset( dvd.data, 0, DVD_DISCKEY_SIZE );
|
|
320
|
|
321 i_ret = ioctl( i_fd, DVDIOCREADSTRUCTURE, &dvd );
|
|
322
|
|
323 if( i_ret < 0 )
|
|
324 {
|
|
325 return i_ret;
|
|
326 }
|
|
327
|
|
328 memcpy( p_key, dvd.data, DVD_DISCKEY_SIZE );
|
|
329
|
|
330 #elif defined( SYS_BEOS )
|
|
331 INIT_RDC( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
|
|
332
|
|
333 rdc.command[ 7 ] = DVD_STRUCT_DISCKEY;
|
|
334 rdc.command[ 10 ] = *pi_agid << 6;
|
|
335
|
|
336 i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
|
|
337
|
|
338 if( i_ret < 0 )
|
|
339 {
|
|
340 return i_ret;
|
|
341 }
|
|
342
|
|
343 memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );
|
|
344
|
|
345 #elif defined( HPUX_SCTL_IO )
|
|
346 INIT_SCTL_IO( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
|
|
347
|
|
348 sctl_io.cdb[ 7 ] = DVD_STRUCT_DISCKEY;
|
|
349 sctl_io.cdb[ 10 ] = *pi_agid << 6;
|
|
350
|
|
351 i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
|
|
352
|
|
353 if( i_ret < 0 )
|
|
354 {
|
|
355 return i_ret;
|
|
356 }
|
|
357
|
|
358 memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );
|
|
359
|
|
360 #elif defined( SOLARIS_USCSI )
|
|
361 INIT_USCSI( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
|
|
362
|
|
363 rs_cdb.cdb_opaque[ 7 ] = DVD_STRUCT_DISCKEY;
|
|
364 rs_cdb.cdb_opaque[ 10 ] = *pi_agid << 6;
|
|
365
|
|
366 i_ret = ioctl( i_fd, USCSICMD, &sc );
|
|
367
|
|
368 if( i_ret < 0 || sc.uscsi_status )
|
|
369 {
|
|
370 i_ret = -1;
|
|
371 return i_ret;
|
|
372 }
|
|
373
|
|
374 memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );
|
|
375
|
|
376 #elif defined( DARWIN_DVD_IOCTL )
|
|
377 INIT_DVDIOCTL( dk_dvd_read_structure_t, DVDDiscKeyInfo,
|
|
378 kDVDStructureFormatDiscKeyInfo );
|
|
379
|
|
380 dvd.grantID = *pi_agid;
|
|
381
|
|
382 i_ret = ioctl( i_fd, DKIOCDVDREADSTRUCTURE, &dvd );
|
|
383
|
|
384 memcpy( p_key, dvdbs.discKeyStructures, DVD_DISCKEY_SIZE );
|
|
385
|
|
386 #elif defined( WIN32 )
|
|
387 if( WIN2K ) /* NT/Win2000/Whistler */
|
|
388 {
|
|
389 DWORD tmp;
|
|
390 u8 buffer[DVD_DISK_KEY_LENGTH];
|
|
391 PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
|
|
392
|
|
393 memset( &buffer, 0, sizeof( buffer ) );
|
|
394
|
|
395 key->KeyLength = DVD_DISK_KEY_LENGTH;
|
|
396 key->SessionId = *pi_agid;
|
|
397 key->KeyType = DvdDiskKey;
|
|
398 key->KeyFlags = 0;
|
|
399
|
|
400 i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
|
|
401 key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
|
|
402
|
|
403 if( i_ret < 0 )
|
|
404 {
|
|
405 return i_ret;
|
|
406 }
|
|
407
|
|
408 memcpy( p_key, key->KeyData, DVD_DISCKEY_SIZE );
|
|
409 }
|
|
410 else
|
|
411 {
|
|
412 INIT_SSC( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
|
|
413
|
|
414 ssc.CDBByte[ 7 ] = DVD_STRUCT_DISCKEY;
|
|
415 ssc.CDBByte[ 10 ] = *pi_agid << 6;
|
|
416
|
|
417 i_ret = WinSendSSC( i_fd, &ssc );
|
|
418
|
|
419 if( i_ret < 0 )
|
|
420 {
|
|
421 return i_ret;
|
|
422 }
|
|
423
|
|
424 memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );
|
|
425 }
|
|
426
|
|
427 #elif defined( __QNXNTO__ )
|
|
428
|
|
429 INIT_CPT( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
|
|
430
|
|
431 p_cpt->cam_cdb[ 7 ] = DVD_STRUCT_DISCKEY;
|
|
432 p_cpt->cam_cdb[ 10 ] = *pi_agid << 6;
|
|
433
|
|
434 i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
|
|
435
|
|
436 memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );
|
|
437
|
|
438 #elif defined ( SYS_OS2 )
|
|
439 INIT_SSC( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
|
|
440
|
|
441 sdc.command[ 7 ] = DVD_STRUCT_DISCKEY;
|
|
442 sdc.command[ 10 ] = *pi_agid << 6;
|
|
443
|
|
444 i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
|
|
445 &sdc, sizeof(sdc), &ulParamLen,
|
|
446 p_buffer, sizeof(p_buffer), &ulDataLen);
|
|
447
|
|
448 if( i_ret < 0 )
|
|
449 {
|
|
450 return i_ret;
|
|
451 }
|
|
452
|
|
453 memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );
|
|
454
|
|
455 #else
|
|
456 # error "DVD ioctls are unavailable on this system"
|
|
457
|
|
458 #endif
|
|
459 return i_ret;
|
|
460 }
|
|
461
|
|
462 /*****************************************************************************
|
|
463 * ioctl_ReadTitleKey: get the title key
|
|
464 *****************************************************************************/
|
|
465 int ioctl_ReadTitleKey( int i_fd, int *pi_agid, int i_pos, u8 *p_key )
|
|
466 {
|
|
467 int i_ret;
|
|
468
|
|
469 #if defined( HAVE_LINUX_DVD_STRUCT )
|
|
470 dvd_authinfo auth_info;
|
|
471
|
|
472 memset( &auth_info, 0, sizeof( auth_info ) );
|
|
473 auth_info.type = DVD_LU_SEND_TITLE_KEY;
|
|
474 auth_info.lstk.agid = *pi_agid;
|
|
475 auth_info.lstk.lba = i_pos;
|
|
476
|
|
477 i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
|
|
478
|
|
479 memcpy( p_key, auth_info.lstk.title_key, DVD_KEY_SIZE );
|
|
480
|
|
481 #elif defined( HAVE_BSD_DVD_STRUCT )
|
|
482 struct dvd_authinfo auth_info;
|
|
483
|
|
484 memset( &auth_info, 0, sizeof( auth_info ) );
|
|
485 auth_info.format = DVD_REPORT_TITLE_KEY;
|
|
486 auth_info.agid = *pi_agid;
|
|
487 auth_info.lba = i_pos;
|
|
488
|
|
489 i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );
|
|
490
|
|
491 memcpy( p_key, auth_info.keychal, DVD_KEY_SIZE );
|
|
492
|
|
493 #elif defined( SYS_BEOS )
|
|
494 INIT_RDC( GPCMD_REPORT_KEY, 12 );
|
|
495
|
|
496 rdc.command[ 2 ] = ( i_pos >> 24 ) & 0xff;
|
|
497 rdc.command[ 3 ] = ( i_pos >> 16 ) & 0xff;
|
|
498 rdc.command[ 4 ] = ( i_pos >> 8 ) & 0xff;
|
|
499 rdc.command[ 5 ] = ( i_pos ) & 0xff;
|
|
500 rdc.command[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);
|
|
501
|
|
502 i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
|
|
503
|
|
504 memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
|
|
505
|
|
506 #elif defined( HPUX_SCTL_IO )
|
|
507 INIT_SCTL_IO( GPCMD_REPORT_KEY, 12 );
|
|
508
|
|
509 sctl_io.cdb[ 2 ] = ( i_pos >> 24 ) & 0xff;
|
|
510 sctl_io.cdb[ 3 ] = ( i_pos >> 16 ) & 0xff;
|
|
511 sctl_io.cdb[ 4 ] = ( i_pos >> 8 ) & 0xff;
|
|
512 sctl_io.cdb[ 5 ] = ( i_pos ) & 0xff;
|
|
513 sctl_io.cdb[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);
|
|
514
|
|
515 i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
|
|
516
|
|
517 memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
|
|
518
|
|
519 #elif defined( SOLARIS_USCSI )
|
|
520 INIT_USCSI( GPCMD_REPORT_KEY, 12 );
|
|
521
|
|
522 rs_cdb.cdb_opaque[ 2 ] = ( i_pos >> 24 ) & 0xff;
|
|
523 rs_cdb.cdb_opaque[ 3 ] = ( i_pos >> 16 ) & 0xff;
|
|
524 rs_cdb.cdb_opaque[ 4 ] = ( i_pos >> 8 ) & 0xff;
|
|
525 rs_cdb.cdb_opaque[ 5 ] = ( i_pos ) & 0xff;
|
|
526 rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);
|
|
527
|
|
528 i_ret = ioctl( i_fd, USCSICMD, &sc );
|
|
529
|
|
530 if( i_ret < 0 || sc.uscsi_status )
|
|
531 {
|
|
532 i_ret = -1;
|
|
533 }
|
|
534
|
|
535 /* Do we want to return the cp_sec flag perhaps? */
|
|
536 /* a->lstk.cpm = (buf[ 4 ] >> 7) & 1; */
|
|
537 /* a->lstk.cp_sec = (buf[ 4 ] >> 6) & 1; */
|
|
538 /* a->lstk.cgms = (buf[ 4 ] >> 4) & 3; */
|
|
539
|
|
540 memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
|
|
541
|
|
542 #elif defined( DARWIN_DVD_IOCTL )
|
|
543 INIT_DVDIOCTL( dk_dvd_report_key_t, DVDTitleKeyInfo,
|
|
544 kDVDKeyFormatTitleKey );
|
|
545
|
|
546 dvd.address = i_pos;
|
|
547 dvd.grantID = *pi_agid;
|
|
548 dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
|
|
549
|
|
550 i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
|
|
551
|
|
552 memcpy( p_key, dvdbs.titleKeyValue, DVD_KEY_SIZE );
|
|
553
|
|
554 #elif defined( WIN32 )
|
|
555 if( WIN2K ) /* NT/Win2000/Whistler */
|
|
556 {
|
|
557 DWORD tmp;
|
|
558 u8 buffer[DVD_BUS_KEY_LENGTH];
|
|
559 PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
|
|
560
|
|
561 memset( &buffer, 0, sizeof( buffer ) );
|
|
562
|
|
563 key->KeyLength = DVD_TITLE_KEY_LENGTH;
|
|
564 key->SessionId = *pi_agid;
|
|
565 key->KeyType = DvdTitleKey;
|
|
566 key->KeyFlags = 0;
|
|
567 key->Parameters.TitleOffset.QuadPart = (LONGLONG) i_pos;
|
|
568
|
|
569 i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
|
|
570 key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
|
|
571
|
|
572 memcpy( p_key, key->KeyData, DVD_KEY_SIZE );
|
|
573 }
|
|
574 else
|
|
575 {
|
|
576 INIT_SSC( GPCMD_REPORT_KEY, 12 );
|
|
577
|
|
578 ssc.CDBByte[ 2 ] = ( i_pos >> 24 ) & 0xff;
|
|
579 ssc.CDBByte[ 3 ] = ( i_pos >> 16 ) & 0xff;
|
|
580 ssc.CDBByte[ 4 ] = ( i_pos >> 8 ) & 0xff;
|
|
581 ssc.CDBByte[ 5 ] = ( i_pos ) & 0xff;
|
|
582 ssc.CDBByte[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);
|
|
583
|
|
584 i_ret = WinSendSSC( i_fd, &ssc );
|
|
585
|
|
586 memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
|
|
587 }
|
|
588
|
|
589 #elif defined( __QNXNTO__ )
|
|
590
|
|
591 INIT_CPT( GPCMD_REPORT_KEY, 12 );
|
|
592
|
|
593 p_cpt->cam_cdb[ 2 ] = ( i_pos >> 24 ) & 0xff;
|
|
594 p_cpt->cam_cdb[ 3 ] = ( i_pos >> 16 ) & 0xff;
|
|
595 p_cpt->cam_cdb[ 4 ] = ( i_pos >> 8 ) & 0xff;
|
|
596 p_cpt->cam_cdb[ 5 ] = ( i_pos ) & 0xff;
|
|
597 p_cpt->cam_cdb[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);
|
|
598
|
|
599 i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
|
|
600
|
|
601 memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
|
|
602
|
|
603 #elif defined( SYS_OS2 )
|
|
604 INIT_SSC( GPCMD_REPORT_KEY, 12 );
|
|
605
|
|
606 sdc.command[ 2 ] = ( i_pos >> 24 ) & 0xff;
|
|
607 sdc.command[ 3 ] = ( i_pos >> 16 ) & 0xff;
|
|
608 sdc.command[ 4 ] = ( i_pos >> 8 ) & 0xff;
|
|
609 sdc.command[ 5 ] = ( i_pos ) & 0xff;
|
|
610 sdc.command[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);
|
|
611
|
|
612 i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
|
|
613 &sdc, sizeof(sdc), &ulParamLen,
|
|
614 p_buffer, sizeof(p_buffer), &ulDataLen);
|
|
615
|
|
616 memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
|
|
617
|
|
618 #else
|
|
619 # error "DVD ioctls are unavailable on this system"
|
|
620
|
|
621 #endif
|
|
622
|
|
623 return i_ret;
|
|
624 }
|
|
625
|
|
626
|
|
627 /*****************************************************************************
|
|
628 * ioctl_ReportAgid: get AGID from the drive
|
|
629 *****************************************************************************/
|
|
630 int ioctl_ReportAgid( int i_fd, int *pi_agid )
|
|
631 {
|
|
632 int i_ret;
|
|
633
|
|
634 #if defined( HAVE_LINUX_DVD_STRUCT )
|
|
635 dvd_authinfo auth_info;
|
|
636
|
|
637 memset( &auth_info, 0, sizeof( auth_info ) );
|
|
638 auth_info.type = DVD_LU_SEND_AGID;
|
|
639 auth_info.lsa.agid = *pi_agid;
|
|
640
|
|
641 i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
|
|
642
|
|
643 *pi_agid = auth_info.lsa.agid;
|
|
644
|
|
645 #elif defined( HAVE_BSD_DVD_STRUCT )
|
|
646 struct dvd_authinfo auth_info;
|
|
647
|
|
648 memset( &auth_info, 0, sizeof( auth_info ) );
|
|
649 auth_info.format = DVD_REPORT_AGID;
|
|
650 auth_info.agid = *pi_agid;
|
|
651
|
|
652 i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );
|
|
653
|
|
654 *pi_agid = auth_info.agid;
|
|
655
|
|
656 #elif defined( SYS_BEOS )
|
|
657 INIT_RDC( GPCMD_REPORT_KEY, 8 );
|
|
658
|
|
659 rdc.command[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
|
|
660
|
|
661 i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
|
|
662
|
|
663 *pi_agid = p_buffer[ 7 ] >> 6;
|
|
664
|
|
665 #elif defined( HPUX_SCTL_IO )
|
|
666 INIT_SCTL_IO( GPCMD_REPORT_KEY, 8 );
|
|
667
|
|
668 sctl_io.cdb[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
|
|
669
|
|
670 i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
|
|
671
|
|
672 *pi_agid = p_buffer[ 7 ] >> 6;
|
|
673
|
|
674 #elif defined( SOLARIS_USCSI )
|
|
675 INIT_USCSI( GPCMD_REPORT_KEY, 8 );
|
|
676
|
|
677 rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
|
|
678
|
|
679 i_ret = ioctl( i_fd, USCSICMD, &sc );
|
|
680
|
|
681 if( i_ret < 0 || sc.uscsi_status )
|
|
682 {
|
|
683 i_ret = -1;
|
|
684 }
|
|
685
|
|
686 *pi_agid = p_buffer[ 7 ] >> 6;
|
|
687
|
|
688 #elif defined( DARWIN_DVD_IOCTL )
|
|
689 INIT_DVDIOCTL( dk_dvd_report_key_t, DVDAuthenticationGrantIDInfo,
|
|
690 kDVDKeyFormatAGID_CSS );
|
|
691
|
|
692 dvd.grantID = *pi_agid;
|
|
693 dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
|
|
694
|
|
695 i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
|
|
696
|
|
697 *pi_agid = dvdbs.grantID;
|
|
698
|
|
699 #elif defined( WIN32 )
|
|
700 if( WIN2K ) /* NT/Win2000/Whistler */
|
|
701 {
|
|
702 ULONG id;
|
|
703 DWORD tmp;
|
|
704
|
|
705 i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_START_SESSION,
|
|
706 &tmp, 4, &id, sizeof( id ), &tmp, NULL ) ? 0 : -1;
|
|
707
|
|
708 *pi_agid = id;
|
|
709 }
|
|
710 else
|
|
711 {
|
|
712 INIT_SSC( GPCMD_REPORT_KEY, 8 );
|
|
713
|
|
714 ssc.CDBByte[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
|
|
715
|
|
716 i_ret = WinSendSSC( i_fd, &ssc );
|
|
717
|
|
718 *pi_agid = p_buffer[ 7 ] >> 6;
|
|
719 }
|
|
720
|
|
721 #elif defined( __QNXNTO__ )
|
|
722
|
|
723 INIT_CPT( GPCMD_REPORT_KEY, 8 );
|
|
724
|
|
725 p_cpt->cam_cdb[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
|
|
726
|
|
727 i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
|
|
728
|
|
729 *pi_agid = p_buffer[ 7 ] >> 6;
|
|
730
|
|
731 #elif defined( SYS_OS2 )
|
|
732 INIT_SSC( GPCMD_REPORT_KEY, 8 );
|
|
733
|
|
734 sdc.command[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
|
|
735
|
|
736 i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
|
|
737 &sdc, sizeof(sdc), &ulParamLen,
|
|
738 p_buffer, sizeof(p_buffer), &ulDataLen);
|
|
739
|
|
740 *pi_agid = p_buffer[ 7 ] >> 6;
|
|
741
|
|
742 #else
|
|
743 # error "DVD ioctls are unavailable on this system"
|
|
744
|
|
745 #endif
|
|
746 return i_ret;
|
|
747 }
|
|
748
|
|
749 /*****************************************************************************
|
|
750 * ioctl_ReportChallenge: get challenge from the drive
|
|
751 *****************************************************************************/
|
|
752 int ioctl_ReportChallenge( int i_fd, int *pi_agid, u8 *p_challenge )
|
|
753 {
|
|
754 int i_ret;
|
|
755
|
|
756 #if defined( HAVE_LINUX_DVD_STRUCT )
|
|
757 dvd_authinfo auth_info;
|
|
758
|
|
759 memset( &auth_info, 0, sizeof( auth_info ) );
|
|
760 auth_info.type = DVD_LU_SEND_CHALLENGE;
|
|
761 auth_info.lsc.agid = *pi_agid;
|
|
762
|
|
763 i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
|
|
764
|
|
765 memcpy( p_challenge, auth_info.lsc.chal, DVD_CHALLENGE_SIZE );
|
|
766
|
|
767 #elif defined( HAVE_BSD_DVD_STRUCT )
|
|
768 struct dvd_authinfo auth_info;
|
|
769
|
|
770 memset( &auth_info, 0, sizeof( auth_info ) );
|
|
771 auth_info.format = DVD_REPORT_CHALLENGE;
|
|
772 auth_info.agid = *pi_agid;
|
|
773
|
|
774 i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );
|
|
775
|
|
776 memcpy( p_challenge, auth_info.keychal, DVD_CHALLENGE_SIZE );
|
|
777
|
|
778 #elif defined( SYS_BEOS )
|
|
779 INIT_RDC( GPCMD_REPORT_KEY, 16 );
|
|
780
|
|
781 rdc.command[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
|
|
782
|
|
783 i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
|
|
784
|
|
785 memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
|
|
786
|
|
787 #elif defined( HPUX_SCTL_IO )
|
|
788 INIT_SCTL_IO( GPCMD_REPORT_KEY, 16 );
|
|
789
|
|
790 sctl_io.cdb[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
|
|
791
|
|
792 i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
|
|
793
|
|
794 memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
|
|
795
|
|
796 #elif defined( SOLARIS_USCSI )
|
|
797 INIT_USCSI( GPCMD_REPORT_KEY, 16 );
|
|
798
|
|
799 rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
|
|
800
|
|
801 i_ret = ioctl( i_fd, USCSICMD, &sc );
|
|
802
|
|
803 if( i_ret < 0 || sc.uscsi_status )
|
|
804 {
|
|
805 i_ret = -1;
|
|
806 }
|
|
807
|
|
808 memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
|
|
809
|
|
810 #elif defined( DARWIN_DVD_IOCTL )
|
|
811 INIT_DVDIOCTL( dk_dvd_report_key_t, DVDChallengeKeyInfo,
|
|
812 kDVDKeyFormatChallengeKey );
|
|
813
|
|
814 dvd.grantID = *pi_agid;
|
|
815
|
|
816 i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
|
|
817
|
|
818 memcpy( p_challenge, dvdbs.challengeKeyValue, DVD_CHALLENGE_SIZE );
|
|
819
|
|
820 #elif defined( WIN32 )
|
|
821 if( WIN2K ) /* NT/Win2000/Whistler */
|
|
822 {
|
|
823 DWORD tmp;
|
|
824 u8 buffer[DVD_CHALLENGE_KEY_LENGTH];
|
|
825 PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
|
|
826
|
|
827 memset( &buffer, 0, sizeof( buffer ) );
|
|
828
|
|
829 key->KeyLength = DVD_CHALLENGE_KEY_LENGTH;
|
|
830 key->SessionId = *pi_agid;
|
|
831 key->KeyType = DvdChallengeKey;
|
|
832 key->KeyFlags = 0;
|
|
833
|
|
834 i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
|
|
835 key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
|
|
836
|
|
837 if( i_ret < 0 )
|
|
838 {
|
|
839 return i_ret;
|
|
840 }
|
|
841
|
|
842 memcpy( p_challenge, key->KeyData, DVD_CHALLENGE_SIZE );
|
|
843 }
|
|
844 else
|
|
845 {
|
|
846 INIT_SSC( GPCMD_REPORT_KEY, 16 );
|
|
847
|
|
848 ssc.CDBByte[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
|
|
849
|
|
850 i_ret = WinSendSSC( i_fd, &ssc );
|
|
851
|
|
852 memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
|
|
853 }
|
|
854
|
|
855 #elif defined( __QNXNTO__ )
|
|
856
|
|
857 INIT_CPT( GPCMD_REPORT_KEY, 16 );
|
|
858
|
|
859 p_cpt->cam_cdb[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
|
|
860
|
|
861 i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
|
|
862
|
|
863 memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
|
|
864
|
|
865 #elif defined( SYS_OS2 )
|
|
866 INIT_SSC( GPCMD_REPORT_KEY, 16 );
|
|
867
|
|
868 sdc.command[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
|
|
869
|
|
870 i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
|
|
871 &sdc, sizeof(sdc), &ulParamLen,
|
|
872 p_buffer, sizeof(p_buffer), &ulDataLen);
|
|
873
|
|
874 memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
|
|
875
|
|
876 #else
|
|
877 # error "DVD ioctls are unavailable on this system"
|
|
878
|
|
879 #endif
|
|
880 return i_ret;
|
|
881 }
|
|
882
|
|
883 /*****************************************************************************
|
|
884 * ioctl_ReportASF: get ASF from the drive
|
|
885 *****************************************************************************/
|
|
886 int ioctl_ReportASF( int i_fd, int *pi_remove_me, int *pi_asf )
|
|
887 {
|
|
888 int i_ret;
|
|
889
|
|
890 #if defined( HAVE_LINUX_DVD_STRUCT )
|
|
891 dvd_authinfo auth_info;
|
|
892
|
|
893 memset( &auth_info, 0, sizeof( auth_info ) );
|
|
894 auth_info.type = DVD_LU_SEND_ASF;
|
|
895 auth_info.lsasf.asf = *pi_asf;
|
|
896
|
|
897 i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
|
|
898
|
|
899 *pi_asf = auth_info.lsasf.asf;
|
|
900
|
|
901 #elif defined( HAVE_BSD_DVD_STRUCT )
|
|
902 struct dvd_authinfo auth_info;
|
|
903
|
|
904 memset( &auth_info, 0, sizeof( auth_info ) );
|
|
905 auth_info.format = DVD_REPORT_ASF;
|
|
906 auth_info.asf = *pi_asf;
|
|
907
|
|
908 i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );
|
|
909
|
|
910 *pi_asf = auth_info.asf;
|
|
911
|
|
912 #elif defined( SYS_BEOS )
|
|
913 INIT_RDC( GPCMD_REPORT_KEY, 8 );
|
|
914
|
|
915 rdc.command[ 10 ] = DVD_REPORT_ASF;
|
|
916
|
|
917 i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
|
|
918
|
|
919 *pi_asf = p_buffer[ 7 ] & 1;
|
|
920
|
|
921 #elif defined( HPUX_SCTL_IO )
|
|
922 INIT_SCTL_IO( GPCMD_REPORT_KEY, 8 );
|
|
923
|
|
924 sctl_io.cdb[ 10 ] = DVD_REPORT_ASF;
|
|
925
|
|
926 i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
|
|
927
|
|
928 *pi_asf = p_buffer[ 7 ] & 1;
|
|
929
|
|
930 #elif defined( SOLARIS_USCSI )
|
|
931 INIT_USCSI( GPCMD_REPORT_KEY, 8 );
|
|
932
|
|
933 rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_ASF;
|
|
934
|
|
935 i_ret = ioctl( i_fd, USCSICMD, &sc );
|
|
936
|
|
937 if( i_ret < 0 || sc.uscsi_status )
|
|
938 {
|
|
939 i_ret = -1;
|
|
940 }
|
|
941
|
|
942 *pi_asf = p_buffer[ 7 ] & 1;
|
|
943
|
|
944 #elif defined( DARWIN_DVD_IOCTL )
|
|
945 INIT_DVDIOCTL( dk_dvd_report_key_t, DVDAuthenticationSuccessFlagInfo,
|
|
946 kDVDKeyFormatASF );
|
|
947
|
|
948 i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
|
|
949
|
|
950 *pi_asf = dvdbs.successFlag;
|
|
951
|
|
952 #elif defined( WIN32 )
|
|
953 if( WIN2K ) /* NT/Win2000/Whistler */
|
|
954 {
|
|
955 DWORD tmp;
|
|
956 u8 buffer[DVD_ASF_LENGTH];
|
|
957 PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
|
|
958
|
|
959 memset( &buffer, 0, sizeof( buffer ) );
|
|
960
|
|
961 key->KeyLength = DVD_ASF_LENGTH;
|
|
962 key->KeyType = DvdAsf;
|
|
963 key->KeyFlags = 0;
|
|
964
|
|
965 ((PDVD_ASF)key->KeyData)->SuccessFlag = *pi_asf;
|
|
966
|
|
967 i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
|
|
968 key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
|
|
969
|
|
970 if( i_ret < 0 )
|
|
971 {
|
|
972 return i_ret;
|
|
973 }
|
|
974
|
|
975 *pi_asf = ((PDVD_ASF)key->KeyData)->SuccessFlag;
|
|
976 }
|
|
977 else
|
|
978 {
|
|
979 INIT_SSC( GPCMD_REPORT_KEY, 8 );
|
|
980
|
|
981 ssc.CDBByte[ 10 ] = DVD_REPORT_ASF;
|
|
982
|
|
983 i_ret = WinSendSSC( i_fd, &ssc );
|
|
984
|
|
985 *pi_asf = p_buffer[ 7 ] & 1;
|
|
986 }
|
|
987
|
|
988 #elif defined( __QNXNTO__ )
|
|
989
|
|
990 INIT_CPT( GPCMD_REPORT_KEY, 8 );
|
|
991
|
|
992 p_cpt->cam_cdb[ 10 ] = DVD_REPORT_ASF;
|
|
993
|
|
994 i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
|
|
995
|
|
996 *pi_asf = p_buffer[ 7 ] & 1;
|
|
997
|
|
998 #elif defined( SYS_OS2 )
|
|
999 INIT_SSC( GPCMD_REPORT_KEY, 8 );
|
|
1000
|
|
1001 sdc.command[ 10 ] = DVD_REPORT_ASF;
|
|
1002
|
|
1003 i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
|
|
1004 &sdc, sizeof(sdc), &ulParamLen,
|
|
1005 p_buffer, sizeof(p_buffer), &ulDataLen);
|
|
1006
|
|
1007 *pi_asf = p_buffer[ 7 ] & 1;
|
|
1008
|
|
1009 #else
|
|
1010 # error "DVD ioctls are unavailable on this system"
|
|
1011
|
|
1012 #endif
|
|
1013 return i_ret;
|
|
1014 }
|
|
1015
|
|
1016 /*****************************************************************************
|
|
1017 * ioctl_ReportKey1: get the first key from the drive
|
|
1018 *****************************************************************************/
|
|
1019 int ioctl_ReportKey1( int i_fd, int *pi_agid, u8 *p_key )
|
|
1020 {
|
|
1021 int i_ret;
|
|
1022
|
|
1023 #if defined( HAVE_LINUX_DVD_STRUCT )
|
|
1024 dvd_authinfo auth_info;
|
|
1025
|
|
1026 memset( &auth_info, 0, sizeof( auth_info ) );
|
|
1027 auth_info.type = DVD_LU_SEND_KEY1;
|
|
1028 auth_info.lsk.agid = *pi_agid;
|
|
1029
|
|
1030 i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
|
|
1031
|
|
1032 memcpy( p_key, auth_info.lsk.key, DVD_KEY_SIZE );
|
|
1033
|
|
1034 #elif defined( HAVE_BSD_DVD_STRUCT )
|
|
1035 struct dvd_authinfo auth_info;
|
|
1036
|
|
1037 memset( &auth_info, 0, sizeof( auth_info ) );
|
|
1038 auth_info.format = DVD_REPORT_KEY1;
|
|
1039 auth_info.agid = *pi_agid;
|
|
1040
|
|
1041 i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );
|
|
1042
|
|
1043 memcpy( p_key, auth_info.keychal, DVD_KEY_SIZE );
|
|
1044
|
|
1045 #elif defined( SYS_BEOS )
|
|
1046 INIT_RDC( GPCMD_REPORT_KEY, 12 );
|
|
1047
|
|
1048 rdc.command[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6);
|
|
1049
|
|
1050 i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
|
|
1051
|
|
1052 memcpy( p_key, p_buffer + 4, DVD_KEY_SIZE );
|
|
1053
|
|
1054 #elif defined( HPUX_SCTL_IO )
|
|
1055 INIT_SCTL_IO( GPCMD_REPORT_KEY, 12 );
|
|
1056
|
|
1057 sctl_io.cdb[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6);
|
|
1058
|
|
1059 i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
|
|
1060
|
|
1061 memcpy( p_key, p_buffer + 4, DVD_KEY_SIZE );
|
|
1062
|
|
1063 #elif defined( SOLARIS_USCSI )
|
|
1064 INIT_USCSI( GPCMD_REPORT_KEY, 12 );
|
|
1065
|
|
1066 rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6);
|
|
1067
|
|
1068 i_ret = ioctl( i_fd, USCSICMD, &sc );
|
|
1069
|
|
1070 if( i_ret < 0 || sc.uscsi_status )
|
|
1071 {
|
|
1072 i_ret = -1;
|
|
1073 }
|
|
1074
|
|
1075 memcpy( p_key, p_buffer + 4, DVD_KEY_SIZE );
|
|
1076
|
|
1077 #elif defined( DARWIN_DVD_IOCTL )
|
|
1078 INIT_DVDIOCTL( dk_dvd_report_key_t, DVDKey1Info,
|
|
1079 kDVDKeyFormatKey1 );
|
|
1080
|
|
1081 dvd.grantID = *pi_agid;
|
|
1082
|
|
1083 i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
|
|
1084
|
|
1085 memcpy( p_key, dvdbs.key1Value, DVD_KEY_SIZE );
|
|
1086
|
|
1087 #elif defined( WIN32 )
|
|
1088 if( WIN2K ) /* NT/Win2000/Whistler */
|
|
1089 {
|
|
1090 DWORD tmp;
|
|
1091 u8 buffer[DVD_BUS_KEY_LENGTH];
|
|
1092 PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
|
|
1093
|
|
1094 memset( &buffer, 0, sizeof( buffer ) );
|
|
1095
|
|
1096 key->KeyLength = DVD_BUS_KEY_LENGTH;
|
|
1097 key->SessionId = *pi_agid;
|
|
1098 key->KeyType = DvdBusKey1;
|
|
1099 key->KeyFlags = 0;
|
|
1100
|
|
1101 i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
|
|
1102 key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
|
|
1103
|
|
1104 memcpy( p_key, key->KeyData, DVD_KEY_SIZE );
|
|
1105 }
|
|
1106 else
|
|
1107 {
|
|
1108 INIT_SSC( GPCMD_REPORT_KEY, 12 );
|
|
1109
|
|
1110 ssc.CDBByte[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6);
|
|
1111
|
|
1112 i_ret = WinSendSSC( i_fd, &ssc );
|
|
1113
|
|
1114 memcpy( p_key, p_buffer + 4, DVD_KEY_SIZE );
|
|
1115 }
|
|
1116
|
|
1117 #elif defined( __QNXNTO__ )
|
|
1118
|
|
1119 INIT_CPT( GPCMD_REPORT_KEY, 12 );
|
|
1120
|
|
1121 p_cpt->cam_cdb[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6);
|
|
1122
|
|
1123 i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
|
|
1124
|
|
1125 memcpy( p_key, p_buffer + 4, DVD_KEY_SIZE );
|
|
1126
|
|
1127 #elif defined( SYS_OS2 )
|
|
1128 INIT_SSC( GPCMD_REPORT_KEY, 12 );
|
|
1129
|
|
1130 sdc.command[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6);
|
|
1131
|
|
1132 i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
|
|
1133 &sdc, sizeof(sdc), &ulParamLen,
|
|
1134 p_buffer, sizeof(p_buffer), &ulDataLen);
|
|
1135
|
|
1136 memcpy( p_key, p_buffer + 4, DVD_KEY_SIZE );
|
|
1137
|
|
1138 #else
|
|
1139 # error "DVD ioctls are unavailable on this system"
|
|
1140
|
|
1141 #endif
|
|
1142 return i_ret;
|
|
1143 }
|
|
1144
|
|
1145 /*****************************************************************************
|
|
1146 * ioctl_InvalidateAgid: invalidate the current AGID
|
|
1147 *****************************************************************************/
|
|
1148 int ioctl_InvalidateAgid( int i_fd, int *pi_agid )
|
|
1149 {
|
|
1150 int i_ret;
|
|
1151
|
|
1152 #if defined( HAVE_LINUX_DVD_STRUCT )
|
|
1153 dvd_authinfo auth_info;
|
|
1154
|
|
1155 memset( &auth_info, 0, sizeof( auth_info ) );
|
|
1156 auth_info.type = DVD_INVALIDATE_AGID;
|
|
1157 auth_info.lsa.agid = *pi_agid;
|
|
1158
|
|
1159 i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
|
|
1160
|
|
1161 #elif defined( HAVE_BSD_DVD_STRUCT )
|
|
1162 struct dvd_authinfo auth_info;
|
|
1163
|
|
1164 memset( &auth_info, 0, sizeof( auth_info ) );
|
|
1165 auth_info.format = DVD_INVALIDATE_AGID;
|
|
1166 auth_info.agid = *pi_agid;
|
|
1167
|
|
1168 i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );
|
|
1169
|
|
1170 #elif defined( SYS_BEOS )
|
|
1171 INIT_RDC( GPCMD_REPORT_KEY, 0 );
|
|
1172
|
|
1173 rdc.command[ 10 ] = DVD_INVALIDATE_AGID | (*pi_agid << 6);
|
|
1174
|
|
1175 i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
|
|
1176
|
|
1177 #elif defined( HPUX_SCTL_IO )
|
|
1178 INIT_SCTL_IO( GPCMD_REPORT_KEY, 0 );
|
|
1179
|
|
1180 sctl_io.cdb[ 10 ] = DVD_INVALIDATE_AGID | (*pi_agid << 6);
|
|
1181
|
|
1182 i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
|
|
1183
|
|
1184 #elif defined( SOLARIS_USCSI )
|
|
1185 INIT_USCSI( GPCMD_REPORT_KEY, 0 );
|
|
1186
|
|
1187 rs_cdb.cdb_opaque[ 10 ] = DVD_INVALIDATE_AGID | (*pi_agid << 6);
|
|
1188
|
|
1189 i_ret = ioctl( i_fd, USCSICMD, &sc );
|
|
1190
|
|
1191 if( i_ret < 0 || sc.uscsi_status )
|
|
1192 {
|
|
1193 i_ret = -1;
|
|
1194 }
|
|
1195
|
|
1196 #elif defined( DARWIN_DVD_IOCTL )
|
|
1197 INIT_DVDIOCTL( dk_dvd_send_key_t, DVDAuthenticationGrantIDInfo,
|
|
1198 kDVDKeyFormatAGID_Invalidate );
|
|
1199
|
|
1200 dvd.grantID = *pi_agid;
|
|
1201
|
|
1202 i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
|
|
1203
|
|
1204 #elif defined( WIN32 )
|
|
1205 if( WIN2K ) /* NT/Win2000/Whistler */
|
|
1206 {
|
|
1207 DWORD tmp;
|
|
1208
|
|
1209 i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_END_SESSION,
|
|
1210 pi_agid, sizeof( *pi_agid ), NULL, 0, &tmp, NULL ) ? 0 : -1;
|
|
1211 }
|
|
1212 else
|
|
1213 {
|
|
1214 #if defined( __MINGW32__ )
|
|
1215 INIT_SSC( GPCMD_REPORT_KEY, 0 );
|
|
1216 #else
|
|
1217 INIT_SSC( GPCMD_REPORT_KEY, 1 );
|
|
1218
|
|
1219 ssc.SRB_BufLen = 0;
|
|
1220 ssc.CDBByte[ 8 ] = 0;
|
|
1221 ssc.CDBByte[ 9 ] = 0;
|
|
1222 #endif
|
|
1223
|
|
1224 ssc.CDBByte[ 10 ] = DVD_INVALIDATE_AGID | (*pi_agid << 6);
|
|
1225
|
|
1226 i_ret = WinSendSSC( i_fd, &ssc );
|
|
1227 }
|
|
1228
|
|
1229 #elif defined( __QNXNTO__ )
|
|
1230
|
|
1231 INIT_CPT( GPCMD_REPORT_KEY, 0 );
|
|
1232
|
|
1233 p_cpt->cam_cdb[ 10 ] = DVD_INVALIDATE_AGID | (*pi_agid << 6);
|
|
1234
|
|
1235 i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
|
|
1236
|
|
1237 #elif defined( SYS_OS2 )
|
|
1238 INIT_SSC( GPCMD_REPORT_KEY, 1 );
|
|
1239
|
|
1240 sdc.data_length = 0;
|
|
1241 sdc.command[ 8 ] = 0;
|
|
1242 sdc.command[ 9 ] = 0;
|
|
1243
|
|
1244 sdc.command[ 10 ] = DVD_INVALIDATE_AGID | (*pi_agid << 6);
|
|
1245
|
|
1246 i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
|
|
1247 &sdc, sizeof(sdc), &ulParamLen,
|
|
1248 NULL, 0, &ulDataLen);
|
|
1249 #else
|
|
1250 # error "DVD ioctls are unavailable on this system"
|
|
1251
|
|
1252 #endif
|
|
1253 return i_ret;
|
|
1254 }
|
|
1255
|
|
1256 /*****************************************************************************
|
|
1257 * ioctl_SendChallenge: send challenge to the drive
|
|
1258 *****************************************************************************/
|
|
1259 int ioctl_SendChallenge( int i_fd, int *pi_agid, u8 *p_challenge )
|
|
1260 {
|
|
1261 int i_ret;
|
|
1262
|
|
1263 #if defined( HAVE_LINUX_DVD_STRUCT )
|
|
1264 dvd_authinfo auth_info;
|
|
1265
|
|
1266 memset( &auth_info, 0, sizeof( auth_info ) );
|
|
1267 auth_info.type = DVD_HOST_SEND_CHALLENGE;
|
|
1268 auth_info.hsc.agid = *pi_agid;
|
|
1269
|
|
1270 memcpy( auth_info.hsc.chal, p_challenge, DVD_CHALLENGE_SIZE );
|
|
1271
|
|
1272 return ioctl( i_fd, DVD_AUTH, &auth_info );
|
|
1273
|
|
1274 #elif defined( HAVE_BSD_DVD_STRUCT )
|
|
1275 struct dvd_authinfo auth_info;
|
|
1276
|
|
1277 memset( &auth_info, 0, sizeof( auth_info ) );
|
|
1278 auth_info.format = DVD_SEND_CHALLENGE;
|
|
1279 auth_info.agid = *pi_agid;
|
|
1280
|
|
1281 memcpy( auth_info.keychal, p_challenge, DVD_CHALLENGE_SIZE );
|
|
1282
|
|
1283 return ioctl( i_fd, DVDIOCSENDKEY, &auth_info );
|
|
1284
|
|
1285 #elif defined( SYS_BEOS )
|
|
1286 INIT_RDC( GPCMD_SEND_KEY, 16 );
|
|
1287
|
|
1288 rdc.command[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
|
|
1289
|
|
1290 p_buffer[ 1 ] = 0xe;
|
|
1291 memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
|
|
1292
|
|
1293 return ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
|
|
1294
|
|
1295 #elif defined( HPUX_SCTL_IO )
|
|
1296 INIT_SCTL_IO( GPCMD_SEND_KEY, 16 );
|
|
1297
|
|
1298 sctl_io.cdb[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
|
|
1299
|
|
1300 p_buffer[ 1 ] = 0xe;
|
|
1301 memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
|
|
1302
|
|
1303 return ioctl( i_fd, SIOC_IO, &sctl_io );
|
|
1304
|
|
1305 #elif defined( SOLARIS_USCSI )
|
|
1306 INIT_USCSI( GPCMD_SEND_KEY, 16 );
|
|
1307
|
|
1308 rs_cdb.cdb_opaque[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
|
|
1309
|
|
1310 p_buffer[ 1 ] = 0xe;
|
|
1311 memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
|
|
1312
|
|
1313 if( ioctl( i_fd, USCSICMD, &sc ) < 0 || sc.uscsi_status )
|
|
1314 {
|
|
1315 return -1;
|
|
1316 }
|
|
1317
|
|
1318 return 0;
|
|
1319
|
|
1320 #elif defined( DARWIN_DVD_IOCTL )
|
|
1321 INIT_DVDIOCTL( dk_dvd_send_key_t, DVDChallengeKeyInfo,
|
|
1322 kDVDKeyFormatChallengeKey );
|
|
1323
|
|
1324 dvd.grantID = *pi_agid;
|
|
1325 dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
|
|
1326
|
|
1327 dvdbs.dataLength[ 1 ] = 0xe;
|
|
1328 memcpy( dvdbs.challengeKeyValue, p_challenge, DVD_CHALLENGE_SIZE );
|
|
1329
|
|
1330 i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
|
|
1331
|
|
1332 #elif defined( WIN32 )
|
|
1333 if( WIN2K ) /* NT/Win2000/Whistler */
|
|
1334 {
|
|
1335 DWORD tmp;
|
|
1336 u8 buffer[DVD_CHALLENGE_KEY_LENGTH];
|
|
1337 PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
|
|
1338
|
|
1339 memset( &buffer, 0, sizeof( buffer ) );
|
|
1340
|
|
1341 key->KeyLength = DVD_CHALLENGE_KEY_LENGTH;
|
|
1342 key->SessionId = *pi_agid;
|
|
1343 key->KeyType = DvdChallengeKey;
|
|
1344 key->KeyFlags = 0;
|
|
1345
|
|
1346 memcpy( key->KeyData, p_challenge, DVD_CHALLENGE_SIZE );
|
|
1347
|
|
1348 return DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_SEND_KEY, key,
|
|
1349 key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
|
|
1350 }
|
|
1351 else
|
|
1352 {
|
|
1353 INIT_SSC( GPCMD_SEND_KEY, 16 );
|
|
1354
|
|
1355 ssc.CDBByte[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
|
|
1356
|
|
1357 p_buffer[ 1 ] = 0xe;
|
|
1358 memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
|
|
1359
|
|
1360 return WinSendSSC( i_fd, &ssc );
|
|
1361 }
|
|
1362
|
|
1363 #elif defined( __QNXNTO__ )
|
|
1364
|
|
1365 INIT_CPT( GPCMD_SEND_KEY, 16 );
|
|
1366
|
|
1367 p_cpt->cam_cdb[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
|
|
1368
|
|
1369 p_buffer[ 1 ] = 0xe;
|
|
1370 memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
|
|
1371
|
|
1372 i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
|
|
1373
|
|
1374 #elif defined( SYS_OS2 )
|
|
1375 INIT_SSC( GPCMD_SEND_KEY, 16 );
|
|
1376
|
|
1377 sdc.command[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
|
|
1378
|
|
1379 p_buffer[ 1 ] = 0xe;
|
|
1380 memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
|
|
1381
|
|
1382 return DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
|
|
1383 &sdc, sizeof(sdc), &ulParamLen,
|
|
1384 p_buffer, sizeof(p_buffer), &ulDataLen);
|
|
1385
|
|
1386 #else
|
|
1387 # error "DVD ioctls are unavailable on this system"
|
|
1388
|
|
1389 #endif
|
|
1390 return i_ret;
|
|
1391 }
|
|
1392
|
|
1393 /*****************************************************************************
|
|
1394 * ioctl_SendKey2: send the second key to the drive
|
|
1395 *****************************************************************************/
|
|
1396 int ioctl_SendKey2( int i_fd, int *pi_agid, u8 *p_key )
|
|
1397 {
|
|
1398 int i_ret;
|
|
1399
|
|
1400 #if defined( HAVE_LINUX_DVD_STRUCT )
|
|
1401 dvd_authinfo auth_info;
|
|
1402
|
|
1403 memset( &auth_info, 0, sizeof( auth_info ) );
|
|
1404 auth_info.type = DVD_HOST_SEND_KEY2;
|
|
1405 auth_info.hsk.agid = *pi_agid;
|
|
1406
|
|
1407 memcpy( auth_info.hsk.key, p_key, DVD_KEY_SIZE );
|
|
1408
|
|
1409 return ioctl( i_fd, DVD_AUTH, &auth_info );
|
|
1410
|
|
1411 #elif defined( HAVE_BSD_DVD_STRUCT )
|
|
1412 struct dvd_authinfo auth_info;
|
|
1413
|
|
1414 memset( &auth_info, 0, sizeof( auth_info ) );
|
|
1415 auth_info.format = DVD_SEND_KEY2;
|
|
1416 auth_info.agid = *pi_agid;
|
|
1417
|
|
1418 memcpy( auth_info.keychal, p_key, DVD_KEY_SIZE );
|
|
1419
|
|
1420 return ioctl( i_fd, DVDIOCSENDKEY, &auth_info );
|
|
1421
|
|
1422 #elif defined( SYS_BEOS )
|
|
1423 INIT_RDC( GPCMD_SEND_KEY, 12 );
|
|
1424
|
|
1425 rdc.command[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
|
|
1426
|
|
1427 p_buffer[ 1 ] = 0xa;
|
|
1428 memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
|
|
1429
|
|
1430 return ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
|
|
1431
|
|
1432 #elif defined( HPUX_SCTL_IO )
|
|
1433 INIT_SCTL_IO( GPCMD_SEND_KEY, 12 );
|
|
1434
|
|
1435 sctl_io.cdb[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
|
|
1436
|
|
1437 p_buffer[ 1 ] = 0xa;
|
|
1438 memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
|
|
1439
|
|
1440 return ioctl( i_fd, SIOC_IO, &sctl_io );
|
|
1441
|
|
1442 #elif defined( SOLARIS_USCSI )
|
|
1443 INIT_USCSI( GPCMD_SEND_KEY, 12 );
|
|
1444
|
|
1445 rs_cdb.cdb_opaque[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
|
|
1446
|
|
1447 p_buffer[ 1 ] = 0xa;
|
|
1448 memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
|
|
1449
|
|
1450 if( ioctl( i_fd, USCSICMD, &sc ) < 0 || sc.uscsi_status )
|
|
1451 {
|
|
1452 return -1;
|
|
1453 }
|
|
1454
|
|
1455 return 0;
|
|
1456
|
|
1457 #elif defined( DARWIN_DVD_IOCTL )
|
|
1458 INIT_DVDIOCTL( dk_dvd_send_key_t, DVDKey2Info,
|
|
1459 kDVDKeyFormatKey2 );
|
|
1460
|
|
1461 dvd.grantID = *pi_agid;
|
|
1462 dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
|
|
1463
|
|
1464 dvdbs.dataLength[ 1 ] = 0xa;
|
|
1465 memcpy( dvdbs.key2Value, p_key, DVD_KEY_SIZE );
|
|
1466
|
|
1467 i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
|
|
1468
|
|
1469 #elif defined( WIN32 )
|
|
1470 if( WIN2K ) /* NT/Win2000/Whistler */
|
|
1471 {
|
|
1472 DWORD tmp;
|
|
1473 u8 buffer[DVD_BUS_KEY_LENGTH];
|
|
1474 PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
|
|
1475
|
|
1476 memset( &buffer, 0, sizeof( buffer ) );
|
|
1477
|
|
1478 key->KeyLength = DVD_BUS_KEY_LENGTH;
|
|
1479 key->SessionId = *pi_agid;
|
|
1480 key->KeyType = DvdBusKey2;
|
|
1481 key->KeyFlags = 0;
|
|
1482
|
|
1483 memcpy( key->KeyData, p_key, DVD_KEY_SIZE );
|
|
1484
|
|
1485 return DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_SEND_KEY, key,
|
|
1486 key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
|
|
1487 }
|
|
1488 else
|
|
1489 {
|
|
1490 INIT_SSC( GPCMD_SEND_KEY, 12 );
|
|
1491
|
|
1492 ssc.CDBByte[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
|
|
1493
|
|
1494 p_buffer[ 1 ] = 0xa;
|
|
1495 memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
|
|
1496
|
|
1497 return WinSendSSC( i_fd, &ssc );
|
|
1498 }
|
|
1499
|
|
1500 #elif defined( __QNXNTO__ )
|
|
1501
|
|
1502 INIT_CPT( GPCMD_SEND_KEY, 12 );
|
|
1503
|
|
1504 p_cpt->cam_cdb[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
|
|
1505
|
|
1506 p_buffer[ 1 ] = 0xa;
|
|
1507 memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
|
|
1508
|
|
1509 i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
|
|
1510
|
|
1511 #elif defined( SYS_OS2 )
|
|
1512 INIT_SSC( GPCMD_SEND_KEY, 12 );
|
|
1513
|
|
1514 sdc.command[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
|
|
1515
|
|
1516 p_buffer[ 1 ] = 0xa;
|
|
1517 memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
|
|
1518
|
|
1519 return DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
|
|
1520 &sdc, sizeof(sdc), &ulParamLen,
|
|
1521 p_buffer, sizeof(p_buffer), &ulDataLen);
|
|
1522
|
|
1523 #else
|
|
1524 # error "DVD ioctls are unavailable on this system"
|
|
1525
|
|
1526 #endif
|
|
1527 return i_ret;
|
|
1528 }
|
|
1529
|
|
1530 /*****************************************************************************
|
|
1531 * ioctl_ReportRPC: get RPC status for the drive
|
|
1532 *****************************************************************************/
|
|
1533 int ioctl_ReportRPC( int i_fd, int *p_type, int *p_mask, int *p_scheme )
|
|
1534 {
|
|
1535 int i_ret;
|
|
1536
|
|
1537 #if defined( HAVE_LINUX_DVD_STRUCT ) && defined( DVD_LU_SEND_RPC_STATE )
|
|
1538 dvd_authinfo auth_info;
|
|
1539
|
|
1540 memset( &auth_info, 0, sizeof( auth_info ) );
|
|
1541 auth_info.type = DVD_LU_SEND_RPC_STATE;
|
|
1542
|
|
1543 i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
|
|
1544
|
|
1545 *p_type = auth_info.lrpcs.type;
|
|
1546 *p_mask = auth_info.lrpcs.region_mask;
|
|
1547 *p_scheme = auth_info.lrpcs.rpc_scheme;
|
|
1548
|
|
1549 #elif defined( HAVE_LINUX_DVD_STRUCT )
|
|
1550 /* FIXME: OpenBSD doesn't know this */
|
|
1551 i_ret = -1;
|
|
1552
|
|
1553 #elif defined( HAVE_BSD_DVD_STRUCT )
|
|
1554 struct dvd_authinfo auth_info;
|
|
1555
|
|
1556 memset( &auth_info, 0, sizeof( auth_info ) );
|
|
1557 auth_info.format = DVD_REPORT_RPC;
|
|
1558
|
|
1559 i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );
|
|
1560
|
|
1561 *p_type = auth_info.reg_type;
|
|
1562 *p_mask = auth_info.region; // ??
|
|
1563 *p_scheme = auth_info.rpc_scheme;
|
|
1564
|
|
1565 #elif defined( SYS_BEOS )
|
|
1566 INIT_RDC( GPCMD_REPORT_KEY, 8 );
|
|
1567
|
|
1568 rdc.command[ 10 ] = DVD_REPORT_RPC;
|
|
1569
|
|
1570 i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
|
|
1571
|
|
1572 *p_type = p_buffer[ 4 ] >> 6;
|
|
1573 *p_mask = p_buffer[ 5 ];
|
|
1574 *p_scheme = p_buffer[ 6 ];
|
|
1575
|
|
1576 #elif defined( HPUX_SCTL_IO )
|
|
1577 INIT_SCTL_IO( GPCMD_REPORT_KEY, 8 );
|
|
1578
|
|
1579 sctl_io.cdb[ 10 ] = DVD_REPORT_RPC;
|
|
1580
|
|
1581 i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
|
|
1582
|
|
1583 *p_type = p_buffer[ 4 ] >> 6;
|
|
1584 *p_mask = p_buffer[ 5 ];
|
|
1585 *p_scheme = p_buffer[ 6 ];
|
|
1586
|
|
1587 #elif defined( SOLARIS_USCSI )
|
|
1588 INIT_USCSI( GPCMD_REPORT_KEY, 8 );
|
|
1589
|
|
1590 rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_RPC;
|
|
1591
|
|
1592 i_ret = ioctl( i_fd, USCSICMD, &sc );
|
|
1593
|
|
1594 if( i_ret < 0 || sc.uscsi_status )
|
|
1595 {
|
|
1596 i_ret = -1;
|
|
1597 }
|
|
1598
|
|
1599 *p_type = p_buffer[ 4 ] >> 6;
|
|
1600 *p_mask = p_buffer[ 5 ];
|
|
1601 *p_scheme = p_buffer[ 6 ];
|
|
1602
|
|
1603 #elif defined( DARWIN_DVD_IOCTL )
|
|
1604 INIT_DVDIOCTL( dk_dvd_report_key_t, DVDRegionPlaybackControlInfo,
|
|
1605 kDVDKeyFormatRegionState );
|
|
1606
|
|
1607 dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
|
|
1608
|
|
1609 i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
|
|
1610
|
|
1611 *p_type = dvdbs.typeCode;
|
|
1612 *p_mask = dvdbs.driveRegion;
|
|
1613 *p_scheme = dvdbs.rpcScheme;
|
|
1614
|
|
1615 #elif defined( WIN32 )
|
|
1616 if( WIN2K ) /* NT/Win2000/Whistler */
|
|
1617 {
|
|
1618 DWORD tmp;
|
|
1619 u8 buffer[ DVD_REGION_LENGTH ];
|
|
1620 PDVD_REGION region = (PDVD_REGION) &buffer;
|
|
1621
|
|
1622 memset( &buffer, 0, sizeof( buffer ) );
|
|
1623
|
|
1624 i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_GET_REGION, NULL, 0,
|
|
1625 region, DVD_REGION_LENGTH, &tmp, NULL ) ? 0 : -1;
|
|
1626
|
|
1627 /* Someone who has the headers should correct all this. */
|
|
1628 /* Use the IOCTL_SCSI_PASS_THROUGH_DIRECT so we get the real
|
|
1629 * values of theses entities? */
|
|
1630 if(region->SystemRegion != 0) {
|
|
1631 *p_type = region->ResetCount > 1 ? 1 : 3 - region->ResetCount;
|
|
1632 *p_mask = 0xff ^ (1 << (region->SystemRegion - 1));
|
|
1633 *p_scheme = 1;
|
|
1634 }
|
|
1635 else
|
|
1636 {
|
|
1637 *p_type = 0; /* ?? */
|
|
1638 *p_mask = 0xff;
|
|
1639 *p_scheme = 1; /* ?? */
|
|
1640 }
|
|
1641 }
|
|
1642 else
|
|
1643 {
|
|
1644 INIT_SSC( GPCMD_REPORT_KEY, 8 );
|
|
1645
|
|
1646 ssc.CDBByte[ 10 ] = DVD_REPORT_RPC;
|
|
1647
|
|
1648 i_ret = WinSendSSC( i_fd, &ssc );
|
|
1649
|
|
1650 *p_type = p_buffer[ 4 ] >> 6;
|
|
1651 *p_mask = p_buffer[ 5 ];
|
|
1652 *p_scheme = p_buffer[ 6 ];
|
|
1653 }
|
|
1654
|
|
1655 #elif defined( __QNXNTO__ )
|
|
1656
|
|
1657 INIT_CPT( GPCMD_REPORT_KEY, 8 );
|
|
1658
|
|
1659 p_cpt->cam_cdb[ 10 ] = DVD_REPORT_RPC;
|
|
1660
|
|
1661 i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
|
|
1662
|
|
1663 *p_type = p_buffer[ 4 ] >> 6;
|
|
1664 *p_mask = p_buffer[ 5 ];
|
|
1665 *p_scheme = p_buffer[ 6 ];
|
|
1666
|
|
1667 #elif defined( SYS_OS2 )
|
|
1668 INIT_SSC( GPCMD_REPORT_KEY, 8 );
|
|
1669
|
|
1670 sdc.command[ 10 ] = DVD_REPORT_RPC;
|
|
1671
|
|
1672 i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
|
|
1673 &sdc, sizeof(sdc), &ulParamLen,
|
|
1674 p_buffer, sizeof(p_buffer), &ulDataLen);
|
|
1675
|
|
1676 *p_type = p_buffer[ 4 ] >> 6;
|
|
1677 *p_mask = p_buffer[ 5 ];
|
|
1678 *p_scheme = p_buffer[ 6 ];
|
|
1679
|
|
1680 #else
|
|
1681 # error "DVD ioctls are unavailable on this system"
|
|
1682
|
|
1683 #endif
|
|
1684 return i_ret;
|
|
1685 }
|
|
1686
|
|
1687 /* Local prototypes */
|
|
1688
|
|
1689 #if defined( SYS_BEOS )
|
|
1690 /*****************************************************************************
|
|
1691 * BeInitRDC: initialize a RDC structure for the BeOS kernel
|
|
1692 *****************************************************************************
|
|
1693 * This function initializes a BeOS raw device command structure for future
|
|
1694 * use, either a read command or a write command.
|
|
1695 *****************************************************************************/
|
|
1696 static void BeInitRDC( raw_device_command *p_rdc, int i_type )
|
|
1697 {
|
|
1698 memset( p_rdc->data, 0, p_rdc->data_length );
|
|
1699
|
|
1700 switch( i_type )
|
|
1701 {
|
|
1702 case GPCMD_SEND_KEY:
|
|
1703 /* leave the flags to 0 */
|
|
1704 break;
|
|
1705
|
|
1706 case GPCMD_READ_DVD_STRUCTURE: case GPCMD_REPORT_KEY:
|
|
1707 p_rdc->flags = B_RAW_DEVICE_DATA_IN; break; }
|
|
1708
|
|
1709 p_rdc->command[ 0 ] = i_type;
|
|
1710
|
|
1711 p_rdc->command[ 8 ] = (p_rdc->data_length >> 8) & 0xff;
|
|
1712 p_rdc->command[ 9 ] = p_rdc->data_length & 0xff;
|
|
1713 p_rdc->command_length = 12;
|
|
1714
|
|
1715 p_rdc->sense_data = NULL;
|
|
1716 p_rdc->sense_data_length = 0;
|
|
1717
|
|
1718 p_rdc->timeout = 1000000;
|
|
1719 }
|
|
1720 #endif
|
|
1721
|
|
1722 #if defined( HPUX_SCTL_IO )
|
|
1723 /*****************************************************************************
|
|
1724 * HPUXInitSCTL: initialize a sctl_io structure for the HP-UX kernel
|
|
1725 *****************************************************************************
|
|
1726 * This function initializes a HP-UX command structure for future
|
|
1727 * use, either a read command or a write command.
|
|
1728 *****************************************************************************/
|
|
1729 static void HPUXInitSCTL( struct sctl_io *sctl_io, int i_type )
|
|
1730 {
|
|
1731 memset( sctl_io->data, 0, sctl_io->data_length );
|
|
1732
|
|
1733 switch( i_type )
|
|
1734 {
|
|
1735 case GPCMD_SEND_KEY:
|
|
1736 /* leave the flags to 0 */
|
|
1737 break;
|
|
1738
|
|
1739 case GPCMD_READ_DVD_STRUCTURE:
|
|
1740 case GPCMD_REPORT_KEY:
|
|
1741 sctl_io->flags = SCTL_READ;
|
|
1742 break;
|
|
1743 }
|
|
1744
|
|
1745 sctl_io->cdb[ 0 ] = i_type;
|
|
1746
|
|
1747 sctl_io->cdb[ 8 ] = (sctl_io->data_length >> 8) & 0xff;
|
|
1748 sctl_io->cdb[ 9 ] = sctl_io->data_length & 0xff;
|
|
1749 sctl_io->cdb_length = 12;
|
|
1750
|
|
1751 sctl_io->max_msecs = 1000000;
|
|
1752 }
|
|
1753 #endif
|
|
1754
|
|
1755 #if defined( SOLARIS_USCSI )
|
|
1756 /*****************************************************************************
|
|
1757 * SolarisInitUSCSI: initialize a USCSICMD structure for the Solaris kernel
|
|
1758 *****************************************************************************
|
|
1759 * This function initializes a Solaris userspace scsi command structure for
|
|
1760 * future use, either a read command or a write command.
|
|
1761 *****************************************************************************/
|
|
1762 static void SolarisInitUSCSI( struct uscsi_cmd *p_sc, int i_type )
|
|
1763 {
|
|
1764 union scsi_cdb *rs_cdb;
|
|
1765 memset( p_sc->uscsi_cdb, 0, sizeof( union scsi_cdb ) );
|
|
1766 memset( p_sc->uscsi_bufaddr, 0, p_sc->uscsi_buflen );
|
|
1767
|
|
1768 switch( i_type )
|
|
1769 {
|
|
1770 case GPCMD_SEND_KEY:
|
|
1771 p_sc->uscsi_flags = USCSI_ISOLATE | USCSI_WRITE;
|
|
1772 break;
|
|
1773
|
|
1774 case GPCMD_READ_DVD_STRUCTURE:
|
|
1775 case GPCMD_REPORT_KEY:
|
|
1776 p_sc->uscsi_flags = USCSI_ISOLATE | USCSI_READ;
|
|
1777 break;
|
|
1778 }
|
|
1779
|
|
1780 rs_cdb = (union scsi_cdb *)p_sc->uscsi_cdb;
|
|
1781
|
|
1782 rs_cdb->scc_cmd = i_type;
|
|
1783
|
|
1784 rs_cdb->cdb_opaque[ 8 ] = (p_sc->uscsi_buflen >> 8) & 0xff;
|
|
1785 rs_cdb->cdb_opaque[ 9 ] = p_sc->uscsi_buflen & 0xff;
|
|
1786 p_sc->uscsi_cdblen = 12;
|
|
1787
|
|
1788 USCSI_TIMEOUT( p_sc, 15 );
|
|
1789 }
|
|
1790 #endif
|
|
1791
|
|
1792 #if defined( WIN32 )
|
|
1793 /*****************************************************************************
|
|
1794 * WinInitSSC: initialize a ssc structure for the win32 aspi layer
|
|
1795 *****************************************************************************
|
|
1796 * This function initializes a ssc raw device command structure for future
|
|
1797 * use, either a read command or a write command.
|
|
1798 *****************************************************************************/
|
|
1799 static void WinInitSSC( struct SRB_ExecSCSICmd *p_ssc, int i_type )
|
|
1800 {
|
|
1801 memset( p_ssc->SRB_BufPointer, 0, p_ssc->SRB_BufLen );
|
|
1802
|
|
1803 switch( i_type )
|
|
1804 {
|
|
1805 case GPCMD_SEND_KEY:
|
|
1806 p_ssc->SRB_Flags = SRB_DIR_OUT;
|
|
1807 break;
|
|
1808
|
|
1809 case GPCMD_READ_DVD_STRUCTURE:
|
|
1810 case GPCMD_REPORT_KEY:
|
|
1811 p_ssc->SRB_Flags = SRB_DIR_IN;
|
|
1812 break;
|
|
1813 }
|
|
1814
|
|
1815 p_ssc->SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
1816 p_ssc->SRB_Flags |= SRB_EVENT_NOTIFY;
|
|
1817
|
|
1818 p_ssc->CDBByte[ 0 ] = i_type;
|
|
1819
|
|
1820 p_ssc->CDBByte[ 8 ] = (u8)(p_ssc->SRB_BufLen >> 8) & 0xff;
|
|
1821 p_ssc->CDBByte[ 9 ] = (u8) p_ssc->SRB_BufLen & 0xff;
|
|
1822 p_ssc->SRB_CDBLen = 12;
|
|
1823
|
|
1824 p_ssc->SRB_SenseLen = SENSE_LEN;
|
|
1825 }
|
|
1826
|
|
1827 /*****************************************************************************
|
|
1828 * WinSendSSC: send a ssc structure to the aspi layer
|
|
1829 *****************************************************************************/
|
|
1830 static int WinSendSSC( int i_fd, struct SRB_ExecSCSICmd *p_ssc )
|
|
1831 {
|
|
1832 HANDLE hEvent = NULL;
|
|
1833 struct w32_aspidev *fd = (struct w32_aspidev *) i_fd;
|
|
1834
|
|
1835 hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
|
|
1836 if( hEvent == NULL )
|
|
1837 {
|
|
1838 return -1;
|
|
1839 }
|
|
1840
|
|
1841 p_ssc->SRB_PostProc = hEvent;
|
|
1842 p_ssc->SRB_HaId = LOBYTE( fd->i_sid );
|
|
1843 p_ssc->SRB_Target = HIBYTE( fd->i_sid );
|
|
1844
|
|
1845 ResetEvent( hEvent );
|
|
1846 if( fd->lpSendCommand( (void*) p_ssc ) == SS_PENDING )
|
|
1847 WaitForSingleObject( hEvent, INFINITE );
|
|
1848
|
|
1849 CloseHandle( hEvent );
|
|
1850
|
|
1851 return p_ssc->SRB_Status == SS_COMP ? 0 : -1;
|
|
1852 }
|
|
1853 #endif
|
|
1854
|
|
1855 #if defined( __QNXNTO__ )
|
|
1856 /*****************************************************************************
|
|
1857 * QNXInitCPT: initialize a ssc structure for the win32 aspi layer
|
|
1858 *****************************************************************************
|
|
1859 * This function initializes a ssc raw device command structure for future
|
|
1860 * use, either a read command or a write command.
|
|
1861 *****************************************************************************/
|
|
1862 static void QNXInitCPT( CAM_PASS_THRU * p_cpt, int i_type )
|
|
1863 {
|
|
1864 switch( i_type )
|
|
1865 {
|
|
1866 case GPCMD_SEND_KEY:
|
|
1867 p_cpt->cam_flags = CAM_DIR_OUT;
|
|
1868 break;
|
|
1869
|
|
1870 case GPCMD_READ_DVD_STRUCTURE:
|
|
1871 case GPCMD_REPORT_KEY:
|
|
1872 p_cpt->cam_flags = CAM_DIR_IN;
|
|
1873 break;
|
|
1874 }
|
|
1875
|
|
1876 p_cpt->cam_cdb[0] = i_type;
|
|
1877
|
|
1878 p_cpt->cam_cdb[ 8 ] = (p_cpt->cam_dxfer_len >> 8) & 0xff;
|
|
1879 p_cpt->cam_cdb[ 9 ] = p_cpt->cam_dxfer_len & 0xff;
|
|
1880 p_cpt->cam_cdb_len = 12;
|
|
1881
|
|
1882 p_cpt->cam_timeout = CAM_TIME_DEFAULT;
|
|
1883 }
|
|
1884 #endif
|
|
1885
|
|
1886 #if defined( SYS_OS2 )
|
|
1887 /*****************************************************************************
|
|
1888 * OS2InitSDC: initialize a SDC structure for the Execute SCSI-command
|
|
1889 *****************************************************************************
|
|
1890 * This function initializes a OS2 'execute SCSI command' structure for
|
|
1891 * future use, either a read command or a write command.
|
|
1892 *****************************************************************************/
|
|
1893 static void OS2InitSDC( struct OS2_ExecSCSICmd *p_sdc, int i_type )
|
|
1894 {
|
|
1895 switch( i_type )
|
|
1896 {
|
|
1897 case GPCMD_SEND_KEY:
|
|
1898 p_sdc->flags = 0;
|
|
1899 break;
|
|
1900
|
|
1901 case GPCMD_READ_DVD_STRUCTURE:
|
|
1902 case GPCMD_REPORT_KEY:
|
|
1903 p_sdc->flags = EX_DIRECTION_IN;
|
|
1904 break;
|
|
1905 }
|
|
1906
|
|
1907 p_sdc->command[ 0 ] = i_type;
|
|
1908 p_sdc->command[ 8 ] = (p_sdc->data_length >> 8) & 0xff;
|
|
1909 p_sdc->command[ 9 ] = p_sdc->data_length & 0xff;
|
|
1910 p_sdc->id_code = 0x31304443; // 'CD01'
|
|
1911 p_sdc->cmd_length = 12;
|
|
1912 }
|
|
1913 #endif
|