Click here to Skip to main content
15,879,326 members
Articles / Programming Languages / C++
Article

How to retrieve DVD region information

Rate me:
Please Sign up or sign in to vote.
4.58/5 (11 votes)
1 Aug 20064 min read 77.1K   1K   19   12
An article showing you how to programmatically retrieve DVD region information

Sample Image - mydvdregion.jpg

Introduction

I've been playing with DVDs recently and stumbled upon many tools for DVD backup, DVD region-free tools, and such. In this article we are going to demonstrate how to programmatically retrieve the DVD's region information.

What is DVD Region?

In short it is a mechanism encoded both in DVD players and on DVD discs dictating if a DVD player can play a certain DVD disk. The DVD region in the DVD player is stored inside the hardware and cannot be reset if windows is re-installed or the player was moved to another PC. Some ways to circumvent this is to update your player's firmware and remove the DVD region support from it. The DVD region in the DVD movie is stored inside one of its IFO file.

From [1] we have the following regions:

Region CodeRegion Name
0No Region Coding
1United States of America, Canada
2Europe, including France, Greece, Turkey, Egypt, Arabia, Japan and South Africa
3Korea, Thailand, Vietnam, Borneo and Indonesia
4Australia and New Zealand, Mexico, the Caribbean, and South America
5India, Africa, Russia and former USSR countries
6Peoples Republic of China
7Unused
8Airlines/Cruise Ships
9Expansion (often used as region free)

DVD region has been defined extensively on the net please check this article's references.

Technical prerequisites

In order to read information from the DVD drive we are going to issue SCSI commands to the hardware itself (DVD player). For simplicity, this article's code do not use ASPI instead uses Microsoft's SPTI (SCSI Pass Through Interface) to talk with the hardware. The SCSI commands issued to the hardware are standards and can be found on the net [3].

Using SPTI to issue SCSI commands

Sending SCSI / CDBs (command descriptor blocks) to the device is very simple with the SPTI interface and consists of only setting up the correct block and sending it.

  1. Open the device, say: \\.\C:\
  2. Prepare a SCSI_PASS_THROUGH_DIRECT structure
  3. Prepare the CDB (Command Descriptor Block), a structure used to select which command and pass appropriate parameters ([4] [6])
  4. Prepare the return or data buffer (buffer returned after the command is issued)
  5. Use DeviceIoControl() with IOCTL code value of IOCTL_SCSI_PASS_THROUGH_DIRECT (value 0x4D014) to issue the call
  6. Interpret the results

Reading the DVD region

After reading in [5] we realize that we need to send to the DVD the SCSI operation code SCSIOP_REPORT_KEY (value 0xA4) with some specific parameters.

The REPORT_KEY can be used to do many things, but we only need to read the DVD region information, for that we fill the "CDB_REPORT_KEY" as:

OperationCode = SCSIOP_REPORT_KEY
AllocationLength = sizeof(REPORT_KEY_DATA_RPC_STATE)
AGID = 0
KeyFormat = KEY_FORMAT_RPC_STATE

After the command is issued, a REPORT_KEY_DATA_RPC_STATE ([5] page 533) will be filled with the region information.

Quoted and paraphrased from [5]:

# of Vendor Resets Available = is a count down counter that indicates the number of times that the vendor may reset the region. The manufacturer of the Drive sets this value to 4 and the value is decremented each time the vendor clears the Drive’s region. When this value is zero, the vendor may no longer clear the Drive's region.

# of User Controlled Changes Available = is a count down counter that indicates the number of times that the user may set the region. This value is initially 5.

The Region Mask returns a value that specifies the Drive Region in which the Drive is located. Once the Drive Region has been set, the Drive shall be located in only one region. Each bit represents one of eight regions. If a bit is cleared in this field, the disc may be played in the corresponding region. If a bit is set in this field, the disc may not be played in the corresponding region. Only one bit can be cleared.

