Blame lib/driver/_cdio_generic.c

Packit dd8086
/*
Packit dd8086
  Copyright (C) 2004-2009, 2011-2013, 2017
Packit dd8086
  Rocky Bernstein <rocky@gnu.org>
Packit dd8086
Packit dd8086
  This program is free software: you can redistribute it and/or modify
Packit dd8086
  it under the terms of the GNU General Public License as published by
Packit dd8086
  the Free Software Foundation, either version 3 of the License, or
Packit dd8086
  (at your option) any later version.
Packit dd8086
Packit dd8086
  This program is distributed in the hope that it will be useful,
Packit dd8086
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit dd8086
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit dd8086
  GNU General Public License for more details.
Packit dd8086
Packit dd8086
  You should have received a copy of the GNU General Public License
Packit dd8086
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit dd8086
*/
Packit dd8086
Packit dd8086
/* This file contains generic implementations of device-driver routines.
Packit dd8086
*/
Packit dd8086

Packit dd8086
#ifdef HAVE_CONFIG_H
Packit dd8086
# include "config.h"
Packit dd8086
# define __CDIO_CONFIG_H__ 1
Packit dd8086
#endif
Packit dd8086
Packit dd8086
#include <stdio.h>
Packit dd8086
#include <stdlib.h>
Packit dd8086
#include <string.h>
Packit dd8086
#include <errno.h>
Packit dd8086
Packit dd8086
#ifdef HAVE_UNISTD_H
Packit dd8086
#include <unistd.h>
Packit dd8086
#endif
Packit dd8086
Packit dd8086
#include <fcntl.h>
Packit dd8086
#include <limits.h>
Packit dd8086
Packit dd8086
#ifdef HAVE_SYS_STAT_H
Packit dd8086
#include <sys/stat.h>
Packit dd8086
#endif
Packit dd8086
#ifdef HAVE_SYS_TYPES_H
Packit dd8086
#include <sys/types.h>
Packit dd8086
#endif
Packit dd8086
Packit dd8086
#include <cdio/sector.h>
Packit dd8086
#include <cdio/util.h>
Packit dd8086
#include <cdio/logging.h>
Packit dd8086
#include "cdio_assert.h"
Packit dd8086
#include "cdio_private.h"
Packit dd8086
#include "_cdio_stdio.h"
Packit dd8086
#include "filemode.h"
Packit dd8086
Packit dd8086
#ifndef PATH_MAX
Packit dd8086
#define PATH_MAX 4096
Packit dd8086
#endif
Packit dd8086
Packit dd8086
/* If available and LFS is enabled, try to use lseek64 */
Packit dd8086
#if defined(HAVE_LSEEK64) && defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)
Packit dd8086
#if defined(_MSC_VER)
Packit dd8086
#include <io.h>
Packit dd8086
#endif
Packit dd8086
#define CDIO_LSEEK lseek64
Packit dd8086
#else
Packit dd8086
#define CDIO_LSEEK lseek
Packit dd8086
#endif
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Eject media -- there's nothing to do here. We always return -2.
Packit dd8086
  Should we also free resources?
Packit dd8086
 */
