cdrom_id.c revision 24be98227483baf67094fa95b5633594446cd21a
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalier * cdrom_id - optical drive and media information prober
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalier * Copyright (C) 2008-2010 Kay Sievers <kay@vrfy.org>
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalier * This program is free software: you can redistribute it and/or modify
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalier * it under the terms of the GNU General Public License as published by
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalier * the Free Software Foundation, either version 2 of the License, or
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalier * (at your option) any later version.
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalier * This program is distributed in the hope that it will be useful,
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalier * but WITHOUT ANY WARRANTY; without even the implied warranty of
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalier * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalier * GNU General Public License for more details.
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalier * You should have received a copy of the GNU General Public License
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalier * along with this program. If not, see <http://www.gnu.org/licenses/>.
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic void log_fn(struct udev *udev, int priority,
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalier/* device info */
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_cd_rom;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_cd_r;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_cd_rw;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_dvd_rom;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_dvd_r;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_dvd_rw;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_dvd_ram;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_dvd_plus_r;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_dvd_plus_rw;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_dvd_plus_r_dl;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_dvd_plus_rw_dl;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_bd;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_bd_r;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_bd_re;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_hddvd;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_hddvd_r;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_hddvd_rw;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_mo;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_mrw;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_mrw_w;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poettering/* media info */
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_media;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_media_cd_rom;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_media_cd_r;
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic unsigned int cd_media_cd_rw;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_dvd_rom;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_dvd_r;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_dvd_rw;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_dvd_rw_ro; /* restricted overwrite mode */
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_dvd_rw_seq; /* sequential mode */
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_dvd_ram;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_dvd_plus_r;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_dvd_plus_rw;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_dvd_plus_r_dl;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_dvd_plus_rw_dl;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_bd;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_bd_r;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_bd_re;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_hddvd;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_hddvd_r;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_hddvd_rw;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_mo;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_mrw;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_mrw_w;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_session_next;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_session_count;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_track_count;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_track_count_data;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned int cd_media_track_count_audio;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalierstatic unsigned long long int cd_media_session_last_offset;
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalier#define ERRCODE(s) ((((s)[2] & 0x0F) << 16) | ((s)[12] << 8) | ((s)[13]))
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalier#define SK(errcode) (((errcode) >> 16) & 0xF)
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalier#define ASC(errcode) (((errcode) >> 8) & 0xFF)
641d1f99b8c4c5427a1fedcb4740586a130ac6cfRonny Chevalier while (fscanf(fp, "%*s %*s %i:%i %*[^\n]", &maj, &min) == 2) {
cda134ab1eac84f874aacf8e885a07112a7fd5ceLennart Poetteringstatic void info_scsi_cmd_err(struct udev *udev, const char *cmd, int err)
struct scsi_cmd {
struct request_sense s;
} _sense;
static int scsi_cmd_run(struct udev *udev, struct scsi_cmd *cmd, int fd, unsigned char *buf, size_t bufsize)
int ret = 0;
if (bufsize > 0) {
if (ret == 0)
return ret;
int err;
if (err < 0)
if (err < 0)
return err;
int err;
if ((err != 0)) {
int capability;
if (capability < 0) {
int err;
if ((err != 0)) {
switch (cur_profile) {
int profile;
switch (profile) {
int err;
if ((err != 0)) {
unsigned int cur_profile = 0;
unsigned int len;
int err;
int ret;
if ((err != 0)) {
goto out;
if (cur_profile > 0) {
if ((err != 0)) {
unsigned int feature;
switch (feature) {
log_debug("GET CONFIGURATION: feature 0x%04x <ignored>, with 0x%02x bytes\n", feature, features[i+3]);
out:
return ret;
static const char *media_status[] = {
int err;
if ((err != 0)) {
if (!cd_media_cd_rom)
if ((cd_media_dvd_rw_ro || cd_media_dvd_plus_rw || cd_media_dvd_plus_rw_dl || cd_media_dvd_ram) && (header[2] & 3) > 1) {
if (cd_media_dvd_ram) {
if ((err != 0)) {
goto determined;
if ((err != 0)) {
goto determined;
if ((err != 0)) {
cd_media = 0;
result = 0;
offset++;
if (!result) {
int err;
if ((err != 0)) {
if ((err != 0)) {
unsigned int block;
unsigned int is_data_track;
if (is_data_track)
if ((err != 0)) {
bool eject = false;
bool lock = false;
bool unlock = false;
int cnt;
int rc = 0;
goto exit;
log_open();
int option;
switch (option) {
lock = true;
unlock = true;
eject = true;
debug = true;
goto exit;
goto exit;
if (!node) {
goto exit;
if (fd < 0) {
goto exit;
goto exit;
goto work;
goto work;
work:
if (eject) {
if (cd_cd_rom)
if (cd_cd_r)
if (cd_cd_rw)
if (cd_dvd_rom)
if (cd_dvd_r)
if (cd_dvd_rw)
if (cd_dvd_ram)
if (cd_dvd_plus_r)
if (cd_dvd_plus_rw)
if (cd_dvd_plus_r_dl)
if (cd_dvd_plus_rw_dl)
if (cd_bd)
if (cd_bd_r)
if (cd_bd_re)
if (cd_hddvd)
if (cd_hddvd_r)
if (cd_hddvd_rw)
if (cd_mo)
if (cd_mrw)
if (cd_mrw_w)
if (cd_media)
if (cd_media_mo)
if (cd_media_mrw)
if (cd_media_mrw_w)
if (cd_media_cd_rom)
if (cd_media_cd_r)
if (cd_media_cd_rw)
if (cd_media_dvd_rom)
if (cd_media_dvd_r)
if (cd_media_dvd_ram)
if (cd_media_dvd_rw)
if (cd_media_dvd_plus_r)
if (cd_media_dvd_plus_rw)
if (cd_media_bd)
if (cd_media_bd_r)
if (cd_media_bd_re)
if (cd_media_hddvd)
if (cd_media_hddvd_r)
if (cd_media_hddvd_rw)
if (cd_media_session_next > 0)
if (cd_media_session_count > 0)
if (cd_media_track_count > 0)
if (cd_media_track_count_audio > 0)
if (cd_media_track_count_data > 0)
exit:
if (fd >= 0)
log_close();
return rc;