Mercurial > mplayer.hg
annotate libdvdcss/ioctl.c @ 37058:a6b7e61e4af1
Disable system DPI scaling on Windows.
We scale the video just fine (or rather, better)
ourselves.
The GUI might be in trouble here though, since it
does not want its video to be scaled by the OS but
it also isn't DPI aware either...
author | reimar |
---|---|
date | Sat, 19 Apr 2014 08:30:17 +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 |