]> git.sesse.net Git - vlc/blob - plugins/dvd/dvd_ioctl.c
* compilation fixes for the BeOS DVD ioctls
[vlc] / plugins / dvd / dvd_ioctl.c
1 /*****************************************************************************
2  * dvd_ioctl.c: DVD ioctl replacement function
3  *****************************************************************************
4  * Copyright (C) 1999-2001 VideoLAN
5  * $Id: dvd_ioctl.c,v 1.6 2001/04/04 16:33:07 sam Exp $
6  *
7  * Authors: Markus Kuespert <ltlBeBoy@beosmail.com>
8  *          Samuel Hocevar <sam@zoy.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include "defs.h"
29
30 #include <sys/types.h>
31 #include <netinet/in.h>
32
33 #ifdef HAVE_SYS_DVDIO_H
34 #   include <sys/ioctl.h>
35 #   include <sys/dvdio.h>
36 #endif
37 #ifdef LINUX_DVD
38 #   include <sys/ioctl.h>
39 #   include <linux/cdrom.h>
40 #endif
41 #ifdef SYS_BEOS
42 #   include <sys/ioctl.h>
43 #   include <malloc.h>
44 #   include <scsi.h>
45 #endif
46 #ifdef SYS_DARWIN1_3
47 #   include <sys/ioctl.h>
48 #endif
49
50 #include "common.h"
51
52 #include "intf_msg.h"
53
54 #ifdef SYS_DARWIN1_3
55 #   include "DVDioctl/DVDioctl.h"
56 #endif
57
58 #include "dvd_css.h"
59 #include "dvd_ioctl.h"
60
61 /*****************************************************************************
62  * Local prototypes - BeOS specific
63  *****************************************************************************/
64 #if defined( SYS_BEOS )
65 static void BeInitRDC ( raw_device_command *, void *, int );
66 #endif
67
68 /*****************************************************************************
69  * ioctl_ReadCopyright: check whether the disc is encrypted or not
70  *****************************************************************************/
71 int ioctl_ReadCopyright( int i_fd, int i_layer, int *pi_copyright )
72 {
73     int i_ret;
74
75 #if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
76     dvd_struct dvd;
77
78     dvd.type = DVD_STRUCT_COPYRIGHT;
79     dvd.copyright.layer_num = i_layer;
80
81     i_ret = ioctl( i_fd, DVD_READ_STRUCT, &dvd );
82
83     *pi_copyright = dvd.copyright.cpst;
84
85 #elif defined( SYS_BEOS )
86     raw_device_command rdc;
87     u8 p_buffer[ 8 ];
88
89     BeInitRDC( &rdc, p_buffer, 8 );
90
91     rdc.flags        = B_RAW_DEVICE_DATA_IN;
92     rdc.command[ 0 ] = GPCMD_READ_DVD_STRUCTURE;
93     rdc.command[ 6 ] = i_layer;
94     rdc.command[ 7 ] = DVD_STRUCT_COPYRIGHT;
95
96     i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
97
98     *pi_copyright = p_buffer[ 4 ];
99
100 #elif defined( SYS_DARWIN1_3 )
101     intf_ErrMsg( "css error: DVD ioctls not fully functional yet" );
102
103     intf_ErrMsg( "css error: assuming disc is unencrypted" );
104     *pi_copyright = 0;
105
106     i_ret = 0;
107
108 #else
109     /* DVD ioctls unavailable - do as if the ioctl failed */
110     i_ret = -1;
111
112 #endif
113     return i_ret;
114 }
115
116 /*****************************************************************************
117  * ioctl_ReadKey: get the disc key
118  *****************************************************************************/
119 int ioctl_ReadKey( css_t *p_css, u8 *p_key )
120 {
121     int i_ret;
122
123 #if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
124     dvd_struct dvd;
125
126     dvd.type = DVD_STRUCT_DISCKEY;
127     dvd.disckey.agid = p_css->i_agid;
128
129     memset( dvd.disckey.value, 0, 2048 );
130
131     i_ret = ioctl( p_css->i_fd, DVD_READ_STRUCT, &dvd );
132
133     if( i_ret < 0 )
134     {
135         return i_ret;
136     }
137
138     memcpy( p_key, dvd.disckey.value, 2048 );
139
140 #elif defined( SYS_BEOS )
141     raw_device_command rdc;
142     u8 p_buffer[ 2048 + 4 ];
143
144     BeInitRDC( &rdc, p_buffer, 2048 + 4 );
145
146     rdc.flags         = B_RAW_DEVICE_DATA_IN;
147     rdc.command[ 0 ]  = GPCMD_READ_DVD_STRUCTURE;
148     rdc.command[ 7 ]  = DVD_STRUCT_DISCKEY;
149     rdc.command[ 10 ] = p_css->i_agid << 6;
150     
151     i_ret = ioctl( p_css->i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
152
153     if( i_ret < 0 )
154     {
155         return i_ret;
156     }
157
158     memcpy( p_key, p_buffer + 4, 2048 );
159
160 #else
161     /* DVD ioctls unavailable - do as if the ioctl failed */
162     i_ret = -1;
163
164 #endif
165     return i_ret;
166 }
167
168 /*****************************************************************************
169  * ioctl_LUSendAgid: get AGID from the drive
170  *****************************************************************************/
171 int ioctl_LUSendAgid( css_t *p_css )
172 {
173     int i_ret;
174
175 #if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
176     dvd_authinfo auth_info;
177
178     auth_info.type = DVD_LU_SEND_AGID;
179     auth_info.lsa.agid = p_css->i_agid;
180
181     i_ret = ioctl( p_css->i_fd, DVD_AUTH, &auth_info );
182
183     p_css->i_agid = auth_info.lsa.agid;
184
185 #elif defined( SYS_BEOS )
186     raw_device_command rdc;
187     u8 p_buffer[ 8 ];
188
189     BeInitRDC( &rdc, p_buffer, 8 );
190
191     rdc.flags         = B_RAW_DEVICE_DATA_IN;
192     rdc.command[ 0 ]  = GPCMD_REPORT_KEY;
193     rdc.command[ 10 ] = 0x00 | (p_css->i_agid << 6);
194
195     i_ret = ioctl( p_css->i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
196
197     p_css->i_agid = p_buffer[ 7 ] >> 6;
198
199 #else
200     /* DVD ioctls unavailable - do as if the ioctl failed */
201     i_ret = -1;
202
203 #endif
204     return i_ret;
205 }
206
207 /*****************************************************************************
208  * ioctl_LUSendChallenge: get challenge from the drive
209  *****************************************************************************/
210 int ioctl_LUSendChallenge( css_t *p_css, u8 *p_challenge )
211 {
212     int i_ret;
213
214 #if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
215     dvd_authinfo auth_info;
216
217     auth_info.type = DVD_LU_SEND_CHALLENGE;
218
219     i_ret = ioctl( p_css->i_fd, DVD_AUTH, &auth_info );
220
221     memcpy( p_challenge, auth_info.lsc.chal, sizeof(dvd_challenge) );
222
223 #elif defined( SYS_BEOS )
224     raw_device_command rdc;
225     u8 p_buffer[ 16 ];
226
227     BeInitRDC( &rdc, p_buffer, 16 );
228
229     rdc.flags         = B_RAW_DEVICE_DATA_IN;
230     rdc.command[ 0 ]  = GPCMD_REPORT_KEY;
231     rdc.command[ 10 ] = 0x01 | (p_css->i_agid << 6);
232
233     i_ret = ioctl( p_css->i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
234
235     memcpy( p_challenge, p_buffer + 4, 12 );
236
237 #else
238     /* DVD ioctls unavailable - do as if the ioctl failed */
239     i_ret = -1;
240
241 #endif
242     return i_ret;
243 }
244
245 /*****************************************************************************
246  * ioctl_LUSendASF: get ASF from the drive
247  *****************************************************************************/
248 int ioctl_LUSendASF( css_t *p_css, int *pi_asf )
249 {
250     int i_ret;
251
252 #if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
253     dvd_authinfo auth_info;
254
255     auth_info.type = DVD_LU_SEND_ASF;
256     auth_info.lsasf.agid = p_css->i_agid;
257     auth_info.lsasf.asf = *pi_asf;
258
259     i_ret = ioctl( p_css->i_fd, DVD_AUTH, &auth_info );
260
261     *pi_asf = auth_info.lsasf.asf;
262
263 #elif defined( SYS_BEOS )
264     raw_device_command rdc;
265     u8 p_buffer[ 8 ];
266
267     BeInitRDC( &rdc, p_buffer, 8 );
268
269     rdc.flags         = B_RAW_DEVICE_DATA_IN;
270     rdc.command[ 0 ]  = GPCMD_REPORT_KEY;
271     rdc.command[ 10 ] = 0x05 | (p_css->i_agid << 6);
272
273     i_ret = ioctl( p_css->i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
274
275     *pi_asf = p_buffer[ 7 ] & 1;
276
277 #elif defined( SYS_DARWIN1_3 )
278     dvdioctl_data_t data;
279     u8 p_buffer[ 8 ];
280
281     data.p_buffer = p_buffer;
282     data.i_lba = 0;
283     data.i_agid = p_css->i_agid;
284     data.i_keyclass = kCSS_CSS2_CPRM;
285     data.i_keyformat = kASF;
286
287     i_ret = ioctl( p_css->i_fd, IODVD_REPORT_KEY, &data );
288
289     *pi_asf = p_buffer[ 7 ] & 1;
290
291 #else
292     /* DVD ioctls unavailable - do as if the ioctl failed */
293     i_ret = -1;
294
295 #endif
296     return i_ret;
297 }
298
299 /*****************************************************************************
300  * ioctl_LUSendKey1: get the first key from the drive
301  *****************************************************************************/
302 int ioctl_LUSendKey1( css_t *p_css, u8 *p_key )
303 {
304     int i_ret;
305
306 #if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
307     dvd_authinfo auth_info;
308
309     auth_info.type = DVD_LU_SEND_KEY1;
310     auth_info.lsk.agid = p_css->i_agid;
311
312     i_ret = ioctl( p_css->i_fd, DVD_AUTH, &auth_info );
313
314     memcpy( p_key, auth_info.lsk.key, sizeof(dvd_key) );
315
316 #elif defined( SYS_BEOS )
317     raw_device_command rdc;
318     u8 p_buffer[ 12 ];
319
320     BeInitRDC( &rdc, p_buffer, 12 );
321
322     rdc.flags         = B_RAW_DEVICE_DATA_IN;
323     rdc.command[ 0 ]  = GPCMD_REPORT_KEY;
324     rdc.command[ 10 ] = 0x02 | (p_css->i_agid << 6);
325
326     i_ret = ioctl( p_css->i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
327
328     memcpy( p_key, p_buffer + 4, 8 );
329
330 #else
331     /* DVD ioctls unavailable - do as if the ioctl failed */
332     i_ret = -1;
333
334 #endif
335     return i_ret;
336 }
337
338 /*****************************************************************************
339  * ioctl_InvalidateAgid: invalidate the current AGID
340  *****************************************************************************/
341 int ioctl_InvalidateAgid( css_t *p_css )
342 {
343     int i_ret;
344
345 #if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
346     dvd_authinfo auth_info;
347
348     auth_info.type = DVD_INVALIDATE_AGID;
349     auth_info.lsa.agid = p_css->i_agid;
350
351     i_ret = ioctl( p_css->i_fd, DVD_AUTH, &auth_info );
352
353     p_css->i_agid = auth_info.lsa.agid;
354
355 #elif defined( SYS_BEOS )
356     raw_device_command rdc;
357     u8 p_buffer[ 0 ];
358
359     BeInitRDC( &rdc, p_buffer, 0 );
360
361     rdc.flags         = B_RAW_DEVICE_DATA_IN;
362     rdc.command[ 0 ]  = GPCMD_REPORT_KEY;
363     rdc.command[ 10 ] = 0x3f | (p_css->i_agid << 6);
364
365     i_ret = ioctl( p_css->i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
366
367 #else
368     /* DVD ioctls unavailable - do as if the ioctl failed */
369     i_ret = -1;
370
371 #endif
372     return i_ret;
373 }
374
375 /*****************************************************************************
376  * ioctl_HostSendChallenge: send challenge to the drive
377  *****************************************************************************/
378 int ioctl_HostSendChallenge( css_t *p_css, u8 *p_challenge )
379 {
380 #if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
381     dvd_authinfo auth_info;
382
383     auth_info.type = DVD_HOST_SEND_CHALLENGE;
384
385     memcpy( auth_info.hsc.chal, p_challenge, sizeof(dvd_challenge) );
386
387     return ioctl( p_css->i_fd, DVD_AUTH, &auth_info );
388
389 #elif defined( SYS_BEOS )
390     raw_device_command rdc;
391     u8 p_buffer[ 16 ];
392
393     BeInitRDC( &rdc, p_buffer, 16 );
394
395     rdc.command[ 0 ]  = GPCMD_SEND_KEY;
396     rdc.command[ 10 ] = 0x01 | (p_css->i_agid << 6);
397
398     p_buffer[ 1 ] = 0xe;
399     memcpy( p_buffer + 4, p_challenge, 12 );
400
401     return ioctl( p_css->i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
402
403 #else
404     /* DVD ioctls unavailable - do as if the ioctl failed */
405     return -1;
406
407 #endif
408 }
409
410 /*****************************************************************************
411  * ioctl_HostSendKey2: send the second key to the drive
412  *****************************************************************************/
413 int ioctl_HostSendKey2( css_t *p_css, u8 *p_key )
414 {
415 #if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
416     dvd_authinfo auth_info;
417
418     auth_info.type = DVD_HOST_SEND_KEY2;
419     auth_info.hsk.agid = p_css->i_agid;
420
421     memcpy( auth_info.hsk.key, p_key, sizeof(dvd_key) );
422
423     return ioctl( p_css->i_fd, DVD_AUTH, &auth_info );
424
425 #elif defined( SYS_BEOS )
426     raw_device_command rdc;
427     u8 p_buffer[ 12 ];
428
429     BeInitRDC( &rdc, p_buffer, 12 );
430
431     rdc.command[ 0 ]  = GPCMD_REPORT_KEY;
432     rdc.command[ 10 ] = 0x3 | (p_css->i_agid << 6);
433
434     p_buffer[ 1 ] = 0xa;
435     memcpy( p_buffer + 4, p_key, 8 );
436
437     return ioctl( p_css->i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
438
439 #else
440     /* DVD ioctls unavailable - do as if the ioctl failed */
441     return -1;
442
443 #endif
444 }
445
446 /* Local prototypes */
447
448 #if defined( SYS_BEOS )
449 /*****************************************************************************
450  * BeInitRDC: initialize a RDC structure for the BeOS kernel
451  *****************************************************************************
452  * This function initializes a BeOS raw device command structure for future
453  * use, either a read command or a write command.
454  *****************************************************************************/
455 static void BeInitRDC( raw_device_command *p_rdc, void *p_buffer, int i_len )
456 {
457     memset( p_rdc, 0, sizeof( raw_device_command ) );
458     memset( p_buffer, 0, i_len );
459
460     p_rdc->command[ 8 ]      = (i_len >> 8) & 0xff;
461     p_rdc->command[ 9 ]      =  i_len       & 0xff;
462     p_rdc->command_length    = 12;
463
464     p_rdc->data              = (char *)p_buffer;
465     p_rdc->data_length       = i_len;
466
467     p_rdc->sense_data        = NULL;
468     p_rdc->sense_data_length = 0;
469
470     p_rdc->timeout           = 1000000;
471 }
472
473 #endif
474