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