4

I'm looking to create a function in C++ running on Linux that returns true if the CDRom media is a DVD and false if its anything else (e.g. Audio CD).

I have been using ioctl with linux/cdrom.h. I tried using the DVD_READ_STRUCT but it always returns true. Maybe I'm using it incorrectly.

dvd_struct s
if (ioctl(hDEV, DVD_READ_STRUCT, &s)) {
    return true;
}
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Bunnies
  • 41
  • 1
  • 1
    What do you actually care about? If it's an audio CD or not; or if it's a DVD or CD? – UKMonkey Jul 19 '19 at 16:10
  • 1
    @UKMonkey _"returns true if the CDRom media is a DVD and false if its anything else"_ – Lightness Races in Orbit Jul 19 '19 at 16:13
  • 1
    At first glance I can't see a feature in that header for that – Lightness Races in Orbit Jul 19 '19 at 16:14
  • @LightnessRacesinOrbit "false if its anything else (ie. Audio CD)" - this false assumption prompted the question..,. remember, people don't ask the question they mean to! – UKMonkey Jul 19 '19 at 16:15
  • @UKMonkey Seems more likely that it's a misspelling of "e.g." (which is very common; also see the title) but fair enough! – Lightness Races in Orbit Jul 19 '19 at 16:17
  • there's also the fact that blueray has been completely ignored ... do you care about that at all? – UKMonkey Jul 19 '19 at 16:18
  • OP can you make a guess from the media size? – Lightness Races in Orbit Jul 19 '19 at 16:19
  • I only care if its a DVD. Any other format should return false (including Bluray). Different DVD media of varying sizes will be used so IDK how media size can help – Bunnies Jul 19 '19 at 16:21
  • _Maybe_ [these macros](https://github.com/torvalds/linux/blob/master/include/uapi/linux/cdrom.h#L387) somewhere in [this struct](https://github.com/torvalds/linux/blob/master/include/linux/cdrom.h#L91) in [this struct](https://github.com/torvalds/linux/blob/master/include/linux/cdrom.h#L41) as returned by `CDROM_DISC_STATUS`. But it seems to be that this whole API is designed to be largely media-agnostic. Which begs the question - why do you want to know? – Lightness Races in Orbit Jul 19 '19 at 16:25
  • _"IDK how media size can help"_ Do DVDs of CD or Bluray size exist? – Lightness Races in Orbit Jul 19 '19 at 16:27
  • https://en.wikipedia.org/wiki/Optical_disc#Overview_of_optical_types - CD 0.7–0.9 GB; DVD 4.7–17 GB; BlueRay: 25 GB; There's no overlap; so for a "make do" version it'll work – UKMonkey Jul 19 '19 at 16:31
  • You can also check how existing apps handle the situation. Like [Cdrdao Homepage](http://cdrdao.sourceforge.net/) – David C. Rankin Jul 19 '19 at 16:35
  • @UKMonkey. Sizing might work then, but now the question is how do I get the total size of the disc? – Bunnies Jul 19 '19 at 16:41
  • Years ago, I had a project where I needed to burn files directly to DVDs. I don't know how to do this in Linux, but on Windows, [I used `DeviceIoControl()` to issue Multimedia MMC commands](https://stackoverflow.com/a/23024802/65863) directly to the optical drives to query the disc type, write status, capacities, etc. If anything other than a DVD was detected, or if a DVD was already written to, I didn't burn the files. This was at a time before Microsoft added better APIs to query devices for such information (or maybe I just wasn't aware of those APIs yet). – Remy Lebeau Jul 19 '19 at 23:19

2 Answers2

1

Look at /proc/sys/dev/cdrom/info, it contains something like this:

CD-ROM information, Id: cdrom.c 3.20 2003/12/17

drive name:         sr0
drive speed:        125
drive # of slots:   1
Can close tray:     1
Can open tray:      1
Can lock tray:      1
Can change speed:   1
Can select disk:    0
Can read multisession:  1
Can read MCN:       1
Reports media changed:  1
Can play audio:     1
Can write CD-R:     1
Can write CD-RW:    1
Can read DVD:       1
Can write DVD-R:    1
Can write DVD-RAM:  1
Can read MRW:       0
Can write MRW:      0
Can write RAM:      1

(it is updated by the kernel and available in all distros) You can use this information in addition to the ioctl's from cdrom.h. Also keep in mind that cdrom.h is an attempt to create a standard interface, it does not yet cater for all manufacturers, some still using SCSI-codes or some other proprietary schemes. So to be safe you should also check at least using the SCSI ioctl codes - do #include <scsi/... to have them available.

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
slashmais
  • 7,069
  • 9
  • 54
  • 80
  • The question is about the media (CD or DVD), this answer is about drive capabilities, that exist and are constant whether a disc is in the drive or not. It cannot answer the question. – Stéphane Gourichon Jul 13 '20 at 21:47
0

The official documentation is a bit more helpful. You have to specify the request type and any required inputs before calling ioctl.

// Is it a DVD?
dvd_struct ds;
ds.type = DVD_STRUCT_PHYSICAL;
ds.physical.layer_num=0;
result = ioctl(drive, DVD_READ_STRUCT, &ds);

if (result == -1) {
    perror("Probably not a DVD: ");
} else {
    printf("Layer 0: %i to %i.\n", ds.physical.layer[0].start_sector, ds.physical.layer[0].end_sector);
}

The really interesting stuff requires issuing SCSI commands like dvd+rw-tools, cdrkit, and cdrdao. Doing this is a bit painful, though, and it's not necessary if you don't need to know if the disc is recordable, rewritable, or pressed.

David A
  • 344
  • 1
  • 4