summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:17:32 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:17:32 +0000
commitb0aad0a966223e66badae8998b35500741e8a7a3 (patch)
treecf49334f2e02738f47dbd09c413b74c248c4901a /test
parentInitial commit. (diff)
downloadlibdvdcss-b0aad0a966223e66badae8998b35500741e8a7a3.tar.xz
libdvdcss-b0aad0a966223e66badae8998b35500741e8a7a3.zip
Adding upstream version 1.4.3.upstream/1.4.3upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'test')
-rw-r--r--test/csstest.c126
-rw-r--r--test/dvd_region.c297
2 files changed, 423 insertions, 0 deletions
diff --git a/test/csstest.c b/test/csstest.c
new file mode 100644
index 0000000..d09565a
--- /dev/null
+++ b/test/csstest.c
@@ -0,0 +1,126 @@
+/* csstest.c - test program for libdvdcss
+ *
+ * Sam Hocevar <sam@zoy.org> - 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 <stdio.h>
+#include <stdlib.h>
+
+#include <dvdcss/dvdcss.h>
+
+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 <target> <sector>\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" );
+}
diff --git a/test/dvd_region.c b/test/dvd_region.c
new file mode 100644
index 0000000..40b15c8
--- /dev/null
+++ b/test/dvd_region.c
@@ -0,0 +1,297 @@
+/*
+ * Set / inspect region settings on a DVD drive. This is most interesting
+ * on a RPC Phase-2 drive, of course.
+ *
+ * Usage: dvd_region [ -d device ] [ [ -s ] [ -r region ] ]
+ *
+ * Based on code from Jens Axboe <axboe@suse.de>.
+ *
+ * FIXME: This code does _not_ work yet.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <getopt.h>
+
+#include <dvdcss/dvdcss.h>
+
+#include "config.h"
+#include "common.h"
+#include "ioctl.h"
+#include "libdvdcss.h"
+
+/* On non-Linux platforms static functions from ioctl.c are used. */
+#include "ioctl.c"
+
+#define DEFAULT_DEVICE "/dev/dvd"
+
+/*****************************************************************************
+ * ioctl_SendRPC: set RPC status for the drive
+ *****************************************************************************/
+static int ioctl_SendRPC( int i_fd, int i_pdrc )
+{
+ int i_ret;
+
+ /* Shut up warnings about unused parameters. */
+ (void)i_fd;
+ (void)i_pdrc;
+
+#if defined( HAVE_LINUX_DVD_STRUCT ) && defined( DVD_HOST_SEND_RPC_STATE )
+ dvd_authinfo auth_info = { 0 };
+
+ auth_info.type = DVD_HOST_SEND_RPC_STATE;
+ auth_info.hrpcs.pdrc = i_pdrc;
+
+ i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
+
+#elif defined( HAVE_LINUX_DVD_STRUCT )
+ /* FIXME: OpenBSD doesn't know this */
+ i_ret = -1;
+
+#elif defined( HAVE_BSD_DVD_STRUCT )
+ struct dvd_authinfo auth_info = { 0 };
+
+ auth_info.format = DVD_SEND_RPC;
+ auth_info.region = i_pdrc;
+
+ i_ret = ioctl( i_fd, DVDIOCSENDKEY, &auth_info );
+
+#elif defined( __HAIKU__ )
+ INIT_RDC( GPCMD_SEND_KEY, 8 );
+
+ rdc.command[ 10 ] = DVD_SEND_RPC;
+
+ p_buffer[ 1 ] = 6;
+ p_buffer[ 4 ] = i_pdrc;
+
+ i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
+
+#elif defined( SOLARIS_USCSI )
+ INIT_USCSI( GPCMD_SEND_KEY, 8 );
+
+ rs_cdb.cdb_opaque[ 10 ] = DVD_SEND_RPC;
+
+ p_buffer[ 1 ] = 6;
+ p_buffer[ 4 ] = i_pdrc;
+
+ i_ret = SolarisSendUSCSI( i_fd, &sc );
+
+ if( i_ret < 0 || sc.uscsi_status )
+ {
+ i_ret = -1;
+ }
+
+#elif defined( DARWIN_DVD_IOCTL )
+ INIT_DVDIOCTL( dk_dvd_send_key_t, DVDRegionPlaybackControlInfo,
+ kDVDKeyFormatSetRegion );
+
+ dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
+ dvdbs.driveRegion = i_pdrc;
+
+ i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
+
+#elif defined( _WIN32 )
+ DWORD tmp;
+ SCSI_PASS_THROUGH_DIRECT sptd = { 0 };
+ uint8_t p_buffer[8];
+ sptd.Length = sizeof( SCSI_PASS_THROUGH_DIRECT );
+ sptd.DataBuffer = p_buffer;
+ sptd.DataTransferLength = sizeof( p_buffer );
+ WinInitSPTD( &sptd, GPCMD_SEND_KEY );
+
+ sptd.Cdb[ 10 ] = DVD_SEND_RPC;
+
+ p_buffer[ 1 ] = 6;
+ p_buffer[ 4 ] = i_pdrc;
+
+ i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_SCSI_PASS_THROUGH_DIRECT,
+ &sptd, sizeof( SCSI_PASS_THROUGH_DIRECT ),
+ &sptd, sizeof( SCSI_PASS_THROUGH_DIRECT ),
+ &tmp, NULL ) ? 0 : -1;
+
+#elif defined( __QNXNTO__ )
+
+ INIT_CPT( GPCMD_SEND_KEY, 8 );
+
+ p_cpt->cam_cdb[ 10 ] = DVD_SEND_RPC;
+
+ p_buffer[ 1 ] = 6;
+ p_buffer[ 4 ] = i_pdrc;
+
+ i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
+
+#elif defined( __OS2__ )
+ INIT_SSC( GPCMD_SEND_KEY, 8 );
+
+ sdc.command[ 10 ] = DVD_SEND_RPC;
+
+ p_buffer[ 1 ] = 6;
+ p_buffer[ 4 ] = i_pdrc;
+
+ i_ret = DosDevIOCtl( i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
+ &sdc, sizeof(sdc), &ulParamLen,
+ p_buffer, sizeof(p_buffer), &ulDataLen );
+
+#else
+# error "DVD ioctls are unavailable on this system"
+
+#endif
+ return i_ret;
+}
+
+static int set_region(int fd, int region)
+{
+ int ret, region_mask;
+
+ if(region > 8 || region <= 0) {
+ printf("Invalid region( %d)\n", region);
+ return 1;
+ }
+ printf("Setting drive region can only be done a finite "
+ "number of times, press Ctrl-C now to cancel!\n");
+ /* Discard returned character, just wait for any key as confirmation. */
+ (void) getchar();
+
+ region_mask = 0xff & ~(1 << (region - 1));
+ printf("Setting region to %d( %x)\n", region, region_mask);
+ if( (ret = ioctl_SendRPC(fd, region_mask)) < 0) {
+ perror("dvd_region");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int print_region(int fd)
+{
+ int type, region_mask, rpc_scheme;
+ int region = 1;
+ int ret;
+
+ printf("Drive region info:\n");
+
+ if( (ret = ioctl_ReportRPC(fd, &type, &region_mask, &rpc_scheme)) < 0) {
+ perror("dvd_region");
+ return ret;
+ }
+
+ printf("Type: ");
+ switch( type ) {
+ case 0:
+ printf("No drive region setting\n");
+ break;
+ case 1:
+ printf("Drive region is set\n");
+ break;
+ case 2:
+ printf("Drive region is set, with additional "
+ "restrictions required to make a change\n");
+ break;
+ case 3:
+ printf("Drive region has been set permanently, but "
+ "may be reset by the vendor if necessary\n");
+ break;
+ default:
+ printf("Invalid( %x)\n", type);
+ break;
+ }
+
+ printf("Region: ");
+ if( region_mask)
+ while(region_mask) {
+ if( !(region_mask & 1) )
+ printf("%d playable\n", region);
+ region++;
+ region_mask >>= 1;
+ }
+ else
+ printf("non-RPC( all)\n");
+
+ printf("RPC Scheme: ");
+ switch( rpc_scheme ) {
+ case 0:
+ printf("The Logical Unit does not enforce Regional "
+ "Playback Control (RPC).\n");
+ break;
+ case 1:
+ printf("The Logical Unit _shall_ adhere to the "
+ "specification and all requirements of the "
+ "Content Scrambling System (CSS) license "
+ "agreement concerning RPC.\n");
+ break;
+ default:
+ printf("Reserved( %x)\n", rpc_scheme);
+ }
+
+ return 0;
+}
+
+static void usage(void)
+{
+ fprintf( stderr,
+ "Usage: dvd_region [ -d device ] [ [ -s ] [ -r region ] ]\n" );
+}
+
+int main(int argc, char *argv[])
+{
+ char device_name[FILENAME_MAX], c, set, region = 0;
+ int ret;
+ dvdcss_t dvdcss;
+
+ strcpy(device_name, DEFAULT_DEVICE);
+ set = 0;
+ while( (c = getopt(argc, argv, "d:sr:h?")) != EOF ) {
+ switch( c ) {
+ case 'd':
+ strncpy(device_name, optarg, FILENAME_MAX - 1);
+ break;
+ case 's':
+ set = 1;
+ break;
+ case 'r':
+ region = strtoul(optarg, NULL, 10);
+ printf("region %d\n", region);
+ break;
+ case 'h':
+ case '?':
+ default:
+ usage();
+ return -1;
+ break;
+ }
+ }
+
+ if( optind != argc ) {
+ fprintf(stderr, "Unknown argument\n");
+ usage();
+ return -1;
+ }
+
+ if( !(dvdcss = dvdcss_open(device_name)) ) {
+ usage();
+ return 1;
+ }
+
+ {
+ int copyright;
+ ret = ioctl_ReadCopyright( dvdcss->i_fd, 0, &copyright );
+ printf( "ret %d, copyright %d\n", ret, copyright );
+ }
+
+ if( (ret = print_region(dvdcss->i_fd)) < 0 )
+ return ret;
+
+ if( set ) {
+ if( !region ) {
+ fprintf( stderr, "you must specify the region!\n" );
+ exit(0);
+ }
+
+ if( (ret = set_region(dvdcss->i_fd, region)) < 0 )
+ return ret;
+ }
+
+ exit( 0 );
+}