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