Commit 95ef185a authored by Stéphane Borel's avatar Stéphane Borel

* Beginning of support for encrypted DVDs.

* It only tests encryption and authenticates disc.

The decryption does not work now et it is very ugly but I'm working on it.
parent 2378ce90
......@@ -187,6 +187,7 @@ INTERFACE = src/interface/main.o \
INPUT = src/input/input_ps.o \
src/input/input_ts.o \
src/input/dvd_ifo.o \
src/input/dvd_css.o \
src/input/input_dvd.o \
src/input/mpeg_system.o \
src/input/input_ext-dec.o \
......
/*****************************************************************************
* css_table.h : Various tables needed by css unencryption
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
*
* Author: Stphane Borel <stef@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
u8 pi_css_mangle0[256] = {
0x00,0x81,0x03,0x82,0x06,0x87,0x05,0x84,0x0C,0x8D,0x0F,0x8E,0x0A,0x8B,0x09,0x88,
0x18,0x99,0x1B,0x9A,0x1E,0x9F,0x1D,0x9C,0x14,0x95,0x17,0x96,0x12,0x93,0x11,0x90,
0x30,0xB1,0x33,0xB2,0x36,0xB7,0x35,0xB4,0x3C,0xBD,0x3F,0xBE,0x3A,0xBB,0x39,0xB8,
0x28,0xA9,0x2B,0xAA,0x2E,0xAF,0x2D,0xAC,0x24,0xA5,0x27,0xA6,0x22,0xA3,0x21,0xA0,
0x60,0xE1,0x63,0xE2,0x66,0xE7,0x65,0xE4,0x6C,0xED,0x6F,0xEE,0x6A,0xEB,0x69,0xE8,
0x78,0xF9,0x7B,0xFA,0x7E,0xFF,0x7D,0xFC,0x74,0xF5,0x77,0xF6,0x72,0xF3,0x71,0xF0,
0x50,0xD1,0x53,0xD2,0x56,0xD7,0x55,0xD4,0x5C,0xDD,0x5F,0xDE,0x5A,0xDB,0x59,0xD8,
0x48,0xC9,0x4B,0xCA,0x4E,0xCF,0x4D,0xCC,0x44,0xC5,0x47,0xC6,0x42,0xC3,0x41,0xC0,
0xC0,0x41,0xC3,0x42,0xC6,0x47,0xC5,0x44,0xCC,0x4D,0xCF,0x4E,0xCA,0x4B,0xC9,0x48,
0xD8,0x59,0xDB,0x5A,0xDE,0x5F,0xDD,0x5C,0xD4,0x55,0xD7,0x56,0xD2,0x53,0xD1,0x50,
0xF0,0x71,0xF3,0x72,0xF6,0x77,0xF5,0x74,0xFC,0x7D,0xFF,0x7E,0xFA,0x7B,0xF9,0x78,
0xE8,0x69,0xEB,0x6A,0xEE,0x6F,0xED,0x6C,0xE4,0x65,0xE7,0x66,0xE2,0x63,0xE1,0x60,
0xA0,0x21,0xA3,0x22,0xA6,0x27,0xA5,0x24,0xAC,0x2D,0xAF,0x2E,0xAA,0x2B,0xA9,0x28,
0xB8,0x39,0xBB,0x3A,0xBE,0x3F,0xBD,0x3C,0xB4,0x35,0xB7,0x36,0xB2,0x33,0xB1,0x30,
0x90,0x11,0x93,0x12,0x96,0x17,0x95,0x14,0x9C,0x1D,0x9F,0x1E,0x9A,0x1B,0x99,0x18,
0x88,0x09,0x8B,0x0A,0x8E,0x0F,0x8D,0x0C,0x84,0x05,0x87,0x06,0x82,0x03,0x81,0x00
};
u8 pi_css_mangle1[256] = {
0xC4,0xCD,0xCE,0xCB,0xC8,0xC9,0xCA,0xCF,0xCC,0xC5,0xC6,0xC3,0xC0,0xC1,0xC2,0xC7,
0x14,0x1D,0x1E,0x1B,0x18,0x19,0x1A,0x1F,0x1C,0x15,0x16,0x13,0x10,0x11,0x12,0x17,
0x24,0x2D,0x2E,0x2B,0x28,0x29,0x2A,0x2F,0x2C,0x25,0x26,0x23,0x20,0x21,0x22,0x27,
0x34,0x3D,0x3E,0x3B,0x38,0x39,0x3A,0x3F,0x3C,0x35,0x36,0x33,0x30,0x31,0x32,0x37,
0x04,0x0D,0x0E,0x0B,0x08,0x09,0x0A,0x0F,0x0C,0x05,0x06,0x03,0x00,0x01,0x02,0x07,
0xD4,0xDD,0xDE,0xDB,0xD8,0xD9,0xDA,0xDF,0xDC,0xD5,0xD6,0xD3,0xD0,0xD1,0xD2,0xD7,
0xE4,0xED,0xEE,0xEB,0xE8,0xE9,0xEA,0xEF,0xEC,0xE5,0xE6,0xE3,0xE0,0xE1,0xE2,0xE7,
0xF4,0xFD,0xFE,0xFB,0xF8,0xF9,0xFA,0xFF,0xFC,0xF5,0xF6,0xF3,0xF0,0xF1,0xF2,0xF7,
0x44,0x4D,0x4E,0x4B,0x48,0x49,0x4A,0x4F,0x4C,0x45,0x46,0x43,0x40,0x41,0x42,0x47,
0x94,0x9D,0x9E,0x9B,0x98,0x99,0x9A,0x9F,0x9C,0x95,0x96,0x93,0x90,0x91,0x92,0x97,
0xA4,0xAD,0xAE,0xAB,0xA8,0xA9,0xAA,0xAF,0xAC,0xA5,0xA6,0xA3,0xA0,0xA1,0xA2,0xA7,
0xB4,0xBD,0xBE,0xBB,0xB8,0xB9,0xBA,0xBF,0xBC,0xB5,0xB6,0xB3,0xB0,0xB1,0xB2,0xB7,
0x84,0x8D,0x8E,0x8B,0x88,0x89,0x8A,0x8F,0x8C,0x85,0x86,0x83,0x80,0x81,0x82,0x87,
0x54,0x5D,0x5E,0x5B,0x58,0x59,0x5A,0x5F,0x5C,0x55,0x56,0x53,0x50,0x51,0x52,0x57,
0x64,0x6D,0x6E,0x6B,0x68,0x69,0x6A,0x6F,0x6C,0x65,0x66,0x63,0x60,0x61,0x62,0x67,
0x74,0x7D,0x7E,0x7B,0x78,0x79,0x7A,0x7F,0x7C,0x75,0x76,0x73,0x70,0x71,0x72,0x77
};
u8 pi_css_mangle2[256] = {
0xC4,0x24,0x14,0x34,0xCE,0x2E,0x1E,0x3E,0xCD,0x2D,0x1D,0x3D,0xCB,0x2B,0x1B,0x3B,
0x44,0xA4,0x94,0xB4,0x4E,0xAE,0x9E,0xBE,0x4D,0xAD,0x9D,0xBD,0x4B,0xAB,0x9B,0xBB,
0x04,0xE4,0xD4,0xF4,0x0E,0xEE,0xDE,0xFE,0x0D,0xED,0xDD,0xFD,0x0B,0xEB,0xDB,0xFB,
0x84,0x64,0x54,0x74,0x8E,0x6E,0x5E,0x7E,0x8D,0x6D,0x5D,0x7D,0x8B,0x6B,0x5B,0x7B,
0xCC,0x2C,0x1C,0x3C,0xC6,0x26,0x16,0x36,0xC5,0x25,0x15,0x35,0xC3,0x23,0x13,0x33,
0x4C,0xAC,0x9C,0xBC,0x46,0xA6,0x96,0xB6,0x45,0xA5,0x95,0xB5,0x43,0xA3,0x93,0xB3,
0x0C,0xEC,0xDC,0xFC,0x06,0xE6,0xD6,0xF6,0x05,0xE5,0xD5,0xF5,0x03,0xE3,0xD3,0xF3,
0x8C,0x6C,0x5C,0x7C,0x86,0x66,0x56,0x76,0x85,0x65,0x55,0x75,0x83,0x63,0x53,0x73,
0xC8,0x28,0x18,0x38,0xCA,0x2A,0x1A,0x3A,0xC9,0x29,0x19,0x39,0xCF,0x2F,0x1F,0x3F,
0x48,0xA8,0x98,0xB8,0x4A,0xAA,0x9A,0xBA,0x49,0xA9,0x99,0xB9,0x4F,0xAF,0x9F,0xBF,
0x08,0xE8,0xD8,0xF8,0x0A,0xEA,0xDA,0xFA,0x09,0xE9,0xD9,0xF9,0x0F,0xEF,0xDF,0xFF,
0x88,0x68,0x58,0x78,0x8A,0x6A,0x5A,0x7A,0x89,0x69,0x59,0x79,0x8F,0x6F,0x5F,0x7F,
0xC0,0x20,0x10,0x30,0xC2,0x22,0x12,0x32,0xC1,0x21,0x11,0x31,0xC7,0x27,0x17,0x37,
0x40,0xA0,0x90,0xB0,0x42,0xA2,0x92,0xB2,0x41,0xA1,0x91,0xB1,0x47,0xA7,0x97,0xB7,
0x00,0xE0,0xD0,0xF0,0x02,0xE2,0xD2,0xF2,0x01,0xE1,0xD1,0xF1,0x07,0xE7,0xD7,0xF7,
0x80,0x60,0x50,0x70,0x82,0x62,0x52,0x72,0x81,0x61,0x51,0x71,0x87,0x67,0x57,0x77
};
u8 pi_reverse[256] = {
0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0,
0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8,
0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4,
0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC,
0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2,
0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA,
0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6,
0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE,
0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1,
0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9,
0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5,
0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD,
0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3,
0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB,
0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7,
0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF
};
This diff is collapsed.
/*****************************************************************************
* dvd_css.h: Structures for DVD authentification and unscrambling
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
*
* Author: Stphane Borel <stef@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define KEY_SIZE 5
typedef unsigned char DVD40bitKey[KEY_SIZE];
typedef struct drive_key_s
{
u8 pi_challenge[2*KEY_SIZE];
u8 pi_key1[KEY_SIZE];
u8 pi_key2[KEY_SIZE];
u8 pi_key_check[KEY_SIZE];
u8 i_version;
} drive_key_t;
typedef struct title_key_s
{
u32 i_lba;
u8 key[KEY_SIZE];
} title_key_t;
typedef struct css_s
{
int i_fd;
boolean_t b_error;
int i_agid;
drive_key_t keys;
u8 pi_disc_key[2048];
int i_title_nb;
title_key_t* p_title_key;
} css_t;
/*****************************************************************************
* Prototypes in dvd_css.c
*****************************************************************************/
struct css_s CSSInit ( int );
int CSSGetKeys ( struct css_s* );
......@@ -39,10 +39,10 @@
*/
/*****************************************************************************
* IfoFindStart : When reading directly on a device, finds the offset to the
* IfoFindVMG : When reading directly on a device, finds the offset to the
* beginning of video_ts.ifo.
*****************************************************************************/
static int IfoFindStart( ifo_t* p_ifo )
static int IfoFindVMG( ifo_t* p_ifo )
{
char psz_ifo_start[12] = "DVDVIDEO-VMG";
char psz_test[12];
......@@ -103,7 +103,7 @@ ifo_t IfoInit( int i_fd )
* 512000 bytes is just another value :) */
ifo.i_pos = lseek64( ifo.i_fd, 250 *DVD_LB_SIZE, SEEK_SET );
/* FIXME : use udf filesystem to find the beginning of the file */
IfoFindStart( &ifo );
IfoFindVMG( &ifo );
return ifo;
}
......@@ -177,7 +177,7 @@ fprintf(stderr, "Pos : %lld Val : %llx\n", \
(long long)(p_ifo->i_pos - i_start), \
(long long)*(p_field) ); \
p_ifo->i_pos = \
lseek64( p_ifo->i_fd, p_ifo->i_pos + (i_len), SEEK_SET ); \
lseek64( p_ifo->i_fd, p_ifo->i_pos + (i_len), SEEK_SET );\
}
#define GETC( p_field ) \
......@@ -186,7 +186,7 @@ fprintf(stderr, "Pos : %lld Val : %llx\n", \
fprintf(stderr, "Pos : %lld Value : %d\n", \
(long long)(p_ifo->i_pos - i_start), \
*(p_field) ); \
p_ifo->i_pos = lseek64( p_ifo->i_fd , p_ifo->i_pos + 1 , SEEK_SET ); \
p_ifo->i_pos = lseek64( p_ifo->i_fd , p_ifo->i_pos + 1 , SEEK_SET );\
}
#define GETS( p_field ) \
......@@ -196,7 +196,7 @@ fprintf(stderr, "Pos : %lld Value : %d\n", \
fprintf(stderr, "Pos : %lld Value : %d\n", \
(long long)(p_ifo->i_pos - i_start), \
*(p_field) ); \
p_ifo->i_pos = lseek64( p_ifo->i_fd , p_ifo->i_pos + 2 , SEEK_SET ); \
p_ifo->i_pos = lseek64( p_ifo->i_fd , p_ifo->i_pos + 2 , SEEK_SET );\
}
#define GETL( p_field ) \
......@@ -206,7 +206,7 @@ fprintf(stderr, "Pos : %lld Value : %d\n", \
fprintf(stderr, "Pos : %lld Value : %d\n", \
(long long)(p_ifo->i_pos - i_start), \
*(p_field) ); \
p_ifo->i_pos = lseek64( p_ifo->i_fd , p_ifo->i_pos + 4 , SEEK_SET ); \
p_ifo->i_pos = lseek64( p_ifo->i_fd , p_ifo->i_pos + 4 , SEEK_SET );\
}
#define GETLL( p_field ) \
......@@ -216,7 +216,7 @@ fprintf(stderr, "Pos : %lld Value : %d\n", \
fprintf(stderr, "Pos : %lld Value : %lld\n", \
(long long)(p_ifo->i_pos - i_start), \
*(p_field) ); \
p_ifo->i_pos = lseek64( p_ifo->i_fd , p_ifo->i_pos + 8 , SEEK_SET ); \
p_ifo->i_pos = lseek64( p_ifo->i_fd , p_ifo->i_pos + 8 , SEEK_SET );\
}
#define FLUSH( i_len ) \
......@@ -1069,10 +1069,10 @@ void IfoRead( ifo_t* p_ifo )
p_ifo->b_error = 1;
return;
}
for( i=0 ; i<p_ifo->vmg.mat.i_tts_nb ; i++ )
for( i=0 ; i<1 /*p_ifo->vmg.mat.i_tts_nb*/ ; i++ )
{
fprintf( stderr, "######### VTS %d #############\n", i );
fprintf( stderr, "######### VTS %d #############\n", i+1 );
i_off = p_ifo->vmg.ptt_srpt.p_tts[i].i_ssector *DVD_LB_SIZE;
p_ifo->i_pos = lseek64( p_ifo->i_fd, i_off, SEEK_SET );
......
/*****************************************************************************
* ifo.h: Structures for ifo parsing
* dvd_ifo.h: Structures for ifo parsing
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
*
......@@ -484,8 +484,3 @@ typedef struct ifo_s
*****************************************************************************/
ifo_t IfoInit( int );
void IfoRead( ifo_t* );
/*****************************************************************************
* Prototypes in input_dvd.c
*****************************************************************************/
off64_t Seek64( int, off64_t, int);
......@@ -4,7 +4,7 @@
* decoders.
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: input.c,v 1.71 2001/01/16 05:04:25 sam Exp $
* $Id: input.c,v 1.72 2001/01/20 20:59:44 stef Exp $
*
* Authors:
*
......@@ -416,7 +416,7 @@ static void DvdOpen( input_thread_t * p_input )
{
intf_Msg( "input: opening DVD %s", p_input->p_config->p_source );
if( (p_input->i_handle = open( p_input->p_config->p_source,
O_RDONLY|O_LARGEFILE )) == (-1) )
O_RDONLY| O_NONBLOCK |O_LARGEFILE )) == (-1) )
{
intf_ErrMsg( "input error: cannot open device (%s)", strerror(errno) );
p_input->b_error = 1;
......
......@@ -2,7 +2,7 @@
* input_dvd.c: DVD reading
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: input_dvd.c,v 1.3 2001/01/16 04:41:20 stef Exp $
* $Id: input_dvd.c,v 1.4 2001/01/20 20:59:44 stef Exp $
*
* Author: Stphane Borel <stef@via.ecp.fr>
*
......@@ -30,10 +30,23 @@
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h>
#include <malloc.h>
#include <sys/ioctl.h>
//#if defined(__NetBSD__) || defined(__OpenBSD__)
//# include <sys/dvdio.h>
//#elif defined(__linux__)
#include <linux/cdrom.h>
//#else
//# error "Need the DVD ioctls"
//#endif
#include "config.h"
#include "common.h"
#include "threads.h"
......@@ -50,6 +63,7 @@
#include "input.h"
#include "dvd_ifo.h"
#include "dvd_css.h"
#include "input_dvd.h"
#include "mpeg_system.h"
......@@ -79,9 +93,18 @@ static void DeletePES ( void *, struct pes_packet_s * );
*****************************************************************************/
static int DVDProbe( input_thread_t * p_input )
{
/* verify that the first three bytes are 0x000001, or unscramble and
* re-do. */
return 1;
dvd_struct dvd;
dvd.type = DVD_STRUCT_COPYRIGHT;
dvd.copyright.layer_num = 0;
if( ioctl( p_input->i_handle, DVD_READ_STRUCT, &dvd ) < 0 )
{
intf_ErrMsg( "DVD ioctl error" );
return -1;
}
return dvd.copyright.cpst;
}
/*****************************************************************************
......@@ -102,18 +125,44 @@ static void DVDInit( input_thread_t * p_input )
p_input->p_plugin_data = (void *)p_method;
p_input->p_method_data = NULL;
p_method->i_fd = p_input->i_handle;
lseek64( p_input->i_handle, 0, SEEK_SET );
/* Ifo initialisation */
p_method->ifo = IfoInit( p_input->i_handle );
IfoRead( &(p_method->ifo) );
/* CSS authentication and keys */
if( ( p_method->b_encrypted = DVDProbe( p_input ) ) )
{
fprintf(stderr, " CSS Init start\n" );
p_method->css = CSSInit( p_input->i_handle );
fprintf(stderr, " CSS Init end\n" );
p_method->css.i_title_nb = 1/*p_method->ifo.vmg.ptt_srpt.i_nb*/;
#if 0
if( (p_title_key =
malloc( p_method->css.i_title_nb *sizeof(title_key_t) )) == NULL )
{
intf_ErrMsg( "Out of memory" );
p_input->b_error = 1;
return;
}
#endif
fprintf(stderr, " CSS Get start\n" );
CSSGetKeys( &(p_method->css) );
fprintf(stderr, " CSS Get end\n" );
}
i_start = p_method->ifo.p_vts[0].i_pos +
p_method->ifo.p_vts[0].mat.i_tt_vobs_ssector *DVD_LB_SIZE;
i_start = lseek64( p_input->i_handle, i_start, SEEK_SET );
fprintf(stderr, "Begin at : %lld\n", (long long)i_start );
#if 1
input_InitStream( p_input, sizeof( stream_ps_data_t ) );
input_AddProgram( p_input, 0, sizeof( stream_ps_data_t ) );
......@@ -232,6 +281,7 @@ static void DVDInit( input_thread_t * p_input )
}
else
{
#endif
/* The programs will be added when we read them. */
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.pp_programs[0]->b_is_ok = 0;
......@@ -270,6 +320,12 @@ static __inline__ int SafeRead( input_thread_t * p_input, byte_t * p_buffer,
default:
break;
}
#if 0
if( p_method->b_encrypted )
{
CSSDescrambleSector( p_method->css.p_title_key.key, p_buffer );
}
#endif
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.i_tell += i_nb;
vlc_mutex_unlock( &p_input->stream.stream_lock );
......
......@@ -25,6 +25,12 @@
*****************************************************************************/
typedef struct thread_dvd_data_s
{
int i_fd;
boolean_t b_encrypted;
/* Scrambling Information */
struct css_s css;
/* Structure that contains all information of the DVD */
struct ifo_s ifo;
} thread_dvd_data_t;
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