Example: if region mask is 0xFE which is 11111110 in binary means that bit1 is cleared thus region 1 is set.

RPC Scheme specifies the type of Region Playback Controls being used by the Drive.
We currently have two schemes RPC1 which do not enforce region playback control, and RPC2 which enforces the region playback control.

The code

void print_region_info(HANDLE device)
{
  static char *region_names[] = 
  {
   "United States of America, Canada", // Region 1
   "Europe, including France, Greece, Turkey, Egypt, Arabia, "
"Japan and South Africa", // 2
   "Korea, Thailand, Vietnam, Borneo and Indonesia", // 3
   "Australia and New Zealand, Mexico, the Caribbean, and South America", // 4
   "India, Africa, Russia and former USSR countries", // 5
   "Peoples Republic of China", // 6
   "Unused", // 7
   "Airlines/Cruise Ships" // 8
  };

  static char *region_set[] =
  {
    "No region set", // 0
    "Region set", // 1
 
    // 2
    "Drive region is set. Additional restrictions required to make changes",
    "Region set permanently, but may be reset by vendor", // 3

  };

  REPORT_KEY_DATA_RPC_STATE region = {0};
  CDB_REPORT_KEY report = {0};

  report.OperationCode = SCSIOP_REPORT_KEY;
  report.AllocationLength = sizeof(REPORT_KEY_DATA_RPC_STATE);
  report.AGID = 0;
  report.KeyFormat = KEY_FORMAT_RPC_STATE;

  if (!carry_cdb(device, &report, sizeof(report), ®ion, sizeof(region)))
  {
    printf("Could not get region info!\n");
    return;
  }

  unsigned char region_code = ~region.region_mask;
  int i;

  char *region_name = "No Region Coding";
  for (i=7;i>=0;i--)
  {
    if ( (1 << i) & region_code) 
    {
      region_name = region_names[i];
      break;
    }
  }

  printf(
    "Region Information:\n"
    "-------------------\n"
    "Vendor changes: %d\n"
    "User changes: %d\n"
    "Region name: %s\n"
    "Type code: %s\n",
    region.nb_vendor_resets,
    region.nb_user_changes,
    region_name,
    region_set[region.type_code]
    );
}

How to programmatically set DVD region?

I did not try it, but apparently one has to issue a SEND_KEY command with appropriate structures. Check [5] page 587.

Conclusions

Hope you learned a little from this article and got pointers about where to look further.
If I find interest and time, perhaps I will extend my knowledge beyond this and write more articles. Meanwhile, happy coding.

References

  • [1] http://www.hometheaterinfo.com/dvd3.htm
  • [2] http://www.codefreedvd.com/dvd_dvdregionlockingexplained.htm
  • [3] http://www.t10.org/
  • [4] http://en.wikipedia.org/wiki/SCSI_CDB
  • [5] T10.org [3] / SCSI Multi-Media Commands – 5 (MMC-5) / mmc5r03a.pdf
  • [6] DDK / SCSI_PASS_THROUGH documentation

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
Elias (aka lallousx86, @0xeb) has always been interested in the making of things and their inner workings.

His computer interests include system programming, reverse engineering, writing libraries, tutorials and articles.

In his free time, and apart from researching, his favorite reading topics include: dreams, metaphysics, philosophy, psychology and any other human/mystical science.

Former employee of Microsoft and Hex-Rays (the creators of IDA Pro), was responsible about many debugger plugins, IDAPython project ownership and what not.

Elias currently works as an Anticheat engineer in Blizzard Entertainment.

Elias co-authored 2 books and authored one book:

- Practical Reverse Engineering
- The Antivirus Hacker's Handbook
- The Art of Batch Files Programming

Comments and Discussions

 
QuestionMedia Code Pin
Pascal Damman21-Jul-11 23:46
Pascal Damman21-Jul-11 23:46 
AnswerRe: Media Code Pin
Elias Bachaalany22-Jul-11 0:29
Elias Bachaalany22-Jul-11 0:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.