Thursday, July 07, 2005

Getting CDROM Track Information using Python

First for some basic info. All CDROM discs(both Audio as well as data CDs) are organised as tracks. The CD tracks are numbered from 1 upto 99. The lead-out is considered as a track and is given a predefined number of 0xAA. The CD-Recordable FAQ is an excellent source of information on all these basics.

Now onto how to use Python for extracting all the track information from a CDROM on Win32. To access any device on your Windows machine from Python(and also to use most of the Win32 API calls), you need to install the Python Win32 extensions. ActiveState has excellent info on all the modules that constitute the Win32 extensions. All windows CDROM ioctls are defined in the Windows DDK, so you will want to install that as well.
The CDROM ioctl we are interested in is the IOCTL_CDROM_READ_TOC, which gives information on the Table of Contents(TOC) of the CD. For working with the CDROM device, we need to first obtain a handle for the CDROM device. This could be done using the CreateFile API.

#Assuming your cdrom drive is at E:
hdevice = win32file.CreateFile("\\\\.\\E:", GENERIC_READ, FILE_SHARE_READ, None, OPEN_EXISTING, 0, 0)


We can now issue the ioctl using the DeviceIoControl function in the win32file python module. The DeviceIoControl function expects the size of the output structure that's expected. For this IOCTL, the return value of this call is the entire TOC information as defined by the CDROM_TOC structure. The maximum size of this structure is 804 bytes. This is the space required for 100 tracks(Max 99 tracks + 1 Leadout). That's defined using MAXIMUM_CDROM_TOC_SIZE. Unfortunately the ioctl numbers are not published at the MSDN website, so you have to browse through the DDK include files for these values. The value for the IOCTL_CDROM_READ_TOC ioctl is 0x24000.

IOCTL_CDROM_READ_TOC = 0x24000
MAXIMUM_CDROM_TOC_SIZE = 804
data = win32file.DeviceIoControl(hdevice,IOCTL_CDROM_READ_TOC,"", MAXIMUM_CDROM_TOC_SIZE, None)


The CDROM_TOC structure, which is returned as a string can be easily unpacked using the python struct module. Even though most CDs will have less than 99 tracks, the structure data that is returned will always have 804 bytes. And when you are done unpacking, do not forget to close the device handle you obtained with a CloseHandle call.

win32file.CloseHandle(hdevice)

So using the code snippets above, we can get the various tracks in the CDROM, along with their start offset in the CDROM in the form of Minute-Second-Frame(MSF) information. Note that this will work for both Audio as well as Data CDs.

2 comments:

Anonymous said...

Like your website for its simplicity in design. I studied in BMS College of Engineering and have been with HP ever since I got out of college (about 4 years ago). You can know more about me at http://www.vinayahs.com

Krishna said...

Vinaya, Thanks for dropping by. Nice to know you liked the blog.