Mercurial > mplayer.hg
annotate libdvdcss/ioctl.c @ 35337:6641819c8f45
stream ftp: Only send QUIT command if connected
Do not attempt to send commands without control connections.
author | al |
---|---|
date | Tue, 20 Nov 2012 22:20:52 +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 |