Commit 2cdf4603 authored by Sam Hocevar's avatar Sam Hocevar

  * libdvdcss segfault fixes, at last!
     (I really wonder how it could have worked before :)
parent c4725d15
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* css.h: Structures for DVD authentification and unscrambling * css.h: Structures for DVD authentification and unscrambling
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: css.h,v 1.4 2001/07/11 02:01:03 sam Exp $ * $Id: css.h,v 1.5 2001/07/25 00:23:40 sam Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -39,12 +39,12 @@ typedef struct disc_s ...@@ -39,12 +39,12 @@ typedef struct disc_s
u8 i_varient; u8 i_varient;
} disc_t; } disc_t;
typedef struct title_key_s typedef struct dvd_title_s
{ {
int i_startlb; int i_startlb;
dvd_key_t p_key; dvd_key_t p_key;
struct title_key_s *p_next; struct dvd_title_s *p_next;
} title_key_t; } dvd_title_t;
typedef struct css_s typedef struct css_s
{ {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ioctl.c: DVD ioctl replacement function * ioctl.c: DVD ioctl replacement function
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: ioctl.c,v 1.4 2001/07/19 11:50:50 massiot Exp $ * $Id: ioctl.c,v 1.5 2001/07/25 00:23:40 sam Exp $
* *
* Authors: Markus Kuespert <ltlBeBoy@beosmail.com> * Authors: Markus Kuespert <ltlBeBoy@beosmail.com>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -115,9 +115,6 @@ int ioctl_ReadCopyright( int i_fd, int i_layer, int *pi_copyright ) ...@@ -115,9 +115,6 @@ int ioctl_ReadCopyright( int i_fd, int i_layer, int *pi_copyright )
*pi_copyright = p_buffer[ 4 ]; *pi_copyright = p_buffer[ 4 ];
#elif defined( SYS_DARWIN ) #elif defined( SYS_DARWIN )
_dvd_error( dvdcss, "DVD ioctls not fully functional yet, "
"assuming disc is encrypted" );
*pi_copyright = 1; *pi_copyright = 1;
i_ret = 0; i_ret = 0;
...@@ -241,9 +238,6 @@ int ioctl_ReadKey( int i_fd, int *pi_agid, u8 *p_key ) ...@@ -241,9 +238,6 @@ int ioctl_ReadKey( int i_fd, int *pi_agid, u8 *p_key )
memcpy( p_key, p_buffer + 4, 2048 ); memcpy( p_key, p_buffer + 4, 2048 );
#elif defined( SYS_DARWIN ) #elif defined( SYS_DARWIN )
_dvd_error( dvdcss, "DVD ioctls not fully functional yet, "
"sending an empty key" );
i_ret = 0; i_ret = 0;
memset( p_key, 0x00, 2048 ); memset( p_key, 0x00, 2048 );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* libdvdcss.c: DVD reading library. * libdvdcss.c: DVD reading library.
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: libdvdcss.c,v 1.7 2001/07/15 09:49:09 gbazin Exp $ * $Id: libdvdcss.c,v 1.8 2001/07/25 00:23:40 sam Exp $
* *
* Authors: Stphane Borel <stef@via.ecp.fr> * Authors: Stphane Borel <stef@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -94,7 +94,7 @@ extern dvdcss_handle dvdcss_open ( char *psz_target, int i_flags ) ...@@ -94,7 +94,7 @@ extern dvdcss_handle dvdcss_open ( char *psz_target, int i_flags )
} }
/* Initialize structure */ /* Initialize structure */
dvdcss->p_keys = NULL; dvdcss->p_titles = NULL;
dvdcss->b_debug = i_flags & DVDCSS_INIT_DEBUG; dvdcss->b_debug = i_flags & DVDCSS_INIT_DEBUG;
dvdcss->b_errors = !(i_flags & DVDCSS_INIT_QUIET); dvdcss->b_errors = !(i_flags & DVDCSS_INIT_QUIET);
dvdcss->psz_error = "no error"; dvdcss->psz_error = "no error";
...@@ -154,9 +154,7 @@ extern int dvdcss_seek ( dvdcss_handle dvdcss, int i_blocks ) ...@@ -154,9 +154,7 @@ extern int dvdcss_seek ( dvdcss_handle dvdcss, int i_blocks )
*****************************************************************************/ *****************************************************************************/
extern int dvdcss_crack ( dvdcss_handle dvdcss, int i_block ) extern int dvdcss_crack ( dvdcss_handle dvdcss, int i_block )
{ {
title_key_t **pp_writekey; dvd_title_t *p_title;
title_key_t **pp_currentkey;
title_key_t *p_titlekey;
dvd_key_t p_key; dvd_key_t p_key;
int i_ret; int i_ret;
...@@ -166,15 +164,16 @@ extern int dvdcss_crack ( dvdcss_handle dvdcss, int i_block ) ...@@ -166,15 +164,16 @@ extern int dvdcss_crack ( dvdcss_handle dvdcss, int i_block )
} }
/* Check if we've already cracked this key */ /* Check if we've already cracked this key */
p_titlekey = dvdcss->p_keys; p_title = dvdcss->p_titles;
while( p_titlekey != NULL while( p_title != NULL
&& p_titlekey->p_next != NULL && p_title->p_next != NULL
&& p_titlekey->p_next->i_startlb < i_block ) && p_title->p_next->i_startlb <= i_block )
{ {
p_titlekey = p_titlekey->p_next; p_title = p_title->p_next;
} }
if( p_titlekey != NULL && p_titlekey->i_startlb == i_block ) if( p_title != NULL
&& p_title->i_startlb == i_block )
{ {
/* We've already cracked this key, nothing to do */ /* We've already cracked this key, nothing to do */
return 0; return 0;
...@@ -195,24 +194,39 @@ extern int dvdcss_crack ( dvdcss_handle dvdcss, int i_block ) ...@@ -195,24 +194,39 @@ extern int dvdcss_crack ( dvdcss_handle dvdcss, int i_block )
} }
/* Add key to keytable if it isn't empty */ /* Add key to keytable if it isn't empty */
if( p_key[0] || p_key[1] || p_key[2] || p_key[3] || p_key[4] ) if( p_key[0] | p_key[1] | p_key[2] | p_key[3] | p_key[4] )
{ {
dvd_title_t *p_newtitle;
/* Find our spot in the list */ /* Find our spot in the list */
pp_writekey = &(dvdcss->p_keys); p_newtitle = NULL;
pp_currentkey = pp_writekey; p_title = dvdcss->p_titles;
while( *pp_currentkey != NULL while( p_title != NULL
&& (*pp_currentkey)->i_startlb < i_block ) && p_title->i_startlb < i_block )
{ {
pp_writekey = pp_currentkey; p_newtitle = p_title;
pp_currentkey = &((*pp_currentkey)->p_next); p_title = p_title->p_next;
} }
/* Write in the new key */ /* Save the found title */
p_titlekey = *pp_writekey; p_title = p_newtitle;
*pp_writekey = malloc( sizeof( title_key_t ) );
(*pp_writekey)->i_startlb = i_block; /* Write in the new title and its key */
memcpy( (*pp_writekey)->p_key, p_key, KEY_SIZE ); p_newtitle = malloc( sizeof( dvd_title_t ) );
(*pp_writekey)->p_next = p_titlekey; p_newtitle->i_startlb = i_block;
memcpy( p_newtitle->p_key, p_key, KEY_SIZE );
/* Link the new title, either at the beginning or inside the list */
if( p_title == NULL )
{
dvdcss->p_titles = p_newtitle;
p_newtitle->p_next = NULL;
}
else
{
p_newtitle->p_next = p_title->p_next;
p_title->p_next = p_newtitle;
}
} }
return 0; return 0;
...@@ -225,7 +239,7 @@ extern int dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer, ...@@ -225,7 +239,7 @@ extern int dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer,
int i_blocks, int i_blocks,
int i_flags ) int i_flags )
{ {
title_key_t *p_current; dvd_title_t *p_title;
int i_ret, i_index; int i_ret, i_index;
i_ret = _dvdcss_read( dvdcss, p_buffer, i_blocks ); i_ret = _dvdcss_read( dvdcss, p_buffer, i_blocks );
...@@ -238,15 +252,15 @@ extern int dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer, ...@@ -238,15 +252,15 @@ extern int dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer,
} }
/* find our key */ /* find our key */
p_current = dvdcss->p_keys; p_title = dvdcss->p_titles;
while( p_current != NULL while( p_title != NULL
&& p_current->p_next && p_title->p_next
&& p_current->p_next->i_startlb < dvdcss->i_seekpos ) && p_title->p_next->i_startlb < dvdcss->i_seekpos )
{ {
p_current = p_current->p_next; p_title = p_title->p_next;
} }
if( p_current == NULL ) if( p_title == NULL )
{ {
/* no css key found to use, so no decryption to do */ /* no css key found to use, so no decryption to do */
return 0; return 0;
...@@ -255,7 +269,7 @@ extern int dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer, ...@@ -255,7 +269,7 @@ extern int dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer,
/* Decrypt the blocks we managed to read */ /* Decrypt the blocks we managed to read */
for( i_index = i_ret; i_index; i_index-- ) for( i_index = i_ret; i_index; i_index-- )
{ {
CSSDescrambleSector( p_current->p_key, p_buffer ); CSSDescrambleSector( p_title->p_key, p_buffer );
((u8*)p_buffer)[0x14] &= 0x8f; ((u8*)p_buffer)[0x14] &= 0x8f;
(u8*)p_buffer += DVDCSS_BLOCK_SIZE; (u8*)p_buffer += DVDCSS_BLOCK_SIZE;
} }
...@@ -271,7 +285,7 @@ extern int dvdcss_readv ( dvdcss_handle dvdcss, void *p_iovec, ...@@ -271,7 +285,7 @@ extern int dvdcss_readv ( dvdcss_handle dvdcss, void *p_iovec,
int i_flags ) int i_flags )
{ {
#define P_IOVEC ((struct iovec*)p_iovec) #define P_IOVEC ((struct iovec*)p_iovec)
title_key_t *p_current; dvd_title_t *p_title;
int i_ret, i_index; int i_ret, i_index;
void *iov_base; void *iov_base;
size_t iov_len; size_t iov_len;
...@@ -286,21 +300,20 @@ extern int dvdcss_readv ( dvdcss_handle dvdcss, void *p_iovec, ...@@ -286,21 +300,20 @@ extern int dvdcss_readv ( dvdcss_handle dvdcss, void *p_iovec,
} }
/* Find our key */ /* Find our key */
p_current = dvdcss->p_keys; p_title = dvdcss->p_titles;
while( p_current != NULL while( p_title != NULL
&& p_current->p_next && p_title->p_next != NULL
&& p_current->p_next->i_startlb < dvdcss->i_seekpos ) && p_title->p_next->i_startlb < dvdcss->i_seekpos )
{ {
p_current = p_current->p_next; p_title = p_title->p_next;
} }
if( p_current == NULL ) if( p_title == NULL )
{ {
/* no css key found to use, so no decryption to do */ /* no css key found to use, so no decryption to do */
return 0; return 0;
} }
/* Initialize loop for decryption */ /* Initialize loop for decryption */
iov_base = P_IOVEC->iov_base; iov_base = P_IOVEC->iov_base;
iov_len = P_IOVEC->iov_len; iov_len = P_IOVEC->iov_len;
...@@ -321,7 +334,7 @@ extern int dvdcss_readv ( dvdcss_handle dvdcss, void *p_iovec, ...@@ -321,7 +334,7 @@ extern int dvdcss_readv ( dvdcss_handle dvdcss, void *p_iovec,
iov_len = P_IOVEC->iov_len; iov_len = P_IOVEC->iov_len;
} }
CSSDescrambleSector( p_current->p_key, iov_base ); CSSDescrambleSector( p_title->p_key, iov_base );
((u8*)iov_base)[0x14] &= 0x8f; ((u8*)iov_base)[0x14] &= 0x8f;
(u8*)iov_base += DVDCSS_BLOCK_SIZE; (u8*)iov_base += DVDCSS_BLOCK_SIZE;
...@@ -337,16 +350,16 @@ extern int dvdcss_readv ( dvdcss_handle dvdcss, void *p_iovec, ...@@ -337,16 +350,16 @@ extern int dvdcss_readv ( dvdcss_handle dvdcss, void *p_iovec,
*****************************************************************************/ *****************************************************************************/
extern int dvdcss_close ( dvdcss_handle dvdcss ) extern int dvdcss_close ( dvdcss_handle dvdcss )
{ {
title_key_t *p_currentkey; dvd_title_t *p_title;
int i_ret; int i_ret;
/* Free our list of keys */ /* Free our list of keys */
p_currentkey = dvdcss->p_keys; p_title = dvdcss->p_titles;
while( p_currentkey ) while( p_title )
{ {
title_key_t *p_tmpkey = p_currentkey->p_next; dvd_title_t *p_tmptitle = p_title->p_next;
free( p_currentkey ); free( p_title );
p_currentkey = p_tmpkey; p_title = p_tmptitle;
} }
i_ret = _dvdcss_close( dvdcss ); i_ret = _dvdcss_close( dvdcss );
...@@ -487,13 +500,15 @@ static int _dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer, int i_blocks ) ...@@ -487,13 +500,15 @@ static int _dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer, int i_blocks )
#else #else
int i_bytes; int i_bytes;
i_bytes = read( dvdcss->i_fd, p_buffer, (size_t)i_blocks * DVDCSS_BLOCK_SIZE ); i_bytes = read( dvdcss->i_fd, p_buffer,
(size_t)i_blocks * DVDCSS_BLOCK_SIZE );
return i_bytes / DVDCSS_BLOCK_SIZE; return i_bytes / DVDCSS_BLOCK_SIZE;
#endif #endif
} }
static int _dvdcss_readv ( dvdcss_handle dvdcss, struct iovec *p_iovec, int i_blocks ) static int _dvdcss_readv ( dvdcss_handle dvdcss, struct iovec *p_iovec,
int i_blocks )
{ {
int i_read; int i_read;
...@@ -522,12 +537,12 @@ static int _win32_dvdcss_readv( int i_fd, struct iovec *p_iovec, ...@@ -522,12 +537,12 @@ static int _win32_dvdcss_readv( int i_fd, struct iovec *p_iovec,
if( WIN2K ) if( WIN2K )
{ {
for( i_index = i_num_buffers; i_index; i_index-- ) for( i_index = i_num_buffers; i_index; i_index-- )
{ {
i_len = p_iovec->iov_len; i_len = p_iovec->iov_len;
p_base = p_iovec->iov_base; p_base = p_iovec->iov_base;
if( i_len > 0 ) if( i_len > 0 )
{ {
unsigned long int i_bytes; unsigned long int i_bytes;
if( !ReadFile( (HANDLE) i_fd, p_base, i_len, &i_bytes, NULL ) ) if( !ReadFile( (HANDLE) i_fd, p_base, i_len, &i_bytes, NULL ) )
{ {
...@@ -539,46 +554,46 @@ static int _win32_dvdcss_readv( int i_fd, struct iovec *p_iovec, ...@@ -539,46 +554,46 @@ static int _win32_dvdcss_readv( int i_fd, struct iovec *p_iovec,
} }
i_blocks = i_bytes / DVDCSS_BLOCK_SIZE; i_blocks = i_bytes / DVDCSS_BLOCK_SIZE;
i_total += i_blocks; i_total += i_blocks;
if( i_blocks != (i_len / DVDCSS_BLOCK_SIZE) ) if( i_blocks != (i_len / DVDCSS_BLOCK_SIZE) )
{ {
/* we reached the end of the file */ /* we reached the end of the file */
return i_total; return i_total;
} }
} }
p_iovec++; p_iovec++;
} }
} }
else /* Win9x */ else /* Win9x */
{ {
for( i_index = i_num_buffers; i_index; i_index-- ) for( i_index = i_num_buffers; i_index; i_index-- )
{ {
i_len = p_iovec->iov_len / DVDCSS_BLOCK_SIZE; i_len = p_iovec->iov_len / DVDCSS_BLOCK_SIZE;
p_base = p_iovec->iov_base; p_base = p_iovec->iov_base;
if( i_len > 0 ) if( i_len > 0 )
{ {
i_blocks = _win32_dvdcss_aread( i_fd, p_base, i_len ); i_blocks = _win32_dvdcss_aread( i_fd, p_base, i_len );
if( i_blocks < 0 ) if( i_blocks < 0 )
{ {
return -1; /* idem */ return -1; /* idem */
} }
i_total += i_blocks; i_total += i_blocks;
if( i_blocks != i_len ) if( i_blocks != i_len )
{ {
/* we reached the end of the file or a signal interrupted /* we reached the end of the file or a signal interrupted
the read */ the read */
return i_total; return i_total;
} }
} }
p_iovec++; p_iovec++;
} }
} }
return i_total; return i_total;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* private.h: private DVD reading library data * private.h: private DVD reading library data
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: libdvdcss.h,v 1.4 2001/07/11 02:01:03 sam Exp $ * $Id: libdvdcss.h,v 1.5 2001/07/25 00:23:40 sam Exp $
* *
* Authors: Stphane Borel <stef@via.ecp.fr> * Authors: Stphane Borel <stef@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -39,7 +39,7 @@ struct dvdcss_s ...@@ -39,7 +39,7 @@ struct dvdcss_s
/* Decryption stuff */ /* Decryption stuff */
css_t css; css_t css;
boolean_t b_encrypted; boolean_t b_encrypted;
title_key_t *p_keys; dvd_title_t *p_titles;
/* Error management */ /* Error management */
char *psz_error; char *psz_error;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment