LinuxNotesDvdRegion
From IckyWiki
dvd_region.c:
/*
* 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 ] ]
*
* Jens Axboe <axboe@suse.de>
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <fcntl.h>
#include <linux/cdrom.h>
#include <sys/ioctl.h>
#define DEFAULT_DEVICE "/dev/dvd"
int do_region(int fd, dvd_authinfo *ai, int set, int region)
{
int ret;
ai->type = DVD_LU_SEND_RPC_STATE;
if ((ret = ioctl(fd, DVD_AUTH, ai)) < 0) {
perror("do_region get");
return ret;
}
if (set) {
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();
ai->type = DVD_HOST_SEND_RPC_STATE;
ai->hrpcs.pdrc = ~(1 << (region - 1));
printf("Setting region to %d (%x)\n", region, ai->hrpcs.pdrc);
if ((ret = ioctl(fd, DVD_AUTH, ai)) < 0) {
perror("do_region set");
return ret;
}
}
return 0;
}
void print_region(dvd_authinfo *ai)
{
printf("Drive region info:\n");
printf("Type: ");
switch (ai->lrpcs.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", ai->lrpcs.type);
break;
}
printf("%d vendor resets available\n", ai->lrpcs.vra);
printf("%d user controlled changes available\n", ai->lrpcs.ucca);
printf("Region: ");
if (ai->lrpcs.region_mask)
printf("%d playable\n", ffs(~ai->lrpcs.region_mask));
else
printf("non-rpc (all)\n");
printf("RPC Scheme: ");
switch (ai->lrpcs.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", ai->lrpcs.rpc_scheme);
}
}
int main(int argc, char *argv[])
{
char device_name[FILENAME_MAX], c, set, get, region;
dvd_authinfo ai;
int fd, ret;
strcpy(device_name, DEFAULT_DEVICE);
set = 0;
get = 1;
while ((c = getopt(argc, argv, "d:sr:")) != 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;
}
}
if ((fd = open(device_name, O_RDONLY | O_NONBLOCK)) < 0) {
perror("open");
return 1;
}
memset(&ai, 0, sizeof(ai));
if ((ret = do_region(fd, &ai, 0, 0)))
return ret;
if (set)
if ((ret = do_region(fd, &ai, 1, region)) < 0)
return ret;
print_region(&ai);
return 0;
}
