summaryrefslogtreecommitdiffstats
path: root/libmpdvdkit2/libdvdcss.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmpdvdkit2/libdvdcss.c')
-rw-r--r--libmpdvdkit2/libdvdcss.c162
1 files changed, 139 insertions, 23 deletions
diff --git a/libmpdvdkit2/libdvdcss.c b/libmpdvdkit2/libdvdcss.c
index d918d51288..81dcd72a13 100644
--- a/libmpdvdkit2/libdvdcss.c
+++ b/libmpdvdkit2/libdvdcss.c
@@ -5,9 +5,6 @@
* Håkan Hjort <d95hjort@dtek.chalmers.se>
*
* Copyright (C) 1998-2002 VideoLAN
- *
- * Modified for use with MPlayer, changes contained in libdvdcss_changes.diff.
- * detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
* $Id$
*
* This program is free software; you can redistribute it and/or modify
@@ -25,7 +22,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*/
-/*
+/**
* \mainpage libdvdcss developer documentation
*
* \section intro Introduction
@@ -105,8 +102,8 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
-#include <unistd.h>
-#include <limits.h>
+# include <unistd.h>
+# include <limits.h>
#include "dvdcss.h"
@@ -192,7 +189,7 @@ extern dvdcss_t dvdcss_open ( char *psz_target )
{
int i = atoi( psz_verbose );
- if( i >= 2 ) dvdcss->b_debug = 1;
+ if( i >= 2 ) dvdcss->b_debug = i;
if( i >= 1 ) dvdcss->b_errors = 1;
}
@@ -215,27 +212,108 @@ extern dvdcss_t dvdcss_open ( char *psz_target )
}
else
{
- _dvdcss_error( dvdcss, "unknown decrypt method, please choose "
- "from 'title', 'key' or 'disc'" );
+ print_error( dvdcss, "unknown decrypt method, please choose "
+ "from 'title', 'key' or 'disc'" );
free( dvdcss->psz_device );
free( dvdcss );
return NULL;
}
}
+#if 0 /* MPlayer caches keys in its own configuration directory */
+
+ /*
+ * If DVDCSS_CACHE was not set, try to guess a default value
+ */
+ if( psz_cache == NULL || psz_cache[0] == '\0' )
+ {
+#ifdef HAVE_DIRECT_H
+ typedef HRESULT( WINAPI *SHGETFOLDERPATH )
+ ( HWND, int, HANDLE, DWORD, LPTSTR );
+
+# define CSIDL_FLAG_CREATE 0x8000
+# define CSIDL_APPDATA 0x1A
+# define SHGFP_TYPE_CURRENT 0
+
+ char psz_home[MAX_PATH];
+ HINSTANCE p_dll;
+ SHGETFOLDERPATH p_getpath;
+
+ *psz_home = '\0';
+
+ /* Load the shfolder dll to retrieve SHGetFolderPath */
+ p_dll = LoadLibrary( "shfolder.dll" );
+ if( p_dll )
+ {
+ p_getpath = (void*)GetProcAddress( p_dll, "SHGetFolderPathA" );
+ if( p_getpath )
+ {
+ /* Get the "Application Data" folder for the current user */
+ if( p_getpath( NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE,
+ NULL, SHGFP_TYPE_CURRENT, psz_home ) == S_OK )
+ {
+ FreeLibrary( p_dll );
+ }
+ else
+ {
+ *psz_home = '\0';
+ }
+ }
+ FreeLibrary( p_dll );
+ }
+
+ /* Cache our keys in
+ * C:\Documents and Settings\$USER\Application Data\dvdcss\ */
+ if( *psz_home )
+ {
+ snprintf( psz_buffer, PATH_MAX, "%s/dvdcss", psz_home );
+ psz_buffer[PATH_MAX-1] = '\0';
+ psz_cache = psz_buffer;
+ }
+#else
+ char *psz_home = NULL;
+# ifdef HAVE_PWD_H
+ struct passwd *p_pwd;
+
+ /* Try looking in password file for home dir. */
+ p_pwd = getpwuid(getuid());
+ if( p_pwd )
+ {
+ psz_home = p_pwd->pw_dir;
+ }
+# endif
+
+ if( psz_home == NULL )
+ {
+ psz_home = getenv( "HOME" );
+ }
+
+ /* Cache our keys in ${HOME}/.dvdcss/ */
+ if( psz_home )
+ {
+ snprintf( psz_buffer, PATH_MAX, "%s/.dvdcss", psz_home );
+ psz_buffer[PATH_MAX-1] = '\0';
+ psz_cache = psz_buffer;
+ }
+#endif
+ }
+
+#endif /* 0 */
+
/*
* Find cache dir from the DVDCSS_CACHE environment variable
*/
if( psz_cache != NULL )
{
- if( psz_cache[0] == '\0' )
+ if( psz_cache[0] == '\0' || !strcmp( psz_cache, "off" ) )
{
psz_cache = NULL;
}
/* Check that we can add the ID directory and the block filename */
- else if( strlen( psz_cache ) + 1 + 32 + 1 + 10 + 1 > PATH_MAX )
+ else if( strlen( psz_cache ) + 1 + 32 + 1 + (KEY_SIZE * 2) + 10 + 1
+ > PATH_MAX )
{
- _dvdcss_error( dvdcss, "cache directory name is too long" );
+ print_error( dvdcss, "cache directory name is too long" );
psz_cache = NULL;
}
}
@@ -261,14 +339,14 @@ extern dvdcss_t dvdcss_open ( char *psz_target )
if( i_ret < 0 )
{
/* Disable the CSS ioctls and hope that it works? */
- _dvdcss_debug( dvdcss,
- "could not check whether the disc was scrambled" );
+ print_debug( dvdcss,
+ "could not check whether the disc was scrambled" );
dvdcss->b_ioctls = 0;
}
else
{
- _dvdcss_debug( dvdcss, i_ret ? "disc is scrambled"
- : "disc is unscrambled" );
+ print_debug( dvdcss, i_ret ? "disc is scrambled"
+ : "disc is unscrambled" );
dvdcss->b_scrambled = i_ret;
}
}
@@ -287,11 +365,31 @@ extern dvdcss_t dvdcss_open ( char *psz_target )
}
}
+ /* If the cache is enabled, write the cache directory tag */
+ if( psz_cache )
+ {
+ char *psz_tag = "Signature: 8a477f597d28d172789f06886806bc55\r\n"
+ "# This file is a cache directory tag created by libdvdcss.\r\n"
+ "# For information about cache directory tags, see:\r\n"
+ "# http://www.brynosaurus.com/cachedir/\r\n";
+ unsigned char psz_tagfile[PATH_MAX+1+12+1];
+ int i_fd;
+
+ sprintf( psz_tagfile, "%s/CACHEDIR.TAG", psz_cache );
+ i_fd = open( psz_tagfile, O_RDWR|O_CREAT, 0644 );
+ if( i_fd >= 0 )
+ {
+ write( i_fd, psz_tag, strlen(psz_tag) );
+ close( i_fd );
+ }
+ }
+
/* If the cache is enabled, extract a unique disc ID */
if( psz_cache )
{
uint8_t p_sector[DVDCSS_BLOCK_SIZE];
unsigned char psz_debug[PATH_MAX+30];
+ unsigned char psz_key[1 + KEY_SIZE * 2 + 1];
unsigned char * psz_title, * psz_serial;
int i;
@@ -358,15 +456,33 @@ extern dvdcss_t dvdcss_open ( char *psz_target )
{
if( psz_serial[i] < '0' || psz_serial[i] > '9' )
{
- sprintf( psz_serial,
- "%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X",
+ unsigned char psz_tmp[16 + 1];
+ sprintf( psz_tmp,
+ "%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
psz_serial[0], psz_serial[1], psz_serial[2],
psz_serial[3], psz_serial[4], psz_serial[5],
psz_serial[6], psz_serial[7] );
+ memcpy( psz_serial, psz_tmp, 16 );
break;
}
}
+ /* Get disk key, since some discs have got same title, manufacturing
+ * date and serial number, but different keys */
+ if( dvdcss->b_scrambled )
+ {
+ psz_key[0] = '-';
+ for( i = 0; i < KEY_SIZE; i++ )
+ {
+ sprintf( &psz_key[1+i*2], "%.2x", dvdcss->css.p_disc_key[i] );
+ }
+ psz_key[1 + KEY_SIZE * 2] = '\0';
+ }
+ else
+ {
+ psz_key[0] = 0;
+ }
+
/* We have a disc name or ID, we can create the cache dir */
i = sprintf( dvdcss->psz_cachefile, "%s", psz_cache );
#if !defined( WIN32 ) || defined( SYS_CYGWIN )
@@ -376,14 +492,14 @@ extern dvdcss_t dvdcss_open ( char *psz_target )
#endif
if( i_ret < 0 && errno != EEXIST )
{
- _dvdcss_error( dvdcss, "failed creating cache directory" );
+ print_error( dvdcss, "failed creating cache directory" );
dvdcss->psz_cachefile[0] = '\0';
goto nocache;
}
i += sprintf( dvdcss->psz_cachefile + i, "/");
// i += sprintf( dvdcss->psz_cachefile + i, "/%s", psz_data );
- i += sprintf( dvdcss->psz_cachefile + i, "/%s#%s", psz_title, psz_serial );
+ i += sprintf( dvdcss->psz_cachefile + i, "/%s#%s", psz_title, psz_serial );
#if !defined( WIN32 ) || defined( SYS_CYGWIN )
i_ret = mkdir( dvdcss->psz_cachefile, 0755 );
#else
@@ -391,7 +507,7 @@ extern dvdcss_t dvdcss_open ( char *psz_target )
#endif
if( i_ret < 0 && errno != EEXIST )
{
- _dvdcss_error( dvdcss, "failed creating cache subdirectory" );
+ print_error( dvdcss, "failed creating cache subdirectory" );
dvdcss->psz_cachefile[0] = '\0';
goto nocache;
}
@@ -402,7 +518,7 @@ extern dvdcss_t dvdcss_open ( char *psz_target )
sprintf( psz_debug, "using CSS key cache dir: %s",
dvdcss->psz_cachefile );
- _dvdcss_debug( dvdcss, psz_debug );
+ print_debug( dvdcss, psz_debug );
}
nocache:
@@ -522,7 +638,7 @@ extern int dvdcss_read ( dvdcss_t dvdcss, void *p_buffer,
{
if( ((uint8_t*)p_buffer)[0x14] & 0x30 )
{
- _dvdcss_error( dvdcss, "no key but found encrypted block" );
+ print_error( dvdcss, "no key but found encrypted block" );
/* Only return the initial range of unscrambled blocks? */
/* or fail completely? return 0; */
break;