shithub: libdvdcss

Download patch

ref: 6aa0ad6b9871d206fc0e582883297e117d6f0c5d
parent: 517fa8b08d106c800f01c4f042d2b68d7036abd2
author: Håkan Hjort <[email protected]>
date: Sun Jul 14 07:44:57 EDT 2002

New utility for querying (and eventualy setting) the region of a DVD drive
using the ioctl wrappers in libdvdcss.


--- /dev/null
+++ b/test/dvd_region.c
@@ -1,0 +1,188 @@
+/*
+ * 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 <[email protected]>.
+ *
+ * FIXME:  This code does _not_ work yet.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "dvdcss/dvdcss.h"
+
+#include "config.h"
+#include "common.h"
+#include "ioctl.h"
+
+#define DEFAULT_DEVICE "/dev/dvd"
+
+int set_region(int fd, int region)
+{
+#if 0
+  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");
+  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;
+  }
+#endif
+  return 0;
+}
+
+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("%d vendor resets available\n", ai->lrpcs.vra);
+  // printf("%d user controlled changes available\n", ai->lrpcs.ucca);
+  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 Region " \
+	   "Playback Controls( RPC)\n");
+    break;
+  case 1:
+    printf("The Logical Unit _shall_ adhere to the "
+	   "specification and all requirements of the " \
+	   "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, get, region = 0;
+  int fd, ret;
+
+  strcpy(device_name, DEFAULT_DEVICE);
+  set = 0;
+  get = 1;
+  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;
+  }
+
+  /* Print version number */
+  printf( "found libdvdcss version %s\n", dvdcss_interface_2 );
+
+
+  if( (fd = open(device_name, O_RDONLY | O_NONBLOCK)) < 0 ) {
+    perror("open");
+    usage();
+    return 1;
+  }
+
+  {
+    int copyright;
+    ret = ioctl_ReadCopyright( fd, 0, &copyright );
+    printf( "ret %d, copyright %d\n", ret, copyright );
+  }
+
+  if( (ret = print_region(fd)) < 0 )
+    return ret;
+
+  if( set ) {
+    if( !region ) {
+      fprintf( stderr, "you must specify the region!\n" );
+      exit(0);
+    }
+    
+    fprintf( stderr, "setting the region is not supported yet!\n");
+    exit( 1 );
+    
+    if( (ret = set_region(fd, region)) < 0 )
+      return ret;
+  }
+
+  exit( 0 );
+}