/* csstest.c - test program for libdvdcss * * Sam Hocevar - June 2001 * Updated on Nov 13th 2001 for libdvdcss version 1.0.0 * Additional error checks on Aug 9th 2002 * Aligned data reads on Jan 28th 2003 * * This piece of code is public domain */ #include #include #include static int isscrambled( unsigned char * ); static void dumpsector ( unsigned char * ); int main( int i_argc, char *ppsz_argv[] ) { dvdcss_t dvdcss; unsigned char p_data[ DVDCSS_BLOCK_SIZE * 2 ]; unsigned char *p_buffer; unsigned int i_sector; int i_ret; /* Check for 2 arguments */ if( i_argc != 3 ) { printf( "usage: %s \n", ppsz_argv[0] ); printf( "examples:\n" ); printf( " %s /dev/hdc 1024\n", ppsz_argv[0] ); printf( " %s D: 1024\n", ppsz_argv[0] ); printf( " %s scrambledfile.vob 1024\n", ppsz_argv[0] ); return -1; } /* Save the requested sector */ i_sector = atoi( ppsz_argv[2] ); /* Initialize libdvdcss */ dvdcss = dvdcss_open( ppsz_argv[1] ); if( dvdcss == NULL ) { printf( "argh ! couldn't open DVD (%s)\n", ppsz_argv[1] ); return -1; } /* Align our read buffer */ p_buffer = p_data + DVDCSS_BLOCK_SIZE - ((long int)p_data & (DVDCSS_BLOCK_SIZE-1)); /* Set the file descriptor at sector i_sector and read one sector */ i_ret = dvdcss_seek( dvdcss, i_sector, DVDCSS_NOFLAGS ); if( i_ret != (int)i_sector ) { printf( "seek failed (%s)\n", dvdcss_error( dvdcss ) ); dvdcss_close( dvdcss ); return i_ret; } i_ret = dvdcss_read( dvdcss, p_buffer, 1, DVDCSS_NOFLAGS ); if( i_ret != 1 ) { printf( "read failed (%s)\n", dvdcss_error( dvdcss ) ); dvdcss_close( dvdcss ); return i_ret; } /* Print the sector */ printf( "requested sector: " ); dumpsector( p_buffer ); /* Check if sector was encrypted */ if( isscrambled( p_buffer ) ) { /* Set the file descriptor position to the previous location */ /* ... and get the appropriate key for this sector */ i_ret = dvdcss_seek( dvdcss, i_sector, DVDCSS_SEEK_KEY ); if( i_ret != (int)i_sector ) { printf( "seek failed (%s)\n", dvdcss_error( dvdcss ) ); dvdcss_close( dvdcss ); return i_ret; } /* Read sector again, and decrypt it on the fly */ i_ret = dvdcss_read( dvdcss, p_buffer, 1, DVDCSS_READ_DECRYPT ); if( i_ret != 1 ) { printf( "read failed (%s)\n", dvdcss_error( dvdcss ) ); dvdcss_close( dvdcss ); return i_ret; } /* Print the decrypted sector */ printf( "unscrambled sector: " ); dumpsector( p_buffer ); } else { printf( "sector is not scrambled\n" ); } /* Close the device */ i_ret = dvdcss_close( dvdcss ); return i_ret; } /* Check if a sector is scrambled */ static int isscrambled( unsigned char *p_buffer ) { return p_buffer[ 0x14 ] & 0x30; } /* Print parts of a 2048 bytes buffer */ static void dumpsector( unsigned char *p_buffer ) { int i_amount = 4; for( ; i_amount ; i_amount--, p_buffer++ ) printf( "%.2x", *p_buffer ); printf( "..." ); i_amount = 22; p_buffer += 200; for( ; i_amount ; i_amount--, p_buffer++ ) printf( "%.2x", *p_buffer ); printf( "...\n" ); }