Packit dd8086
int
Packit dd8086
cdio_generic_unimplemented_eject_media (void *p_user_data) {
Packit dd8086
  /* Sort of a stub here. Perhaps log a message? */
Packit dd8086
  return DRIVER_OP_UNSUPPORTED;
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Set the blocksize for subsequent reads.
Packit dd8086
*/
Packit dd8086
int
Packit dd8086
cdio_generic_unimplemented_set_blocksize (void *p_user_data,
Packit dd8086
                                          uint16_t i_blocksize) {
Packit dd8086
  /* Sort of a stub here. Perhaps log a message? */
Packit dd8086
  return DRIVER_OP_UNSUPPORTED;
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Set the drive speed.
Packit dd8086
*/
Packit dd8086
int
Packit dd8086
cdio_generic_unimplemented_set_speed (void *p_user_data, int i_speed) {
Packit dd8086
  /* Sort of a stub here. Perhaps log a message? */
Packit dd8086
  return DRIVER_OP_UNSUPPORTED;
Packit dd8086
}
Packit dd8086
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Release and free resources associated with cd.
Packit dd8086
 */
Packit dd8086
void
Packit dd8086
cdio_generic_free (void *p_user_data)
Packit dd8086
{
Packit dd8086
  generic_img_private_t *p_env = p_user_data;
Packit dd8086
Packit dd8086
  if (NULL == p_env) return;
Packit dd8086
  if (p_env->source_name) free (p_env->source_name);
Packit dd8086
Packit dd8086
  if (NULL != p_env->cdtext) {
Packit dd8086
      cdtext_destroy(p_env->cdtext);
Packit dd8086
      p_env->cdtext = NULL;
Packit dd8086
  }
Packit dd8086
Packit dd8086
  if (p_env->fd >= 0)
Packit dd8086
    close (p_env->fd);
Packit dd8086
Packit dd8086
  if (p_env->scsi_tuple != NULL)
Packit dd8086
    free (p_env->scsi_tuple);
Packit dd8086
Packit dd8086
  free (p_env);
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Initialize CD device.
Packit dd8086
 */
Packit dd8086
bool
Packit dd8086
cdio_generic_init (void *user_data, int open_flags)
Packit dd8086
{
Packit dd8086
  generic_img_private_t *p_env = user_data;
Packit dd8086
  if (p_env->init) {
Packit dd8086
    cdio_warn ("init called more than once");
Packit dd8086
    return false;
Packit dd8086
  }
Packit dd8086
Packit dd8086
  p_env->fd = open (p_env->source_name, open_flags, 0);
Packit dd8086
Packit dd8086
  if (p_env->fd < 0)
Packit dd8086
    {
Packit dd8086
      cdio_warn ("open (%s): %s", p_env->source_name, strerror (errno));
Packit dd8086
      return false;
Packit dd8086
    }
Packit dd8086
Packit dd8086
  p_env->init = true;
Packit dd8086
  p_env->toc_init = false;
Packit dd8086
  p_env->cdtext  = NULL;
Packit dd8086
  p_env->scsi_tuple  = NULL;
Packit dd8086
  p_env->b_cdtext_error = false;
Packit dd8086
  p_env->u_joliet_level = 0;  /* Assume no Joliet extensions initally */
Packit dd8086
  return true;
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
   Reads a single form1 sector from cd device into data starting
Packit dd8086
   from lsn.
Packit dd8086
 */
Packit dd8086
driver_return_code_t
Packit dd8086
cdio_generic_read_form1_sector (void * user_data, void *data, lsn_t lsn)
Packit dd8086
{
Packit dd8086
  if (0 > cdio_generic_lseek(user_data, CDIO_CD_FRAMESIZE*lsn, SEEK_SET))
Packit dd8086
    return DRIVER_OP_ERROR;
Packit dd8086
  return cdio_generic_read(user_data, data, CDIO_CD_FRAMESIZE);
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Reads into buf the next size bytes.
Packit dd8086
  Returns -1 on error.
Packit dd8086
  Is in fact libc's lseek()/lseek64().
Packit dd8086
*/
Packit dd8086
off_t
Packit dd8086
cdio_generic_lseek (void *user_data, off_t offset, int whence)
Packit dd8086
{
Packit dd8086
  generic_img_private_t *p_env = user_data;
Packit dd8086
  return CDIO_LSEEK(p_env->fd, offset, whence);
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Reads into buf the next size bytes.
Packit dd8086
  Returns -1 on error.
Packit dd8086
  Is in fact libc's read().
Packit dd8086
*/
Packit dd8086
ssize_t
Packit dd8086
cdio_generic_read (void *user_data, void *buf, size_t size)
Packit dd8086
{
Packit dd8086
  generic_img_private_t *p_env = user_data;
Packit dd8086
  return read(p_env->fd, buf, size);
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Release and free resources associated with stream or disk image.
Packit dd8086
*/
Packit dd8086
void
Packit dd8086
cdio_generic_stdio_free (void *p_user_data)
Packit dd8086
{
Packit dd8086
  generic_img_private_t *p_env = p_user_data;
Packit dd8086
Packit dd8086
  if (NULL == p_env) return;
Packit dd8086
  if (NULL != p_env->source_name)
Packit dd8086
    free (p_env->source_name);
Packit dd8086
Packit dd8086
  if (p_env->data_source)
Packit dd8086
    cdio_stdio_destroy (p_env->data_source);
Packit dd8086
}
Packit dd8086
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Return true if source_name could be a device containing a CD-ROM.
Packit dd8086
*/
Packit dd8086
bool
Packit dd8086
cdio_is_device_generic(const char *source_name)
Packit dd8086
{
Packit dd8086
  struct stat buf;
Packit dd8086
  if (0 != stat(source_name, &buf)) {
Packit dd8086
    cdio_warn ("Can't get file status for %s:\n%s", source_name,
Packit dd8086
                strerror(errno));
Packit dd8086
    return false;
Packit dd8086
  }
Packit dd8086
  return (S_ISBLK(buf.st_mode) || S_ISCHR(buf.st_mode));
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Like above, but don't give a warning device doesn't exist.
Packit dd8086
*/
Packit dd8086
bool
Packit dd8086
cdio_is_device_quiet_generic(const char *source_name)
Packit dd8086
{
Packit dd8086
  struct stat buf;
Packit dd8086
  if (0 != stat(source_name, &buf)) {
Packit dd8086
    return false;
Packit dd8086
  }
Packit dd8086
  return (S_ISBLK(buf.st_mode) || S_ISCHR(buf.st_mode));
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Add/allocate a drive to the end of drives.
Packit dd8086
  Use cdio_free_device_list() to free this device_list.
Packit dd8086
*/
Packit dd8086
void
Packit dd8086
cdio_add_device_list(char **device_list[], const char *drive,
Packit dd8086
                     unsigned int *num_drives)
Packit dd8086
{
Packit dd8086
  if (NULL != drive) {
Packit dd8086
    unsigned int j;
Packit dd8086
    char real_device_1[PATH_MAX];
Packit dd8086
    char real_device_2[PATH_MAX];
Packit dd8086
    cdio_realpath(drive, real_device_1);
Packit dd8086
    /* Check if drive is already in list. */
Packit dd8086
    for (j=0; j<*num_drives; j++) {
Packit dd8086
      cdio_realpath((*device_list)[j], real_device_2);
Packit dd8086
      if (strcmp(real_device_1, real_device_2) == 0) break;
Packit dd8086
    }
Packit dd8086
Packit dd8086
    if (j==*num_drives) {
Packit dd8086
      /* Drive not in list. Add it. */
Packit dd8086
      (*num_drives)++;
Packit dd8086
      *device_list = realloc(*device_list, (*num_drives) * sizeof(char *));
Packit dd8086
      cdio_debug("Adding drive %s to list of devices", drive);
Packit dd8086
      (*device_list)[*num_drives-1] = strdup(drive);
Packit dd8086
      }
Packit dd8086
Packit dd8086
  } else {
Packit dd8086
    (*num_drives)++;
Packit dd8086
    if (*device_list) {
Packit dd8086
      *device_list = realloc(*device_list, (*num_drives) * sizeof(char *));
Packit dd8086
    } else {
Packit dd8086
      *device_list = malloc((*num_drives) * sizeof(char *));
Packit dd8086
    }
Packit dd8086
    cdio_debug("Adding NULL to end of drive list of size %d", (*num_drives)-1);
Packit dd8086
    (*device_list)[*num_drives-1] = NULL;
Packit dd8086
  }
Packit dd8086
}
Packit dd8086
Packit dd8086
/*
Packit dd8086
  Get cdtext information in p_user_data for track i_track.
Packit dd8086
  For disc information i_track is 0.
Packit dd8086
Packit dd8086
  Return the CD-TEXT or NULL if obj is NULL, CD-TEXT information does
Packit dd8086
  not exist, or we don't know how to get this implemented.
Packit dd8086
*/
Packit dd8086
cdtext_t *
Packit dd8086
get_cdtext_generic (void *p_user_data)
Packit dd8086
{
Packit dd8086
  generic_img_private_t *p_env = p_user_data;
Packit dd8086
  uint8_t *p_cdtext_data = NULL;
Packit dd8086
  size_t  len;
Packit dd8086
Packit dd8086
  if (!p_env) return NULL;
Packit dd8086
Packit dd8086
  if (p_env->b_cdtext_error) return NULL;
Packit dd8086
Packit dd8086
  if (NULL == p_env->cdtext) {
Packit dd8086
    p_cdtext_data = read_cdtext_generic (p_env);
Packit dd8086
Packit dd8086
    if (NULL != p_cdtext_data) {
Packit dd8086
      len = CDIO_MMC_GET_LEN16(p_cdtext_data)-2;
Packit dd8086
      p_env->cdtext = cdtext_init();
Packit dd8086
Packit dd8086
      if(len <= 0 || 0 != cdtext_data_init (p_env->cdtext, &p_cdtext_data[4], len)) {
Packit dd8086
        p_env->b_cdtext_error = true;
Packit dd8086
        cdtext_destroy (p_env->cdtext);
Packit dd8086
        p_env->cdtext = NULL;
Packit dd8086
      }
Packit dd8086
Packit dd8086
      free(p_cdtext_data);
Packit dd8086
    }
Packit dd8086
  }
Packit dd8086
Packit dd8086
  return p_env->cdtext;
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Get disc type associated with cd object.
Packit dd8086
*/
Packit dd8086
discmode_t
Packit dd8086
get_discmode_generic (void *p_user_data )
Packit dd8086
{
Packit dd8086
  generic_img_private_t *p_env = p_user_data;
Packit dd8086
Packit dd8086
  /* See if this is a DVD. */
Packit dd8086
  cdio_dvd_struct_t dvd;  /* DVD READ STRUCT for layer 0. */
Packit dd8086
Packit dd8086
  memset(&dvd, 0, sizeof(dvd));
Packit dd8086
Packit dd8086
  dvd.physical.type = CDIO_DVD_STRUCT_PHYSICAL;
Packit dd8086
  dvd.physical.layer_num = 0;
Packit dd8086
  if (0 == mmc_get_dvd_struct_physical (p_env->cdio, &dvd)) {
Packit dd8086
    switch(dvd.physical.layer[0].book_type) {
Packit dd8086
    case CDIO_DVD_BOOK_DVD_ROM:    return CDIO_DISC_MODE_DVD_ROM;
Packit dd8086
    case CDIO_DVD_BOOK_DVD_RAM:    return CDIO_DISC_MODE_DVD_RAM;
Packit dd8086
    case CDIO_DVD_BOOK_DVD_R:      return CDIO_DISC_MODE_DVD_R;
Packit dd8086
    case CDIO_DVD_BOOK_DVD_RW:     return CDIO_DISC_MODE_DVD_RW;
Packit dd8086
    case CDIO_DVD_BOOK_HD_DVD_ROM: return CDIO_DISC_MODE_HD_DVD_ROM;
Packit dd8086
    case CDIO_DVD_BOOK_HD_DVD_RAM: return CDIO_DISC_MODE_HD_DVD_RAM;
Packit dd8086
    case CDIO_DVD_BOOK_HD_DVD_R:   return CDIO_DISC_MODE_HD_DVD_R;
Packit dd8086
    case CDIO_DVD_BOOK_DVD_PR:     return CDIO_DISC_MODE_DVD_PR;
Packit dd8086
    case CDIO_DVD_BOOK_DVD_PRW:    return CDIO_DISC_MODE_DVD_PRW;
Packit dd8086
    case CDIO_DVD_BOOK_DVD_PRW_DL: return CDIO_DISC_MODE_DVD_PRW_DL;
Packit dd8086
    case CDIO_DVD_BOOK_DVD_PR_DL:  return CDIO_DISC_MODE_DVD_PR_DL;
Packit dd8086
    default: return CDIO_DISC_MODE_DVD_OTHER;
Packit dd8086
    }
Packit dd8086
  }
Packit dd8086
Packit dd8086
  return get_discmode_cd_generic(p_user_data);
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Get disc type associated with cd object.
Packit dd8086
*/
Packit dd8086
discmode_t
Packit dd8086
get_discmode_cd_generic (void *p_user_data )
Packit dd8086
{
Packit dd8086
  generic_img_private_t *p_env = p_user_data;
Packit dd8086
  track_t i_track;
Packit dd8086
  discmode_t discmode=CDIO_DISC_MODE_NO_INFO;
Packit dd8086
Packit dd8086
  if (!p_env->toc_init)
Packit dd8086
    p_env->cdio->op.read_toc (p_user_data);
Packit dd8086
Packit dd8086
  if (!p_env->toc_init)
Packit dd8086
    return CDIO_DISC_MODE_NO_INFO;
Packit dd8086
Packit dd8086
  for (i_track = p_env->i_first_track;
Packit dd8086
       i_track < p_env->i_first_track + p_env->i_tracks ;
Packit dd8086
       i_track ++) {
Packit dd8086
    track_format_t track_fmt =
Packit dd8086
      p_env->cdio->op.get_track_format(p_env, i_track);
Packit dd8086
Packit dd8086
    switch(track_fmt) {
Packit dd8086
    case TRACK_FORMAT_AUDIO:
Packit dd8086
      switch(discmode) {
Packit dd8086
        case CDIO_DISC_MODE_NO_INFO:
Packit dd8086
          discmode = CDIO_DISC_MODE_CD_DA;
Packit dd8086
          break;
Packit dd8086
        case CDIO_DISC_MODE_CD_DA:
Packit dd8086
        case CDIO_DISC_MODE_CD_MIXED:
Packit dd8086
        case CDIO_DISC_MODE_ERROR:
Packit dd8086
          /* No change*/
Packit dd8086
          break;
Packit dd8086
      default:
Packit dd8086
          discmode = CDIO_DISC_MODE_CD_MIXED;
Packit dd8086
      }
Packit dd8086
      break;
Packit dd8086
    case TRACK_FORMAT_XA:
Packit dd8086
      switch(discmode) {
Packit dd8086
        case CDIO_DISC_MODE_NO_INFO:
Packit dd8086
          discmode = CDIO_DISC_MODE_CD_XA;
Packit dd8086
          break;
Packit dd8086
        case CDIO_DISC_MODE_CD_XA:
Packit dd8086
        case CDIO_DISC_MODE_CD_MIXED:
Packit dd8086
        case CDIO_DISC_MODE_ERROR:
Packit dd8086
          /* No change*/
Packit dd8086
          break;
Packit dd8086
      default:
Packit dd8086
        discmode = CDIO_DISC_MODE_CD_MIXED;
Packit dd8086
      }
Packit dd8086
      break;
Packit dd8086
    case TRACK_FORMAT_CDI:
Packit dd8086
    case TRACK_FORMAT_DATA:
Packit dd8086
      switch(discmode) {
Packit dd8086
        case CDIO_DISC_MODE_NO_INFO:
Packit dd8086
          discmode = CDIO_DISC_MODE_CD_DATA;
Packit dd8086
          break;
Packit dd8086
        case CDIO_DISC_MODE_CD_DATA:
Packit dd8086
        case CDIO_DISC_MODE_CD_MIXED:
Packit dd8086
        case CDIO_DISC_MODE_ERROR:
Packit dd8086
          /* No change*/
Packit dd8086
          break;
Packit dd8086
      default:
Packit dd8086
        discmode = CDIO_DISC_MODE_CD_MIXED;
Packit dd8086
      }
Packit dd8086
      break;
Packit dd8086
    case TRACK_FORMAT_ERROR:
Packit dd8086
    default:
Packit dd8086
      discmode = CDIO_DISC_MODE_ERROR;
Packit dd8086
    }
Packit dd8086
  }
Packit dd8086
  return discmode;
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Return the number of of the first track.
Packit dd8086
  CDIO_INVALID_TRACK is returned on error.
Packit dd8086
*/
Packit dd8086
track_t
Packit dd8086
get_first_track_num_generic(void *p_user_data)
Packit dd8086
{
Packit dd8086
  const generic_img_private_t *p_env = p_user_data;
Packit dd8086
Packit dd8086
  if (!p_env->toc_init)
Packit dd8086
    p_env->cdio->op.read_toc (p_user_data);
Packit dd8086
Packit dd8086
  return p_env->toc_init ? p_env->i_first_track : CDIO_INVALID_TRACK;
Packit dd8086
}
Packit dd8086
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Return the number of tracks in the current medium.
Packit dd8086
*/
Packit dd8086
track_t
Packit dd8086
get_num_tracks_generic(void *p_user_data)
Packit dd8086
{
Packit dd8086
  generic_img_private_t *p_env = p_user_data;
Packit dd8086
Packit dd8086
  if (!p_env->toc_init)
Packit dd8086
    p_env->cdio->op.read_toc (p_user_data);
Packit dd8086
Packit dd8086
  return p_env->toc_init ? p_env->i_tracks : CDIO_INVALID_TRACK;
Packit dd8086
}
Packit dd8086
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Read CD-Text information for a CdIo_t object .
Packit dd8086
Packit dd8086
  return pointer to raw cdtext on success,
Packit dd8086
  NULL on failure
Packit dd8086
  free when done and not NULL
Packit dd8086
*/
Packit dd8086
uint8_t *
Packit dd8086
read_cdtext_generic(void *p_env)
Packit dd8086
{
Packit dd8086
  generic_img_private_t *p_user_data = p_env;
Packit dd8086
  return mmc_read_cdtext ( p_user_data->cdio );
Packit dd8086
}
Packit dd8086
Packit dd8086
/*! Return number of channels in track: 2 or 4; -2 if not
Packit dd8086
  implemented or -1 for error.
Packit dd8086
  Not meaningful if track is not an audio track.
Packit dd8086
*/
Packit dd8086
int
Packit dd8086
get_track_channels_generic(const void *p_user_data, track_t i_track)
Packit dd8086
{
Packit dd8086
  const generic_img_private_t *p_env = p_user_data;
Packit dd8086
  return p_env->track_flags[i_track].channels;
Packit dd8086
}
Packit dd8086
Packit dd8086
/*! Return 1 if copy is permitted on the track, 0 if not, or -1 for error.
Packit dd8086
  Is this meaningful if not an audio track?
Packit dd8086
*/
Packit dd8086
track_flag_t
Packit dd8086
get_track_copy_permit_generic(void *p_user_data, track_t i_track)
Packit dd8086
{
Packit dd8086
  const generic_img_private_t *p_env = p_user_data;
Packit dd8086
  return p_env->track_flags[i_track].copy_permit;
Packit dd8086
}
Packit dd8086
Packit dd8086
/*! Return 1 if track has pre-emphasis, 0 if not, or -1 for error.
Packit dd8086
  Is this meaningful if not an audio track?
Packit dd8086
Packit dd8086
  pre-emphasis is a non linear frequency response.
Packit dd8086
*/
Packit dd8086
track_flag_t
Packit dd8086
get_track_preemphasis_generic(const void *p_user_data, track_t i_track)
Packit dd8086
{
Packit dd8086
  const generic_img_private_t *p_env = p_user_data;
Packit dd8086
  return p_env->track_flags[i_track].preemphasis;
Packit dd8086
}
Packit dd8086
Packit dd8086
void
Packit dd8086
set_track_flags(track_flags_t *p_track_flag, uint8_t i_flag)
Packit dd8086
{
Packit dd8086
  p_track_flag->preemphasis = ( i_flag & CDIO_TRACK_FLAG_PRE_EMPHASIS )
Packit dd8086
    ? CDIO_TRACK_FLAG_TRUE : CDIO_TRACK_FLAG_FALSE;
Packit dd8086
Packit dd8086
  p_track_flag->copy_permit = ( i_flag & CDIO_TRACK_FLAG_COPY_PERMITTED )
Packit dd8086
    ? CDIO_TRACK_FLAG_TRUE : CDIO_TRACK_FLAG_FALSE;
Packit dd8086
Packit dd8086
  p_track_flag->channels = ( i_flag & CDIO_TRACK_FLAG_FOUR_CHANNEL_AUDIO )
Packit dd8086
    ? 4 : 2;
Packit dd8086
}
Packit dd8086
Packit dd8086
driver_return_code_t
Packit dd8086
read_data_sectors_generic (void *p_user_data, void *p_buf, lsn_t i_lsn,
Packit dd8086
                           uint16_t i_blocksize, uint32_t i_blocks)
Packit dd8086
{
Packit dd8086
  int rc;
Packit dd8086
  if (0 > cdio_generic_lseek(p_user_data, i_blocksize*i_lsn, SEEK_SET))
Packit dd8086
    return DRIVER_OP_ERROR;
Packit dd8086
  rc = cdio_generic_read(p_user_data, p_buf, i_blocksize*i_blocks);
Packit dd8086
  if (rc > 0) return DRIVER_OP_SUCCESS;
Packit dd8086
  return DRIVER_OP_ERROR;
Packit dd8086
}
Packit dd8086
Packit dd8086

Packit dd8086
/*
Packit dd8086
 * Local variables:
Packit dd8086
 *  c-file-style: "gnu"
Packit dd8086
 *  tab-width: 8
Packit dd8086
 *  indent-tabs-mode: nil
Packit dd8086
 * End:
Packit dd8086
 */