comparison libmpdvdkit2/libdvdcss.c @ 16630:954cdf2171f6

upgrade to libdvdcss 1.2.9
author diego
date Sat, 01 Oct 2005 17:19:33 +0000
parents c2ddedd0619e
children 0af14c5fee82
comparison
equal deleted inserted replaced
16629:045e93202e4a 16630:954cdf2171f6
3 * Authors: Stéphane Borel <stef@via.ecp.fr> 3 * Authors: Stéphane Borel <stef@via.ecp.fr>
4 * Samuel Hocevar <sam@zoy.org> 4 * Samuel Hocevar <sam@zoy.org>
5 * Håkan Hjort <d95hjort@dtek.chalmers.se> 5 * Håkan Hjort <d95hjort@dtek.chalmers.se>
6 * 6 *
7 * Copyright (C) 1998-2002 VideoLAN 7 * Copyright (C) 1998-2002 VideoLAN
8 *
9 * Modified for use with MPlayer, changes contained in libdvdcss_changes.diff.
10 * detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
11 * $Id$ 8 * $Id$
12 * 9 *
13 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or 12 * the Free Software Foundation; either version 2 of the License, or
23 * You should have received a copy of the GNU General Public License 20 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software 21 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. 22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
26 */ 23 */
27 24
28 /* 25 /**
29 * \mainpage libdvdcss developer documentation 26 * \mainpage libdvdcss developer documentation
30 * 27 *
31 * \section intro Introduction 28 * \section intro Introduction
32 * 29 *
33 * \e libdvdcss is a simple library designed for accessing DVDs like a block 30 * \e libdvdcss is a simple library designed for accessing DVDs like a block
103 #include <string.h> 100 #include <string.h>
104 #include <sys/types.h> 101 #include <sys/types.h>
105 #include <sys/stat.h> 102 #include <sys/stat.h>
106 #include <fcntl.h> 103 #include <fcntl.h>
107 #include <errno.h> 104 #include <errno.h>
108 #include <unistd.h> 105 # include <unistd.h>
109 #include <limits.h> 106 # include <limits.h>
110 107
111 #include "dvdcss.h" 108 #include "dvdcss.h"
112 109
113 #include "common.h" 110 #include "common.h"
114 #include "css.h" 111 #include "css.h"
190 */ 187 */
191 if( psz_verbose != NULL ) 188 if( psz_verbose != NULL )
192 { 189 {
193 int i = atoi( psz_verbose ); 190 int i = atoi( psz_verbose );
194 191
195 if( i >= 2 ) dvdcss->b_debug = 1; 192 if( i >= 2 ) dvdcss->b_debug = i;
196 if( i >= 1 ) dvdcss->b_errors = 1; 193 if( i >= 1 ) dvdcss->b_errors = 1;
197 } 194 }
198 195
199 /* 196 /*
200 * Find method from DVDCSS_METHOD environment variable 197 * Find method from DVDCSS_METHOD environment variable
213 { 210 {
214 dvdcss->i_method = DVDCSS_METHOD_TITLE; 211 dvdcss->i_method = DVDCSS_METHOD_TITLE;
215 } 212 }
216 else 213 else
217 { 214 {
218 _dvdcss_error( dvdcss, "unknown decrypt method, please choose " 215 print_error( dvdcss, "unknown decrypt method, please choose "
219 "from 'title', 'key' or 'disc'" ); 216 "from 'title', 'key' or 'disc'" );
220 free( dvdcss->psz_device ); 217 free( dvdcss->psz_device );
221 free( dvdcss ); 218 free( dvdcss );
222 return NULL; 219 return NULL;
223 } 220 }
224 } 221 }
222
223 #if 0 /* MPlayer caches keys in its own configuration directory */
224
225 /*
226 * If DVDCSS_CACHE was not set, try to guess a default value
227 */
228 if( psz_cache == NULL || psz_cache[0] == '\0' )
229 {
230 #ifdef HAVE_DIRECT_H
231 typedef HRESULT( WINAPI *SHGETFOLDERPATH )
232 ( HWND, int, HANDLE, DWORD, LPTSTR );
233
234 # define CSIDL_FLAG_CREATE 0x8000
235 # define CSIDL_APPDATA 0x1A
236 # define SHGFP_TYPE_CURRENT 0
237
238 char psz_home[MAX_PATH];
239 HINSTANCE p_dll;
240 SHGETFOLDERPATH p_getpath;
241
242 *psz_home = '\0';
243
244 /* Load the shfolder dll to retrieve SHGetFolderPath */
245 p_dll = LoadLibrary( "shfolder.dll" );
246 if( p_dll )
247 {
248 p_getpath = (void*)GetProcAddress( p_dll, "SHGetFolderPathA" );
249 if( p_getpath )
250 {
251 /* Get the "Application Data" folder for the current user */
252 if( p_getpath( NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE,
253 NULL, SHGFP_TYPE_CURRENT, psz_home ) == S_OK )
254 {
255 FreeLibrary( p_dll );
256 }
257 else
258 {
259 *psz_home = '\0';
260 }
261 }
262 FreeLibrary( p_dll );
263 }
264
265 /* Cache our keys in
266 * C:\Documents and Settings\$USER\Application Data\dvdcss\ */
267 if( *psz_home )
268 {
269 snprintf( psz_buffer, PATH_MAX, "%s/dvdcss", psz_home );
270 psz_buffer[PATH_MAX-1] = '\0';
271 psz_cache = psz_buffer;
272 }
273 #else
274 char *psz_home = NULL;
275 # ifdef HAVE_PWD_H
276 struct passwd *p_pwd;
277
278 /* Try looking in password file for home dir. */
279 p_pwd = getpwuid(getuid());
280 if( p_pwd )
281 {
282 psz_home = p_pwd->pw_dir;
283 }
284 # endif
285
286 if( psz_home == NULL )
287 {
288 psz_home = getenv( "HOME" );
289 }
290
291 /* Cache our keys in ${HOME}/.dvdcss/ */
292 if( psz_home )
293 {
294 snprintf( psz_buffer, PATH_MAX, "%s/.dvdcss", psz_home );
295 psz_buffer[PATH_MAX-1] = '\0';
296 psz_cache = psz_buffer;
297 }
298 #endif
299 }
300
301 #endif /* 0 */
225 302
226 /* 303 /*
227 * Find cache dir from the DVDCSS_CACHE environment variable 304 * Find cache dir from the DVDCSS_CACHE environment variable
228 */ 305 */
229 if( psz_cache != NULL ) 306 if( psz_cache != NULL )
230 { 307 {
231 if( psz_cache[0] == '\0' ) 308 if( psz_cache[0] == '\0' || !strcmp( psz_cache, "off" ) )
232 { 309 {
233 psz_cache = NULL; 310 psz_cache = NULL;
234 } 311 }
235 /* Check that we can add the ID directory and the block filename */ 312 /* Check that we can add the ID directory and the block filename */
236 else if( strlen( psz_cache ) + 1 + 32 + 1 + 10 + 1 > PATH_MAX ) 313 else if( strlen( psz_cache ) + 1 + 32 + 1 + (KEY_SIZE * 2) + 10 + 1
237 { 314 > PATH_MAX )
238 _dvdcss_error( dvdcss, "cache directory name is too long" ); 315 {
316 print_error( dvdcss, "cache directory name is too long" );
239 psz_cache = NULL; 317 psz_cache = NULL;
240 } 318 }
241 } 319 }
242 else psz_cache = get_path( "DVDKeys" ); 320 else psz_cache = get_path( "DVDKeys" );
243 321
259 { 337 {
260 i_ret = _dvdcss_test( dvdcss ); 338 i_ret = _dvdcss_test( dvdcss );
261 if( i_ret < 0 ) 339 if( i_ret < 0 )
262 { 340 {
263 /* Disable the CSS ioctls and hope that it works? */ 341 /* Disable the CSS ioctls and hope that it works? */
264 _dvdcss_debug( dvdcss, 342 print_debug( dvdcss,
265 "could not check whether the disc was scrambled" ); 343 "could not check whether the disc was scrambled" );
266 dvdcss->b_ioctls = 0; 344 dvdcss->b_ioctls = 0;
267 } 345 }
268 else 346 else
269 { 347 {
270 _dvdcss_debug( dvdcss, i_ret ? "disc is scrambled" 348 print_debug( dvdcss, i_ret ? "disc is scrambled"
271 : "disc is unscrambled" ); 349 : "disc is unscrambled" );
272 dvdcss->b_scrambled = i_ret; 350 dvdcss->b_scrambled = i_ret;
273 } 351 }
274 } 352 }
275 353
276 /* If disc is CSS protected and the ioctls work, authenticate the drive */ 354 /* If disc is CSS protected and the ioctls work, authenticate the drive */
285 free( dvdcss ); 363 free( dvdcss );
286 return NULL; 364 return NULL;
287 } 365 }
288 } 366 }
289 367
368 /* If the cache is enabled, write the cache directory tag */
369 if( psz_cache )
370 {
371 char *psz_tag = "Signature: 8a477f597d28d172789f06886806bc55\r\n"
372 "# This file is a cache directory tag created by libdvdcss.\r\n"
373 "# For information about cache directory tags, see:\r\n"
374 "# http://www.brynosaurus.com/cachedir/\r\n";
375 unsigned char psz_tagfile[PATH_MAX+1+12+1];
376 int i_fd;
377
378 sprintf( psz_tagfile, "%s/CACHEDIR.TAG", psz_cache );
379 i_fd = open( psz_tagfile, O_RDWR|O_CREAT, 0644 );
380 if( i_fd >= 0 )
381 {
382 write( i_fd, psz_tag, strlen(psz_tag) );
383 close( i_fd );
384 }
385 }
386
290 /* If the cache is enabled, extract a unique disc ID */ 387 /* If the cache is enabled, extract a unique disc ID */
291 if( psz_cache ) 388 if( psz_cache )
292 { 389 {
293 uint8_t p_sector[DVDCSS_BLOCK_SIZE]; 390 uint8_t p_sector[DVDCSS_BLOCK_SIZE];
294 unsigned char psz_debug[PATH_MAX+30]; 391 unsigned char psz_debug[PATH_MAX+30];
392 unsigned char psz_key[1 + KEY_SIZE * 2 + 1];
295 unsigned char * psz_title, * psz_serial; 393 unsigned char * psz_title, * psz_serial;
296 int i; 394 int i;
297 395
298 /* We read sector 0. If it starts with 0x000001ba (BE), we are 396 /* We read sector 0. If it starts with 0x000001ba (BE), we are
299 * reading a VOB file, and we should not cache anything. */ 397 * reading a VOB file, and we should not cache anything. */
356 /* Check that all characters are digits, otherwise convert. */ 454 /* Check that all characters are digits, otherwise convert. */
357 for( i = 0 ; i < 16 ; i++ ) 455 for( i = 0 ; i < 16 ; i++ )
358 { 456 {
359 if( psz_serial[i] < '0' || psz_serial[i] > '9' ) 457 if( psz_serial[i] < '0' || psz_serial[i] > '9' )
360 { 458 {
361 sprintf( psz_serial, 459 unsigned char psz_tmp[16 + 1];
362 "%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X", 460 sprintf( psz_tmp,
461 "%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
363 psz_serial[0], psz_serial[1], psz_serial[2], 462 psz_serial[0], psz_serial[1], psz_serial[2],
364 psz_serial[3], psz_serial[4], psz_serial[5], 463 psz_serial[3], psz_serial[4], psz_serial[5],
365 psz_serial[6], psz_serial[7] ); 464 psz_serial[6], psz_serial[7] );
465 memcpy( psz_serial, psz_tmp, 16 );
366 break; 466 break;
367 } 467 }
468 }
469
470 /* Get disk key, since some discs have got same title, manufacturing
471 * date and serial number, but different keys */
472 if( dvdcss->b_scrambled )
473 {
474 psz_key[0] = '-';
475 for( i = 0; i < KEY_SIZE; i++ )
476 {
477 sprintf( &psz_key[1+i*2], "%.2x", dvdcss->css.p_disc_key[i] );
478 }
479 psz_key[1 + KEY_SIZE * 2] = '\0';
480 }
481 else
482 {
483 psz_key[0] = 0;
368 } 484 }
369 485
370 /* We have a disc name or ID, we can create the cache dir */ 486 /* We have a disc name or ID, we can create the cache dir */
371 i = sprintf( dvdcss->psz_cachefile, "%s", psz_cache ); 487 i = sprintf( dvdcss->psz_cachefile, "%s", psz_cache );
372 #if !defined( WIN32 ) || defined( SYS_CYGWIN ) 488 #if !defined( WIN32 ) || defined( SYS_CYGWIN )
374 #else 490 #else
375 i_ret = mkdir( dvdcss->psz_cachefile ); 491 i_ret = mkdir( dvdcss->psz_cachefile );
376 #endif 492 #endif
377 if( i_ret < 0 && errno != EEXIST ) 493 if( i_ret < 0 && errno != EEXIST )
378 { 494 {
379 _dvdcss_error( dvdcss, "failed creating cache directory" ); 495 print_error( dvdcss, "failed creating cache directory" );
380 dvdcss->psz_cachefile[0] = '\0'; 496 dvdcss->psz_cachefile[0] = '\0';
381 goto nocache; 497 goto nocache;
382 } 498 }
383 i += sprintf( dvdcss->psz_cachefile + i, "/"); 499 i += sprintf( dvdcss->psz_cachefile + i, "/");
384 500
385 // i += sprintf( dvdcss->psz_cachefile + i, "/%s", psz_data ); 501 // i += sprintf( dvdcss->psz_cachefile + i, "/%s", psz_data );
386 i += sprintf( dvdcss->psz_cachefile + i, "/%s#%s", psz_title, psz_serial ); 502 i += sprintf( dvdcss->psz_cachefile + i, "/%s#%s", psz_title, psz_serial );
387 #if !defined( WIN32 ) || defined( SYS_CYGWIN ) 503 #if !defined( WIN32 ) || defined( SYS_CYGWIN )
388 i_ret = mkdir( dvdcss->psz_cachefile, 0755 ); 504 i_ret = mkdir( dvdcss->psz_cachefile, 0755 );
389 #else 505 #else
390 i_ret = mkdir( dvdcss->psz_cachefile ); 506 i_ret = mkdir( dvdcss->psz_cachefile );
391 #endif 507 #endif
392 if( i_ret < 0 && errno != EEXIST ) 508 if( i_ret < 0 && errno != EEXIST )
393 { 509 {
394 _dvdcss_error( dvdcss, "failed creating cache subdirectory" ); 510 print_error( dvdcss, "failed creating cache subdirectory" );
395 dvdcss->psz_cachefile[0] = '\0'; 511 dvdcss->psz_cachefile[0] = '\0';
396 goto nocache; 512 goto nocache;
397 } 513 }
398 i += sprintf( dvdcss->psz_cachefile + i, "/"); 514 i += sprintf( dvdcss->psz_cachefile + i, "/");
399 515
400 /* Pointer to the filename we will use. */ 516 /* Pointer to the filename we will use. */
401 dvdcss->psz_block = dvdcss->psz_cachefile + i; 517 dvdcss->psz_block = dvdcss->psz_cachefile + i;
402 518
403 sprintf( psz_debug, "using CSS key cache dir: %s", 519 sprintf( psz_debug, "using CSS key cache dir: %s",
404 dvdcss->psz_cachefile ); 520 dvdcss->psz_cachefile );
405 _dvdcss_debug( dvdcss, psz_debug ); 521 print_debug( dvdcss, psz_debug );
406 } 522 }
407 nocache: 523 nocache:
408 524
409 #ifndef WIN32 525 #ifndef WIN32
410 if( psz_raw_device != NULL ) 526 if( psz_raw_device != NULL )
520 * check that there are no encrypted blocks */ 636 * check that there are no encrypted blocks */
521 for( i_index = i_ret; i_index; i_index-- ) 637 for( i_index = i_ret; i_index; i_index-- )
522 { 638 {
523 if( ((uint8_t*)p_buffer)[0x14] & 0x30 ) 639 if( ((uint8_t*)p_buffer)[0x14] & 0x30 )
524 { 640 {
525 _dvdcss_error( dvdcss, "no key but found encrypted block" ); 641 print_error( dvdcss, "no key but found encrypted block" );
526 /* Only return the initial range of unscrambled blocks? */ 642 /* Only return the initial range of unscrambled blocks? */
527 /* or fail completely? return 0; */ 643 /* or fail completely? return 0; */
528 break; 644 break;
529 } 645 }
530 p_buffer = (void *) ((uint8_t *)p_buffer + DVDCSS_BLOCK_SIZE); 646 p_buffer = (void *) ((uint8_t *)p_buffer + DVDCSS_BLOCK_SIZE);