
  Here is the patch again, including some code to free the list I
created. :(

-- 
Billy Biggs                     bbiggs@dumbterm.net
http://www.billybiggs.com/      wbiggs@uwaterloo.ca


-- Attached file included as plaintext by Listar --

diff -urN libdvdcss-0.0.1/extras/libdvdcss/css.c libdvdcss-0.0.1-mod/extras/libdvdcss/css.c
--- libdvdcss-0.0.1/extras/libdvdcss/css.c	Wed Jun 13 22:47:44 2001
+++ libdvdcss-0.0.1-mod/extras/libdvdcss/css.c	Fri Jun 29 11:27:41 2001
@@ -275,12 +275,6 @@
     }
     memcpy( dvdcss->css.disc.pi_key_check, p_buffer, 2048 );
 
-    /* initialize title key to know it empty */
-    for( i = 0 ; i < KEY_SIZE ; i++ )
-    {
-        dvdcss->css.pi_title_key[i] = 0;
-    }
-
     /* Test authentication success */
     switch( CSSGetASF( dvdcss ) )
     {
@@ -309,7 +303,7 @@
  *****************************************************************************
  * The DVD should have been opened and authenticated before.
  *****************************************************************************/
-int CSSGetKey( dvdcss_handle dvdcss )
+int CSSGetKey( dvdcss_handle dvdcss, off_t i_pos, dvd_key_t pi_title_key )
 {
 #ifdef HAVE_CSS
     /*
@@ -319,7 +313,6 @@
      */
     u8          pi_buf[0x800];
     dvd_key_t   pi_key;
-    off_t       i_pos;
     boolean_t   b_encrypted;
     boolean_t   b_stop_scanning;
     int         i_blocks_read;
@@ -335,9 +328,6 @@
     b_encrypted = 0;
     b_stop_scanning = 0;
 
-    /* Position of the title on the disc */
-    i_pos = (off_t)dvdcss->css.i_title_pos;
-
     do {
     i_pos = dvdcss_seek( dvdcss, i_pos );
     i_blocks_read = dvdcss_read( dvdcss, pi_buf, 1, DVDCSS_NOFLAGS );
@@ -377,7 +367,7 @@
 
     if( b_stop_scanning)
     {
-            memcpy( dvdcss->css.pi_title_key,
+            memcpy( pi_title_key,
                     &pi_key, sizeof(dvd_key_t) );
         _dvdcss_debug( dvdcss, "vts key initialized" );
         return 0;
diff -urN libdvdcss-0.0.1/extras/libdvdcss/css.h libdvdcss-0.0.1-mod/extras/libdvdcss/css.h
--- libdvdcss-0.0.1/extras/libdvdcss/css.h	Tue Jun 12 18:14:44 2001
+++ libdvdcss-0.0.1-mod/extras/libdvdcss/css.h	Fri Jun 29 11:26:43 2001
@@ -39,20 +39,20 @@
     u8              i_varient;
 } disc_t;
 
-typedef struct title_key_s
+typedef struct title_key_s title_key_t;
+
+struct title_key_s
 {
-    int             i_occ;
+    int             i_startlb;
     dvd_key_t       pi_key;
-} title_key_t;
+    title_key_t    *next;
+};
 
 typedef struct css_s
 {
     int             i_agid;
     disc_t          disc;
     u8              pi_disc_key[2048];
-    int             i_title;
-    off_t           i_title_pos;
-    dvd_key_t       pi_title_key;
 } css_t;
 
 /*****************************************************************************
@@ -62,6 +62,7 @@
 
 int   CSSTest             ( dvdcss_handle );
 int   CSSInit             ( dvdcss_handle );
-int   CSSGetKey           ( dvdcss_handle );
+int   CSSGetKey           ( dvdcss_handle dvdcss, off_t ipos,
+                            dvd_key_t pi_title_key );
 int   CSSDescrambleSector ( u8 * , u8 * );
 
diff -urN libdvdcss-0.0.1/extras/libdvdcss/libdvdcss.c libdvdcss-0.0.1-mod/extras/libdvdcss/libdvdcss.c
--- libdvdcss-0.0.1/extras/libdvdcss/libdvdcss.c	Wed Jun 13 22:47:44 2001
+++ libdvdcss-0.0.1-mod/extras/libdvdcss/libdvdcss.c	Fri Jun 29 11:53:02 2001
@@ -94,6 +94,7 @@
     }
 
     /* Initialize structure */
+    dvdcss->pi_key_list = NULL;
     dvdcss->b_debug = i_flags & DVDCSS_INIT_DEBUG;
     dvdcss->b_errors = !(i_flags & DVDCSS_INIT_QUIET);
     dvdcss->psz_error = "no error";
@@ -151,20 +152,36 @@
 /*****************************************************************************
  * dvdcss_crack: crack the current title key
  *****************************************************************************/
-extern int dvdcss_crack ( dvdcss_handle dvdcss, int i_title, int i_block )
+extern int dvdcss_crack ( dvdcss_handle dvdcss, int i_block )
 {
-    int i_ret;
+    title_key_t **pi_write_key;
+    title_key_t **pi_cur_key;
+    title_key_t *pi_title_key;
+    dvd_key_t pi_tmp_key;
+    boolean_t b_empty;
+    int i_ret, i;
 
     if( ! dvdcss->b_encrypted )
     {
         return 0;
     }
 
-    /* Crack CSS title key for current VTS */
-    dvdcss->css.i_title = i_title;
-    dvdcss->css.i_title_pos = i_block;
+    /* Check if we've already cracked this key */
+    pi_title_key = dvdcss->pi_key_list;
+    while( pi_title_key && pi_title_key->next
+                        && pi_title_key->next->i_startlb < i_block )
+    {
+        pi_title_key = pi_title_key->next;
+    }
+
+    if( pi_title_key && pi_title_key->i_startlb == i_block )
+    {
+        /* We've already cracked this key, nothing to do */
+        return 0;
+    }
 
-    i_ret = CSSGetKey( dvdcss );
+    /* Crack CSS title key for current VTS */
+    i_ret = CSSGetKey( dvdcss, i_block, pi_tmp_key );
 
     if( i_ret < 0 )
     {
@@ -177,6 +194,36 @@
         return -1;
     }
 
+    /* Add key to keytable if it isn't empty */
+    b_empty = 1;
+    for( i = 0 ; i < KEY_SIZE ; i++ )
+    {
+        if( pi_tmp_key[ i ] )
+        {
+            b_empty = 0;
+            break;
+        }
+    }
+
+    if( !b_empty )
+    {
+        /* Find our spot in the list */
+        pi_write_key = &(dvdcss->pi_key_list);
+        pi_cur_key = pi_write_key;
+        while( *pi_cur_key && (*pi_cur_key)->i_startlb < i_block )
+        {
+            pi_write_key = pi_cur_key;
+            pi_cur_key = &((*pi_cur_key)->next);
+        }
+
+        /* Write in the new key */
+        pi_title_key = *pi_write_key;
+        *pi_write_key = malloc( sizeof( title_key_t ) );
+        (*pi_write_key)->i_startlb = i_block;
+        memcpy( (*pi_write_key)->pi_key, pi_tmp_key, KEY_SIZE );
+        (*pi_write_key)->next = pi_title_key;
+    }
+
     return 0;
 }
 
@@ -187,6 +234,7 @@
                                                int i_blocks,
                                                int i_flags )
 {
+    title_key_t *curpos;
     int i_ret;
 
     i_ret = _dvdcss_read( dvdcss, p_buffer, i_blocks );
@@ -198,9 +246,22 @@
         return i_ret;
     }
 
+    /* find our key */
+    curpos = dvdcss->pi_key_list;
+    while( curpos && curpos->next && curpos->next->i_startlb < dvdcss->i_seekpos )
+    {
+        curpos = curpos->next;
+    }
+
+    if( !curpos )
+    {
+        /* no css key found to use, so no decryption to do */
+        return 0;
+    }
+
     while( i_ret )
     {
-        CSSDescrambleSector( dvdcss->css.pi_title_key, p_buffer );
+        CSSDescrambleSector( curpos->pi_key, p_buffer );
         ((u8*)p_buffer)[0x14] &= 0x8f;
         (u8*)p_buffer += DVDCSS_BLOCK_SIZE;
         i_ret--;
@@ -217,6 +278,7 @@
                                                 int i_flags )
 {
 #define P_IOVEC ((struct iovec*)p_iovec)
+    title_key_t *curpos;
     int i_ret;
     void *iov_base;
     size_t iov_len;
@@ -230,6 +292,20 @@
         return i_ret;
     }
 
+    /* find our key */
+    curpos = dvdcss->pi_key_list;
+    while( curpos && curpos->next && curpos->next->i_startlb < dvdcss->i_seekpos )
+    {
+        curpos = curpos->next;
+    }
+
+    if( !curpos )
+    {
+        /* no css key found to use, so no decryption to do */
+        return 0;
+    }
+
+
     /* Initialize loop for decryption */
     iov_base = P_IOVEC->iov_base;
     iov_len = P_IOVEC->iov_len;
@@ -249,7 +325,7 @@
             iov_len = P_IOVEC->iov_len;
         }
 
-        CSSDescrambleSector( dvdcss->css.pi_title_key, iov_base );
+        CSSDescrambleSector( curpos->pi_key, iov_base );
         ((u8*)iov_base)[0x14] &= 0x8f;
 
         (u8*)iov_base += DVDCSS_BLOCK_SIZE;
@@ -267,8 +343,18 @@
  *****************************************************************************/
 extern int dvdcss_close ( dvdcss_handle dvdcss )
 {
+    title_key_t *pi_cur_key;
     int i_ret;
 
+    /* Free our list of keys */
+    pi_cur_key = dvdcss->pi_key_list;
+    while( pi_cur_key )
+    {
+        title_key_t *pi_tmp_key = pi_cur_key->next;
+        free( pi_cur_key );
+        pi_cur_key = pi_tmp_key;
+    }
+
     i_ret = _dvdcss_close( dvdcss );
 
     if( i_ret < 0 )
@@ -346,6 +432,8 @@
 {
     off_t i_read;
 
+    dvdcss->i_seekpos = i_blocks;
+
 #if defined( WIN32 )
     if( WIN2K )
     {
@@ -683,9 +771,9 @@
 
     if(ssc.SRB_Status != SS_COMP)
     {
-		return -1;
+        return -1;
     }
-	
+
     fd->i_pos += i_len;
 
     return i_len;
diff -urN libdvdcss-0.0.1/extras/libdvdcss/libdvdcss.h libdvdcss-0.0.1-mod/extras/libdvdcss/libdvdcss.h
--- libdvdcss-0.0.1/extras/libdvdcss/libdvdcss.h	Wed Jun 13 22:47:44 2001
+++ libdvdcss-0.0.1-mod/extras/libdvdcss/libdvdcss.h	Fri Jun 29 11:26:30 2001
@@ -34,10 +34,12 @@
 {
     /* File descriptor */
     int i_fd;
+    int i_seekpos;
 
     /* Decryption stuff */
-    css_t     css;
-    boolean_t b_encrypted;
+    css_t        css;
+    boolean_t    b_encrypted;
+    title_key_t *pi_key_list;
 
     /* Error management */
     char     *psz_error;
diff -urN libdvdcss-0.0.1/extras/libdvdcss/videolan/dvdcss.h libdvdcss-0.0.1-mod/extras/libdvdcss/videolan/dvdcss.h
--- libdvdcss-0.0.1/extras/libdvdcss/videolan/dvdcss.h	Wed Jun 13 21:49:44 2001
+++ libdvdcss-0.0.1-mod/extras/libdvdcss/videolan/dvdcss.h	Fri Jun 29 11:34:29 2001
@@ -46,7 +46,6 @@
                                     int i_flags );
 extern int           dvdcss_close ( dvdcss_handle );
 extern int           dvdcss_crack ( dvdcss_handle,
-                                    int i_title,
                                     int i_block );
 extern int           dvdcss_seek  ( dvdcss_handle,
                                     int i_blocks );
Binary files libdvdcss-0.0.1/lib/libdvdcss.a and libdvdcss-0.0.1-mod/lib/libdvdcss.a differ
Binary files libdvdcss-0.0.1/lib/libdvdcss.so and libdvdcss-0.0.1-mod/lib/libdvdcss.so differ
Binary files libdvdcss-0.0.1/lib/libdvdcss.so.0 and libdvdcss-0.0.1-mod/lib/libdvdcss.so.0 differ
Binary files libdvdcss-0.0.1/lib/libdvdcss.so.0.0.1 and libdvdcss-0.0.1-mod/lib/libdvdcss.so.0.0.1 differ



