[iso] add ISO support part 1 (iso9660)

* uses GNU libcdio
This commit is contained in:
Pete Batard 2012-01-12 22:29:27 +00:00
parent 9d2f9faa70
commit ab109bf844
50 changed files with 13684 additions and 33 deletions

146
src/libcdio/cdio/audio.h Normal file
View File

@ -0,0 +1,146 @@
/* -*- c -*-
Copyright (C) 2005, 2007, 2008 Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file audio.h
*
* \brief The top-level header for CD audio-related libcdio
* calls. These control playing of the CD-ROM through its
* line-out jack.
*/
#ifndef __CDIO_AUDIO_H__
#define __CDIO_AUDIO_H__
#include <cdio/types.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*! This struct is used by the cdio_audio_read_subchannel */
typedef struct cdio_subchannel_s
{
uint8_t format;
uint8_t audio_status;
uint8_t address: 4;
uint8_t control: 4;
uint8_t track;
uint8_t index;
msf_t abs_addr;
msf_t rel_addr;
} cdio_subchannel_t;
/*! This struct is used by cdio_audio_get_volume and cdio_audio_set_volume */
typedef struct cdio_audio_volume_s
{
uint8_t level[4];
} cdio_audio_volume_t;
/*! This struct is used by the CDROMPLAYTRKIND ioctl */
typedef struct cdio_track_index_s
{
uint8_t i_start_track; /**< start track */
uint8_t i_start_index; /**< start index */
uint8_t i_end_track; /**< end track */
uint8_t i_end_index; /**< end index */
} cdio_track_index_t;
/*!
Get volume of an audio CD.
@param p_cdio the CD object to be acted upon.
@param p_volume place to put the list of volume outputs levels
p_volume can be NULL in which case we return only whether the driver
has the ability to get the volume or not.
*/
driver_return_code_t cdio_audio_get_volume (CdIo_t *p_cdio, /*out*/
cdio_audio_volume_t *p_volume);
/*!
Return the number of seconds (discarding frame portion) of an MSF
*/
uint32_t cdio_audio_get_msf_seconds(msf_t *p_msf);
/*!
Pause playing CD through analog output
@param p_cdio the CD object to be acted upon.
*/
driver_return_code_t cdio_audio_pause (CdIo_t *p_cdio);
/*!
Playing CD through analog output at the given MSF.
@param p_cdio the CD object to be acted upon.
@param p_start_msf pointer to staring MSF
@param p_end_msf pointer to ending MSF
*/
driver_return_code_t cdio_audio_play_msf (CdIo_t *p_cdio,
/*in*/msf_t *p_start_msf,
/*in*/ msf_t *p_end_msf);
/*!
Playing CD through analog output at the desired track and index
@param p_cdio the CD object to be acted upon.
@param p_track_index location to start/end.
*/
driver_return_code_t cdio_audio_play_track_index
( CdIo_t *p_cdio, cdio_track_index_t *p_track_index);
/*!
Get subchannel information.
@param p_cdio the CD object to be acted upon.
@param p_subchannel place for returned subchannel information
*/
driver_return_code_t cdio_audio_read_subchannel (CdIo_t *p_cdio,
/*out*/ cdio_subchannel_t *p_subchannel);
/*!
Resume playing an audio CD.
@param p_cdio the CD object to be acted upon.
*/
driver_return_code_t cdio_audio_resume (CdIo_t *p_cdio);
/*!
Set volume of an audio CD.
@param p_cdio the CD object to be acted upon.
@param p_volume place for returned volume-level information
*/
driver_return_code_t cdio_audio_set_volume (CdIo_t *p_cdio, /*out*/
cdio_audio_volume_t *p_volume);
/*!
Stop playing an audio CD.
@param p_cdio the CD object to be acted upon.
*/
driver_return_code_t cdio_audio_stop (CdIo_t *p_cdio);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __CDIO_AUDIO_H__ */

220
src/libcdio/cdio/bytesex.h Normal file
View File

@ -0,0 +1,220 @@
/*
$Id: bytesex.h,v 1.5 2008/03/25 15:59:08 karl Exp $
Copyright (C) 2000, 2004 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2005, 2008 Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file bytesex.h
* \brief Generic Byte-swapping routines.
*
* Note: this header will is slated to get removed and libcdio will
* use glib.h routines instead.
*/
#ifndef __CDIO_BYTESEX_H__
#define __CDIO_BYTESEX_H__
#include <cdio/types.h>
#include <cdio/bytesex_asm.h>
#include <cdio/logging.h>
/** 16-bit big-endian to little-endian */
#define UINT16_SWAP_LE_BE_C(val) ((uint16_t) ( \
(((uint16_t) (val) & (uint16_t) 0x00ffU) << 8) | \
(((uint16_t) (val) & (uint16_t) 0xff00U) >> 8)))
/** 32-bit big-endian to little-endian */
#define UINT32_SWAP_LE_BE_C(val) ((uint32_t) ( \
(((uint32_t) (val) & (uint32_t) 0x000000ffU) << 24) | \
(((uint32_t) (val) & (uint32_t) 0x0000ff00U) << 8) | \
(((uint32_t) (val) & (uint32_t) 0x00ff0000U) >> 8) | \
(((uint32_t) (val) & (uint32_t) 0xff000000U) >> 24)))
/** 64-bit big-endian to little-endian */
#define UINT64_SWAP_LE_BE_C(val) ((uint64_t) ( \
(((uint64_t) (val) & (uint64_t) UINT64_C(0x00000000000000ff)) << 56) | \
(((uint64_t) (val) & (uint64_t) UINT64_C(0x000000000000ff00)) << 40) | \
(((uint64_t) (val) & (uint64_t) UINT64_C(0x0000000000ff0000)) << 24) | \
(((uint64_t) (val) & (uint64_t) UINT64_C(0x00000000ff000000)) << 8) | \
(((uint64_t) (val) & (uint64_t) UINT64_C(0x000000ff00000000)) >> 8) | \
(((uint64_t) (val) & (uint64_t) UINT64_C(0x0000ff0000000000)) >> 24) | \
(((uint64_t) (val) & (uint64_t) UINT64_C(0x00ff000000000000)) >> 40) | \
(((uint64_t) (val) & (uint64_t) UINT64_C(0xff00000000000000)) >> 56)))
#ifndef UINT16_SWAP_LE_BE
# define UINT16_SWAP_LE_BE UINT16_SWAP_LE_BE_C
#endif
#ifndef UINT32_SWAP_LE_BE
# define UINT32_SWAP_LE_BE UINT32_SWAP_LE_BE_C
#endif
#ifndef UINT64_SWAP_LE_BE
# define UINT64_SWAP_LE_BE UINT64_SWAP_LE_BE_C
#endif
inline static
uint16_t uint16_swap_le_be (const uint16_t val)
{
return UINT16_SWAP_LE_BE (val);
}
inline static
uint32_t uint32_swap_le_be (const uint32_t val)
{
return UINT32_SWAP_LE_BE (val);
}
inline static
uint64_t uint64_swap_le_be (const uint64_t val)
{
return UINT64_SWAP_LE_BE (val);
}
# define UINT8_TO_BE(val) ((uint8_t) (val))
# define UINT8_TO_LE(val) ((uint8_t) (val))
#ifdef WORDS_BIGENDIAN
# define UINT16_TO_BE(val) ((uint16_t) (val))
# define UINT16_TO_LE(val) ((uint16_t) UINT16_SWAP_LE_BE(val))
# define UINT32_TO_BE(val) ((uint32_t) (val))
# define UINT32_TO_LE(val) ((uint32_t) UINT32_SWAP_LE_BE(val))
# define UINT64_TO_BE(val) ((uint64_t) (val))
# define UINT64_TO_LE(val) ((uint64_t) UINT64_SWAP_LE_BE(val))
#else
# define UINT16_TO_BE(val) ((uint16_t) UINT16_SWAP_LE_BE(val))
# define UINT16_TO_LE(val) ((uint16_t) (val))
# define UINT32_TO_BE(val) ((uint32_t) UINT32_SWAP_LE_BE(val))
# define UINT32_TO_LE(val) ((uint32_t) (val))
# define UINT64_TO_BE(val) ((uint64_t) UINT64_SWAP_LE_BE(val))
# define UINT64_TO_LE(val) ((uint64_t) (val))
#endif
/** symmetric conversions */
#define UINT8_FROM_BE(val) (UINT8_TO_BE (val))
#define UINT8_FROM_LE(val) (UINT8_TO_LE (val))
#define UINT16_FROM_BE(val) (UINT16_TO_BE (val))
#define UINT16_FROM_LE(val) (UINT16_TO_LE (val))
#define UINT32_FROM_BE(val) (UINT32_TO_BE (val))
#define UINT32_FROM_LE(val) (UINT32_TO_LE (val))
#define UINT64_FROM_BE(val) (UINT64_TO_BE (val))
#define UINT64_FROM_LE(val) (UINT64_TO_LE (val))
/** converter function template */
#define CVT_TO_FUNC(bits) \
static inline uint ## bits ## _t \
uint ## bits ## _to_be (uint ## bits ## _t val) \
{ return UINT ## bits ## _TO_BE (val); } \
static inline uint ## bits ## _t \
uint ## bits ## _to_le (uint ## bits ## _t val) \
{ return UINT ## bits ## _TO_LE (val); } \
CVT_TO_FUNC(8)
CVT_TO_FUNC(16)
CVT_TO_FUNC(32)
CVT_TO_FUNC(64)
#undef CVT_TO_FUNC
#define uint8_from_be(val) (uint8_to_be (val))
#define uint8_from_le(val) (uint8_to_le (val))
#define uint16_from_be(val) (uint16_to_be (val))
#define uint16_from_le(val) (uint16_to_le (val))
#define uint32_from_be(val) (uint32_to_be (val))
#define uint32_from_le(val) (uint32_to_le (val))
#define uint64_from_be(val) (uint64_to_be (val))
#define uint64_from_le(val) (uint64_to_le (val))
/** ISO9660-related field conversion routines */
/** Convert from uint8_t to ISO 9660 7.1.1 format */
#define to_711(i) uint8_to_le(i)
/** Convert from ISO 9660 7.1.1 format to uint8_t */
#define from_711(i) uint8_from_le(i)
/** Convert from uint16_t to ISO 9669 7.2.1 format */
#define to_721(i) uint16_to_le(i)
/** Convert from ISO 9660 7.2.1 format to uint16_t */
#define from_721(i) uint16_from_le(i)
/** Convert from uint16_t to ISO 9669 7.2.2 format */
#define to_722(i) uint16_to_be(i)
/** Convert from ISO 9660 7.2.2 format to uint16_t */
#define from_722(i) uint16_from_be(i)
/** Convert from uint16_t to ISO 9669 7.2.3 format */
static inline uint32_t
to_723(uint16_t i)
{
return uint32_swap_le_be(i) | i;
}
/** Convert from ISO 9660 7.2.3 format to uint16_t */
static inline uint16_t
from_723 (uint32_t p)
{
if (uint32_swap_le_be (p) != p)
cdio_warn ("from_723: broken byte order");
return (0xFFFF & p);
}
/** Convert from uint16_t to ISO 9669 7.3.1 format */
#define to_731(i) uint32_to_le(i)
/** Convert from ISO 9660 7.3.1 format to uint32_t */
#define from_731(i) uint32_from_le(i)
/** Convert from uint32_t to ISO 9669 7.3.2 format */
#define to_732(i) uint32_to_be(i)
/** Convert from ISO 9660 7.3.2 format to uint32_t */
#define from_732(i) uint32_from_be(i)
/** Convert from uint16_t to ISO 9669 7.3.3 format */
static inline uint64_t
to_733(uint32_t i)
{
return uint64_swap_le_be(i) | i;
}
/** Convert from ISO 9660 7.3.3 format to uint32_t */
static inline uint32_t
from_733 (uint64_t p)
{
if (uint64_swap_le_be (p) != p)
cdio_warn ("from_733: broken byte order");
return (UINT32_C(0xFFFFFFFF) & p);
}
#endif /* __CDIO_BYTESEX_H__ */
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

View File

@ -0,0 +1,130 @@
/*
$Id: bytesex_asm.h,v 1.3 2008/03/25 15:59:08 karl Exp $
Copyright (C) 2008 Rocky Bernstein <rocky@gnu.org>
2001, 2004, 2005 Herbert Valerio Riedel <hvr@gnu.org>
2001 Sven Ottemann <ac-logic@freenet.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file bytesex_asm.h
* \brief Assembly code to handle byte-swapping.
Note: this header will is slated to get removed and libcdio will use
glib.h routines instead.
*/
#ifndef __CDIO_BYTESEX_ASM_H__
#define __CDIO_BYTESEX_ASM_H__
#if !defined(DISABLE_ASM_OPTIMIZE)
#include <cdio/types.h>
#if defined(__powerpc__) && defined(__GNUC__)
inline static
uint32_t uint32_swap_le_be_asm(const uint32_t a)
{
uint32_t b;
__asm__ ("lwbrx %0,0,%1"
:"=r"(b)
:"r"(&a), "m"(a));
return b;
}
inline static
uint16_t uint16_swap_le_be_asm(const uint16_t a)
{
uint32_t b;
__asm__ ("lhbrx %0,0,%1"
:"=r"(b)
:"r"(&a), "m"(a));
return b;
}
#define UINT16_SWAP_LE_BE uint16_swap_le_be_asm
#define UINT32_SWAP_LE_BE uint32_swap_le_be_asm
#elif defined(__mc68000__) && defined(__STORMGCC__)
inline static
uint32_t uint32_swap_le_be_asm(uint32_t a __asm__("d0"))
{
/* __asm__("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val)); */
__asm__("move.l %1,d0;rol.w #8,d0;swap d0;rol.w #8,d0;move.l d0,%0"
:"=r"(a)
:"r"(a));
return(a);
}
inline static
uint16_t uint16_swap_le_be_asm(uint16_t a __asm__("d0"))
{
__asm__("move.l %1,d0;rol.w #8,d0;move.l d0,%0"
:"=r"(a)
:"r"(a));
return(a);
}
#define UINT16_SWAP_LE_BE uint16_swap_le_be_asm
#define UINT32_SWAP_LE_BE uint32_swap_le_be_asm
#elif 0 && defined(__i386__) && defined(__GNUC__)
inline static
uint32_t uint32_swap_le_be_asm(uint32_t a)
{
__asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
"rorl $16,%0\n\t" /* swap words */
"xchgb %b0,%h0" /* swap higher bytes */
:"=q" (a)
: "0" (a));
return(a);
}
inline static
uint16_t uint16_swap_le_be_asm(uint16_t a)
{
__asm__("xchgb %b0,%h0" /* swap bytes */
: "=q" (a)
: "0" (a));
return(a);
}
#define UINT16_SWAP_LE_BE uint16_swap_le_be_asm
#define UINT32_SWAP_LE_BE uint32_swap_le_be_asm
#endif
#endif /* !defined(DISABLE_ASM_OPTIMIZE) */
#endif /* __CDIO_BYTESEX_ASM_H__ */
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

80
src/libcdio/cdio/cdio.h Normal file
View File

@ -0,0 +1,80 @@
/* -*- c -*-
Copyright (C) 2003, 2004, 2005, 2008, 2009 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file cdio.h
*
* \brief The top-level header for libcdio: the CD Input and Control
* library. Applications include this for anything regarding libcdio.
*/
#ifndef __CDIO_H__
#define __CDIO_H__
/** Application Interface or Protocol version number. If the public
* interface changes, we increase this number.
*/
#define CDIO_API_VERSION 5
#include <cdio/version.h>
#include <cdio/types.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <cdio/sector.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* For compatibility. */
#define CdIo CdIo_t
/** This is an opaque structure for the CD object. */
typedef struct _CdIo CdIo_t;
typedef struct cdtext_s cdtext_t;
#ifdef __cplusplus
}
#endif /* __cplusplus */
/* Drive(r)/Device-related functions. Perhaps we should break out
Driver from device?
*/
#include <cdio/device.h>
/* Disc-related functions. */
#include <cdio/disc.h>
/* Sector (frame, or block)-related functions. Uses driver_return_code_t
from <cdio/device.h> so it should come after that.
*/
#include <cdio/read.h>
/* CD-Text-related functions. */
#include <cdio/cdtext.h>
/* Track-related functions. */
#include <cdio/track.h>
#endif /* __CDIO_H__ */

View File

@ -0,0 +1,188 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* compiler does lsbf in struct bitfields */
#undef BITFIELD_LSBF
/* Define 1 if you are compiling using cygwin */
#undef CYGWIN
/* what to put between the brackets for empty arrays */
#define EMPTY_ARRAY_SIZE MAX_PATH
/* Define 1 if you have BSDI-type CD-ROM support */
#undef HAVE_BSDI_CDROM
/* Define to 1 if you have the `bzero' function. */
#undef HAVE_BZERO
/* Define this if you have libcddb installed */
#undef HAVE_CDDB
/* Define to 1 if you have the <CoreFoundation/CFBase.h> header file. */
#undef HAVE_COREFOUNDATION_CFBASE_H
/* Define 1 if you have Darwin OS X-type CD-ROM support */
#undef HAVE_DARWIN_CDROM
/* Define if time.h defines extern long timezone and int daylight vars. */
#undef HAVE_DAYLIGHT
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the <dvd.h> header file. */
#undef HAVE_DVD_H
/* Define to 1 if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define 1 if you have FreeBSD CD-ROM support */
#undef HAVE_FREEBSD_CDROM
/* Define to 1 if you have the <glob.h> header file. */
#undef HAVE_GLOB_H
/* Define if you have the iconv() function. */
#undef HAVE_ICONV
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <IOKit/IOKitLib.h> header file. */
#undef HAVE_IOKIT_IOKITLIB_H
/* Supports ISO _Pragma() macro */
#undef HAVE_ISOC99_PRAGMA
/* Define 1 if you want ISO-9660 Joliet extension support. You must have also
libiconv installed to get Joliet extension support. */
#undef HAVE_JOLIET
/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
#undef HAVE_LANGINFO_CODESET
/* Define to 1 if you have the `nsl' library (-lnsl). */
#undef HAVE_LIBNSL
/* Define to 1 if you have the `socket' library (-lsocket). */
#undef HAVE_LIBSOCKET
/* Define 1 if you have Linux-type CD-ROM support */
#undef HAVE_LINUX_CDROM
/* Define to 1 if you have the <linux/cdrom.h> header file. */
#undef HAVE_LINUX_CDROM_H
/* Define 1 if timeout is in cdrom_generic_command struct */
#undef HAVE_LINUX_CDROM_TIMEOUT
/* Define to 1 if you have the <linux/version.h> header file. */
#undef HAVE_LINUX_VERSION_H
/* Define to 1 if you have the `memcpy' function. */
#define HAVE_MEMCPY 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
/* Define 1 if you have Solaris CD-ROM support */
#undef HAVE_SOLARIS_CDROM
/* Define to 1 if you have the <stdbool.h> header file. */
#undef HAVE_STDBOOL_H
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/cdio.h> header file. */
#undef HAVE_SYS_CDIO_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define if struct tm has the tm_gmtoff member. */
#undef HAVE_TM_GMTOFF
/* Define if time.h defines extern extern char *tzname[2] variable */
#undef HAVE_TZNAME
/* Define to 1 if you have the `tzset' function. */
#undef HAVE_TZSET
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define this if you have libvcdinfo installed */
#undef HAVE_VCDINFO
/* Define to 1 if you have the `vsnprintf' function. */
#undef HAVE_VSNPRINTF
/* Define 1 if you have MinGW CD-ROM support */
#define HAVE_WIN32_CDROM 1
/* Define as const if the declaration of iconv() needs const. */
#undef ICONV_CONST
/* Define 1 if you are compiling using MinGW */
#undef MINGW32
/* Name of package */
#define PACKAGE "libcdio"
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#define PACKAGE_NAME "libcdio"
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#define PACKAGE_VERSION 1
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "1"
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#define inline __inline

177
src/libcdio/cdio/cdtext.h Normal file
View File

@ -0,0 +1,177 @@
/*
$Id: cdtext.h,v 1.14 2008/03/25 15:59:08 karl Exp $
Copyright (C) 2004, 2005, 2008 Rocky Bernstein <rocky@gnu.org>
adapted from cuetools
Copyright (C) 2003 Svend Sanjay Sorensen <ssorensen@fastmail.fm>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*!
* \file cdtext.h
*
* \brief The top-level header for CD-Text information. Applications
* include this for CD-Text access.
*/
#ifndef __CDIO_CDTEXT_H__
#define __CDIO_CDTEXT_H__
#include <cdio/cdio.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define MAX_CDTEXT_FIELDS 13
#define MIN_CDTEXT_FIELD 0
#define MAX_CDTEXT_DATA_LENGTH 5000
#define MAX_CDTEXT_GENRE_CODE 28
/*! \brief structure for holding CD-Text information
@see cdtext_init, cdtext_destroy, cdtext_get, and cdtext_set.
*/
struct cdtext {
char *field[MAX_CDTEXT_FIELDS];
};
typedef struct cdtext cdtext_track_t;
struct cdtext_s {
cdtext_track_t track[100]; /* cdtext for track 1..99. 0 represents cd-text of disc */
uint16_t genre_code; /* genre code */
uint8_t block;
char encoding[16]; /* encoding of character strings */
char language[3]; /* ISO 639-1 (2 letter) language code */
};
/*! \brief A list of all of the CD-Text fields. Because
the interval has no gaps, we can use ++ to iterate over fields.
*/
typedef enum {
CDTEXT_ARRANGER = 0, /**< name(s) of the arranger(s) */
CDTEXT_COMPOSER = 1, /**< name(s) of the composer(s) */
CDTEXT_DISCID = 2, /**< disc identification information */
CDTEXT_GENRE = 3, /**< genre identification and genre information */
CDTEXT_MESSAGE = 4, /**< ISRC code of each track */
CDTEXT_ISRC = 5, /**< message(s) from the content provider or artist */
CDTEXT_PERFORMER = 6, /**< name(s) of the performer(s) */
CDTEXT_SIZE_INFO = 7, /**< size information of the block */
CDTEXT_SONGWRITER = 8, /**< name(s) of the songwriter(s) */
CDTEXT_TITLE = 9, /**< title of album name or track titles */
CDTEXT_TOC_INFO = 10, /**< table of contents information */
CDTEXT_TOC_INFO2 = 11, /**< second table of contents information */
CDTEXT_UPC_EAN = 12,
CDTEXT_INVALID = MAX_CDTEXT_FIELDS
} cdtext_field_t;
/*! Return string representation of the enum values above */
const char *cdtext_field2str (cdtext_field_t i);
/*! CD-Text genre codes */
typedef enum {
CDIO_CDTEXT_GENRE_UNUSED = 0, /**< not used */
CDIO_CDTEXT_GENRE_UNDEFINED = 1, /**< not defined */
CDIO_CDTEXT_GENRE_ADULT_CONTEMP = 2, /**< Adult Contemporary */
CDIO_CDTEXT_GENRE_ALT_ROCK = 3, /**< Alternative Rock */
CDIO_CDTEXT_GENRE_CHILDRENS = 4, /**< Childrens Music */
CDIO_CDTEXT_GENRE_CLASSIC = 5, /**< Classical */
CDIO_CDTEXT_GENRE_CHRIST_CONTEMP = 6, /**< Contemporary Christian */
CDIO_CDTEXT_GENRE_COUNTRY = 7, /**< Country */
CDIO_CDTEXT_GENRE_DANCE = 8, /**< Dance */
CDIO_CDTEXT_GENRE_EASY_LISTENING = 9, /**< Easy Listening */
CDIO_CDTEXT_GENRE_EROTIC = 10, /**< Erotic */
CDIO_CDTEXT_GENRE_FOLK = 11, /**< Folk */
CDIO_CDTEXT_GENRE_GOSPEL = 12, /**< Gospel */
CDIO_CDTEXT_GENRE_HIPHOP = 13, /**< Hip Hop */
CDIO_CDTEXT_GENRE_JAZZ = 14, /**< Jazz */
CDIO_CDTEXT_GENRE_LATIN = 15, /**< Latin */
CDIO_CDTEXT_GENRE_MUSICAL = 16, /**< Musical */
CDIO_CDTEXT_GENRE_NEWAGE = 17, /**< New Age */
CDIO_CDTEXT_GENRE_OPERA = 18, /**< Opera */
CDIO_CDTEXT_GENRE_OPERETTA = 19, /**< Operetta */
CDIO_CDTEXT_GENRE_POP = 20, /**< Pop Music */
CDIO_CDTEXT_GENRE_RAP = 21, /**< RAP */
CDIO_CDTEXT_GENRE_REGGAE = 22, /**< Reggae */
CDIO_CDTEXT_GENRE_ROCK = 23, /**< Rock Music */
CDIO_CDTEXT_GENRE_RYTHMANDBLUES = 24, /**< Rhythm & Blues */
CDIO_CDTEXT_GENRE_SOUNDEFFECTS = 25, /**< Sound Effects */
CDIO_CDTEXT_GENRE_SOUNDTRACK = 26, /**< Soundtrack */
CDIO_CDTEXT_GENRE_SPOKEN_WORD = 27, /**< Spoken Word */
CDIO_CDTEXT_GENRE_WORLD_MUSIC = 28 /**< World Music */
} cdtext_genre_t;
/*! Return string representation of the given genre code */
const char *cdtext_genre2str (cdtext_genre_t i);
/*! Initialize a new cdtext structure.
When the structure is no longer needed, release the
resources using cdtext_delete.
*/
void cdtext_init (cdtext_t *cdtext);
/*! Parse raw CD-Text data into cdtext structure */
bool cdtext_data_init(cdtext_t *cdtext, uint8_t *wdata, size_t length);
/*! Free memory assocated with cdtext*/
void cdtext_destroy (cdtext_t *cdtext);
/*! returns an allocated string associated with the given field. NULL is
returned if key is CDTEXT_INVALID or the field is not set.
The user needs to free the string when done with it.
@see cdio_get_const to retrieve a constant string that doesn't
have to be freed.
*/
char *cdtext_get (cdtext_field_t key, track_t track, const cdtext_t *cdtext);
/*! returns a const string associated with the given field. NULL is
returned if key is CDTEXT_INVALID or the field is not set.
Don't use the string when the cdtext object (i.e. the CdIo_t object
you got it from) is no longer valid.
@see cdio_get to retrieve an allocated string that persists past
the cdtext object.
*/
const char *cdtext_get_const (cdtext_field_t key, track_t track, const cdtext_t *cdtext);
/*!
returns enum of keyword if key is a CD-Text keyword,
returns MAX_CDTEXT_FIELDS non-zero otherwise.
*/
cdtext_field_t cdtext_is_keyword (const char *key);
/*!
sets cdtext's keyword entry to field
*/
void cdtext_set (cdtext_field_t key, track_t track, const char *value, cdtext_t *cdtext);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __CDIO_CDTEXT_H__ */
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

1058
src/libcdio/cdio/device.h Normal file

File diff suppressed because it is too large Load Diff

136
src/libcdio/cdio/disc.h Normal file
View File

@ -0,0 +1,136 @@
/* -*- c -*-
Copyright (C) 2004, 2005, 2006, 2008, 2010 Rocky Bernstein
<rocky@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
\file disc.h
\brief The top-level header for disc-related libcdio calls.
*/
#ifndef __CDIO_DISC_H__
#define __CDIO_DISC_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
disc modes. The first combined from MMC-5 6.33.3.13 (Send
CUESHEET), "DVD Book" from MMC-5 Table 400, page 419. and
GNU/Linux /usr/include/linux/cdrom.h and we've added DVD.
*/
typedef enum {
CDIO_DISC_MODE_CD_DA, /**< CD-DA */
CDIO_DISC_MODE_CD_DATA, /**< CD-ROM form 1 */
CDIO_DISC_MODE_CD_XA, /**< CD-ROM XA form2 */
CDIO_DISC_MODE_CD_MIXED, /**< Some combo of above. */
CDIO_DISC_MODE_DVD_ROM, /**< DVD ROM (e.g. movies) */
CDIO_DISC_MODE_DVD_RAM, /**< DVD-RAM */
CDIO_DISC_MODE_DVD_R, /**< DVD-R */
CDIO_DISC_MODE_DVD_RW, /**< DVD-RW */
CDIO_DISC_MODE_HD_DVD_ROM, /**< HD DVD-ROM */
CDIO_DISC_MODE_HD_DVD_RAM, /**< HD DVD-RAM */
CDIO_DISC_MODE_HD_DVD_R, /**< HD DVD-R */
CDIO_DISC_MODE_DVD_PR, /**< DVD+R */
CDIO_DISC_MODE_DVD_PRW, /**< DVD+RW */
CDIO_DISC_MODE_DVD_PRW_DL, /**< DVD+RW DL */
CDIO_DISC_MODE_DVD_PR_DL, /**< DVD+R DL */
CDIO_DISC_MODE_DVD_OTHER, /**< Unknown/unclassified DVD type */
CDIO_DISC_MODE_NO_INFO,
CDIO_DISC_MODE_ERROR,
CDIO_DISC_MODE_CD_I /**< CD-i. */
} discmode_t;
extern const char *discmode2str[];
/**
Get binary CD-Text information for a CdIo_t object.
@param p_cdio the CD object that may contain CD-Text information.
@return malloc'd pointer to raw CD-Text data as stored on the disc
or NULL if p_cdio is NULL or CD-Text information does not exist.
Return value should be freed when done with it and not NULL.
*/
uint8_t * cdio_get_cdtext_raw (CdIo_t *p_cdio);
/**
Get CD-Text information for a CdIo_t object.
@param p_cdio the CD object that may contain CD-Text information.
@return the CD-Text object or NULL if p_cdio is NULL
or CD-Text information does not exist.
*/
cdtext_t *cdio_get_cdtext (CdIo_t *p_cdio);
/**
Get disc mode - the kind of CD (CD-DA, CD-ROM mode 1, CD-MIXED, etc.
that we've got. The notion of "CD" is extended a little to include
DVD's.
*/
discmode_t cdio_get_discmode (CdIo_t *p_cdio);
/**
Get the lsn of the end of the CD
@return the lsn. On error 0 or CDIO_INVALD_LSN.
*/
lsn_t cdio_get_disc_last_lsn(const CdIo_t *p_cdio);
/**
Return the Joliet level recognized for p_cdio.
*/
uint8_t cdio_get_joliet_level(const CdIo_t *p_cdio);
/**
Get the media catalog number (MCN) from the CD.
@return the media catalog number or NULL if there is none or we
don't have the ability to get it.
Note: string is malloc'd so caller has to free() the returned
string when done with it.
*/
char * cdio_get_mcn (const CdIo_t *p_cdio);
/**
Get the number of tracks on the CD.
@return the number of tracks, or CDIO_INVALID_TRACK if there is
an error.
*/
track_t cdio_get_num_tracks (const CdIo_t *p_cdio);
/**
Return true if discmode is some sort of CD.
*/
bool cdio_is_discmode_cdrom (discmode_t discmode);
/**
Return true if discmode is some sort of DVD.
*/
bool cdio_is_discmode_dvd (discmode_t discmode);
/**
cdio_stat_size is deprecated. @see cdio_get_disc_last_lsn
*/
#define cdio_stat_size cdio_get_disc_last_lsn
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __CDIO_DISC_H__ */

98
src/libcdio/cdio/ds.h Normal file
View File

@ -0,0 +1,98 @@
/*
$Id: ds.h,v 1.5 2008/03/25 15:59:09 karl Exp $
Copyright (C) 2005, 2008 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2000, 2004 Herbert Valerio Riedel <hvr@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file ds.h
* \brief The top-level header for list-related data structures.
Note: this header will is slated to get removed and libcdio will use
glib.h routines instead.
*/
#ifndef __CDIO_DS_H__
#define __CDIO_DS_H__
#include <cdio/types.h>
/** opaque types... */
typedef struct _CdioList CdioList_t;
typedef struct _CdioListNode CdioListNode_t;
typedef int (*_cdio_list_cmp_func_t) (void *p_data1, void *p_data2);
typedef int (*_cdio_list_iterfunc_t) (void *p_data, void *p_user_data);
/** The below are given compatibility with old code. Please use
the above type names, not these. */
#define CdioList CdioList_t
#define CdioListNode CdioListNode_t
#define _cdio_list_cmp_func _cdio_list_cmp_func_t
#define _cdio_list_iterfunc _cdio_list_iterfunc_t
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/** methods */
CdioList_t *_cdio_list_new (void);
void _cdio_list_free (CdioList_t *p_list, int free_data);
unsigned _cdio_list_length (const CdioList_t *list);
void _cdio_list_prepend (CdioList_t *p_list, void *p_data);
void _cdio_list_append (CdioList_t *p_list, void *p_data);
void _cdio_list_foreach (CdioList_t *p_list, _cdio_list_iterfunc_t func,
void *p_user_data);
CdioListNode_t *_cdio_list_find (CdioList_t *p_list,
_cdio_list_iterfunc_t cmp_func,
void *p_user_data);
#define _CDIO_LIST_FOREACH(node, list) \
for (node = _cdio_list_begin (list); node; node = _cdio_list_node_next (node))
/** node operations */
CdioListNode_t *_cdio_list_begin (const CdioList_t *p_list);
CdioListNode_t *_cdio_list_end (CdioList_t *p_list);
CdioListNode_t *_cdio_list_node_next (CdioListNode_t *p_node);
void _cdio_list_node_free (CdioListNode_t *p_node, int i_free_data);
void *_cdio_list_node_data (CdioListNode_t *p_node);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __CDIO_DS_H__ */
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

127
src/libcdio/cdio/dvd.h Normal file
View File

@ -0,0 +1,127 @@
/*
Copyright (C) 2004, 2010 Rocky Bernstein <rocky@gnu.org>
Modeled after GNU/Linux definitions in linux/cdrom.h
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
\file dvd.h
\brief Definitions for DVD access.
The documents we make use of are described Multi-Media Commands
(MMC). This document generally has a numeric level number
appended. For example MMC-5 refers to ``Multi-Media Commands - 5'
which is the current version in 2010.
*/
#ifndef __CDIO_DVD_H__
#define __CDIO_DVD_H__
#include <cdio/types.h>
/**
Values used in a READ DVD STRUCTURE
*/
#define CDIO_DVD_STRUCT_PHYSICAL 0x00
#define CDIO_DVD_STRUCT_COPYRIGHT 0x01
#define CDIO_DVD_STRUCT_DISCKEY 0x02
#define CDIO_DVD_STRUCT_BCA 0x03
#define CDIO_DVD_STRUCT_MANUFACT 0x04
/**
Media definitions for "DVD Book" from MMC-5 Table 400, page 419.
*/
#define CDIO_DVD_BOOK_DVD_ROM 0x0 /**< DVD-ROM */
#define CDIO_DVD_BOOK_DVD_RAM 0x1 /**< DVD-RAM */
#define CDIO_DVD_BOOK_DVD_R 0x2 /**< DVD-R */
#define CDIO_DVD_BOOK_DVD_RW 0x3 /**< DVD-RW */
#define CDIO_DVD_BOOK_HD_DVD_ROM 0x4 /**< HD DVD-ROM */
#define CDIO_DVD_BOOK_HD_DVD_RAM 0x5 /**< HD DVD-RAM */
#define CDIO_DVD_BOOK_HD_DVD_R 0x6 /**< HD DVD-R */
#define CDIO_DVD_BOOK_DVD_PRW 0x9 /**< DVD+RW */
#define CDIO_DVD_BOOK_DVD_PR 0xa /**< DVD+R */
#define CDIO_DVD_BOOK_DVD_PRW_DL 0xd /**< DVD+RW DL */
#define CDIO_DVD_BOOK_DVD_PR_DL 0xe /**< DVD+R DL */
typedef struct cdio_dvd_layer {
unsigned int book_version : 4;
unsigned int book_type : 4;
unsigned int min_rate : 4;
unsigned int disc_size : 4;
unsigned int layer_type : 4;
unsigned int track_path : 1;
unsigned int nlayers : 2;
unsigned int track_density : 4;
unsigned int linear_density : 4;
unsigned int bca : 1;
uint32_t start_sector;
uint32_t end_sector;
uint32_t end_sector_l0;
} cdio_dvd_layer_t;
/**
Maximum number of layers in a DVD.
*/
#define CDIO_DVD_MAX_LAYERS 4
typedef struct cdio_dvd_physical {
uint8_t type;
uint8_t layer_num;
cdio_dvd_layer_t layer[CDIO_DVD_MAX_LAYERS];
} cdio_dvd_physical_t;
typedef struct cdio_dvd_copyright {
uint8_t type;
uint8_t layer_num;
uint8_t cpst;
uint8_t rmi;
} cdio_dvd_copyright_t;
typedef struct cdio_dvd_disckey {
uint8_t type;
unsigned agid : 2;
uint8_t value[2048];
} cdio_dvd_disckey_t;
typedef struct cdio_dvd_bca {
uint8_t type;
int len;
uint8_t value[188];
} cdio_dvd_bca_t;
typedef struct cdio_dvd_manufact {
uint8_t type;
uint8_t layer_num;
int len;
uint8_t value[2048];
} cdio_dvd_manufact_t;
typedef union {
uint8_t type;
cdio_dvd_physical_t physical;
cdio_dvd_copyright_t copyright;
cdio_dvd_disckey_t disckey;
cdio_dvd_bca_t bca;
cdio_dvd_manufact_t manufact;
} cdio_dvd_struct_t;
#endif /* __CDIO_DVD_H__ */

1134
src/libcdio/cdio/iso9660.h Normal file

File diff suppressed because it is too large Load Diff

136
src/libcdio/cdio/logging.h Normal file
View File

@ -0,0 +1,136 @@
/*
$Id: logging.h,v 1.11 2008/03/25 15:59:09 karl Exp $
Copyright (C) 2003, 2004, 2008 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file logging.h
* \brief Header to control logging and level of detail of output.
*
*/
#ifndef __LOGGING_H__
#define __LOGGING_H__
#include <cdio/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* The different log levels supported.
*/
typedef enum {
CDIO_LOG_DEBUG = 1, /**< Debug-level messages - helps debug what's up. */
CDIO_LOG_INFO, /**< Informational - indicates perhaps something of
interest. */
CDIO_LOG_WARN, /**< Warning conditions - something that looks funny. */
CDIO_LOG_ERROR, /**< Error conditions - may terminate program. */
CDIO_LOG_ASSERT /**< Critical conditions - may abort program. */
} cdio_log_level_t;
/**
* The place to save the preference concerning how much verbosity
* is desired. This is used by the internal default log handler, but
* it could be use by applications which provide their own log handler.
*/
extern cdio_log_level_t cdio_loglevel_default;
/**
* This type defines the signature of a log handler. For every
* message being logged, the handler will receive the log level and
* the message string.
*
* @see cdio_log_set_handler
* @see cdio_log_level_t
*
* @param level The log level.
* @param message The log message.
*/
typedef void (*cdio_log_handler_t) (cdio_log_level_t level,
const char message[]);
/**
* Set a custom log handler for libcdio. The return value is the log
* handler being replaced. If the provided parameter is NULL, then
* the handler will be reset to the default handler.
*
* @see cdio_log_handler_t
*
* @param new_handler The new log handler.
* @return The previous log handler.
*/
cdio_log_handler_t cdio_log_set_handler (cdio_log_handler_t new_handler);
/**
* Handle an message with the given log level.
*
* @see cdio_debug
* @see cdio_info
* @see cdio_warn
* @see cdio_error
* @param level The log level.
* @param format printf-style format string
* @param ... remaining arguments needed by format string
*/
void cdio_log (cdio_log_level_t level,
const char format[], ...) GNUC_PRINTF(2, 3);
/**
* Handle a debugging message.
*
* @see cdio_log for a more generic routine
*/
void cdio_debug (const char format[], ...) GNUC_PRINTF(1,2);
/**
* Handle an informative message.
*
* @see cdio_log for a more generic routine
*/
void cdio_info (const char format[], ...) GNUC_PRINTF(1,2);
/**
* Handle a warning message.
*
* @see cdio_log for a more generic routine
*/
void cdio_warn (const char format[], ...) GNUC_PRINTF(1,2);
/**
* Handle an error message. Execution is terminated.
*
* @see cdio_log for a more generic routine.
*/
void cdio_error (const char format[], ...) GNUC_PRINTF(1,2);
#ifdef __cplusplus
}
#endif
#endif /* __LOGGING_H__ */
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

811
src/libcdio/cdio/mmc.h Normal file
View File

@ -0,0 +1,811 @@
/*
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
\file mmc.h
\brief Common definitions for MMC (Multimedia Commands). Applications
include this for direct MMC access.
The documents we make use of are described in several
specifications made by the SCSI committee T10
http://www.t10.org. In particular, SCSI Primary Commands (SPC),
SCSI Block Commands (SBC), and Multi-Media Commands (MMC). These
documents generally have a numeric level number appended. For
example SPC-3 refers to ``SCSI Primary Commands - 3'.
In year 2010 the current versions were SPC-3, SBC-2, MMC-5.
*/
#ifndef __CDIO_MMC_H__
#define __CDIO_MMC_H__
#include <cdio/cdio.h>
#include <cdio/types.h>
#include <cdio/dvd.h>
#include <cdio/audio.h>
#include <cdio/mmc_util.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* On GNU/Linux see <linux/byteorder/big_endian.h> and
<linux/byteorder/little_endian.h>
*/
#ifdef WORDS_BIGENDIAN
# if !defined(__LITTLE_ENDIAN_BITFIELD) && !defined(__BIG_ENDIAN_BITFIELD)
# define __MMC_BIG_ENDIAN_BITFIELD
# endif
#else
# if !defined(__LITTLE_ENDIAN_BITFIELD) && !defined(__BIG_ENDIAN_BITFIELD)
# define __MMC_LITTLE_ENDIAN_BITFIELD
# endif
#endif
/**
Structure of a SCSI/MMC sense reply.
This has been adapted from GNU/Linux request_sense of <linux/cdrom.h>
include this for direct MMC access.
See SCSI Primary Commands-2 (SPC-3) table 26 page 38.
*/
typedef struct cdio_mmc_request_sense {
#if defined(__MMC_BIG_ENDIAN_BITFIELD)
uint8_t valid : 1; /**< valid bit is 1 if info is valid */
uint8_t error_code : 7;
#else
uint8_t error_code : 7;
uint8_t valid : 1; /**< valid bit is 1 if info is valid */
#endif
uint8_t segment_number;
#if defined(__MMC_BIG_ENDIAN_BITFIELD)
uint8_t filemark : 1; /**< manditory in sequential
* access devices */
uint8_t eom : 1; /**< end of medium. manditory in
* sequential access and
* printer devices */
uint8_t ili : 1; /**< incorrect length indicator */
uint8_t reserved1 : 1;
uint8_t sense_key : 4;
#else
uint8_t sense_key : 4;
uint8_t reserved1 : 1;
uint8_t ili : 1; /**< incorrect length indicator */
uint8_t eom : 1; /**< end of medium. manditory in
* sequential access and
* printer devices */
uint8_t filemark : 1; /**< manditory in sequential
* access devices */
#endif
uint8_t information[4];
uint8_t additional_sense_len; /**< Additional sense length (n-7) */
uint8_t command_info[4]; /**< Command-specific information */
uint8_t asc; /**< Additional sense code */
uint8_t ascq; /**< Additional sense code qualifier */
uint8_t fruc; /**< Field replaceable unit code */
uint8_t sks[3]; /**< Sense-key specific */
uint8_t asb[46]; /**< Additional sense bytes */
} cdio_mmc_request_sense_t;
/**
Meanings of the values of mmc_request_sense.sense_key
*/
typedef enum {
CDIO_MMC_SENSE_KEY_NO_SENSE = 0,
CDIO_MMC_SENSE_KEY_RECOVERED_ERROR = 1,
CDIO_MMC_SENSE_KEY_NOT_READY = 2,
CDIO_MMC_SENSE_KEY_MEDIUM_ERROR = 3,
CDIO_MMC_SENSE_KEY_HARDWARE_ERROR = 4,
CDIO_MMC_SENSE_KEY_ILLEGAL_REQUEST = 5,
CDIO_MMC_SENSE_KEY_UNIT_ATTENTION = 6,
CDIO_MMC_SENSE_KEY_DATA_PROTECT = 7,
CDIO_MMC_SENSE_KEY_BLANK_CHECK = 8,
CDIO_MMC_SENSE_KEY_VENDOR_SPECIFIC = 9,
CDIO_MMC_SENSE_KEY_COPY_ABORTED = 10,
CDIO_MMC_SENSE_KEY_ABORTED_COMMAND = 11,
CDIO_MMC_SENSE_KEY_OBSOLETE = 12,
} cdio_mmc_sense_key_t;
/**
\brief The opcode-portion (generic packet commands) of an MMC command.
In general, those opcodes that end in 6 take a 6-byte command
descriptor, those that end in 10 take a 10-byte
descriptor and those that in in 12 take a 12-byte descriptor.
(Not that you need to know that, but it seems to be a
big deal in the MMC specification.)
*/
typedef enum {
CDIO_MMC_GPCMD_TEST_UNIT_READY = 0x00, /**< test if drive ready. */
CDIO_MMC_GPCMD_INQUIRY = 0x12, /**< Request drive
information. */
CDIO_MMC_GPCMD_MODE_SELECT_6 = 0x15, /**< Select medium
(6 bytes). */
CDIO_MMC_GPCMD_MODE_SENSE_6 = 0x1a, /**< Get medium or device
information. Should be issued
before MODE SELECT to get
mode support or save current
settings. (6 bytes). */
CDIO_MMC_GPCMD_START_STOP_UNIT = 0x1b, /**< Enable/disable Disc
operations. (6 bytes). */
CDIO_MMC_GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL
= 0x1e, /**< Enable/disable Disc
removal. (6 bytes). */
/**
Group 2 Commands (CDB's here are 10-bytes)
*/
CDIO_MMC_GPCMD_READ_10 = 0x28, /**< Read data from drive
(10 bytes). */
CDIO_MMC_GPCMD_READ_SUBCHANNEL = 0x42, /**< Read Sub-Channel data.
(10 bytes). */
CDIO_MMC_GPCMD_READ_TOC = 0x43, /**< READ TOC/PMA/ATIP.
(10 bytes). */
CDIO_MMC_GPCMD_READ_HEADER = 0x44,
CDIO_MMC_GPCMD_PLAY_AUDIO_10 = 0x45, /**< Begin audio playing at
current position
(10 bytes). */
CDIO_MMC_GPCMD_GET_CONFIGURATION = 0x46, /**< Get drive Capabilities
(10 bytes) */
CDIO_MMC_GPCMD_PLAY_AUDIO_MSF = 0x47, /**< Begin audio playing at
specified MSF (10
bytes). */
CDIO_MMC_GPCMD_PLAY_AUDIO_TI = 0x48,
CDIO_MMC_GPCMD_PLAY_TRACK_REL_10 = 0x49, /**< Play audio at the track
relative LBA. (10 bytes).
Doesn't seem to be part
of MMC standards but is
handled by Plextor drives.
*/
CDIO_MMC_GPCMD_GET_EVENT_STATUS = 0x4a, /**< Report events and
Status. */
CDIO_MMC_GPCMD_PAUSE_RESUME = 0x4b, /**< Stop or restart audio
playback. (10 bytes).
Used with a PLAY command. */
CDIO_MMC_GPCMD_READ_DISC_INFO = 0x51, /**< Get CD information.
(10 bytes). */
CDIO_MMC_GPCMD_READ_TRACK_INFORMATION = 0x52, /**< Information about a
logical track. */
CDIO_MMC_GPCMD_MODE_SELECT_10 = 0x55, /**< Select medium
(10-bytes). */
CDIO_MMC_GPCMD_MODE_SENSE_10 = 0x5a, /**< Get medium or device
information. Should be issued
before MODE SELECT to get
mode support or save current
settings. (6 bytes). */
/**
Group 5 Commands (CDB's here are 12-bytes)
*/
CDIO_MMC_GPCMD_PLAY_AUDIO_12 = 0xa5, /**< Begin audio playing at
current position
(12 bytes) */
CDIO_MMC_GPCMD_LOAD_UNLOAD = 0xa6, /**< Load/unload a Disc
(12 bytes) */
CDIO_MMC_GPCMD_READ_12 = 0xa8, /**< Read data from drive
(12 bytes). */
CDIO_MMC_GPCMD_PLAY_TRACK_REL_12 = 0xa9, /**< Play audio at the track
relative LBA. (12 bytes).
Doesn't seem to be part
of MMC standards but is
handled by Plextor drives.
*/
CDIO_MMC_GPCMD_READ_DVD_STRUCTURE = 0xad, /**< Get DVD structure info
from media (12 bytes). */
CDIO_MMC_GPCMD_READ_MSF = 0xb9, /**< Read almost any field
of a CD sector at specified
MSF. (12 bytes). */
CDIO_MMC_GPCMD_SET_SPEED = 0xbb, /**< Set drive speed
(12 bytes). This is listed
as optional in ATAPI 2.6,
but is (curiously)
missing from Mt. Fuji,
Table 57. It is mentioned
in Mt. Fuji Table 377 as an
MMC command for SCSI
devices though... Most
ATAPI drives support it. */
CDIO_MMC_GPCMD_READ_CD = 0xbe, /**< Read almost any field
of a CD sector at current
location. (12 bytes). */
/**
Vendor-unique Commands
*/
CDIO_MMC_GPCMD_CD_PLAYBACK_STATUS = 0xc4 /**< SONY unique = command */,
CDIO_MMC_GPCMD_PLAYBACK_CONTROL = 0xc9 /**< SONY unique = command */,
CDIO_MMC_GPCMD_READ_CDDA = 0xd8 /**< Vendor unique = command */,
CDIO_MMC_GPCMD_READ_CDXA = 0xdb /**< Vendor unique = command */,
CDIO_MMC_GPCMD_READ_ALL_SUBCODES = 0xdf /**< Vendor unique = command */
} cdio_mmc_gpcmd_t;
/**
Read Subchannel states
*/
typedef enum {
CDIO_MMC_READ_SUB_ST_INVALID = 0x00, /**< audio status not supported */
CDIO_MMC_READ_SUB_ST_PLAY = 0x11, /**< audio play operation in
progress */
CDIO_MMC_READ_SUB_ST_PAUSED = 0x12, /**< audio play operation paused */
CDIO_MMC_READ_SUB_ST_COMPLETED = 0x13, /**< audio play successfully
completed */
CDIO_MMC_READ_SUB_ST_ERROR = 0x14, /**< audio play stopped due to
error */
CDIO_MMC_READ_SUB_ST_NO_STATUS = 0x15, /**< no current audio status to
return */
} cdio_mmc_read_sub_state_t;
/** Level values that can go into READ_CD */
typedef enum {
CDIO_MMC_READ_TYPE_ANY = 0, /**< All types */
CDIO_MMC_READ_TYPE_CDDA = 1, /**< Only CD-DA sectors */
CDIO_MMC_READ_TYPE_MODE1 = 2, /**< mode1 sectors (user data = 2048) */
CDIO_MMC_READ_TYPE_MODE2 = 3, /**< mode2 sectors form1 or form2 */
CDIO_MMC_READ_TYPE_M2F1 = 4, /**< mode2 sectors form1 */
CDIO_MMC_READ_TYPE_M2F2 = 5 /**< mode2 sectors form2 */
} cdio_mmc_read_cd_type_t;
/**
Format values for READ_TOC
*/
typedef enum {
CDIO_MMC_READTOC_FMT_TOC = 0,
CDIO_MMC_READTOC_FMT_SESSION = 1,
CDIO_MMC_READTOC_FMT_FULTOC = 2,
CDIO_MMC_READTOC_FMT_PMA = 3, /**< Q subcode data */
CDIO_MMC_READTOC_FMT_ATIP = 4, /**< includes media type */
CDIO_MMC_READTOC_FMT_CDTEXT = 5 /**< CD-TEXT info */
} cdio_mmc_readtoc_t;
/**
Page codes for MODE SENSE and MODE SET.
*/
typedef enum {
CDIO_MMC_R_W_ERROR_PAGE = 0x01,
CDIO_MMC_WRITE_PARMS_PAGE = 0x05,
CDIO_MMC_CDR_PARMS_PAGE = 0x0d,
CDIO_MMC_AUDIO_CTL_PAGE = 0x0e,
CDIO_MMC_POWER_PAGE = 0x1a,
CDIO_MMC_FAULT_FAIL_PAGE = 0x1c,
CDIO_MMC_TO_PROTECT_PAGE = 0x1d,
CDIO_MMC_CAPABILITIES_PAGE = 0x2a,
CDIO_MMC_ALL_PAGES = 0x3f,
} cdio_mmc_mode_page_t;
/**
READ DISC INFORMATION Data Types
*/
typedef enum {
CDIO_MMC_READ_DISC_INFO_STANDARD = 0x0,
CDIO_MMC_READ_DISC_INFO_TRACK = 0x1,
CDIO_MMC_READ_DISC_INFO_POW = 0x2,
} cdio_mmc_read_disc_info_datatype_t;
PRAGMA_BEGIN_PACKED
struct mmc_audio_volume_entry_s
{
uint8_t selection; /* Only the lower 4 bits are used. */
uint8_t volume;
} GNUC_PACKED;
typedef struct mmc_audio_volume_entry_s mmc_audio_volume_entry_t;
/**
This struct is used by cdio_audio_get_volume and cdio_audio_set_volume
*/
struct mmc_audio_volume_s
{
mmc_audio_volume_entry_t port[4];
} GNUC_PACKED;
typedef struct mmc_audio_volume_s mmc_audio_volume_t;
PRAGMA_END_PACKED
/**
Return type codes for GET_CONFIGURATION.
*/
typedef enum {
CDIO_MMC_GET_CONF_ALL_FEATURES = 0, /**< all features without regard
to currency. */
CDIO_MMC_GET_CONF_CURRENT_FEATURES = 1, /**< features which are currently
in effect (e.g. based on
medium inserted). */
CDIO_MMC_GET_CONF_NAMED_FEATURE = 2 /**< just the feature named in
the GET_CONFIGURATION cdb. */
} cdio_mmc_get_conf_t;
/**
FEATURE codes used in GET CONFIGURATION.
*/
typedef enum {
CDIO_MMC_FEATURE_PROFILE_LIST = 0x000, /**< Profile List Feature */
CDIO_MMC_FEATURE_CORE = 0x001,
CDIO_MMC_FEATURE_MORPHING = 0x002, /**< Report/prevent operational
changes */
CDIO_MMC_FEATURE_REMOVABLE_MEDIUM = 0x003, /**< Removable Medium Feature */
CDIO_MMC_FEATURE_WRITE_PROTECT = 0x004, /**< Write Protect Feature */
CDIO_MMC_FEATURE_RANDOM_READABLE = 0x010, /**< Random Readable Feature */
CDIO_MMC_FEATURE_MULTI_READ = 0x01D, /**< Multi-Read Feature */
CDIO_MMC_FEATURE_CD_READ = 0x01E, /**< CD Read Feature */
CDIO_MMC_FEATURE_DVD_READ = 0x01F, /**< DVD Read Feature */
CDIO_MMC_FEATURE_RANDOM_WRITABLE = 0x020, /**< Random Writable Feature */
CDIO_MMC_FEATURE_INCR_WRITE = 0x021, /**< Incremental Streaming
Writable Feature */
CDIO_MMC_FEATURE_SECTOR_ERASE = 0x022, /**< Sector Erasable Feature */
CDIO_MMC_FEATURE_FORMATABLE = 0x023, /**< Formattable Feature */
CDIO_MMC_FEATURE_DEFECT_MGMT = 0x024, /**< Management Ability of the
Logical Unit/media system to
provide an apparently
defect-free space.*/
CDIO_MMC_FEATURE_WRITE_ONCE = 0x025, /**< Write Once
Feature */
CDIO_MMC_FEATURE_RESTRICT_OVERW = 0x026, /**< Restricted Overwrite
Feature */
CDIO_MMC_FEATURE_CD_RW_CAV = 0x027, /**< CD-RW CAV Write Feature */
CDIO_MMC_FEATURE_MRW = 0x028, /**< MRW Feature */
CDIO_MMC_FEATURE_ENHANCED_DEFECT = 0x029, /**< Enhanced Defect Reporting */
CDIO_MMC_FEATURE_DVD_PRW = 0x02A, /**< DVD+RW Feature */
CDIO_MMC_FEATURE_DVD_PR = 0x02B, /**< DVD+R Feature */
CDIO_MMC_FEATURE_RIGID_RES_OVERW = 0x02C, /**< Rigid Restricted Overwrite */
CDIO_MMC_FEATURE_CD_TAO = 0x02D, /**< CD Track at Once */
CDIO_MMC_FEATURE_CD_SAO = 0x02E, /**< CD Mastering (Session at
Once) */
CDIO_MMC_FEATURE_DVD_R_RW_WRITE = 0x02F, /**< DVD-R/RW Write */
CDIO_MMC_FEATURE_CD_RW_MEDIA_WRITE= 0x037, /**< CD-RW Media Write Support */
CDIO_MMC_FEATURE_DVD_PR_2_LAYER = 0x03B, /**< DVD+R Double Layer */
CDIO_MMC_FEATURE_POWER_MGMT = 0x100, /**< Initiator and device directed
power management */
CDIO_MMC_FEATURE_CDDA_EXT_PLAY = 0x103, /**< Ability to play audio CDs
via the Logical Unit's own
analog output */
CDIO_MMC_FEATURE_MCODE_UPGRADE = 0x104, /* Ability for the device to
accept new microcode via
the interface */
CDIO_MMC_FEATURE_TIME_OUT = 0x105, /**< Ability to respond to all
commands within a specific
time */
CDIO_MMC_FEATURE_DVD_CSS = 0x106, /**< Ability to perform DVD
CSS/CPPM authentication and
RPC */
CDIO_MMC_FEATURE_RT_STREAMING = 0x107, /**< Ability to read and write
using Initiator requested
performance parameters */
CDIO_MMC_FEATURE_LU_SN = 0x108, /**< The Logical Unit has a unique
identifier. */
CDIO_MMC_FEATURE_FIRMWARE_DATE = 0x1FF, /**< Firmware creation date
report */
} cdio_mmc_feature_t;
typedef enum {
CDIO_MMC_FEATURE_INTERFACE_UNSPECIFIED = 0,
CDIO_MMC_FEATURE_INTERFACE_SCSI = 1,
CDIO_MMC_FEATURE_INTERFACE_ATAPI = 2,
CDIO_MMC_FEATURE_INTERFACE_IEEE_1394 = 3,
CDIO_MMC_FEATURE_INTERFACE_IEEE_1394A = 4,
CDIO_MMC_FEATURE_INTERFACE_FIBRE_CH = 5
} cdio_mmc_feature_interface_t;
/**
The largest Command Descriptor Block (CDB) size.
The possible sizes are 6, 10, and 12 bytes.
*/
#define MAX_CDB_LEN 12
/**
\brief A Command Descriptor Block (CDB) used in sending MMC
commands.
*/
typedef struct mmc_cdb_s {
uint8_t field[MAX_CDB_LEN];
} mmc_cdb_t;
/**
\brief Format of header block in data returned from an MMC
GET_CONFIGURATION command.
*/
typedef struct mmc_feature_list_header_s {
unsigned char length_msb;
unsigned char length_1sb;
unsigned char length_2sb;
unsigned char length_lsb;
unsigned char reserved1;
unsigned char reserved2;
unsigned char profile_msb;
unsigned char profile_lsb;
} cdio_mmc_feature_list_header_t;
/**
An enumeration indicating whether an MMC command is sending
data, or getting data, or does none of both.
*/
typedef enum mmc_direction_s {
SCSI_MMC_DATA_READ,
SCSI_MMC_DATA_WRITE,
SCSI_MMC_DATA_NONE
} cdio_mmc_direction_t;
/**
Indicate to applications that SCSI_MMC_DATA_NONE is available.
It has been added after version 0.82 and should be used with commands
that neither read nor write payload bytes. (At least on Linux such
commands did work with SCSI_MMC_DATA_READ or SCSI_MMC_DATA_WRITE, too.)
*/
#define SCSI_MMC_HAS_DIR_NONE 1
typedef struct mmc_subchannel_s
{
uint8_t reserved;
uint8_t audio_status;
uint16_t data_length; /**< Really ISO 9660 7.2.2 */
uint8_t format;
uint8_t address: 4;
uint8_t control: 4;
uint8_t track;
uint8_t index;
uint8_t abs_addr[4];
uint8_t rel_addr[4];
} cdio_mmc_subchannel_t;
#define CDIO_MMC_SET_COMMAND(cdb, command) \
cdb[0] = command
#define CDIO_MMC_SET_READ_TYPE(cdb, sector_type) \
cdb[1] = (sector_type << 2)
#define CDIO_MMC_GETPOS_LEN16(p, pos) \
(p[pos]<<8) + p[pos+1]
#define CDIO_MMC_GET_LEN16(p) \
(p[0]<<8) + p[1]
#define CDIO_MMC_GET_LEN32(p) \
(p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3];
#define CDIO_MMC_SET_LEN16(cdb, pos, len) \
cdb[pos ] = (len >> 8) & 0xff; \
cdb[pos+1] = (len ) & 0xff
#define CDIO_MMC_SET_READ_LBA(cdb, lba) \
cdb[2] = (lba >> 24) & 0xff; \
cdb[3] = (lba >> 16) & 0xff; \
cdb[4] = (lba >> 8) & 0xff; \
cdb[5] = (lba ) & 0xff
#define CDIO_MMC_SET_START_TRACK(cdb, command) \
cdb[6] = command
#define CDIO_MMC_SET_READ_LENGTH24(cdb, len) \
cdb[6] = (len >> 16) & 0xff; \
cdb[7] = (len >> 8) & 0xff; \
cdb[8] = (len ) & 0xff
#define CDIO_MMC_SET_READ_LENGTH16(cdb, len) \
CDIO_MMC_SET_LEN16(cdb, 7, len)
#define CDIO_MMC_SET_READ_LENGTH8(cdb, len) \
cdb[8] = (len ) & 0xff
#define CDIO_MMC_MCSB_ALL_HEADERS 0xf
#define CDIO_MMC_SET_MAIN_CHANNEL_SELECTION_BITS(cdb, val) \
cdb[9] = val << 3;
/**
Get the output port volumes and port selections used on AUDIO PLAY
commands via a MMC MODE SENSE command using the CD Audio Control
Page.
@param p_cdio the CD object to be acted upon.
@param p_volume volume parameters retrieved
@return DRIVER_OP_SUCCESS if we ran the command ok.
*/
driver_return_code_t mmc_audio_get_volume (CdIo_t *p_cdio, /*out*/
mmc_audio_volume_t *p_volume);
/**
Read Audio Subchannel information
@param p_cdio the CD object to be acted upon.
@param p_subchannel place for returned subchannel information
*/
driver_return_code_t
mmc_audio_read_subchannel (CdIo_t *p_cdio,
/*out*/ cdio_subchannel_t *p_subchannel);
/**
Read ISRC Subchannel information. Contributed by
Scot C. Bontrager (scot@indievisible.org)
May 15, 2011 -
@param p_cdio the CD object to be acted upon.
@param track the track you to get ISRC info
@param p_isrc place to put ISRC info
*/
driver_return_code_t
mmc_isrc_track_read_subchannel (CdIo_t *p_cdio, /*in*/ const track_t track,
/*out*/ char *p_isrc);
/**
Return a string containing the name of the audio state as returned from
the Q_SUBCHANNEL.
*/
const char *mmc_audio_state2str( uint8_t i_audio_state );
/**
Get the block size used in read requests, via MMC (e.g. READ_10,
READ_MSF, ...)
@param p_cdio the CD object to be acted upon.
@return the blocksize if > 0; error if <= 0
*/
int mmc_get_blocksize ( CdIo_t *p_cdio );
/**
Return the length in bytes of the Command Descriptor
Buffer (CDB) for a given MMC command. The length will be
either 6, 10, or 12.
*/
uint8_t mmc_get_cmd_len(uint8_t mmc_cmd);
/**
Get the lsn of the end of the CD
@param p_cdio the CD object to be acted upon.
@return the lsn. On error return CDIO_INVALID_LSN.
*/
lsn_t mmc_get_disc_last_lsn( const CdIo_t *p_cdio );
/**
Return the discmode as reported by the MMC Read (FULL) TOC
command.
Information was obtained from Section 5.1.13 (Read TOC/PMA/ATIP)
pages 56-62 from the MMC draft specification, revision 10a
at http://www.t10.org/ftp/t10/drafts/mmc/mmc-r10a.pdf See
especially tables 72, 73 and 75.
*/
discmode_t mmc_get_discmode( const CdIo_t *p_cdio );
typedef enum {
CDIO_MMC_LEVEL_WEIRD,
CDIO_MMC_LEVEL_1,
CDIO_MMC_LEVEL_2,
CDIO_MMC_LEVEL_3,
CDIO_MMC_LEVEL_NONE
} cdio_mmc_level_t;
/**
Get the MMC level supported by the device.
@param p_cdio the CD object to be acted upon.
@return MMC level supported by the device.
*/
cdio_mmc_level_t mmc_get_drive_mmc_cap(CdIo_t *p_cdio);
/**
Get the DVD type associated with cd object.
@param p_cdio the CD object to be acted upon.
@param s location to store DVD information.
@return the DVD discmode.
*/
discmode_t mmc_get_dvd_struct_physical ( const CdIo_t *p_cdio,
cdio_dvd_struct_t *s);
/**
Find out if media tray is open or closed.
@param p_cdio the CD object to be acted upon.
@return 1 if media is open, 0 if closed. Error
return codes are the same as driver_return_code_t
*/
int mmc_get_tray_status ( const CdIo_t *p_cdio );
/**
Get the CD-ROM hardware info via an MMC INQUIRY command.
@param p_cdio the CD object to be acted upon.
@param p_hw_info place to store hardware information retrieved
@return true if we were able to get hardware info, false if we had
an error.
*/
bool mmc_get_hwinfo ( const CdIo_t *p_cdio,
/* out*/ cdio_hwinfo_t *p_hw_info );
/**
Find out if media has changed since the last call.
@param p_cdio the CD object to be acted upon.
@return 1 if media has changed since last call, 0 if not. Error
return codes are the same as driver_return_code_t
*/
int mmc_get_media_changed(const CdIo_t *p_cdio);
/**
Get the media catalog number (MCN) from the CD via MMC.
@param p_cdio the CD object to be acted upon.
@return the media catalog number r NULL if there is none or we
don't have the ability to get it.
Note: string is malloc'd so caller has to free() the returned
string when done with it.
*/
char * mmc_get_mcn(const CdIo_t *p_cdio);
/**
Report if CD-ROM has a particular kind of interface (ATAPI, SCSCI, ...)
Is it possible for an interface to have several? If not this
routine could probably return the single mmc_feature_interface_t.
@param p_cdio the CD object to be acted upon.
@param e_interface
@return true if we have the interface and false if not.
*/
bool_3way_t mmc_have_interface(CdIo_t *p_cdio,
cdio_mmc_feature_interface_t e_interface );
/**
Read just the user data part of some sort of data sector (via
mmc_read_cd).
@param p_cdio object to read from
@param p_buf place to read data into. The caller should make
sure this location can store at least CDIO_CD_FRAMESIZE,
M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE depending on the
kind of sector getting read. If you don't know whether
you have a Mode 1/2, Form 1/ Form 2/Formless sector best
to reserve space for the maximum, M2RAW_SECTOR_SIZE.
@param i_lsn sector to read
@param i_blocksize size of each block
@param i_blocks number of blocks to read
*/
driver_return_code_t mmc_read_data_sectors ( CdIo_t *p_cdio, void *p_buf,
lsn_t i_lsn,
uint16_t i_blocksize,
uint32_t i_blocks );
/**
Read sectors using SCSI-MMC GPCMD_READ_CD.
Can read only up to 25 blocks.
*/
driver_return_code_t mmc_read_sectors ( const CdIo_t *p_cdio, void *p_buf,
lsn_t i_lsn, int read_sector_type,
uint32_t i_blocks);
/**
Run a Multimedia command (MMC).
@param p_cdio CD structure set by cdio_open().
@param i_timeout_ms time in milliseconds we will wait for the command
to complete.
@param p_cdb CDB bytes. All values that are needed should be set
on input. We'll figure out what the right CDB length
should be.
@param e_direction direction the transfer is to go.
@param i_buf Size of buffer
@param p_buf Buffer for data, both sending and receiving.
@return 0 if command completed successfully.
*/
driver_return_code_t
mmc_run_cmd( const CdIo_t *p_cdio, unsigned int i_timeout_ms,
const mmc_cdb_t *p_cdb,
cdio_mmc_direction_t e_direction, unsigned int i_buf,
/*in/out*/ void *p_buf );
/**
Run a Multimedia command (MMC) specifying the CDB length.
The motivation here is for example ot use in is an undocumented
debug command for LG drives (namely E7), whose length is being
miscalculated by mmc_get_cmd_len(); it doesn't follow the usual
code number to length conventions. Patch supplied by SukkoPera.
@param p_cdio CD structure set by cdio_open().
@param i_timeout_ms time in milliseconds we will wait for the command
to complete.
@param p_cdb CDB bytes. All values that are needed should be set
on input.
@param i_cdb number of CDB bytes.
@param e_direction direction the transfer is to go.
@param i_buf Size of buffer
@param p_buf Buffer for data, both sending and receiving.
@return 0 if command completed successfully.
*/
driver_return_code_t
mmc_run_cmd_len( const CdIo_t *p_cdio, unsigned int i_timeout_ms,
const mmc_cdb_t *p_cdb, unsigned int i_cdb,
cdio_mmc_direction_t e_direction, unsigned int i_buf,
/*in/out*/ void *p_buf );
/**
Obtain the SCSI sense reply of the most-recently-performed MMC command.
These bytes give an indication of possible problems which occured in
the drive while the command was performed. With some commands they tell
about the current state of the drive (e.g. 00h TEST UNIT READY).
@param p_cdio CD structure set by cdio_open().
@param pp_sense returns the sense bytes received from the drive.
This is allocated memory or NULL if no sense bytes are
available. Dispose non-NULL pointers by free() when no longer
needed. See SPC-3 4.5.3 Fixed format sense data. SCSI error
codes as of SPC-3 Annex D, MMC-5 Annex F: sense[2]&15 = Key ,
sense[12] = ASC , sense[13] = ASCQ
@return number of valid bytes in sense, 0 in case of no sense
bytes available, <0 in case of internal error.
*/
int mmc_last_cmd_sense ( const CdIo_t *p_cdio,
cdio_mmc_request_sense_t **pp_sense);
/**
Set the block size for subsequest read requests, via MMC.
*/
driver_return_code_t mmc_set_blocksize ( const CdIo_t *p_cdio,
uint16_t i_blocksize);
#ifdef __cplusplus
}
#endif /* __cplusplus */
/**
The below variables are trickery to force the above enum symbol
values to be recorded in debug symbol tables. They are used to
allow one to refer to the enumeration value names in the typedefs
above in a debugger and debugger expressions
*/
extern cdio_mmc_feature_t debug_cdio_mmc_feature;
extern cdio_mmc_feature_interface_t debug_cdio_mmc_feature_interface;
extern cdio_mmc_feature_profile_t debug_cdio_mmc_feature_profile;
extern cdio_mmc_get_conf_t debug_cdio_mmc_get_conf;
extern cdio_mmc_gpcmd_t debug_cdio_mmc_gpcmd;
extern cdio_mmc_read_sub_state_t debug_cdio_mmc_read_sub_state;
extern cdio_mmc_read_cd_type_t debug_cdio_mmc_read_cd_type;
extern cdio_mmc_readtoc_t debug_cdio_mmc_readtoc;
extern cdio_mmc_mode_page_t debug_cdio_mmc_mode_page;
#ifndef DO_NOT_WANT_OLD_MMC_COMPATIBILITY
#define CDIO_MMC_GPCMD_START_STOP CDIO_MMC_GPCMD_START_STOP_UNIT
#define CDIO_MMC_GPCMD_ALLOW_MEDIUM_REMOVAL \
CDIO_MMC_GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL
#endif /*DO_NOT_WANT_PARANOIA_COMPATIBILITY*/
#endif /* __MMC_H__ */
/*
* Local variables:
* c-file-style: "ruby"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

157
src/libcdio/cdio/mmc_util.h Normal file
View File

@ -0,0 +1,157 @@
/*
Copyright (C) 2010 Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
\file mmc_util.h
\brief Multimedia Command (MMC) "helper" routines that don't depend
on anything other than headers.
*/
#ifndef __CDIO_MMC_UTIL_H__
#define __CDIO_MMC_UTIL_H__
#include <cdio/device.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
Profile profile codes used in GET_CONFIGURATION - PROFILE LIST. */
typedef enum {
CDIO_MMC_FEATURE_PROF_NON_REMOVABLE = 0x0001, /**< Re-writable disc, capable
of changing behavior */
CDIO_MMC_FEATURE_PROF_REMOVABLE = 0x0002, /**< disk Re-writable; with
removable media */
CDIO_MMC_FEATURE_PROF_MO_ERASABLE = 0x0003, /**< Erasable Magneto-Optical
disk with sector erase
capability */
CDIO_MMC_FEATURE_PROF_MO_WRITE_ONCE = 0x0004, /**< Write Once Magneto-Optical
write once */
CDIO_MMC_FEATURE_PROF_AS_MO = 0x0005, /**< Advance Storage
Magneto-Optical */
CDIO_MMC_FEATURE_PROF_CD_ROM = 0x0008, /**< Read only Compact Disc
capable */
CDIO_MMC_FEATURE_PROF_CD_R = 0x0009, /**< Write once Compact Disc
capable */
CDIO_MMC_FEATURE_PROF_CD_RW = 0x000A, /**< CD-RW Re-writable
Compact Disc capable */
CDIO_MMC_FEATURE_PROF_DVD_ROM = 0x0010, /**< Read only DVD */
CDIO_MMC_FEATURE_PROF_DVD_R_SEQ = 0x0011, /**< Re-recordable DVD using
Sequential recording */
CDIO_MMC_FEATURE_PROF_DVD_RAM = 0x0012, /**< Re-writable DVD */
CDIO_MMC_FEATURE_PROF_DVD_RW_RO = 0x0013, /**< Re-recordable DVD using
Restricted Overwrite */
CDIO_MMC_FEATURE_PROF_DVD_RW_SEQ = 0x0014, /**< Re-recordable DVD using
Sequential recording */
CDIO_MMC_FEATURE_PROF_DVD_R_DL_SEQ = 0x0015, /**< DVD-R/DL sequential
recording */
CDIO_MMC_FEATURE_PROF_DVD_R_DL_JR = 0x0016, /**< DVD-R/DL layer jump
recording */
CDIO_MMC_FEATURE_PROF_DVD_PRW = 0x001A, /**< DVD+RW - DVD ReWritable */
CDIO_MMC_FEATURE_PROF_DVD_PR = 0x001B, /**< DVD+R - DVD Recordable */
CDIO_MMC_FEATURE_PROF_DDCD_ROM = 0x0020, /**< Read only DDCD */
CDIO_MMC_FEATURE_PROF_DDCD_R = 0x0021, /**< DDCD-R Write only DDCD */
CDIO_MMC_FEATURE_PROF_DDCD_RW = 0x0022, /**< Re-Write only DDCD */
CDIO_MMC_FEATURE_PROF_DVD_PRW_DL = 0x002A, /**< "DVD+RW/DL */
CDIO_MMC_FEATURE_PROF_DVD_PR_DL = 0x002B, /**< DVD+R - DVD Recordable
double layer */
CDIO_MMC_FEATURE_PROF_BD_ROM = 0x0040, /**< BD-ROM */
CDIO_MMC_FEATURE_PROF_BD_SEQ = 0x0041, /**< BD-R sequential
recording */
CDIO_MMC_FEATURE_PROF_BD_R_RANDOM = 0x0042, /**< BD-R random recording */
CDIO_MMC_FEATURE_PROF_BD_RE = 0x0043, /**< BD-RE */
CDIO_MMC_FEATURE_PROF_HD_DVD_ROM = 0x0050, /**< HD-DVD-ROM */
CDIO_MMC_FEATURE_PROF_HD_DVD_R = 0x0051, /**< HD-DVD-R */
CDIO_MMC_FEATURE_PROF_HD_DVD_RAM = 0x0052, /**<"HD-DVD-RAM */
CDIO_MMC_FEATURE_PROF_NON_CONFORM = 0xFFFF, /**< The Logical Unit does not
conform to any Profile. */
} cdio_mmc_feature_profile_t;
/**
@param i_feature MMC feature number
@return string containing the name of the given feature
*/
const char *mmc_feature2str( int i_feature );
/**
Get drive capabilities for a device.
@param p_cdio the CD object to be acted upon.
@param p_read_cap list of read capabilities that are set on return
@param p_write_cap list of write capabilities that are set on return
@param p_misc_cap list of miscellaneous capabilities (that are neither
read nor write related) that are set on return
*/
void mmc_get_drive_cap ( CdIo_t *p_cdio,
/*out*/ cdio_drive_read_cap_t *p_read_cap,
/*out*/ cdio_drive_write_cap_t *p_write_cap,
/*out*/ cdio_drive_misc_cap_t *p_misc_cap);
/**
Return a string containing the name of the given feature
*/
const char *mmc_feature_profile2str( int i_feature_profile );
bool mmc_is_disctype_bd(cdio_mmc_feature_profile_t disctype);
bool mmc_is_disctype_cdrom(cdio_mmc_feature_profile_t disctype);
bool mmc_is_disctype_dvd(cdio_mmc_feature_profile_t disctype);
bool mmc_is_disctype_hd_dvd (cdio_mmc_feature_profile_t disctype);
bool mmc_is_disctype_overwritable (cdio_mmc_feature_profile_t disctype);
bool mmc_is_disctype_rewritable(cdio_mmc_feature_profile_t disctype);
/** The default read timeout is 3 minutes. */
#define MMC_READ_TIMEOUT_DEFAULT 3*60*1000
/**
Set this to the maximum value in milliseconds that we will
wait on an MMC read command.
*/
extern uint32_t mmc_read_timeout_ms;
/**
Maps a mmc_sense_key_t into a string name.
*/
extern const char mmc_sense_key2str[16][40];
/**
The default timeout (non-read) is 6 seconds.
*/
#define MMC_TIMEOUT_DEFAULT 6000
/**
Set this to the maximum value in milliseconds that we will
wait on an MMC command.
*/
extern uint32_t mmc_timeout_ms;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __MMC_UTIL_H__ */
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

43
src/libcdio/cdio/posix.h Normal file
View File

@ -0,0 +1,43 @@
/*
$Id: posix.h,v 1.2 2008/03/25 15:59:09 karl Exp $
Copyright (C) 2005, 2008 Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*!
* \file posix.h
*
* \brief various POSIX definitions.
*/
#ifndef __CDIO_POSIX_H__
#define __CDIO_POSIX_H__
typedef uint32_t posix_mode_t;
typedef uint32_t posix_nlink_t;
typedef uint32_t posix_uid_t;
typedef uint32_t posix_gid_t;
typedef uint16_t unicode16_t;
#endif /* __CDIO_POSIX_H__ */
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

235
src/libcdio/cdio/read.h Normal file
View File

@ -0,0 +1,235 @@
/*
$Id: read.h,v 1.15 2008/03/25 15:59:09 karl Exp $
Copyright (C) 2005, 2006, 2007, 2008 Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file read.h
*
* \brief The top-level header for sector (block, frame)-related
* libcdio calls.
*/
#ifndef __CDIO_READ_H__
#define __CDIO_READ_H__
#ifndef EXTERNAL_LIBCDIO_CONFIG_H
#define EXTERNAL_LIBCDIO_CONFIG_H
/* Need for HAVE_SYS_TYPES_H */
#include <cdio/cdio_config.h>
#endif
#ifdef HAVE_SYS_TYPES_H
/* Some systems need this for off_t and ssize. */
#include <sys/types.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/** All the different ways a block/sector can be read. */
typedef enum {
CDIO_READ_MODE_AUDIO, /**< CD-DA, audio, Red Book */
CDIO_READ_MODE_M1F1, /**< Mode 1 Form 1 */
CDIO_READ_MODE_M1F2, /**< Mode 1 Form 2 */
CDIO_READ_MODE_M2F1, /**< Mode 2 Form 1 */
CDIO_READ_MODE_M2F2 /**< Mode 2 Form 2 */
} cdio_read_mode_t;
/*!
Reposition read offset
Similar to (if not the same as) libc's fseek()
@param p_cdio object which gets adjusted
@param offset amount to seek
@param whence like corresponding parameter in libc's fseek, e.g.
SEEK_SET or SEEK_END.
@return (off_t) -1 on error.
*/
off_t cdio_lseek(const CdIo_t *p_cdio, off_t offset, int whence);
/*! Reads into buf the next size bytes. Similar to (if not the
same as) libc's read(). This is a "cooked" read, or one handled by
the OS. It probably won't work on audio data. For that use
cdio_read_audio_sector(s).
@param p_cdio object to read from
@param p_buf place to read data into. The caller should make sure
this location can store at least i_size bytes.
@param i_size number of bytes to read
@return (ssize_t) -1 on error.
*/
ssize_t cdio_read(const CdIo_t *p_cdio, void *p_buf, size_t i_size);
/*!
Read an audio sector
@param p_cdio object to read from
@param p_buf place to read data into. The caller should make sure
this location can store at least CDIO_FRAMESIZE_RAW
bytes.
@param i_lsn sector to read
*/
driver_return_code_t cdio_read_audio_sector (const CdIo_t *p_cdio,
void *p_buf, lsn_t i_lsn);
/*!
Reads audio sectors
@param p_cdio object to read from
@param p_buf place to read data into. The caller should make sure
this location can store at least CDIO_FRAMESIZE_RAW
* i_blocks bytes.
@param i_lsn sector to read
@param i_blocks number of sectors to read
*/
driver_return_code_t cdio_read_audio_sectors (const CdIo_t *p_cdio,
void *p_buf, lsn_t i_lsn,
uint32_t i_blocks);
/*!
Read data sectors
@param p_cdio object to read from
@param p_buf place to read data into. The caller should make sure
this location can store at least ISO_BLOCKSIZE,
M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE depending
on the kind of sector getting read. If you don't
know whether you have a Mode 1/2, Form 1/ Form 2/Formless
sector best to reserve space for the maximum,
M2RAW_SECTOR_SIZE.
@param i_lsn sector to read
@param i_blocksize size of block. Should be either CDIO_CD_FRAMESIZE,
M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE. See comment above under p_buf.
@param i_blocks number of blocks to read
*/
driver_return_code_t cdio_read_data_sectors ( const CdIo_t *p_cdio,
void *p_buf, lsn_t i_lsn,
uint16_t i_blocksize,
uint32_t i_blocks );
/*!
Reads a mode 1 sector
@param p_cdio object to read from
@param p_buf place to read data into.
@param i_lsn sector to read
@param b_form2 true for reading mode 1 form 2 sectors or false for
mode 1 form 1 sectors.
*/
driver_return_code_t cdio_read_mode1_sector (const CdIo_t *p_cdio,
void *p_buf, lsn_t i_lsn,
bool b_form2);
/*!
Reads mode 1 sectors
@param p_cdio object to read from
@param p_buf place to read data into
@param i_lsn sector to read
@param b_form2 true for reading mode 1 form 2 sectors or false for
mode 1 form 1 sectors.
@param i_blocks number of sectors to read
*/
driver_return_code_t cdio_read_mode1_sectors (const CdIo_t *p_cdio,
void *p_buf, lsn_t i_lsn,
bool b_form2,
uint32_t i_blocks);
/*!
Reads a mode 2 sector
@param p_cdio object to read from
@param p_buf place to read data into. The caller should make sure
this location can store at least
M2RAW_SECTOR_SIZE (for form 1) or CDIO_CD_FRAMESIZE (for
form 2) bytes.
@param i_lsn sector to read
@param b_form2 true for reading mode 2 form 2 sectors or false for
mode 2 form 1 sectors.
@return 0 if no error, nonzero otherwise.
*/
driver_return_code_t cdio_read_mode2_sector (const CdIo_t *p_cdio,
void *p_buf, lsn_t i_lsn,
bool b_form2);
/** The special case of reading a single block is a common one so we
provide a routine for that as a convenience.
*/
driver_return_code_t cdio_read_sector(const CdIo_t *p_cdio, void *p_buf,
lsn_t i_lsn,
cdio_read_mode_t read_mode);
/*!
Reads mode 2 sectors
@param p_cdio object to read from
@param p_buf place to read data into. The caller should make sure
this location can store at least
M2RAW_SECTOR_SIZE (for form 1) or CDIO_CD_FRAMESIZE (for
form 2) * i_blocks bytes.
@param i_lsn sector to read
@param b_form2 true for reading mode2 form 2 sectors or false for
mode 2 form 1 sectors.
@param i_blocks number of sectors to read
@return 0 if no error, nonzero otherwise.
*/
driver_return_code_t cdio_read_mode2_sectors (const CdIo_t *p_cdio,
void *p_buf, lsn_t i_lsn,
bool b_form2,
uint32_t i_blocks);
/*!
Reads a number of sectors (AKA blocks).
@param p_cdio cdio object
@param p_buf place to read data into. The caller should make sure
this location is large enough. See below for size information.
@param read_mode the kind of "mode" to use in reading.
@param i_lsn sector to read
@param i_blocks number of sectors to read
@return DRIVER_OP_SUCCESS (0) if no error, other (negative) enumerations
are returned on error.
If read_mode is CDIO_MODE_AUDIO,
*p_buf should hold at least CDIO_FRAMESIZE_RAW * i_blocks bytes.
If read_mode is CDIO_MODE_DATA,
*p_buf should hold at least i_blocks times either ISO_BLOCKSIZE,
M1RAW_SECTOR_SIZE or M2F2_SECTOR_SIZE depending on the kind of
sector getting read. If you don't know whether you have a Mode 1/2,
Form 1/ Form 2/Formless sector best to reserve space for the maximum
which is M2RAW_SECTOR_SIZE.
If read_mode is CDIO_MODE_M2F1,
*p_buf should hold at least M2RAW_SECTOR_SIZE * i_blocks bytes.
If read_mode is CDIO_MODE_M2F2,
*p_buf should hold at least CDIO_CD_FRAMESIZE * i_blocks bytes.
*/
driver_return_code_t cdio_read_sectors(const CdIo_t *p_cdio, void *p_buf,
lsn_t i_lsn,
cdio_read_mode_t read_mode,
uint32_t i_blocks);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __CDIO_TRACK_H__ */

394
src/libcdio/cdio/rock.h Normal file
View File

@ -0,0 +1,394 @@
/*
Copyright (C) 2005, 2006 2008 Rocky Bernstein <rocky@gnu.org>
See also rock.c by Eric Youngdale (1993) from GNU/Linux
This is Copyright 1993 Yggdrasil Computing, Incorporated
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*!
\file rock.h
\brief Things related to the Rock Ridge Interchange Protocol (RRIP)
Applications will probably not include this directly but via
the iso9660.h header.
*/
#ifndef __CDIO_ROCK_H__
#define __CDIO_ROCK_H__
#include <cdio/types.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* MSYS 1.0.10 with MinGW 3.4.2 (and perhaps others) don't have
S_ISSOCK() or S_ISLNK() macros, so we'll roll our own. */
#if !defined(HAVE_S_ISSOCK) && !defined(S_ISSOCK)
#define S_ISSOCK(st_mode) ((((st_mode)) & 0170000) == (0140000))
#endif
#if !defined(HAVE_S_ISLNK) && !defined(S_ISLNK)
#define S_ISLNK(st_mode) ((((st_mode)) & 0170000) == (0010000))
#endif
/*! An enumeration for some of the ISO_ROCK_* \#defines below. This isn't
really an enumeration one would really use in a program it is to
be helpful in debuggers where wants just to refer to the ISO_ROCK_*
names and get something.
*/
extern enum iso_rock_enums {
ISO_ROCK_IRUSR = 000400, /**< read permission (owner) */
ISO_ROCK_IWUSR = 000200, /**< write permission (owner) */
ISO_ROCK_IXUSR = 000100, /**< execute permission (owner) */
ISO_ROCK_IRGRP = 000040, /**< read permission (group) */
ISO_ROCK_IWGRP = 000020, /**< write permission (group) */
ISO_ROCK_IXGRP = 000010, /**< execute permission (group) */
ISO_ROCK_IROTH = 000004, /**< read permission (other) */
ISO_ROCK_IWOTH = 000002, /**< write permission (other) */
ISO_ROCK_IXOTH = 000001, /**< execute permission (other) */
ISO_ROCK_ISUID = 004000, /**< set user ID on execution */
ISO_ROCK_ISGID = 002000, /**< set group ID on execution */
ISO_ROCK_ISVTX = 001000, /**< save swapped text even after use */
ISO_ROCK_ISSOCK = 0140000, /**< socket */
ISO_ROCK_ISLNK = 0120000, /**< symbolic link */
ISO_ROCK_ISREG = 0100000, /**< regular */
ISO_ROCK_ISBLK = 060000, /**< block special */
ISO_ROCK_ISCHR = 020000, /**< character special */
ISO_ROCK_ISDIR = 040000, /**< directory */
ISO_ROCK_ISFIFO = 010000 /**< pipe or FIFO */
} iso_rock_enums;
#define ISO_ROCK_IRUSR 000400 /** read permission (owner) */
#define ISO_ROCK_IWUSR 000200 /** write permission (owner) */
#define ISO_ROCK_IXUSR 000100 /** execute permission (owner) */
#define ISO_ROCK_IRGRP 000040 /** read permission (group) */
#define ISO_ROCK_IWGRP 000020 /** write permission (group) */
#define ISO_ROCK_IXGRP 000010 /** execute permission (group) */
#define ISO_ROCK_IROTH 000004 /** read permission (other) */
#define ISO_ROCK_IWOTH 000002 /** write permission (other) */
#define ISO_ROCK_IXOTH 000001 /** execute permission (other) */
#define ISO_ROCK_ISUID 004000 /** set user ID on execution */
#define ISO_ROCK_ISGID 002000 /** set group ID on execution */
#define ISO_ROCK_ISVTX 001000 /** save swapped text even after use */
#define ISO_ROCK_ISSOCK 0140000 /** socket */
#define ISO_ROCK_ISLNK 0120000 /** symbolic link */
#define ISO_ROCK_ISREG 0100000 /** regular */
#define ISO_ROCK_ISBLK 060000 /** block special */
#define ISO_ROCK_ISCHR 020000 /** character special */
#define ISO_ROCK_ISDIR 040000 /** directory */
#define ISO_ROCK_ISFIFO 010000 /** pipe or FIFO */
/** Enforced file locking (shared w/set group ID) */
#define ISO_ROCK_ENFMT ISO_ROCK_ISGID
PRAGMA_BEGIN_PACKED
/*! The next two structs are used by the system-use-sharing protocol
(SUSP), in which the Rock Ridge extensions are embedded. It is
quite possible that other extensions are present on the disk, and
this is fine as long as they all use SUSP. */
/*! system-use-sharing protocol */
typedef struct iso_su_sp_s{
unsigned char magic[2];
uint8_t skip;
} GNUC_PACKED iso_su_sp_t;
/*! system-use extension record */
typedef struct iso_su_er_s {
iso711_t len_id; /**< Identifier length. Value 10?. */
unsigned char len_des;
unsigned char len_src;
iso711_t ext_ver; /**< Extension version. Value 1? */
char data[EMPTY_ARRAY_SIZE];
} GNUC_PACKED iso_su_er_t;
typedef struct iso_su_ce_s {
char extent[8];
char offset[8];
char size[8];
} iso_su_ce_t;
/*! POSIX file attributes, PX. See Rock Ridge Section 4.1.2 */
typedef struct iso_rock_px_s {
iso733_t st_mode; /*! file mode permissions; same as st_mode
of POSIX:5.6.1 */
iso733_t st_nlinks; /*! number of links to file; same as st_nlinks
of POSIX:5.6.1 */
iso733_t st_uid; /*! user id owner of file; same as st_uid
of POSIX:5.6.1 */
iso733_t st_gid; /*! group id of file; same as st_gid of
of POSIX:5.6.1 */
} GNUC_PACKED iso_rock_px_t ;
/*! POSIX device number, PN. A PN is mandatory if the file type
recorded in the "PX" File Mode field for a Directory Record
indicates a character or block device (ISO_ROCK_ISCHR |
ISO_ROCK_ISBLK). This entry is ignored for other (non-Direcotry)
file types. No more than one "PN" is recorded in the System Use Area
of a Directory Record.
See Rock Ridge Section 4.1.2 */
typedef struct iso_rock_pn_s {
iso733_t dev_high; /**< high-order 32 bits of the 64 bit device number.
7.2.3 encoded */
iso733_t dev_low; /**< low-order 32 bits of the 64 bit device number.
7.2.3 encoded */
} GNUC_PACKED iso_rock_pn_t ;
/*! These are the bits and their meanings for flags in the SL structure. */
typedef enum {
ISO_ROCK_SL_CONTINUE = 1,
ISO_ROCK_SL_CURRENT = 2,
ISO_ROCK_SL_PARENT = 4,
ISO_ROCK_SL_ROOT = 8
} iso_rock_sl_flag_t;
#define ISO_ROCK_SL_CONTINUE 1
#define ISO_ROCK_SL_CURRENT 2
#define ISO_ROCK_SL_PARENT 4
#define ISO_ROCK_SL_ROOT 8
typedef struct iso_rock_sl_part_s {
uint8_t flags;
uint8_t len;
char text[EMPTY_ARRAY_SIZE];
} GNUC_PACKED iso_rock_sl_part_t ;
/*! Symbolic link. See Rock Ridge Section 4.1.3 */
typedef struct iso_rock_sl_s {
unsigned char flags;
iso_rock_sl_part_t link;
} GNUC_PACKED iso_rock_sl_t ;
/*! Alternate name. See Rock Ridge Section 4.1.4 */
/*! These are the bits and their meanings for flags in the NM structure. */
typedef enum {
ISO_ROCK_NM_CONTINUE = 1,
ISO_ROCK_NM_CURRENT = 2,
ISO_ROCK_NM_PARENT = 4,
} iso_rock_nm_flag_t;
#define ISO_ROCK_NM_CONTINUE 1
#define ISO_ROCK_NM_CURRENT 2
#define ISO_ROCK_NM_PARENT 4
typedef struct iso_rock_nm_s {
unsigned char flags;
char name[EMPTY_ARRAY_SIZE];
} GNUC_PACKED iso_rock_nm_t ;
/*! Child link. See Section 4.1.5.1 */
typedef struct iso_rock_cl_s {
char location[1];
} GNUC_PACKED iso_rock_cl_t ;
/*! Parent link. See Section 4.1.5.2 */
typedef struct iso_rock_pl_s {
char location[1];
} GNUC_PACKED iso_rock_pl_t ;
/*! These are the bits and their meanings for flags in the TF structure. */
typedef enum {
ISO_ROCK_TF_CREATE = 1,
ISO_ROCK_TF_MODIFY = 2,
ISO_ROCK_TF_ACCESS = 4,
ISO_ROCK_TF_ATTRIBUTES = 8,
ISO_ROCK_TF_BACKUP = 16,
ISO_ROCK_TF_EXPIRATION = 32,
ISO_ROCK_TF_EFFECTIVE = 64,
ISO_ROCK_TF_LONG_FORM = 128
} iso_rock_tf_flag_t;
/* These are the bits and their meanings for flags in the TF structure. */
#define ISO_ROCK_TF_CREATE 1
#define ISO_ROCK_TF_MODIFY 2
#define ISO_ROCK_TF_ACCESS 4
#define ISO_ROCK_TF_ATTRIBUTES 8
#define ISO_ROCK_TF_BACKUP 16
#define ISO_ROCK_TF_EXPIRATION 32
#define ISO_ROCK_TF_EFFECTIVE 64
#define ISO_ROCK_TF_LONG_FORM 128
/*! Time stamp(s) for a file. See Rock Ridge Section 4.1.6 */
typedef struct iso_rock_tf_s {
uint8_t flags; /**< See ISO_ROCK_TF_* bits above. */
uint8_t time_bytes[EMPTY_ARRAY_SIZE]; /**< A homogenious array of
iso9660_ltime_t or
iso9660_dtime_t entries
depending on flags &
ISO_ROCK_TF_LONG_FORM. Lacking
a better method, we store
this as an array of bytes
and a cast to the
appropriate type will have
to be made before
extraction. */
} GNUC_PACKED iso_rock_tf_t ;
/*! File data in sparse format. See Rock Ridge Section 4.1.7 */
typedef struct iso_rock_sf_s {
iso733_t virtual_size_high; /**< high-order 32 bits of virtual size */
iso733_t virtual_size_low; /**< low-order 32 bits of virtual size */
uint8_t table_depth;
} GNUC_PACKED iso_rock_sf_t ;
typedef struct iso_extension_record_s {
char signature[2]; /**< signature word; either 'SP', 'CE', 'ER', 'RR',
'PX', 'PN', 'SL', 'NM', 'CL', 'PL', 'TF', or
'ZF' */
iso711_t len; /**< length of system-user area - 44 for PX
20 for PN, 5+strlen(text) for SL, 21 for
SF, etc. */
iso711_t version; /**< version number - value 1 */
union {
iso_su_sp_t SP; /**< system-use-sharing protocol - not
strictly part of Rock Ridge */
iso_su_er_t ER; /**< system-use extension packet - not
strictly part of Rock Ridge */
iso_su_ce_t CE; /**< system-use - strictly part of Rock Ridge */
iso_rock_px_t PX; /**< Rock Ridge POSIX file attributes */
iso_rock_pn_t PN; /**< Rock Ridge POSIX device number */
iso_rock_sl_t SL; /**< Rock Ridge symbolic link */
iso_rock_nm_t NM; /**< Rock Ridge alternate name */
iso_rock_cl_t CL; /**< Rock Ridge child link */
iso_rock_pl_t PL; /**< Rock Ridge parent link */
iso_rock_tf_t TF; /**< Rock Ridge timestamp(s) for a file */
} u;
} GNUC_PACKED iso_extension_record_t;
typedef struct iso_rock_time_s {
bool b_used; /**< If true, field has been set and is valid.
Otherwise remaning fields are meaningless. */
bool b_longdate; /**< If true date format is a iso9660_ltime_t.
Otherwise date is iso9660_dtime_t */
union
{
iso9660_ltime_t ltime;
iso9660_dtime_t dtime;
} t;
} GNUC_PACKED iso_rock_time_t;
typedef struct iso_rock_statbuf_s {
bool_3way_t b3_rock; /**< has Rock Ridge extension.
If "yep", then the fields
are used.
*/
posix_mode_t st_mode; /**< protection */
posix_nlink_t st_nlinks; /**< number of hard links */
posix_uid_t st_uid; /**< user ID of owner */
posix_gid_t st_gid; /**< group ID of owner */
uint8_t s_rock_offset;
int i_symlink; /**< size of psz_symlink */
int i_symlink_max; /**< max allocated to psz_symlink */
char *psz_symlink; /**< if symbolic link, name
of pointed to file. */
iso_rock_time_t create; /**< create time See ISO 9660:9.5.4. */
iso_rock_time_t modify; /**< time of last modification
ISO 9660:9.5.5. st_mtime field of
POSIX:5.6.1. */
iso_rock_time_t access; /**< time of last file access st_atime
field of POSIX:5.6.1. */
iso_rock_time_t attributes; /**< time of last attribute change.
st_ctime field of POSIX:5.6.1. */
iso_rock_time_t backup; /**< time of last backup. */
iso_rock_time_t expiration; /**< time of expiration; See ISO
9660:9.5.6. */
iso_rock_time_t effective; /**< Effective time; See ISO 9660:9.5.7.
*/
uint32_t i_rdev; /**< the upper 16-bits is major device
number, the lower 16-bits is the
minor device number */
} iso_rock_statbuf_t;
PRAGMA_END_PACKED
/*! return length of name field; 0: not found, -1: to be ignored */
int get_rock_ridge_filename(iso9660_dir_t * de, /*out*/ char * retname,
/*out*/ iso9660_stat_t *p_stat);
int parse_rock_ridge_stat(iso9660_dir_t *de, /*out*/ iso9660_stat_t *p_stat);
/*!
Returns POSIX mode bitstring for a given file.
*/
mode_t
iso9660_get_posix_filemode_from_rock(const iso_rock_statbuf_t *rr);
/*!
Returns a string which interpreting the POSIX mode st_mode.
For example:
\verbatim
drwxrws---
-rw---Sr--
lrwxrwxrwx
\endverbatim
A description of the characters in the string follows
The 1st character is either "d" if the entry is a directory, "l" is
a symbolic link or "-" if neither.
The 2nd to 4th characters refer to permissions for a user while the
the 5th to 7th characters refer to permissions for a group while, and
the 8th to 10h characters refer to permissions for everyone.
In each of these triplets the first character (2, 5, 8) is "r" if
the entry is allowed to be read.
The second character of a triplet (3, 6, 9) is "w" if the entry is
allowed to be written.
The third character of a triplet (4, 7, 10) is "x" if the entry is
executable but not user (for character 4) or group (for characters
6) settable and "s" if the item has the corresponding user/group set.
For a directory having an executable property on ("x" or "s") means
the directory is allowed to be listed or "searched". If the execute
property is not allowed for a group or user but the corresponding
group/user is set "S" indicates this. If none of these properties
holds the "-" indicates this.
*/
const char *iso9660_get_rock_attr_str(posix_mode_t st_mode);
/** These variables are not used, but are defined to facilatate debugging
by letting us use enumerations values (which also correspond to
\#define's inside a debugged program.
*/
extern iso_rock_nm_flag_t iso_rock_nm_flag;
extern iso_rock_sl_flag_t iso_rock_sl_flag;
extern iso_rock_tf_flag_t iso_rock_tf_flag;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __ISO_ROCK_H__ */
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

286
src/libcdio/cdio/sector.h Normal file
View File

@ -0,0 +1,286 @@
/*
$Id: sector.h,v 1.38 2008/03/25 15:59:09 karl Exp $
Copyright (C) 2003, 2004, 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*!
\file sector.h
\brief Things related to CD-ROM layout: tracks, sector sizes, MSFs, LBAs.
A CD-ROM physical sector size is 2048, 2052, 2056, 2324, 2332, 2336,
2340, or 2352 bytes long.
Sector types of the standard CD-ROM data formats:
\verbatim
format sector type user data size (bytes)
-----------------------------------------------------------------------------
1 (Red Book) CD-DA 2352 (CDIO_CD_FRAMESIZE_RAW)
2 (Yellow Book) Mode1 Form1 2048 (CDIO_CD_FRAMESIZE)
3 (Yellow Book) Mode1 Form2 2336 (M2RAW_SECTOR_SIZE)
4 (Green Book) Mode2 Form1 2048 (CDIO_CD_FRAMESIZE)
5 (Green Book) Mode2 Form2 2328 (2324+4 spare bytes)
The layout of the standard CD-ROM data formats:
-----------------------------------------------------------------------------
- audio (red): | audio_sample_bytes |
| 2352 |
- data (yellow, mode1): | sync - head - data - EDC - zero - ECC |
| 12 - 4 - 2048 - 4 - 8 - 276 |
- data (yellow, mode2): | sync - head - data |
| 12 - 4 - 2336 |
- XA data (green, mode2 form1): | sync - head - sub - data - EDC - ECC |
| 12 - 4 - 8 - 2048 - 4 - 276 |
- XA data (green, mode2 form2): | sync - head - sub - data - Spare |
| 12 - 4 - 8 - 2324 - 4 |
\endverbatim
*/
#ifndef _CDIO_SECTOR_H_
#define _CDIO_SECTOR_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <cdio/types.h>
/*! Information that can be obtained through a Read Subchannel
command.
*/
#define CDIO_SUBCHANNEL_SUBQ_DATA 0
#define CDIO_SUBCHANNEL_CURRENT_POSITION 1
#define CDIO_SUBCHANNEL_MEDIA_CATALOG 2
#define CDIO_SUBCHANNEL_TRACK_ISRC 3
/*! track flags
* Q Sub-channel Control Field (4.2.3.3)
*/
typedef enum {
NONE = 0x00, /* no flags set */
PRE_EMPHASIS = 0x01, /* audio track recorded with pre-emphasis */
COPY_PERMITTED = 0x02, /* digital copy permitted */
DATA = 0x04, /* data track */
FOUR_CHANNEL_AUDIO = 0x08, /* 4 audio channels */
SCMS = 0x10 /* SCMS (5.29.2.7) */
} flag_t;
#define CDIO_PREGAP_SECTORS 150
#define CDIO_POSTGAP_SECTORS 150
/*! An enumeration for some of the CDIO_CD \#defines below. This isn't
really an enumeration one would really use in a program it is to
be helpful in debuggers where wants just to refer to the CDIO_CD_
names and get something.
*/
extern enum cdio_cd_enums {
CDIO_CD_MINS = 74, /**< max. minutes per CD, not really
a limit */
CDIO_CD_SECS_PER_MIN = 60, /**< seconds per minute */
CDIO_CD_FRAMES_PER_SEC = 75, /**< frames per second */
CDIO_CD_SYNC_SIZE = 12, /**< 12 sync bytes per raw data
frame */
CDIO_CD_CHUNK_SIZE = 24, /**< lowest-level "data bytes
piece" */
CDIO_CD_NUM_OF_CHUNKS = 98, /**< chunks per frame */
CDIO_CD_FRAMESIZE_SUB = 96, /**< subchannel data "frame" size */
CDIO_CD_HEADER_SIZE = 4, /**< header (address) bytes per raw
frame */
CDIO_CD_SUBHEADER_SIZE = 8, /**< subheader bytes per raw XA data
frame */
CDIO_CD_ECC_SIZE = 276, /**< bytes ECC per most raw data
frame types */
CDIO_CD_FRAMESIZE = 2048, /**< bytes per frame, "cooked"
mode */
CDIO_CD_FRAMESIZE_RAW = 2352, /**< bytes per frame, "raw" mode */
CDIO_CD_FRAMESIZE_RAWER = 2646, /**< The maximum possible
returned */
CDIO_CD_FRAMESIZE_RAW1 = 2340,
CDIO_CD_FRAMESIZE_RAW0 = 2336,
CDIO_CD_MAX_SESSIONS = 99,
CDIO_CD_MIN_SESSION_NO = 1, /**<, Smallest CD session number */
CDIO_CD_MAX_LSN = 450150, /**< Largest LSN in a CD */
CDIO_CD_MIN_LSN = -450150, /**< Smallest LSN in a CD */
} cdio_cd_enums;
/*!
Some generally useful CD-ROM information -- mostly based on the above.
This is from linux.h - not to slight other OS's. This was the first
place I came across such useful stuff.
*/
#define CDIO_CD_MINS 74 /**< max. minutes per CD, not really
a limit */
#define CDIO_CD_SECS_PER_MIN 60 /**< seconds per minute */
#define CDIO_CD_FRAMES_PER_SEC 75 /**< frames per second */
#define CDIO_CD_SYNC_SIZE 12 /**< 12 sync bytes per raw data frame */
#define CDIO_CD_CHUNK_SIZE 24 /**< lowest-level "data bytes piece" */
#define CDIO_CD_NUM_OF_CHUNKS 98 /**< chunks per frame */
#define CDIO_CD_FRAMESIZE_SUB 96 /**< subchannel data "frame" size */
#define CDIO_CD_HEADER_SIZE 4 /**< header (address) bytes per raw
data frame */
#define CDIO_CD_SUBHEADER_SIZE 8 /**< subheader bytes per raw XA data
frame */
#define CDIO_CD_EDC_SIZE 4 /**< bytes EDC per most raw data
frame types */
#define CDIO_CD_M1F1_ZERO_SIZE 8 /**< bytes zero per yellow book mode
1 frame */
#define CDIO_CD_ECC_SIZE 276 /**< bytes ECC per most raw data frame
types */
#define CDIO_CD_FRAMESIZE 2048 /**< bytes per frame, "cooked" mode */
#define CDIO_CD_FRAMESIZE_RAW 2352 /**< bytes per frame, "raw" mode */
#define CDIO_CD_FRAMESIZE_RAWER 2646 /**< The maximum possible returned
bytes */
#define CDIO_CD_FRAMESIZE_RAW1 (CDIO_CD_CD_FRAMESIZE_RAW-CDIO_CD_SYNC_SIZE) /*2340*/
#define CDIO_CD_FRAMESIZE_RAW0 (CDIO_CD_FRAMESIZE_RAW-CDIO_CD_SYNC_SIZE-CDIO_CD_HEADER_SIZE) /*2336*/
/*! "before data" part of raw XA (green, mode2) frame */
#define CDIO_CD_XA_HEADER (CDIO_CD_HEADER_SIZE+CDIO_CD_SUBHEADER_SIZE)
/*! "after data" part of raw XA (green, mode2 form1) frame */
#define CDIO_CD_XA_TAIL (CDIO_CD_EDC_SIZE+CDIO_CD_ECC_SIZE)
/*! "before data" sync bytes + header of XA (green, mode2) frame */
#define CDIO_CD_XA_SYNC_HEADER (CDIO_CD_SYNC_SIZE+CDIO_CD_XA_HEADER)
/*! String of bytes used to identify the beginning of a Mode 1 or
Mode 2 sector. */
extern const uint8_t CDIO_SECTOR_SYNC_HEADER[CDIO_CD_SYNC_SIZE];
/**<
{0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0};
*/
/*! An enumeration for some of the M2*_SECTOR_SIZE \#defines
below. This isn't really an enumeration one would really use in a
program it is to be helpful in debuggers where wants just to refer
to the M2*_SECTOR_SIZE names and get something.
*/
extern enum m2_sector_enums {
M2F2_SECTOR_SIZE = 2324,
M2SUB_SECTOR_SIZE = 2332,
M2RAW_SECTOR_SIZE = 2336
} m2_sector_enums;
#define M2F2_SECTOR_SIZE 2324
#define M2SUB_SECTOR_SIZE 2332
#define M2RAW_SECTOR_SIZE 2336
/*! Largest CD session number */
#define CDIO_CD_MAX_SESSIONS 99
/*! Smallest CD session number */
#define CDIO_CD_MIN_SESSION_NO 1
/*! Largest LSN in a CD */
#define CDIO_CD_MAX_LSN 450150
/*! Smallest LSN in a CD */
#define CDIO_CD_MIN_LSN -450150
#define CDIO_CD_FRAMES_PER_MIN \
(CDIO_CD_FRAMES_PER_SEC*CDIO_CD_SECS_PER_MIN)
#define CDIO_CD_74MIN_SECTORS (UINT32_C(74)*CDIO_CD_FRAMES_PER_MIN)
#define CDIO_CD_80MIN_SECTORS (UINT32_C(80)*CDIO_CD_FRAMES_PER_MIN)
#define CDIO_CD_90MIN_SECTORS (UINT32_C(90)*CDIO_CD_FRAMES_PER_MIN)
#define CDIO_CD_MAX_SECTORS \
(UINT32_C(100)*CDIO_CD_FRAMES_PER_MIN-CDIO_PREGAP_SECTORS)
#define msf_t_SIZEOF 3
/*!
Convert an LBA into a string representation of the MSF.
\warning cdio_lba_to_msf_str returns new allocated string */
char *cdio_lba_to_msf_str (lba_t i_lba);
/*!
Convert an MSF into a string representation of the MSF.
\warning cdio_msf_to_msf_str returns new allocated string */
char *cdio_msf_to_str (const msf_t *p_msf);
/*!
Convert an LBA into the corresponding LSN.
*/
lba_t cdio_lba_to_lsn (lba_t i_lba);
/*!
Convert an LBA into the corresponding MSF.
*/
void cdio_lba_to_msf(lba_t i_lba, msf_t *p_msf);
/*!
Convert an LSN into the corresponding LBA.
CDIO_INVALID_LBA is returned if there is an error.
*/
lba_t cdio_lsn_to_lba (lsn_t i_lsn);
/*!
Convert an LSN into the corresponding MSF.
*/
void cdio_lsn_to_msf (lsn_t i_lsn, msf_t *p_msf);
/*!
Convert a MSF into the corresponding LBA.
CDIO_INVALID_LBA is returned if there is an error.
*/
lba_t cdio_msf_to_lba (const msf_t *p_msf);
/*!
Convert a MSF into the corresponding LSN.
CDIO_INVALID_LSN is returned if there is an error.
*/
lsn_t cdio_msf_to_lsn (const msf_t *p_msf);
/*!
Convert a MSF - broken out as 3 integer components into the
corresponding LBA.
CDIO_INVALID_LBA is returned if there is an error.
*/
lba_t cdio_msf3_to_lba (unsigned int minutes, unsigned int seconds,
unsigned int frames);
/*!
Convert a string of the form MM:SS:FF into the corresponding LBA.
CDIO_INVALID_LBA is returned if there is an error.
*/
lba_t cdio_mmssff_to_lba (const char *psz_mmssff);
#ifdef __cplusplus
}
#endif
#ifndef DO_NOT_WANT_PARANOIA_COMPATIBILITY
/** For compatibility with good ol' paranoia */
#define CD_FRAMESIZE_RAW CDIO_CD_FRAMESIZE_RAW
#endif /*DO_NOT_WANT_PARANOIA_COMPATIBILITY*/
#endif /* _CDIO_SECTOR_H_ */
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

256
src/libcdio/cdio/track.h Normal file
View File

@ -0,0 +1,256 @@
/*
$Id: track.h,v 1.14 2008/03/25 15:59:09 karl Exp $
Copyright (C) 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file track.h
* \brief The top-level header for track-related libcdio calls.
*/
#ifndef __CDIO_TRACK_H__
#define __CDIO_TRACK_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*! Printable tags for track_format_t enumeration. */
extern const char *track_format2str[6];
typedef enum {
TRACK_FORMAT_AUDIO, /**< Audio track, e.g. CD-DA */
TRACK_FORMAT_CDI, /**< CD-i. How this is different from DATA below? */
TRACK_FORMAT_XA, /**< Mode2 of some sort */
TRACK_FORMAT_DATA, /**< Mode1 of some sort */
TRACK_FORMAT_PSX, /**< Playstation CD. Like audio but only 2336 bytes
* of user data.
*/
TRACK_FORMAT_ERROR /**< Dunno what is, or some other error. */
} track_format_t;
typedef enum {
CDIO_TRACK_FLAG_FALSE,
CDIO_TRACK_FLAG_TRUE,
CDIO_TRACK_FLAG_ERROR,
CDIO_TRACK_FLAG_UNKNOWN
} track_flag_t;
/*! \brief Structure containing attributes associated with a track */
typedef struct {
track_flag_t preemphasis; /**< Linear preemphasis on an audio track */
track_flag_t copy_permit; /**< Whether copying is permitted */
int channels; /**< Number of audio channels, 2, 4. -2 if not
implemented or -1 for error.
*/
} track_flags_t;
/*! The leadout track is always 0xAA, regardless of # of tracks on
disc, or what value may be used internally. For example although
OS X uses a different value for the lead-out track internally than
given below, programmers should use CDIO_CDROM_LEADOUT_TRACK and
not worry about this.
*/
/*! An enumeration for some of the CDIO_CDROM_* \#defines below. This
isn't really an enumeration one would really use in a program; it
is to be helpful in debuggers where wants just to refer to the
CDIO_CDROM_* names and get something.
*/
extern enum cdio_track_enums {
CDIO_CDROM_LBA = 0x01, /**< "logical block": first frame is #0 */
CDIO_CDROM_MSF = 0x02, /**< "minute-second-frame": binary, not
BCD here! */
CDIO_CDROM_DATA_TRACK = 0x04,
CDIO_CDROM_CDI_TRACK = 0x10,
CDIO_CDROM_XA_TRACK = 0x20,
CDIO_CD_MAX_TRACKS = 99, /**< Largest CD track number */
CDIO_CDROM_LEADOUT_TRACK = 0xAA, /**< Lead-out track number */
CDIO_INVALID_TRACK = 0xFF, /**< Constant for invalid track number */
} cdio_track_enums;
#define CDIO_CD_MIN_TRACK_NO 1 /**< Smallest CD track number */
/*! track modes (Table 350)
reference: MMC-3 draft revsion - 10g
*/
typedef enum {
AUDIO, /**< 2352 byte block length */
MODE1, /**< 2048 byte block length */
MODE1_RAW, /**< 2352 byte block length */
MODE2, /**< 2336 byte block length */
MODE2_FORM1, /**< 2048 byte block length */
MODE2_FORM2, /**< 2324 byte block length */
MODE2_FORM_MIX, /**< 2336 byte block length */
MODE2_RAW /**< 2352 byte block length */
} trackmode_t;
/*!
Get the number of the first track.
@return the track number or CDIO_INVALID_TRACK
on error.
*/
track_t cdio_get_first_track_num(const CdIo_t *p_cdio);
/*!
Return the last track number.
CDIO_INVALID_TRACK is returned on error.
*/
track_t cdio_get_last_track_num (const CdIo_t *p_cdio);
/*! Find the track which contains lsn.
CDIO_INVALID_TRACK is returned if the lsn outside of the CD or
if there was some error.
If the lsn is before the pregap of the first track 0 is returned.
Otherwise we return the track that spans the lsn.
*/
track_t cdio_get_track(const CdIo_t *p_cdio, lsn_t lsn);
/*! Return number of channels in track: 2 or 4; -2 if not
implemented or -1 for error.
Not meaningful if track is not an audio track.
*/
int cdio_get_track_channels(const CdIo_t *p_cdio, track_t i_track);
/*! Return copy protection status on a track. Is this meaningful
if not an audio track?
*/
track_flag_t cdio_get_track_copy_permit(const CdIo_t *p_cdio,
track_t i_track);
/*!
Get the format (audio, mode2, mode1) of track.
*/
track_format_t cdio_get_track_format(const CdIo_t *p_cdio, track_t i_track);
/*!
Return true if we have XA data (green, mode2 form1) or
XA data (green, mode2 form2). That is track begins:
sync - header - subheader
12 4 - 8
FIXME: there's gotta be a better design for this and get_track_format?
*/
bool cdio_get_track_green(const CdIo_t *p_cdio, track_t i_track);
/*!
Return the ending LSN for track number
i_track in cdio. CDIO_INVALID_LSN is returned on error.
*/
lsn_t cdio_get_track_last_lsn(const CdIo_t *p_cdio, track_t i_track);
/*!
Get the starting LBA for track number
i_track in p_cdio. Track numbers usually start at something
greater than 0, usually 1.
The "leadout" track is specified either by
using i_track CDIO_CDROM_LEADOUT_TRACK or the total tracks+1.
@param p_cdio object to get information from
@param i_track the track number we want the LSN for
@return the starting LBA or CDIO_INVALID_LBA on error.
*/
lba_t cdio_get_track_lba(const CdIo_t *p_cdio, track_t i_track);
/*!
Return the starting LSN for track number
i_track in p_cdio. Track numbers usually start at something
greater than 0, usually 1.
The "leadout" track is specified either by
using i_track CDIO_CDROM_LEADOUT_TRACK or the total tracks+1.
@param p_cdio object to get information from
@param i_track the track number we want the LSN for
@return the starting LSN or CDIO_INVALID_LSN on error.
*/
lsn_t cdio_get_track_lsn(const CdIo_t *p_cdio, track_t i_track);
/*!
Return the starting LBA for the pregap for track number
i_track in p_cdio. Track numbers usually start at something
greater than 0, usually 1.
@param p_cdio object to get information from
@param i_track the track number we want the LBA for
@return the starting LBA or CDIO_INVALID_LBA on error.
*/
lba_t cdio_get_track_pregap_lba(const CdIo_t *p_cdio, track_t i_track);
/*!
Return the starting LSN for the pregap for track number
i_track in p_cdio. Track numbers usually start at something
greater than 0, usually 1.
@param p_cdio object to get information from
@param i_track the track number we want the LSN for
@return the starting LSN or CDIO_INVALID_LSN on error.
*/
lsn_t cdio_get_track_pregap_lsn(const CdIo_t *p_cdio, track_t i_track);
/*!
Get the International Standard Recording Code (ISRC) for track number
i_track in p_cdio. Track numbers usually start at something
greater than 0, usually 1.
@return the International Standard Recording Code (ISRC) or NULL
if there is none or we don't have the ability to get it.
Note: string is malloc'd so caller has to free() the returned
string when done with it.
*/
char * cdio_get_track_isrc (const CdIo_t *p_cdio, track_t i_track);
/*!
Return the starting MSF (minutes/secs/frames) for track number
i_track in p_cdio. Track numbers usually start at something
greater than 0, usually 1.
The "leadout" track is specified either by
using i_track CDIO_CDROM_LEADOUT_TRACK or the total tracks+1.
@return true if things worked or false if there is no track entry.
*/
bool cdio_get_track_msf(const CdIo_t *p_cdio, track_t i_track,
/*out*/ msf_t *msf);
/*! Get linear preemphasis status on an audio track
This is not meaningful if not an audio track?
*/
track_flag_t cdio_get_track_preemphasis(const CdIo_t *p_cdio,
track_t i_track);
/*!
Get the number of sectors between this track an the next. This
includes any pregap sectors before the start of the next track.
Track numbers usually start at something
greater than 0, usually 1.
@return the number of sectors or 0 if there is an error.
*/
unsigned int cdio_get_track_sec_count(const CdIo_t *p_cdio, track_t i_track);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __CDIO_TRACK_H__ */

332
src/libcdio/cdio/types.h Normal file
View File

@ -0,0 +1,332 @@
/*
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2008
Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file types.h
* \brief Common type definitions used pervasively in libcdio.
*/
#ifndef __CDIO_TYPES_H__
#define __CDIO_TYPES_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifndef EXTERNAL_LIBCDIO_CONFIG_H
#define EXTERNAL_LIBCDIO_CONFIG_H
#include <cdio/cdio_config.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
/* provide some C99 definitions */
#if defined(HAVE_SYS_TYPES_H)
#include <sys/types.h>
#endif
#ifdef _MSC_VER
#include <windows.h>
typedef unsigned short mode_t;
#endif
#if defined(HAVE_STDINT_H)
# include <stdint.h>
#elif defined(HAVE_INTTYPES_H)
# include <inttypes.h>
#elif defined(AMIGA) || defined(__linux__)
typedef u_int8_t uint8_t;
typedef u_int16_t uint16_t;
typedef u_int32_t uint32_t;
typedef u_int64_t uint64_t;
#else
/* warning ISO/IEC 9899:1999 <stdint.h> was missing and even <inttypes.h> */
/* fixme */
#endif /* HAVE_STDINT_H */
typedef uint8_t ubyte;
/* default HP/UX macros are broken */
#if defined(__hpux__)
# undef UINT16_C
# undef UINT32_C
# undef UINT64_C
# undef INT64_C
#endif
/* if it's still not defined, take a good guess... should work for
most 32bit and 64bit archs */
#ifndef UINT16_C
# define UINT16_C(c) c ## U
#endif
#ifndef UINT32_C
# if defined (SIZEOF_INT) && SIZEOF_INT == 4
# define UINT32_C(c) c ## U
# elif defined (SIZEOF_LONG) && SIZEOF_LONG == 4
# define UINT32_C(c) c ## UL
# else
# define UINT32_C(c) c ## U
# endif
#endif
#ifndef UINT64_C
# if defined (SIZEOF_LONG) && SIZEOF_LONG == 8
# define UINT64_C(c) c ## UL
# elif defined (SIZEOF_INT) && SIZEOF_INT == 8
# define UINT64_C(c) c ## U
# else
# define UINT64_C(c) c ## ULL
# endif
#endif
#ifndef INT64_C
# if defined (SIZEOF_LONG) && SIZEOF_LONG == 8
# define INT64_C(c) c ## L
# elif defined (SIZEOF_INT) && SIZEOF_INT == 8
# define INT64_C(c) c
# else
# define INT64_C(c) c ## LL
# endif
#endif
#ifndef __cplusplus
# if defined(HAVE_STDBOOL_H)
# include <stdbool.h>
# else
/* ISO/IEC 9899:1999 <stdbool.h> missing -- enabling workaround */
# define false 0
# define true 1
# define bool uint8_t
# endif /*HAVE_STDBOOL_H*/
#endif /*C++*/
/* some GCC optimizations -- gcc 2.5+ */
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
#define GNUC_PRINTF( format_idx, arg_idx ) \
__attribute__((format (printf, format_idx, arg_idx)))
#define GNUC_SCANF( format_idx, arg_idx ) \
__attribute__((format (scanf, format_idx, arg_idx)))
#define GNUC_FORMAT( arg_idx ) \
__attribute__((format_arg (arg_idx)))
#define GNUC_NORETURN \
__attribute__((noreturn))
#define GNUC_CONST \
__attribute__((const))
#define GNUC_UNUSED \
__attribute__((unused))
#define GNUC_PACKED \
__attribute__((packed))
#else /* !__GNUC__ */
#define GNUC_PRINTF( format_idx, arg_idx )
#define GNUC_SCANF( format_idx, arg_idx )
#define GNUC_FORMAT( arg_idx )
#define GNUC_NORETURN
#define GNUC_CONST
#define GNUC_UNUSED
#define GNUC_PACKED
#endif /* !__GNUC__ */
#if defined(__GNUC__)
/* for GCC we try to use GNUC_PACKED */
# define PRAGMA_BEGIN_PACKED
# define PRAGMA_END_PACKED
#elif defined(HAVE_ISOC99_PRAGMA)
/* should work with most EDG-frontend based compilers */
# define PRAGMA_BEGIN_PACKED _Pragma("pack(1)")
# define PRAGMA_END_PACKED _Pragma("pack()")
#else /* neither gcc nor _Pragma() available... */
/* ...so let's be naive and hope the regression testsuite is run... */
// TODO!
# define PRAGMA_BEGIN_PACKED
# define PRAGMA_END_PACKED
#endif
/*
* user directed static branch prediction gcc 2.96+
*/
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 95)
# define GNUC_LIKELY(x) __builtin_expect((x),true)
# define GNUC_UNLIKELY(x) __builtin_expect((x),false)
#else
# define GNUC_LIKELY(x) (x)
# define GNUC_UNLIKELY(x) (x)
#endif
#ifndef NULL
# define NULL ((void*) 0)
#endif
/* our own offsetof()-like macro */
#define __cd_offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
/*!
\brief MSF (minute/second/frame) structure
One CD-ROMs addressing scheme especially used in audio formats
(Red Book) is an address by minute, sector and frame which
BCD-encoded in three bytes. An alternative format is an lba_t.
Note: the fields in this structure are BCD encoded. Use
cdio_to_bcd8() or cdio_from_bcd8() to convert an integer into or
out of this format. The format specifier %x (not %d) can be used
if you need to format or print values in this structure.
@see lba_t
*/
PRAGMA_BEGIN_PACKED
struct msf_s {
uint8_t m, s, f; /* BCD encoded! */
} GNUC_PACKED;
PRAGMA_END_PACKED
typedef struct msf_s msf_t;
#define msf_t_SIZEOF 3
/*!
\brief UTF-8 char definition
Type to denote UTF-8 strings.
*/
typedef char cdio_utf8_t;
typedef enum {
nope = 0,
yep = 1,
dunno = 2
} bool_3way_t;
/* type used for bit-fields in structs (1 <= bits <= 8) */
#if defined(__GNUC__)
/* this is strict ISO C99 which allows only 'unsigned int', 'signed
int' and '_Bool' explicitly as bit-field type */
typedef unsigned int bitfield_t;
#else
/* other compilers might increase alignment requirements to match the
'unsigned int' type -- fixme: find out how unalignment accesses can
be pragma'ed on non-gcc compilers */
typedef uint8_t bitfield_t;
#endif
/*! The type of a Logical Block Address. We allow for an lba to be
negative to be consistent with an lba, although I'm not sure this
this is possible.
*/
typedef int32_t lba_t;
/*! The type of a Logical Sector Number. Note that an lba can be negative
and the MMC3 specs allow for a conversion of a negative lba.
@see msf_t
*/
typedef int32_t lsn_t;
/* Address in either MSF or logical format */
union cdio_cdrom_addr
{
msf_t msf;
lba_t lba;
};
/*! The type of a track number 0..99. */
typedef uint8_t track_t;
/*! The type of a session number 0..99. */
typedef uint8_t session_t;
/*!
Constant for invalid session number
*/
#define CDIO_INVALID_SESSION 0xFF
/*!
Constant for invalid LBA. It is 151 less than the most negative
LBA -45150. This provide slack for the 150-frame offset in
LBA to LSN 150 conversions
*/
#define CDIO_INVALID_LBA -45301
/*!
Constant for invalid LSN
*/
#define CDIO_INVALID_LSN CDIO_INVALID_LBA
/*!
Number of ASCII bytes in a media catalog number (MCN).
We include an extra 0 byte so these can be used as C strings.
*/
#define CDIO_MCN_SIZE 13
/*!
Type to hold ASCII bytes in a media catalog number (MCN).
We include an extra 0 byte so these can be used as C strings.
*/
typedef char cdio_mcn_t[CDIO_MCN_SIZE+1];
/*!
Number of ASCII bytes in International Standard Recording Codes (ISRC)
*/
#define CDIO_ISRC_SIZE 12
/*!
Type to hold ASCII bytes in a ISRC.
We include an extra 0 byte so these can be used as C strings.
*/
typedef char cdio_isrc_t[CDIO_ISRC_SIZE+1];
typedef int cdio_fs_anal_t;
/*!
track flags
Q Sub-channel Control Field (4.2.3.3)
*/
typedef enum {
CDIO_TRACK_FLAG_NONE = 0x00, /**< no flags set */
CDIO_TRACK_FLAG_PRE_EMPHASIS = 0x01, /**< audio track recorded with
pre-emphasis */
CDIO_TRACK_FLAG_COPY_PERMITTED = 0x02, /**< digital copy permitted */
CDIO_TRACK_FLAG_DATA = 0x04, /**< data track */
CDIO_TRACK_FLAG_FOUR_CHANNEL_AUDIO = 0x08, /**< 4 audio channels */
CDIO_TRACK_FLAG_SCMS = 0x10 /**< SCMS (5.29.2.7) */
} cdio_track_flag;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __CDIO_TYPES_H__ */
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

92
src/libcdio/cdio/utf8.h Normal file
View File

@ -0,0 +1,92 @@
/*
$Id: utf8.h,v 1.2 2008/03/25 15:59:09 karl Exp $
Copyright (C) 2008 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2006 Burkhard Plaum <plaum@ipf.uni-stuttgart.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* UTF-8 support */
#include <cdio/types.h>
/** \brief Opaque characterset converter
*/
typedef struct cdio_charset_coverter_s cdio_charset_coverter_t;
/** \brief Create a charset converter
* \param src_charset Source charset
* \param dst_charset Destination charset
* \returns A newly allocated charset converter
*/
cdio_charset_coverter_t *
cdio_charset_converter_create(const char * src_charset,
const char * dst_charset);
/** \brief Destroy a characterset converter
* \param cnv A characterset converter
*/
void cdio_charset_converter_destroy(cdio_charset_coverter_t*cnv);
/** \brief Convert a string from one character set to another
* \param cnv A charset converter
* \param src Source string
* \param src_len Length of source string
* \param dst Returns destination string
* \param dst_len If non NULL, returns the length of the destination string
* \returns true if conversion was sucessful, false else.
*
* The destination string must be freed by the caller with free().
* If you pass -1 for src_len, strlen() will be used.
*/
bool cdio_charset_convert(cdio_charset_coverter_t*cnv,
char * src, int src_len,
char ** dst, int * dst_len);
/** \brief Convert a string from UTF-8 to another charset
* \param src Source string (0 terminated)
* \param dst Returns destination string
* \param dst_len If non NULL, returns the length of the destination string
* \param dst_charset The characterset to convert to
* \returns true if conversion was sucessful, false else.
*
* This is a convenience function, which creates a charset converter,
* converts one string and destroys the charset converter.
*/
bool cdio_charset_from_utf8(cdio_utf8_t * src, char ** dst,
int * dst_len, const char * dst_charset);
/** \brief Convert a string from another charset to UTF-8
* \param src Source string
* \param src_len Length of the source string
* \param dst Returns destination string (0 terminated)
* \param src_charset The characterset to convert from
* \returns true if conversion was sucessful, false else.
*
* This is a convenience function, which creates a charset converter,
* converts one string and destroys the charset converter. If you pass -1
* for src_len, strlen() will be used.
*/
bool cdio_charset_to_utf8(char *src, size_t src_len, cdio_utf8_t **dst,
const char * src_charset);

122
src/libcdio/cdio/util.h Normal file
View File

@ -0,0 +1,122 @@
/*
Copyright (C) 2004, 2005, 2006, 2008, 2010 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CDIO_UTIL_H__
#define __CDIO_UTIL_H__
/*!
\file util.h
\brief Miscellaneous utility functions.
Warning: this will probably get removed/replaced by using glib.h
*/
#include <stdlib.h>
#include <cdio/types.h>
#undef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#undef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#undef IN
#define IN(x, low, high) ((x) >= (low) && (x) <= (high))
#undef CLAMP
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
static inline uint32_t
_cdio_len2blocks (uint32_t i_len, uint16_t i_blocksize)
{
uint32_t i_blocks;
i_blocks = i_len / (uint32_t) i_blocksize;
if (i_len % i_blocksize)
i_blocks++;
return i_blocks;
}
/* round up to next block boundary */
static inline unsigned
_cdio_ceil2block (unsigned offset, uint16_t i_blocksize)
{
return _cdio_len2blocks (offset, i_blocksize) * i_blocksize;
}
static inline unsigned int
_cdio_ofs_add (unsigned offset, unsigned length, uint16_t i_blocksize)
{
if (i_blocksize - (offset % i_blocksize) < length)
offset = _cdio_ceil2block (offset, i_blocksize);
offset += length;
return offset;
}
static inline const char *
_cdio_bool_str (bool b)
{
return b ? "yes" : "no";
}
#ifdef __cplusplus
extern "C" {
#endif
void *
_cdio_memdup (const void *mem, size_t count);
char *
_cdio_strdup_upper (const char str[]);
void
_cdio_strfreev(char **strv);
size_t
_cdio_strlenv(char **str_array);
char **
_cdio_strsplit(const char str[], char delim);
uint8_t cdio_to_bcd8(uint8_t n);
uint8_t cdio_from_bcd8(uint8_t p);
/*! cdio_realpath() same as POSIX.1-2001 realpath if that's
around. If not we do poor-man's simulation of that behavior. */
char *cdio_realpath (const char *psz_src, char *psz_dst);
#ifdef WANT_FOLLOW_SYMLINK_COMPATIBILITY
# define cdio_follow_symlink cdio_realpath
#endif
#ifdef __cplusplus
}
#endif
#endif /* __CDIO_UTIL_H__ */
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

View File

@ -0,0 +1,20 @@
/* $Id: version.h.in,v 1.6 2005/01/29 20:54:20 rocky Exp $ */
/** \file version.h
*
* \brief A file containing the libcdio package version
* number (84) and OS build name.
*/
/*! CDIO_VERSION is a C-Preprocessor macro of a string that shows what
version is used. cdio_version_string has the same value, but it is a
constant variable that can be accessed at run time. */
#define CDIO_VERSION "0.84git i686-pc-mingw32"
extern const char *cdio_version_string; /**< = CDIO_VERSION */
/*! LIBCDIO_VERSION_NUM is a C-Preprocessor macro that can be used for
testing in the C preprocessor. libcdio_version_num has the same
value, but it is a constant variable that can be accessed at run
time. */
#define LIBCDIO_VERSION_NUM 84
extern const unsigned int libcdio_version_num; /**< = LIBCDIO_VERSION_NUM */

179
src/libcdio/cdio/xa.h Normal file
View File

@ -0,0 +1,179 @@
/*
$Id: xa.h,v 1.19 2008/03/25 15:59:10 karl Exp $
Copyright (C) 2003, 2004, 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
See also iso9660.h by Eric Youngdale (1993) and in cdrtools. These are
Copyright 1993 Yggdrasil Computing, Incorporated
Copyright (c) 1999,2000 J. Schilling
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*!
\file xa.h
\brief Things related to the ISO-9660 XA (Extended Attributes) format
Applications will probably not include this directly but via
the iso9660.h header.
*/
#ifndef __CDIO_XA_H__
#define __CDIO_XA_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*! An enumeration for some of the XA_* \#defines below. This isn't
really an enumeration one would really use in a program it is to
be helpful in debuggers where wants just to refer to the XA_*
names and get something.
*/
typedef enum {
ISO_XA_MARKER_OFFSET = 1024,
XA_PERM_RSYS = 0x0001, /**< System Group Read */
XA_PERM_XSYS = 0x0004, /**< System Group Execute */
XA_PERM_RUSR = 0x0010, /**< User (owner) Read */
XA_PERM_XUSR = 0x0040, /**< User (owner) Execute */
XA_PERM_RGRP = 0x0100, /**< Group Read */
XA_PERM_XGRP = 0x0400, /**< Group Execute */
XA_PERM_ROTH = 0x1000, /**< Other (world) Read */
XA_PERM_XOTH = 0x4000, /**< Other (world) Execute */
XA_ATTR_MODE2FORM1 = (1 << 11),
XA_ATTR_MODE2FORM2 = (1 << 12),
XA_ATTR_INTERLEAVED = (1 << 13),
XA_ATTR_CDDA = (1 << 14),
XA_ATTR_DIRECTORY = (1 << 15),
XA_PERM_ALL_READ = (XA_PERM_RUSR | XA_PERM_RSYS | XA_PERM_RGRP),
XA_PERM_ALL_EXEC = (XA_PERM_XUSR | XA_PERM_XSYS | XA_PERM_XGRP),
XA_PERM_ALL_ALL = (XA_PERM_ALL_READ | XA_PERM_ALL_EXEC),
XA_FORM1_DIR = (XA_ATTR_DIRECTORY | XA_ATTR_MODE2FORM1 | XA_PERM_ALL_ALL),
XA_FORM1_FILE = (XA_ATTR_MODE2FORM1 | XA_PERM_ALL_ALL),
XA_FORM2_FILE = (XA_ATTR_MODE2FORM2 | XA_PERM_ALL_ALL)
} xa_misc_enum_t;
extern const char ISO_XA_MARKER_STRING[sizeof("CD-XA001")-1];
#define ISO_XA_MARKER_STRING "CD-XA001"
/*! \brief "Extended Architecture" according to the Philips Yellow Book.
CD-ROM EXtended Architecture is a modification to the CD-ROM
specification that defines two new types of sectors. CD-ROM XA was
developed jointly by Sony, Philips, and Microsoft, and announced in
August 1988. Its specifications were published in an extension to the
Yellow Book. CD-i, Photo CD, Video CD and CD-EXTRA have all
subsequently been based on CD-ROM XA.
CD-XA defines another way of formatting sectors on a CD-ROM, including
headers in the sectors that describe the type (audio, video, data) and
some additional info (markers, resolution in case of a video or audio
sector, file numbers, etc).
The data written on a CD-XA is consistent with and can be in ISO-9660
file system format and therefore be readable by ISO-9660 file system
translators. But also a CD-I player can also read CD-XA discs even if
its own `Green Book' file system only resembles ISO 9660 and isn't
fully compatible.
Note structure is big-endian.
*/
typedef struct iso9660_xa_s
{
uint16_t group_id; /**< 0 */
uint16_t user_id; /**< 0 */
uint16_t attributes; /**< XA_ATTR_ */
char signature[2]; /**< { 'X', 'A' } */
uint8_t filenum; /**< file number, see also XA subheader */
uint8_t reserved[5]; /**< zero */
} GNUC_PACKED iso9660_xa_t;
/*!
Returns POSIX mode bitstring for a given file.
*/
posix_mode_t iso9660_get_posix_filemode_from_xa(uint16_t i_perms);
/*!
Returns a string interpreting the extended attribute xa_attr.
For example:
\verbatim
d---1xrxrxr
---2--r-r-r
-a--1xrxrxr
\endverbatim
A description of the characters in the string follows.
The 1st character is either "d" if the entry is a directory, or "-" if not
The 2nd character is either "a" if the entry is CDDA (audio), or "-" if not
The 3rd character is either "i" if the entry is interleaved, or "-" if not
The 4th character is either "2" if the entry is mode2 form2 or "-" if not
The 5th character is either "1" if the entry is mode2 form1 or "-" if not
Note that an entry will either be in mode2 form1 or mode form2. That
is you will either see "2-" or "-1" in the 4th & 5th positions.
The 6th and 7th characters refer to permissions for a user while the
the 8th and 9th characters refer to permissions for a group while, and
the 10th and 11th characters refer to permissions for everyone.
In each of these pairs the first character (6, 8, 10) is "x" if the
entry is executable. For a directory this means the directory is
allowed to be listed or "searched".
The second character of a pair (7, 9, 11) is "r" if the entry is allowed
to be read.
*/
const char *
iso9660_get_xa_attr_str (uint16_t xa_attr);
/*!
Allocates and initalizes a new iso9600_xa_t variable and returns
it. The caller should free the returned result.
@see iso9660_xa
*/
iso9660_xa_t *
iso9660_xa_init (iso9660_xa_t *_xa, uint16_t uid, uint16_t gid, uint16_t attr,
uint8_t filenum);
#ifdef __cplusplus
}
/** The below variables are trickery to force the above enum symbol
values to be recorded in debug symbol tables. They are used to
allow one to refer to the enumeration value names in the typedefs
above in a debugger and debugger expressions.
*/
extern xa_misc_enum_t debugger_xa_misc_enum;
#endif /* __cplusplus */
#endif /* __CDIO_XA_H__ */
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

View File

@ -0,0 +1,51 @@
/*
$Id: _cdio_stdio.h,v 1.3 2008/04/22 15:29:11 karl Exp $
Copyright (C) 2003, 2008 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CDIO_STDIO_H__
#define __CDIO_STDIO_H__
#include "_cdio_stream.h"
/*!
Initialize a new stdio stream reading from pathname.
A pointer to the stream is returned or NULL if there was an error.
cdio_stream_free should be called on the returned value when you
don't need the stream any more. No other finalization is needed.
*/
CdioDataSource_t * cdio_stdio_new(const char psz_path[]);
/*!
Deallocate resources assocaited with obj. After this obj is unusable.
*/
void cdio_stdio_destroy(CdioDataSource_t *p_obj);
#endif /* __CDIO_STREAM_STDIO_H__ */
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

View File

@ -0,0 +1,139 @@
/*
$Id: _cdio_stream.h,v 1.5 2008/04/22 15:29:11 karl Exp $
Copyright (C) 2003, 2004, 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CDIO_STREAM_H__
#define __CDIO_STREAM_H__
#include <cdio/types.h>
#include "cdio_private.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* typedef'ed IO functions prototypes */
typedef int(*cdio_data_open_t)(void *user_data);
typedef long(*cdio_data_read_t)(void *user_data, void *buf, long count);
typedef driver_return_code_t(*cdio_data_seek_t)(void *user_data, long offset,
int whence);
typedef long(*cdio_data_stat_t)(void *user_data);
typedef int(*cdio_data_close_t)(void *user_data);
typedef void(*cdio_data_free_t)(void *user_data);
/* abstract data source */
typedef struct {
cdio_data_open_t open;
cdio_data_seek_t seek;
cdio_data_stat_t stat;
cdio_data_read_t read;
cdio_data_close_t close;
cdio_data_free_t free;
} cdio_stream_io_functions;
/**
Like 3 fgetpos.
This function gets the current file position indicator for the stream
pointed to by stream.
@return unpon successful completion, return value is positive, else,
the global variable errno is set to indicate the error.
*/
ssize_t cdio_stream_getpos(CdioDataSource_t* p_obj,
/*out*/ ssize_t *i_offset);
CdioDataSource_t *
cdio_stream_new(void *user_data, const cdio_stream_io_functions *funcs);
/**
Like fread(3) and in fact may be the same.
DESCRIPTION:
The function fread reads nmemb elements of data, each size bytes long,
from the stream pointed to by stream, storing them at the location
given by ptr.
RETURN VALUE:
return the number of items successfully read or written (i.e.,
not the number of characters). If an error occurs, or the
end-of-file is reached, the return value is a short item count
(or zero).
We do not distinguish between end-of-file and error, and callers
must use feof(3) and ferror(3) to determine which occurred.
*/
ssize_t cdio_stream_read(CdioDataSource_t* p_obj, void *ptr, long i_size,
long nmemb);
/**
Like fseek(3) and in fact may be the same.
This function sets the file position indicator for the stream
pointed to by stream. The new position, measured in bytes, is obtained
by adding offset bytes to the position specified by whence. If whence
is set to SEEK_SET, SEEK_CUR, or SEEK_END, the offset is relative to
the start of the file, the current position indicator, or end-of-file,
respectively. A successful call to the fseek function clears the end-
of-file indicator for the stream and undoes any effects of the
ungetc(3) function on the same stream.
@return upon successful completion, DRIVER_OP_SUCCESS, else,
DRIVER_OP_ERROR is returned and the global variable errno is set to
indicate the error.
*/
ssize_t cdio_stream_seek(CdioDataSource_t *p_obj, ssize_t i_offset,
int whence);
/**
Return whatever size of stream reports, I guess unit size is bytes.
On error return -1;
*/
ssize_t cdio_stream_stat(CdioDataSource_t *p_obj);
/**
Deallocate resources associated with p_obj. After this p_obj is unusable.
*/
void cdio_stream_destroy(CdioDataSource_t *p_obj);
void cdio_stream_close(CdioDataSource_t *p_obj);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __CDIO_STREAM_H__ */
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

View File

@ -0,0 +1,58 @@
/*
Copyright (C) 2008, 2011 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CDIO_ASSERT_H__
#define __CDIO_ASSERT_H__
#if defined(__GNUC__)
#if defined(HAVE_CONFIG_H) && !defined(__CDIO_CONFIG_H__)
# include "config.h"
# define __CDIO_CONFIG_H__ 1
#endif
#include <cdio/types.h>
#include <cdio/logging.h>
#define cdio_assert(expr) \
{ \
if (GNUC_UNLIKELY (!(expr))) cdio_log (CDIO_LOG_ASSERT, \
"file %s: line %d (%s): assertion failed: (%s)", \
__FILE__, __LINE__, __PRETTY_FUNCTION__, #expr); \
}
#define cdio_assert_not_reached() \
{ \
cdio_log (CDIO_LOG_ASSERT, \
"file %s: line %d (%s): should not be reached", \
__FILE__, __LINE__, __PRETTY_FUNCTION__); \
}
#else /* non GNU C */
#include <assert.h>
#define cdio_assert(expr) \
assert(expr)
#define cdio_assert_not_reached() \
assert(0)
#endif
#endif /* __CDIO_ASSERT_H__ */

View File

@ -0,0 +1,562 @@
/*
Copyright (C) 2003, 2004, 2005, 2008, 2009, 2011
Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Internal routines for CD I/O drivers. */
#ifndef __CDIO_PRIVATE_H__
#define __CDIO_PRIVATE_H__
#if defined(HAVE_CONFIG_H) && !defined(LIBCDIO_CONFIG_H)
# include "config.h"
#endif
#include <cdio/cdio.h>
#include <cdio/audio.h>
#include <cdio/cdtext.h>
#include "mmc/mmc_private.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
extern const char * cdio_dirname(const char *fname);
extern const char *cdio_abspath(const char *cwd, const char *fname);
/* Opaque type */
typedef struct _CdioDataSource CdioDataSource_t;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#include "generic.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct {
/*!
Get volume of an audio CD.
@param p_env the CD object to be acted upon.
*/
driver_return_code_t (*audio_get_volume)
(void *p_env, /*out*/ cdio_audio_volume_t *p_volume);
/*!
Pause playing CD through analog output
@param p_env the CD object to be acted upon.
*/
driver_return_code_t (*audio_pause) (void *p_env);
/*!
Playing CD through analog output
@param p_env the CD object to be acted upon.
*/
driver_return_code_t (*audio_play_msf) ( void *p_env,
msf_t *p_start_msf,
msf_t *p_end_msf );
/*!
Playing CD through analog output
@param p_env the CD object to be acted upon.
*/
driver_return_code_t (*audio_play_track_index)
( void *p_env, cdio_track_index_t *p_track_index );
/*!
Get subchannel information.
@param p_env the CD object to be acted upon.
*/
driver_return_code_t (*audio_read_subchannel)
( void *p_env, cdio_subchannel_t *subchannel );
/*!
Resume playing an audio CD.
@param p_env the CD object to be acted upon.
*/
driver_return_code_t (*audio_resume) ( void *p_env );
/*!
Set volume of an audio CD.
@param p_env the CD object to be acted upon.
*/
driver_return_code_t (*audio_set_volume)
( void *p_env, cdio_audio_volume_t *p_volume );
/*!
Stop playing an audio CD.
@param p_env the CD object to be acted upon.
*/
driver_return_code_t (*audio_stop) ( void *p_env );
/*!
Eject media in CD drive. If successful, as a side effect we
also free p_env.
@param p_env the CD object to be acted upon.
If the CD is ejected *p_env is freed and p_env set to NULL.
*/
driver_return_code_t (*eject_media) ( void *p_env );
/*!
Release and free resources associated with cd.
*/
void (*free) (void *p_env);
/*!
Return the value associated with the key "arg".
*/
const char * (*get_arg) (void *p_env, const char key[]);
/*!
Get the block size for subsequest read requests, via a SCSI MMC
MODE_SENSE 6 command.
*/
int (*get_blocksize) ( void *p_env );
/*!
Get cdtext information for a CdIo object.
@param obj the CD object that may contain CD-TEXT information.
@return the CD-TEXT object or NULL if obj is NULL
or CD-TEXT information does not exist.
*/
cdtext_t * (*get_cdtext) ( void *p_env );
/*!
Get raw cdtext information as on the disc for a CdIo object
@param obj the CD object that may contain CD-TEXT information.
@return pointer to the raw CD-TEXT data or NULL if obj is NULL
or no CD-TEXT information present on the disc.
free when done and not NULL.
*/
uint8_t * (*get_cdtext_raw) ( void *p_env );
/*!
Return an array of device names. if CdIo is NULL (we haven't
initialized a specific device driver), then find a suitable device
driver.
NULL is returned if we couldn't return a list of devices.
*/
char ** (*get_devices) ( void );
/*!
Get the default CD device.
@return a string containing the default CD device or NULL is
if we couldn't get a default device.
In some situations of drivers or OS's we can't find a CD device if
there is no media in it and it is possible for this routine to return
NULL even though there may be a hardware CD-ROM.
*/
char * (*get_default_device) ( void );
/*!
Return the size of the CD in logical block address (LBA) units.
@return the lsn. On error 0 or CDIO_INVALD_LSN.
*/
lsn_t (*get_disc_last_lsn) ( void *p_env );
/*!
Get disc mode associated with cd_obj.
*/
discmode_t (*get_discmode) ( void *p_env );
/*!
Return the what kind of device we've got.
See cd_types.h for a list of bitmasks for the drive type;
*/
void (*get_drive_cap) (const void *p_env,
cdio_drive_read_cap_t *p_read_cap,
cdio_drive_write_cap_t *p_write_cap,
cdio_drive_misc_cap_t *p_misc_cap);
/*!
Return the number of of the first track.
CDIO_INVALID_TRACK is returned on error.
*/
track_t (*get_first_track_num) ( void *p_env );
/*!
Get the CD-ROM hardware info via a SCSI MMC INQUIRY command.
False is returned if we had an error getting the information.
*/
bool (*get_hwinfo)
( const CdIo_t *p_cdio, /* out*/ cdio_hwinfo_t *p_hw_info );
/*! Get the LSN of the first track of the last session of
on the CD.
@param p_cdio the CD object to be acted upon.
@param i_last_session pointer to the session number to be returned.
*/
driver_return_code_t (*get_last_session)
( void *p_env, /*out*/ lsn_t *i_last_session );
/*!
Find out if media has changed since the last call.
@param p_env the CD object to be acted upon.
@return 1 if media has changed since last call, 0 if not. Error
return codes are the same as driver_return_code_t
*/
int (*get_media_changed) ( const void *p_env );
/*!
Return the media catalog number MCN from the CD or NULL if
there is none or we don't have the ability to get it.
*/
char * (*get_mcn) ( const void *p_env );
/*!
Return the number of tracks in the current medium.
CDIO_INVALID_TRACK is returned on error.
*/
track_t (*get_num_tracks) ( void *p_env );
/*! Return number of channels in track: 2 or 4; -2 if not
implemented or -1 for error.
Not meaningful if track is not an audio track.
*/
int (*get_track_channels) ( const void *p_env, track_t i_track );
/*! Return 0 if track is copy protected, 1 if not, or -1 for error
or -2 if not implimented (yet). Is this meaningful if not an
audio track?
*/
track_flag_t (*get_track_copy_permit) ( void *p_env, track_t i_track );
/*!
Return the starting LBA for track number
i_track in p_env. Tracks numbers start at 1.
The "leadout" track is specified either by
using track_num LEADOUT_TRACK or the total tracks+1.
CDIO_INVALID_LBA is returned on error.
*/
lba_t (*get_track_lba) ( void *p_env, track_t i_track );
/*!
Return the starting LBA for the pregap for track number
i_track in p_env. Tracks numbers start at 1.
CDIO_INVALID_LBA is returned on error.
*/
lba_t (*get_track_pregap_lba) ( const void *p_env, track_t i_track );
/*!
Return the International Standard Recording Code (ISRC) for track number
i_track in p_cdio. Track numbers start at 1.
Note: string is malloc'd so caller has to free() the returned
string when done with it.
*/
char * (*get_track_isrc) ( const void *p_env, track_t i_track );
/*!
Get format of track.
*/
track_format_t (*get_track_format) ( void *p_env, track_t i_track );
/*!
Return true if we have XA data (green, mode2 form1) or
XA data (green, mode2 form2). That is track begins:
sync - header - subheader
12 4 - 8
FIXME: there's gotta be a better design for this and get_track_format?
*/
bool (*get_track_green) ( void *p_env, track_t i_track );
/*!
Return the starting MSF (minutes/secs/frames) for track number
i_track in p_env. Tracks numbers start at 1.
The "leadout" track is specified either by
using i_track LEADOUT_TRACK or the total tracks+1.
False is returned on error.
*/
bool (*get_track_msf) ( void *p_env, track_t i_track, msf_t *p_msf );
/*! Return 1 if track has pre-emphasis, 0 if not, or -1 for error
or -2 if not implimented (yet). Is this meaningful if not an
audio track?
*/
track_flag_t (*get_track_preemphasis)
( const void *p_env, track_t i_track );
/*!
lseek - reposition read/write file offset
Returns (off_t) -1 on error.
Similar to libc's lseek()
*/
off_t (*lseek) ( void *p_env, off_t offset, int whence );
/*!
Reads into buf the next size bytes.
Returns -1 on error.
Similar to libc's read()
*/
ssize_t (*read) ( void *p_env, void *p_buf, size_t i_size );
/*!
Reads a single mode2 sector from cd device into buf starting
from lsn. Returns 0 if no error.
*/
int (*read_audio_sectors) ( void *p_env, void *p_buf, lsn_t i_lsn,
unsigned int i_blocks );
/*!
Read a data sector
@param p_env environment to read from
@param p_buf place to read data into. The caller should make sure
this location can store at least CDIO_CD_FRAMESIZE,
M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE depending
on the kind of sector getting read. If you don't
know whether you have a Mode 1/2, Form 1/ Form 2/Formless
sector best to reserve space for the maximum,
M2RAW_SECTOR_SIZE.
@param i_lsn sector to read
@param i_blocksize size of block. Should be either CDIO_CD_FRAMESIZE,
M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE. See comment above under p_buf.
*/
driver_return_code_t (*read_data_sectors)
( void *p_env, void *p_buf, lsn_t i_lsn, uint16_t i_blocksize,
uint32_t i_blocks );
/*!
Reads a single mode2 sector from cd device into buf starting
from lsn. Returns 0 if no error.
*/
int (*read_mode2_sector)
( void *p_env, void *p_buf, lsn_t i_lsn, bool b_mode2_form2 );
/*!
Reads i_blocks of mode2 sectors from cd device into data starting
from lsn.
Returns 0 if no error.
*/
int (*read_mode2_sectors)
( void *p_env, void *p_buf, lsn_t i_lsn, bool b_mode2_form2,
unsigned int i_blocks );
/*!
Reads a single mode1 sector from cd device into buf starting
from lsn. Returns 0 if no error.
*/
int (*read_mode1_sector)
( void *p_env, void *p_buf, lsn_t i_lsn, bool mode1_form2 );
/*!
Reads i_blocks of mode1 sectors from cd device into data starting
from lsn.
Returns 0 if no error.
*/
int (*read_mode1_sectors)
( void *p_env, void *p_buf, lsn_t i_lsn, bool mode1_form2,
unsigned int i_blocks );
bool (*read_toc) ( void *p_env ) ;
/*!
Run a SCSI MMC command.
cdio CD structure set by cdio_open().
i_timeout_ms time in milliseconds we will wait for the command
to complete.
cdb_len number of bytes in cdb (6, 10, or 12).
cdb CDB bytes. All values that are needed should be set on
input.
b_return_data TRUE if the command expects data to be returned in
the buffer
len Size of buffer
buf Buffer for data, both sending and receiving
Returns 0 if command completed successfully.
*/
mmc_run_cmd_fn_t run_mmc_cmd;
/*!
Set the arg "key" with "value" in the source device.
*/
int (*set_arg) ( void *p_env, const char key[], const char value[] );
/*!
Set the blocksize for subsequent reads.
*/
driver_return_code_t (*set_blocksize) ( void *p_env,
uint16_t i_blocksize );
/*!
Set the drive speed.
@return 0 if everything went okay, -1 if we had an error. is -2
returned if this is not implemented for the current driver.
*/
int (*set_speed) ( void *p_env, int i_speed );
} cdio_funcs_t;
/*! Implementation of CdIo type */
struct _CdIo {
driver_id_t driver_id; /**< Particular driver opened. */
cdio_funcs_t op; /**< driver-specific routines handling
implementation*/
void *env; /**< environment. Passed to routine above. */
};
/* This is used in drivers that must keep their own internal
position pointer for doing seeks. Stream-based drivers (like bincue,
nrg, toc, network) would use this.
*/
typedef struct
{
off_t buff_offset; /* buffer offset in disk-image seeks. */
track_t index; /* Current track index in tocent. */
lba_t lba; /* Current LBA */
} internal_position_t;
CdIo_t * cdio_new (generic_img_private_t *p_env, cdio_funcs_t *p_funcs);
/* The below structure describes a specific CD Input driver */
typedef struct
{
driver_id_t id;
unsigned int flags;
const char *name;
const char *describe;
bool (*have_driver) (void);
CdIo_t *(*driver_open) (const char *psz_source_name);
CdIo_t *(*driver_open_am) (const char *psz_source_name,
const char *psz_access_mode);
char *(*get_default_device) (void);
bool (*is_device) (const char *psz_source_name);
char **(*get_devices) (void);
driver_return_code_t (*close_tray) (const char *psz_device);
} CdIo_driver_t;
/* The below array gives of the drivers that are currently available for
on a particular host. */
extern CdIo_driver_t CdIo_driver[];
/* The last valid entry of Cdio_driver. -1 means uninitialzed. -2
means some sort of error.
*/
extern int CdIo_last_driver;
/* The below array gives all drivers that can possibly appear.
on a particular host. */
extern CdIo_driver_t CdIo_all_drivers[];
/*!
Add/allocate a drive to the end of drives.
Use cdio_free_device_list() to free this device_list.
*/
void cdio_add_device_list(char **device_list[], const char *psz_drive,
unsigned int *i_drives);
driver_return_code_t close_tray_bsdi (const char *psz_drive);
driver_return_code_t close_tray_freebsd (const char *psz_drive);
driver_return_code_t close_tray_linux (const char *psz_drive);
driver_return_code_t close_tray_netbsd (const char *psz_drive);
driver_return_code_t close_tray_os2 (const char *psz_drive);
driver_return_code_t close_tray_osx (const char *psz_drive);
driver_return_code_t close_tray_solaris (const char *psz_drive);
driver_return_code_t close_tray_win32 (const char *psz_drive);
bool cdio_have_netbsd(void);
CdIo_t * cdio_open_netbsd (const char *psz_source);
char * cdio_get_default_device_netbsd(void);
char **cdio_get_devices_netbsd(void);
/*! Set up CD-ROM for reading using the NetBSD driver. The device_name is
the some sort of device name.
NULL is returned on error or there is no FreeBSD driver.
@see cdio_open_cd, cdio_open
*/
CdIo_t * cdio_open_am_netbsd (const char *psz_source,
const char *psz_access_mode);
/*! DEPRICATED: use cdio_have_driver().
True if AIX driver is available. */
bool cdio_have_aix (void);
/*! DEPRICATED: use cdio_have_driver().
True if BSDI driver is available. */
bool cdio_have_bsdi (void);
/*! DEPRICATED: use cdio_have_driver().
True if FreeBSD driver is available. */
bool cdio_have_freebsd (void);
/*! DEPRICATED: use cdio_have_driver().
True if GNU/Linux driver is available. */
bool cdio_have_linux (void);
/*! DEPRICATED: use cdio_have_driver().
True if Sun Solaris driver is available. */
bool cdio_have_solaris (void);
/*! DEPRICATED: use cdio_have_driver().
True if IBM OS2 driver is available. */
bool cdio_have_os2 (void);
/*! DEPRICATED: use cdio_have_driver().
True if Apple OSX driver is available. */
bool cdio_have_osx (void);
/*! DEPRICATED: use cdio_have_driver().
True if Microsoft Windows driver is available. */
bool cdio_have_win32 (void);
/*! True if Nero driver is available. */
bool cdio_have_nrg (void);
/*! True if BIN/CUE driver is available. */
bool cdio_have_bincue (void);
/*! True if cdrdao CDRDAO driver is available. */
bool cdio_have_cdrdao (void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __CDIO_PRIVATE_H__ */

View File

@ -0,0 +1,249 @@
/*
Copyright (C) 2004, 2005, 2006, 2008, 2009 Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Internal routines for CD I/O drivers. */
#ifndef __CDIO_GENERIC_H__
#define __CDIO_GENERIC_H__
#if defined(HAVE_CONFIG_H) && !defined(LIBCDIO_CONFIG_H)
# include "config.h"
#endif
#include <cdio/cdio.h>
#include <cdio/cdtext.h>
#include <cdio/iso9660.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*!
Things common to private device structures. Even though not all
devices may have some of these fields, by listing common ones
we facilitate writing generic routines and even cut-and-paste
code.
*/
typedef struct {
char *source_name; /**< Name used in open. */
bool init; /**< True if structure has been initialized */
bool toc_init; /**< True if TOC read in */
bool b_cdtext_error; /**< True if trouble reading CD-Text */
int ioctls_debugged; /**< for debugging */
/* Only one of data_source or fd is used; fd is for CD-ROM
devices and the data_source for stream reading (bincue, nrg, toc,
network).
*/
CdioDataSource_t *data_source;
int fd; /**< File descriptor of device */
track_t i_first_track; /**< The starting track number. */
track_t i_tracks; /**< The number of tracks. */
uint8_t i_joliet_level; /**< 0 = no Joliet extensions.
1-3: Joliet level. */
iso9660_pvd_t pvd;
iso9660_svd_t svd;
CdIo_t *cdio; /**< a way to call general cdio routines. */
cdtext_t *cdtext; /**< CD-Text for disc. */
track_flags_t track_flags[CDIO_CD_MAX_TRACKS+1];
/* Memorized sense reply of the most recent SCSI command.
Recorded by driver implementations of cdio_funcs_t.run_mmc_cmd().
Read by API function mmc_get_cmd_scsi_sense().
*/
unsigned char scsi_mmc_sense[263]; /* See SPC-3 4.5.3 : 252 bytes legal
but 263 bytes possible */
int scsi_mmc_sense_valid; /* Number of valid sense bytes */
/* Memorized eventual system specific SCSI address tuple text.
Empty text means that there is no such text defined for the drive.
NULL means that the driver does not support "scsi-tuple".
To be read by cdio_get_arg("scsi-tuple").
System specific suffixes to the key may demand and eventually
guarantee a further specified format.
E.g. "scsi-tuple-linux" guarantees either "Bus,Host,Channel,Target,Lun",
or empty text, or NULL. No other forms.
*/
char *scsi_tuple;
} generic_img_private_t;
/*!
Bogus eject media when there is no ejectable media, e.g. a disk image
We always return 2. Should we also free resources?
*/
driver_return_code_t cdio_generic_unimplemented_eject_media (void *p_env);
/*!
Set the blocksize for subsequent reads.
@return -2 since it's not implemented.
*/
driver_return_code_t
cdio_generic_unimplemented_set_blocksize (void *p_user_data,
uint16_t i_blocksize);
/*!
Set the drive speed.
@return -2 since it's not implemented.
*/
driver_return_code_t cdio_generic_unimplemented_set_speed (void *p_user_data,
int i_speed);
/*!
Release and free resources associated with cd.
*/
void cdio_generic_free (void *p_env);
/*!
Initialize CD device.
*/
bool cdio_generic_init (void *p_env, int open_mode);
/*!
Reads into buf the next size bytes.
Returns -1 on error.
Is in fact libc's read().
*/
off_t cdio_generic_lseek (void *p_env, off_t offset, int whence);
/*!
Reads into buf the next size bytes.
Returns -1 on error.
Is in fact libc's read().
*/
ssize_t cdio_generic_read (void *p_env, void *p_buf, size_t size);
/*!
Reads a single form1 sector from cd device into data starting
from lsn. Returns 0 if no error.
*/
int cdio_generic_read_form1_sector (void * user_data, void *data,
lsn_t lsn);
/*!
Release and free resources associated with stream or disk image.
*/
void cdio_generic_stdio_free (void *env);
/*!
Return true if source_name could be a device containing a CD-ROM on
Win32
*/
bool cdio_is_device_win32(const char *source_name);
/*!
Return true if source_name could be a device containing a CD-ROM on
OS/2
*/
bool cdio_is_device_os2(const char *source_name);
/*!
Return true if source_name could be a device containing a CD-ROM on
most Unix servers with block and character devices.
*/
bool cdio_is_device_generic(const char *source_name);
/*!
Like above, but don't give a warning device doesn't exist.
*/
bool cdio_is_device_quiet_generic(const char *source_name);
/*!
Get cdtext information for a CdIo object .
@param obj the CD object that may contain CD-TEXT information.
@return the CD-TEXT object or NULL if obj is NULL
or CD-TEXT information does not exist.
*/
cdtext_t *get_cdtext_generic (void *p_user_data);
/*!
Return the number of of the first track.
CDIO_INVALID_TRACK is returned on error.
*/
track_t get_first_track_num_generic(void *p_user_data);
/*!
Return the number of tracks in the current medium.
*/
track_t get_num_tracks_generic(void *p_user_data);
/*!
Get disc type associated with cd object.
*/
discmode_t get_discmode_generic (void *p_user_data );
/*!
Same as above but only handles CD cases
*/
discmode_t get_discmode_cd_generic (void *p_user_data );
/*! Return number of channels in track: 2 or 4; -2 if not
implemented or -1 for error.
Not meaningful if track is not an audio track.
*/
int get_track_channels_generic(const void *p_user_data, track_t i_track);
/*! Return 1 if copy is permitted on the track, 0 if not, or -1 for error.
Is this meaningful if not an audio track?
*/
track_flag_t get_track_copy_permit_generic(void *p_user_data,
track_t i_track);
/*! Return 1 if track has pre-emphasis, 0 if not, or -1 for error.
Is this meaningful if not an audio track?
pre-emphasis is a non linear frequency response.
*/
track_flag_t get_track_preemphasis_generic(const void *p_user_data,
track_t i_track);
/*!
Read cdtext information for a CdIo object .
return true on success, false on error or CD-Text information does
not exist.
*/
uint8_t * read_cdtext_generic (void *p_env);
void set_track_flags(track_flags_t *p_track_flag, uint8_t flag);
/*! Read mode 1 or mode2 sectors (using cooked mode). */
driver_return_code_t read_data_sectors_generic (void *p_user_data,
void *p_buf, lsn_t i_lsn,
uint16_t i_blocksize,
uint32_t i_blocks);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __CDIO_GENERIC_H__ */
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

View File

@ -0,0 +1,150 @@
/* private MMC helper routines.
Copyright (C) 2004, 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <cdio/mmc.h>
/*! Convert milliseconds to seconds taking the ceiling value, i.e.
1002 milliseconds gets rounded to 2 seconds.
*/
#define SECS2MSECS 1000
static inline unsigned int
msecs2secs(unsigned int msecs)
{
return (msecs+(SECS2MSECS-1)) / SECS2MSECS;
}
#undef SECS2MSECS
/***********************************************************
MMC CdIo Operations which a driver may use.
These are not directly user-accessible.
************************************************************/
/*!
Read Audio Subchannel information
@param p_user_data the CD object to be acted upon.
*/
driver_return_code_t
audio_read_subchannel_mmc ( void *p_user_data,
cdio_subchannel_t *p_subchannel);
/*!
Get the block size for subsequest read requests, via a SCSI MMC
MODE_SENSE 6 command.
*/
int get_blocksize_mmc (void *p_user_data);
/*!
Get the lsn of the end of the CD
@return the lsn. On error return CDIO_INVALID_LSN.
*/
lsn_t get_disc_last_lsn_mmc( void *p_user_data );
void get_drive_cap_mmc (const void *p_user_data,
/*out*/ cdio_drive_read_cap_t *p_read_cap,
/*out*/ cdio_drive_write_cap_t *p_write_cap,
/*out*/ cdio_drive_misc_cap_t *p_misc_cap);
int get_media_changed_mmc (const void *p_user_data);
char *get_mcn_mmc (const void *p_user_data);
driver_return_code_t get_tray_status (const void *p_user_data);
/*! Read just the user data part of some sort of data sector (via
mmc_read_cd).
@param p_user_data object to read from
@param p_buf place to read data into. The caller should make sure
this location can store at least CDIO_CD_FRAMESIZE,
M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE depending on
the kind of sector getting read. If you don't know
whether you have a Mode 1/2, Form 1/ Form 2/Formless
sector best to reserve space for the maximum,
M2RAW_SECTOR_SIZE.
@param i_lsn sector to read
@param i_blocksize size of block. Should be either CDIO_CD_FRAMESIZE,
M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE. See comment above under p_buf.
*/
driver_return_code_t read_data_sectors_mmc ( void *p_user_data,
void *p_buf, lsn_t i_lsn,
uint16_t i_blocksize,
uint32_t i_blocks );
char *get_mcn_mmc (const void *p_user_data);
/* Set read blocksize (via MMC) */
driver_return_code_t set_blocksize_mmc (void *p_user_data,
uint16_t i_blocksize);
/* Set the drive speed in CD-ROM speed units (via MMC). */
driver_return_code_t set_drive_speed_mmc (void *p_user_data, int i_speed);
/* Set CD-ROM drive speed in K bytes per second. (via MMC) */
driver_return_code_t set_speed_mmc (void *p_user_data, int i_Kbs_speed);
/***********************************************************
Miscellaenous other "private" routines. Probably need
to better classify these.
************************************************************/
typedef driver_return_code_t (*mmc_run_cmd_fn_t)
( void *p_user_data,
unsigned int i_timeout_ms,
unsigned int i_cdb,
const mmc_cdb_t *p_cdb,
cdio_mmc_direction_t e_direction,
unsigned int i_buf, /*in/out*/ void *p_buf );
int mmc_set_blocksize_mmc_private ( const void *p_env, const
mmc_run_cmd_fn_t run_mmc_cmd,
uint16_t i_blocksize );
/*!
Get the DVD type associated with cd object.
*/
discmode_t
mmc_get_dvd_struct_physical_private ( void *p_env,
mmc_run_cmd_fn_t run_mmc_cmd,
cdio_dvd_struct_t *s );
char *mmc_get_mcn_private ( void *p_env,
mmc_run_cmd_fn_t run_mmc_cmd
);
uint8_t * mmc_read_cdtext_private ( void *p_user_data,
mmc_run_cmd_fn_t run_mmc_cmd
);
/*!
On input a MODE_SENSE command was issued and we have the results
in p. We interpret this and return a bit mask set according to the
capabilities.
*/
void mmc_get_drive_cap_buf(const uint8_t *p,
/*out*/ cdio_drive_read_cap_t *p_read_cap,
/*out*/ cdio_drive_write_cap_t *p_write_cap,
/*out*/ cdio_drive_misc_cap_t *p_misc_cap);
driver_return_code_t
mmc_set_blocksize_private ( void *p_env,
const mmc_run_cmd_fn_t run_mmc_cmd,
uint16_t i_blocksize);

View File

@ -0,0 +1,171 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\iso9660_private.h" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\iso9660.c" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\iso9660_fs.c" />
<ClCompile Include="..\rock.c" />
<ClCompile Include="..\xa.c" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{D4E80F35-2604-40AC-B436-97B052ECB572}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>iso9660</RootNamespace>
<ProjectName>libcdio-iso9660</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)x86_32\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)x86_32\$(Configuration)\$(ProjectName)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)x86_32\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)x86_32\$(Configuration)\$(ProjectName)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)x86_64\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)x86_64\$(Configuration)\$(ProjectName)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)x86_64\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)x86_64\$(Configuration)\$(ProjectName)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..;..\..;..\..\driver;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Lib>
<TargetMachine>MachineX86</TargetMachine>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..;..\..;..\..\driver;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Lib>
<TargetMachine>MachineX86</TargetMachine>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..;..\..;..\..\driver;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Lib>
<TargetMachine>MachineX64</TargetMachine>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..;..\..;..\..\driver;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Lib>
<TargetMachine>MachineX64</TargetMachine>
</Lib>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\iso9660_private.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\iso9660.c">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\iso9660_fs.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\rock.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\xa.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,150 @@
# $Id: Makefile.am,v 1.18 2008/10/20 01:25:15 rocky Exp $
#
# Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
# Rocky Bernstein <rocky@gnu.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
########################################################
# Things to make the libiso9660 library
########################################################
#
# From libtool documentation amended with guidance from N. Boullis:
#
# 1. Start with version information of `0:0:0' for each libtool library.
#
# 2. It is probably not a good idea to update the version information
# several times between public releases, but rather once per public
# release. (This seems to be more an aesthetic consideration than
# a hard technical one.)
#
# 3. If the library source code has changed at all since the last
# update, then increment REVISION (`C:R:A' becomes `C:R+1:A').
#
# 4. If any interfaces have been added, removed, or changed since the
# last update, increment CURRENT, and set REVISION to 0.
#
# 5. If any interfaces have been added since the last public release,
# then increment AGE.
#
# 6. If any interfaces have been removed or changed since the last
# public release, then set AGE to 0. A changed interface means an
# incompatibility with previous versions.
libiso9660_la_CURRENT = 8
libiso9660_la_REVISION = 0
libiso9660_la_AGE = 0
EXTRA_DIST = libiso9660.sym
noinst_HEADERS = iso9660_private.h
lib_LTLIBRARIES = libiso9660.la
if ENABLE_ROCK
rock_src = rock.c
else
rock_src =
endif
libiso9660_la_SOURCES = \
iso9660.c \
iso9660_private.h \
iso9660_fs.c \
$(rock_src) \
xa.c
libiso9660_la_LIBADD = @LIBCDIO_LIBS@
libiso9660_la_ldflags = -version-info $(libiso9660_la_CURRENT):$(libiso9660_la_REVISION):$(libiso9660_la_AGE) @LT_NO_UNDEFINED@
libiso9660_la_dependencies = $(top_builddir)/lib/driver/libcdio.la
INCLUDES = $(LIBCDIO_CFLAGS)
########################################################
# Things to version the symbols in the libraries
########################################################
# An explanation of the versioning problem from Nicolas Boullis and
# the versioned symbol solution he uses below...
#
# Currently, libvcdinfo uses the cdio_open function from libcdio.
# Let's imagine a program foobar that uses both the vcdinfo_open
# function from libvcdinfo and the cdio_open function from libcdio.
# Currently, libcdio has SONAME libcdio.so.0, libvcdinfo has SONAME
# libvcdinfo.so.0 and requires libcdio.so.0, and foobar requires both
# libvcdinfo.so.0 and libcdio.so.0. Everything looks fine.
#
# Now, for some reason, you decide to change the cdio_open function.
# That's your right, but you have to bump the CURRENT version and (if I
# understand it correctly, athough this is not that clear in libtool's
# documentation) set the AGE to 0. Anyway, this bumps the SONAME, which is
# sane since the interface changes incompatibly.
# Now, you have a new libcdio with SONAME libcdio.so.1. But libvcdinfo and
# foobar still require libcdio.so.0. Everything is still fine.
# Now, after some minor changes, the author of foobar recompiles foobar.
# Then, foobar now requires libvcdinfo.so.0 and libcdio.so.1. And foobar
# now segfaults...
# What is happening? When you run foobar, if brings both libvcdinfo.so.0
# and libcdio.so.1, but libvcdinfo.so.0 also brings libcdio.so.0. So you
# have both libcdio.so.0 and libcdio.so.1 that bring their symbols to the
# global namespace. Hence, you have to incompatible versions of the
# cdio_open function in the name space. When foobar calls cdio_open, it
# may choose the wrong function, and segfaults...
# With versioned symbols, the cdio_open function from libcdio.so.0 may be
# known as (something that looks like) cdio_open@@CDIO_0. An the cdio_open
# function from libcdio.so.1 as cdio_open@@CDIO_1. Both versions of
# libcdio would still be brought in by the most recent foobar, but foobar
# (and libvcdinfo) know which versioned function to use and then use the
# good one.
# This is some simple versioning where every symbol is versioned with
# something that looks like the SONAME of the library. More complex (and
# better) versioning is possible; it is for example what is used by glibc.
# But good complex versioning is something that requires much more
# work...
# The below is a impliments symbol versioning. First of all, I
# compute MAJOR as CURENT - AGE; that is what is used within libtool
# (at least on GNU/Linux systems) for the number in the SONAME. The
# nm command gives the list of symbols known in each of the object
# files that will be part of the shared library. And the sed command
# extracts from this list those symbols that will be shared. (This sed
# command comes from libtool.)
libiso9660_la_MAJOR = $(shell expr $(libiso9660_la_CURRENT) - $(libiso9660_la_AGE))
if BUILD_VERSIONED_LIBS
libiso9660_la_LDFLAGS = $(libiso9660_la_ldflags) -Wl,--version-script=libiso9660.la.ver
libiso9660_la_DEPENDENCIES = $(libcdio9660_la_dependencies) libiso9660.la.ver
libiso9660.la.ver: $(libiso9660_la_OBJECTS) $(srcdir)/libiso9660.sym
echo 'ISO9660_$(libiso9660_la_MAJOR) {' > $@
objs=`for obj in $(libiso9660_la_OBJECTS); do sed -ne "s/^pic_object='\(.*\)'$$/\1/p" $$obj; done`;
if test -n "$$objs" ; then \
nm $${objs} | sed -n -e 's/^.*[ ][ABCDGIRSTW][ABCDGIRSTW]*[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$$/\1/p' | sort -u | { first=true; while read symbol; do if grep -q "^$${symbol}\$$" $(srcdir)/libiso9660.sym; then if test $$first = true; then echo " global:"; first=false; fi; echo " $${symbol};"; fi; done; } >> $@; \
nm $${objs} | sed -n -e 's/^.*[ ][ABCDGIRSTW][ABCDGIRSTW]*[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$$/\1/p' | sort -u | { first=true; while read symbol; do if grep -q "^$${symbol}\$$" $(srcdir)/libiso9660.sym; then :; else if test $$first = true; then echo " local:"; first=false; fi; echo " $${symbol};"; fi; done; } >> $@; \
fi
echo '};' >> $@
MOSTLYCLEANFILES = libiso9660.la.ver
else
libiso9660_la_LDFLAGS = $(libiso9660_la_ldflags)
libiso9660_la_DEPENDENCIES = $(libcdio9660_la_dependencies)
endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,83 @@
/*
Copyright (C) 2003, 2004, 2005, 2008, 2011
Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
See also iso9660.h by Eric Youngdale (1993).
Copyright 1993 Yggdrasil Computing, Incorporated
Copyright (c) 1999,2000 J. Schilling
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CDIO_ISO9660_PRIVATE_H__
#define __CDIO_ISO9660_PRIVATE_H__
#if defined(HAVE_CONFIG_H) && !defined(__CDIO_CONFIG_H__)
# include "config.h"
# define __CDIO_CONFIG_H__ 1
#endif
#include <cdio/types.h>
#define ISO_VERSION 1
PRAGMA_BEGIN_PACKED
typedef struct iso_volume_descriptor_s {
uint8_t type; /**< 7.1.1 */
char id[5]; /**< "CD001" (ISO_STANDARD_ID) */
uint8_t version; /**< 7.1.1 */
char data[2041];
} GNUC_PACKED iso_volume_descriptor_t;
#define iso_volume_descriptor_t_SIZEOF ISO_BLOCKSIZE
#define iso9660_pvd_t_SIZEOF ISO_BLOCKSIZE
/*
* XXX JS: The next structure has an odd length!
* Some compilers (e.g. on Sun3/mc68020) padd the structures to even length.
* For this reason, we cannot use sizeof (struct iso_path_table) or
* sizeof (struct iso_directory_record) to compute on disk sizes.
* Instead, we use offsetof(..., name) and add the name size.
* See mkisofs.h
*/
/** We use this to help us look up the parent inode numbers. */
typedef struct iso_path_table_s {
uint8_t name_len; /**< 7.1.1 */
uint8_t xa_len; /**< 7.1.1 */
uint32_t extent; /**< 7.3.1/7.3.2 */
uint16_t parent; /**< 7.2.1/7.2.2 */
char name[EMPTY_ARRAY_SIZE];
} GNUC_PACKED iso_path_table_t;
#define iso_path_table_t_SIZEOF 8
#define iso9660_dir_t_SIZEOF 33
PRAGMA_END_PACKED
#endif /* __CDIO_ISO9660_PRIVATE_H__ */
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

625
src/libcdio/iso9660/rock.c Normal file
View File

@ -0,0 +1,625 @@
/*
Copyright (C) 2005, 2008, 2010, 2011 Rocky Bernstein <rocky@gnu.org>
Adapted from GNU/Linux fs/isofs/rock.c (C) 1992, 1993 Eric Youngdale
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Rock Ridge Extensions to iso9660 */
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifndef HAVE_S_ISLNK
# define S_ISLNK(s) ((void)s,0)
#endif
#ifndef HAVE_S_ISSOCK
# define S_ISSOCK(s) ((void)s,0)
#endif
#include <cdio/iso9660.h>
#include <cdio/logging.h>
#include <cdio/bytesex.h>
#include <malloc.h>
#define CDIO_MKDEV(ma,mi) ((ma)<<16 | (mi))
enum iso_rock_enums iso_rock_enums;
iso_rock_nm_flag_t iso_rock_nm_flag;
iso_rock_sl_flag_t iso_rock_sl_flag;
iso_rock_tf_flag_t iso_rock_tf_flag;
/* Our own realloc routine tailored for the iso9660_stat_t symlink
field. I can't figure out how to make realloc() work without
valgrind complaint.
*/
static bool
realloc_symlink(/*in/out*/ iso9660_stat_t *p_stat, uint8_t i_grow)
{
if (!p_stat->rr.i_symlink) {
const uint16_t i_max = 2*i_grow+1;
p_stat->rr.psz_symlink = (char *) calloc(1, i_max);
p_stat->rr.i_symlink_max = i_max;
return (NULL != p_stat->rr.psz_symlink);
} else {
int i_needed = p_stat->rr.i_symlink + i_grow ;
if ( i_needed <= p_stat->rr.i_symlink_max)
return true;
else {
char * psz_newsymlink = (char *) calloc(1, 2*i_needed);
if (!psz_newsymlink) return false;
p_stat->rr.i_symlink_max = 2*i_needed;
memcpy(psz_newsymlink, p_stat->rr.psz_symlink, p_stat->rr.i_symlink);
free(p_stat->rr.psz_symlink);
p_stat->rr.psz_symlink = psz_newsymlink;
return true;
}
}
}
/* These functions are designed to read the system areas of a directory record
* and extract relevant information. There are different functions provided
* depending upon what information we need at the time. One function fills
* out an inode structure, a second one extracts a filename, a third one
* returns a symbolic link name, and a fourth one returns the extent number
* for the file. */
#define SIG(A,B) ((A) | ((B) << 8)) /* isonum_721() */
/* This is a way of ensuring that we have something in the system
use fields that is compatible with Rock Ridge */
#define CHECK_SP(FAIL) \
if(rr->u.SP.magic[0] != 0xbe) FAIL; \
if(rr->u.SP.magic[1] != 0xef) FAIL; \
p_stat->rr.s_rock_offset = rr->u.SP.skip;
/* We define a series of macros because each function must do exactly the
same thing in certain places. We use the macros to ensure that everything
is done correctly */
#define CONTINUE_DECLS \
int cont_extent = 0, cont_offset = 0, cont_size = 0; \
void *buffer = NULL
#define CHECK_CE \
{ cont_extent = from_733(*rr->u.CE.extent); \
cont_offset = from_733(*rr->u.CE.offset); \
cont_size = from_733(*rr->u.CE.size); }
#define SETUP_ROCK_RIDGE(DE,CHR,LEN) \
{ \
LEN= sizeof(iso9660_dir_t) + DE->filename_len; \
if(LEN & 1) LEN++; \
CHR = ((unsigned char *) DE) + LEN; \
LEN = *((unsigned char *) DE) - LEN; \
if (0xff != p_stat->rr.s_rock_offset) \
{ \
LEN -= p_stat->rr.s_rock_offset; \
CHR += p_stat->rr.s_rock_offset; \
if (LEN<0) LEN=0; \
} \
}
/* Copy a long or short time from the iso_rock_tf_t into
the specified field of a iso_rock_statbuf_t.
non-paramater variables are p_stat, rr, and cnt.
*/
#define add_time(FLAG, TIME_FIELD) \
if (rr->u.TF.flags & FLAG) { \
p_stat->rr.TIME_FIELD.b_used = true; \
p_stat->rr.TIME_FIELD.b_longdate = \
(0 != (rr->u.TF.flags & ISO_ROCK_TF_LONG_FORM)); \
if (p_stat->rr.TIME_FIELD.b_longdate) { \
memcpy(&(p_stat->rr.TIME_FIELD.t.ltime), \
&(rr->u.TF.time_bytes[cnt]), \
sizeof(iso9660_ltime_t)); \
cnt += sizeof(iso9660_ltime_t); \
} else { \
memcpy(&(p_stat->rr.TIME_FIELD.t.dtime), \
&(rr->u.TF.time_bytes[cnt]), \
sizeof(iso9660_dtime_t)); \
cnt += sizeof(iso9660_dtime_t); \
} \
}
/*!
Get
@return length of name field; 0: not found, -1: to be ignored
*/
int
get_rock_ridge_filename(iso9660_dir_t * p_iso9660_dir,
/*out*/ char * psz_name,
/*in/out*/ iso9660_stat_t *p_stat)
{
int len;
unsigned char *chr;
int symlink_len = 0;
CONTINUE_DECLS;
int i_namelen = 0;
int truncate=0;
if (!p_stat || nope == p_stat->rr.b3_rock) return 0;
*psz_name = 0;
SETUP_ROCK_RIDGE(p_iso9660_dir, chr, len);
/*repeat:*/
{
iso_extension_record_t * rr;
int sig;
int rootflag;
while (len > 1){ /* There may be one byte for padding somewhere */
rr = (iso_extension_record_t *) chr;
if (rr->len == 0) goto out; /* Something got screwed up here */
sig = *chr+(*(chr+1) << 8);
chr += rr->len;
len -= rr->len;
switch(sig){
case SIG('S','P'):
CHECK_SP(goto out);
break;
case SIG('C','E'):
{
iso711_t i_fname = from_711(p_iso9660_dir->filename_len);
if ('\0' == p_iso9660_dir->filename[0] && 1 == i_fname)
break;
if ('\1' == p_iso9660_dir->filename[0] && 1 == i_fname)
break;
}
CHECK_CE;
break;
case SIG('E','R'):
p_stat->rr.b3_rock = yep;
cdio_debug("ISO 9660 Extensions: ");
{
int p;
for(p=0;p<rr->u.ER.len_id;p++) cdio_debug("%c",rr->u.ER.data[p]);
}
break;
case SIG('N','M'):
/* Alternate name */
p_stat->rr.b3_rock = yep;
if (truncate) break;
if (rr->u.NM.flags & ISO_ROCK_NM_PARENT) {
i_namelen = sizeof("..");
strncat(psz_name, "..", i_namelen);
} else if (rr->u.NM.flags & ISO_ROCK_NM_CURRENT) {
i_namelen = sizeof(".");
strncat(psz_name, ".", i_namelen);
break;
}
if (rr->u.NM.flags & ~1) {
cdio_info("Unsupported NM flag settings (%d)",rr->u.NM.flags);
break;
}
if((strlen(psz_name) + rr->len - 5) >= 254) {
truncate = 1;
break;
}
strncat(psz_name, rr->u.NM.name, rr->len - 5);
i_namelen += rr->len - 5;
break;
case SIG('P','X'):
/* POSIX file attributes */
p_stat->rr.st_mode = from_733(rr->u.PX.st_mode);
p_stat->rr.st_nlinks = from_733(rr->u.PX.st_nlinks);
p_stat->rr.st_uid = from_733(rr->u.PX.st_uid);
p_stat->rr.st_gid = from_733(rr->u.PX.st_gid);
p_stat->rr.b3_rock = yep;
break;
case SIG('S','L'):
{
/* Symbolic link */
uint8_t slen;
iso_rock_sl_part_t * p_sl;
iso_rock_sl_part_t * p_oldsl;
slen = rr->len - 5;
p_sl = &rr->u.SL.link;
p_stat->rr.i_symlink = symlink_len;
while (slen > 1){
rootflag = 0;
switch(p_sl->flags &~1){
case 0:
realloc_symlink(p_stat, p_sl->len);
memcpy(&(p_stat->rr.psz_symlink[p_stat->rr.i_symlink]),
p_sl->text, p_sl->len);
p_stat->rr.i_symlink += p_sl->len;
break;
case 4:
realloc_symlink(p_stat, 1);
p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '.';
/* continue into next case. */
case 2:
realloc_symlink(p_stat, 1);
p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '.';
break;
case 8:
rootflag = 1;
realloc_symlink(p_stat, 1);
p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '/';
break;
default:
cdio_warn("Symlink component flag not implemented");
}
slen -= p_sl->len + 2;
p_oldsl = p_sl;
p_sl = (iso_rock_sl_part_t *) (((char *) p_sl) + p_sl->len + 2);
if (slen < 2) {
if (((rr->u.SL.flags & 1) != 0) && ((p_oldsl->flags & 1) == 0))
p_stat->rr.i_symlink += 1;
break;
}
/*
* If this component record isn't continued, then append a '/'.
*/
if (!rootflag && (p_oldsl->flags & 1) == 0) {
realloc_symlink(p_stat, 1);
p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '/';
}
}
}
symlink_len = p_stat->rr.i_symlink;
realloc_symlink(p_stat, 1);
p_stat->rr.psz_symlink[symlink_len]='\0';
break;
case SIG('R','E'):
free(buffer);
return -1;
case SIG('T','F'):
/* Time stamp(s) for a file */
{
int cnt = 0;
add_time(ISO_ROCK_TF_CREATE, create);
add_time(ISO_ROCK_TF_MODIFY, modify);
add_time(ISO_ROCK_TF_ACCESS, access);
add_time(ISO_ROCK_TF_ATTRIBUTES, attributes);
add_time(ISO_ROCK_TF_BACKUP, backup);
add_time(ISO_ROCK_TF_EXPIRATION, expiration);
add_time(ISO_ROCK_TF_EFFECTIVE, effective);
p_stat->rr.b3_rock = yep;
break;
}
default:
break;
}
}
}
free(buffer);
return i_namelen; /* If 0, this file did not have a NM field */
out:
free(buffer);
return 0;
}
static int
parse_rock_ridge_stat_internal(iso9660_dir_t *p_iso9660_dir,
iso9660_stat_t *p_stat, int regard_xa)
{
int len;
unsigned char * chr;
int symlink_len = 0;
CONTINUE_DECLS;
if (nope == p_stat->rr.b3_rock) return 0;
SETUP_ROCK_RIDGE(p_iso9660_dir, chr, len);
if (regard_xa)
{
chr+=14;
len-=14;
if (len<0) len=0;
}
/* repeat:*/
{
int sig;
iso_extension_record_t * rr;
int rootflag;
while (len > 1){ /* There may be one byte for padding somewhere */
rr = (iso_extension_record_t *) chr;
if (rr->len == 0) goto out; /* Something got screwed up here */
sig = from_721(*chr);
chr += rr->len;
len -= rr->len;
switch(sig){
case SIG('S','P'):
CHECK_SP(goto out);
break;
case SIG('C','E'):
CHECK_CE;
break;
case SIG('E','R'):
p_stat->rr.b3_rock = yep;
cdio_debug("ISO 9660 Extensions: ");
{ int p;
for(p=0;p<rr->u.ER.len_id;p++) cdio_debug("%c",rr->u.ER.data[p]);
}
break;
case SIG('P','X'):
p_stat->rr.st_mode = from_733(rr->u.PX.st_mode);
p_stat->rr.st_nlinks = from_733(rr->u.PX.st_nlinks);
p_stat->rr.st_uid = from_733(rr->u.PX.st_uid);
p_stat->rr.st_gid = from_733(rr->u.PX.st_gid);
break;
case SIG('P','N'):
/* Device major,minor number */
{ int32_t high, low;
high = from_733(rr->u.PN.dev_high);
low = from_733(rr->u.PN.dev_low);
/*
* The Rock Ridge standard specifies that if sizeof(dev_t) <= 4,
* then the high field is unused, and the device number is completely
* stored in the low field. Some writers may ignore this subtlety,
* and as a result we test to see if the entire device number is
* stored in the low field, and use that.
*/
if((low & ~0xff) && high == 0) {
p_stat->rr.i_rdev = CDIO_MKDEV(low >> 8, low & 0xff);
} else {
p_stat->rr.i_rdev = CDIO_MKDEV(high, low);
}
}
break;
case SIG('T','F'):
/* Time stamp(s) for a file */
{
int cnt = 0;
add_time(ISO_ROCK_TF_CREATE, create);
add_time(ISO_ROCK_TF_MODIFY, modify);
add_time(ISO_ROCK_TF_ACCESS, access);
add_time(ISO_ROCK_TF_ATTRIBUTES, attributes);
add_time(ISO_ROCK_TF_BACKUP, backup);
add_time(ISO_ROCK_TF_EXPIRATION, expiration);
add_time(ISO_ROCK_TF_EFFECTIVE, effective);
p_stat->rr.b3_rock = yep;
break;
}
case SIG('S','L'):
{
/* Symbolic link */
uint8_t slen;
iso_rock_sl_part_t * p_sl;
iso_rock_sl_part_t * p_oldsl;
slen = rr->len - 5;
p_sl = &rr->u.SL.link;
p_stat->rr.i_symlink = symlink_len;
while (slen > 1){
rootflag = 0;
switch(p_sl->flags &~1){
case 0:
realloc_symlink(p_stat, p_sl->len);
memcpy(&(p_stat->rr.psz_symlink[p_stat->rr.i_symlink]),
p_sl->text, p_sl->len);
p_stat->rr.i_symlink += p_sl->len;
break;
case 4:
realloc_symlink(p_stat, 1);
p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '.';
/* continue into next case. */
case 2:
realloc_symlink(p_stat, 1);
p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '.';
break;
case 8:
rootflag = 1;
realloc_symlink(p_stat, 1);
p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '/';
p_stat->rr.i_symlink++;
break;
default:
cdio_warn("Symlink component flag not implemented");
}
slen -= p_sl->len + 2;
p_oldsl = p_sl;
p_sl = (iso_rock_sl_part_t *) (((char *) p_sl) + p_sl->len + 2);
if (slen < 2) {
if (((rr->u.SL.flags & 1) != 0) && ((p_oldsl->flags & 1) == 0))
p_stat->rr.i_symlink += 1;
break;
}
/*
* If this component record isn't continued, then append a '/'.
*/
if (!rootflag && (p_oldsl->flags & 1) == 0) {
realloc_symlink(p_stat, 1);
p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '/';
}
}
}
symlink_len = p_stat->rr.i_symlink;
realloc_symlink(p_stat, 1);
p_stat->rr.psz_symlink[symlink_len]='\0';
break;
case SIG('R','E'):
cdio_warn("Attempt to read p_stat for relocated directory");
goto out;
#if FINISHED
case SIG('C','L'):
{
iso9660_stat_t * reloc;
ISOFS_I(p_stat)->i_first_extent = from_733(rr->u.CL.location);
reloc = isofs_iget(p_stat->rr.i_sb, p_stat->rr.i_first_extent, 0);
if (!reloc)
goto out;
p_stat->rr.st_mode = reloc->st_mode;
p_stat->rr.st_nlinks = reloc->st_nlinks;
p_stat->rr.st_uid = reloc->st_uid;
p_stat->rr.st_gid = reloc->st_gid;
p_stat->rr.i_rdev = reloc->i_rdev;
p_stat->rr.i_symlink = reloc->i_symlink;
p_stat->rr.i_blocks = reloc->i_blocks;
p_stat->rr.i_atime = reloc->i_atime;
p_stat->rr.i_ctime = reloc->i_ctime;
p_stat->rr.i_mtime = reloc->i_mtime;
iput(reloc);
}
break;
#endif
default:
break;
}
}
}
out:
free(buffer);
return 0;
}
int
parse_rock_ridge_stat(iso9660_dir_t *p_iso9660_dir,
/*out*/ iso9660_stat_t *p_stat)
{
int result;
if (!p_stat) return 0;
result = parse_rock_ridge_stat_internal(p_iso9660_dir, p_stat, 0);
/* if Rock-Ridge flag was reset and we didn't look for attributes
* behind eventual XA attributes, have a look there */
if (0xFF == p_stat->rr.s_rock_offset && nope != p_stat->rr.b3_rock) {
result = parse_rock_ridge_stat_internal(p_iso9660_dir, p_stat, 14);
}
return result;
}
#define BUF_COUNT 16
#define BUF_SIZE sizeof("drwxrwxrwx")
/* Return a pointer to a internal free buffer */
static char *
_getbuf (void)
{
static char _buf[BUF_COUNT][BUF_SIZE];
static int _i = -1;
_i++;
_i %= BUF_COUNT;
memset (_buf[_i], 0, BUF_SIZE);
return _buf[_i];
}
/*!
Returns a string which interpreting the POSIX mode st_mode.
For example:
\verbatim
drwxrws---
-rw-rw-r--
lrwxrwxrwx
\endverbatim
A description of the characters in the string follows
The 1st character is either "b" for a block device,
"c" for a character device, "d" if the entry is a directory, "l" for
a symbolic link, "p" for a pipe or FIFO, "s" for a "socket",
or "-" if none of the these.
The 2nd to 4th characters refer to permissions for a user while the
the 5th to 7th characters refer to permissions for a group while, and
the 8th to 10h characters refer to permissions for everyone.
In each of these triplets the first character (2, 5, 8) is "r" if
the entry is allowed to be read.
The second character of a triplet (3, 6, 9) is "w" if the entry is
allowed to be written.
The third character of a triplet (4, 7, 10) is "x" if the entry is
executable but not user (for character 4) or group (for characters
6) settable and "s" if the item has the corresponding user/group set.
For a directory having an executable property on ("x" or "s") means
the directory is allowed to be listed or "searched". If the execute
property is not allowed for a group or user but the corresponding
group/user is set "S" indicates this. If none of these properties
holds the "-" indicates this.
*/
const char *
iso9660_get_rock_attr_str(posix_mode_t st_mode)
{
char *result = _getbuf();
if (S_ISBLK(st_mode))
result[ 0] = 'b';
else if (S_ISDIR(st_mode))
result[ 0] = 'd';
else if (S_ISCHR(st_mode))
result[ 0] = 'c';
else if (S_ISLNK(st_mode))
result[ 0] = 'l';
else if (S_ISFIFO(st_mode))
result[ 0] = 'p';
else if (S_ISSOCK(st_mode))
result[ 0] = 's';
/* May eventually fill in others.. */
else
result[ 0] = '-';
result[ 1] = (st_mode & ISO_ROCK_IRUSR) ? 'r' : '-';
result[ 2] = (st_mode & ISO_ROCK_IWUSR) ? 'w' : '-';
if (st_mode & ISO_ROCK_ISUID)
result[ 3] = (st_mode & ISO_ROCK_IXUSR) ? 's' : 'S';
else
result[ 3] = (st_mode & ISO_ROCK_IXUSR) ? 'x' : '-';
result[ 4] = (st_mode & ISO_ROCK_IRGRP) ? 'r' : '-';
result[ 5] = (st_mode & ISO_ROCK_IWGRP) ? 'w' : '-';
if (st_mode & ISO_ROCK_ISGID)
result[ 6] = (st_mode & ISO_ROCK_IXGRP) ? 's' : 'S';
else
result[ 6] = (st_mode & ISO_ROCK_IXGRP) ? 'x' : '-';
result[ 7] = (st_mode & ISO_ROCK_IROTH) ? 'r' : '-';
result[ 8] = (st_mode & ISO_ROCK_IWOTH) ? 'w' : '-';
result[ 9] = (st_mode & ISO_ROCK_IXOTH) ? 'x' : '-';
result[11] = '\0';
return result;
}
/*!
Returns POSIX mode bitstring for a given file.
*/
mode_t
iso9660_get_posix_filemode_from_rock(const iso_rock_statbuf_t *rr)
{
return (mode_t) rr->st_mode;
}

190
src/libcdio/iso9660/xa.c Normal file
View File

@ -0,0 +1,190 @@
/*
Copyright (C) 2003, 2005, 2008, 2011 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
# define __CDIO_CONFIG_H__ 1
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
// TODO: Why the frack can't we redef using sys/stat.h?!?
#ifdef _MSC_VER
#define S_IRUSR 0x0100
#define S_IWUSR 0x0080
#define S_IXUSR 0x0040
#define S_IFDIR 0x4000
#endif
/*! String inside frame which identifies XA attributes. Note should
come *before* public headers which does a #define of
this name.
*/
const char ISO_XA_MARKER_STRING[] = {'C', 'D', '-', 'X', 'A', '0', '0', '1'};
/* Public headers */
#include <cdio/iso9660.h>
#include <cdio/util.h>
#include <cdio/bytesex.h>
/* Private headers */
#include "cdio_assert.h"
/** The below variable is trickery to force enum symbol values to be
recorded in debug symbol tables. It is used to allow one to refer
to the enumeration value names in the typedefs above in a debugger
and debugger expressions.
*/
xa_misc_enum_t debugger_xa_misc_enum;
#define BUF_COUNT 16
#define BUF_SIZE 80
/* Return a pointer to a internal free buffer */
static char *
_getbuf (void)
{
static char _buf[BUF_COUNT][BUF_SIZE];
static int _num = -1;
_num++;
_num %= BUF_COUNT;
memset (_buf[_num], 0, BUF_SIZE);
return _buf[_num];
}
/*!
Returns a string which interpreting the extended attribute xa_attr.
For example:
\verbatim
d---1xrxrxr
---2--r-r-r
-a--1xrxrxr
\endverbatim
A description of the characters in the string follows
The 1st character is either "d" if the entry is a directory, or "-" if not.
The 2nd character is either "a" if the entry is CDDA (audio), or "-" if not.
The 3rd character is either "i" if the entry is interleaved, or "-" if not.
The 4th character is either "2" if the entry is mode2 form2 or "-" if not.
The 5th character is either "1" if the entry is mode2 form1 or "-" if not.
Note that an entry will either be in mode2 form1 or mode form2. That
is you will either see "2-" or "-1" in the 4th & 5th positions.
The 6th and 7th characters refer to permissions for a user while the
the 8th and 9th characters refer to permissions for a group while, and
the 10th and 11th characters refer to permissions for a others.
In each of these pairs the first character (6, 8, 10) is "x" if the
entry is executable. For a directory this means the directory is
allowed to be listed or "searched".
The second character of a pair (7, 9, 11) is "r" if the entry is allowed
to be read.
*/
const char *
iso9660_get_xa_attr_str (uint16_t xa_attr)
{
char *result = _getbuf();
xa_attr = uint16_from_be (xa_attr);
result[ 0] = (xa_attr & XA_ATTR_DIRECTORY) ? 'd' : '-';
result[ 1] = (xa_attr & XA_ATTR_CDDA) ? 'a' : '-';
result[ 2] = (xa_attr & XA_ATTR_INTERLEAVED) ? 'i' : '-';
result[ 3] = (xa_attr & XA_ATTR_MODE2FORM2) ? '2' : '-';
result[ 4] = (xa_attr & XA_ATTR_MODE2FORM1) ? '1' : '-';
result[ 5] = (xa_attr & XA_PERM_XUSR) ? 'x' : '-';
result[ 6] = (xa_attr & XA_PERM_RUSR) ? 'r' : '-';
result[ 7] = (xa_attr & XA_PERM_XGRP) ? 'x' : '-';
result[ 8] = (xa_attr & XA_PERM_RGRP) ? 'r' : '-';
/* Hack alert: wonder if this should be ROTH and XOTH? */
result[ 9] = (xa_attr & XA_PERM_XSYS) ? 'x' : '-';
result[10] = (xa_attr & XA_PERM_RSYS) ? 'r' : '-';
result[11] = '\0';
return result;
}
iso9660_xa_t *
iso9660_xa_init (iso9660_xa_t *_xa, uint16_t uid, uint16_t gid, uint16_t attr,
uint8_t filenum)
{
cdio_assert (_xa != NULL);
_xa->user_id = uint16_to_be (uid);
_xa->group_id = uint16_to_be (gid);
_xa->attributes = uint16_to_be (attr);
_xa->signature[0] = 'X';
_xa->signature[1] = 'A';
_xa->filenum = filenum;
_xa->reserved[0]
= _xa->reserved[1]
= _xa->reserved[2]
= _xa->reserved[3]
= _xa->reserved[4] = 0x00;
return _xa;
}
/*!
Returns POSIX mode bitstring for a given file.
*/
posix_mode_t
iso9660_get_posix_filemode_from_xa(uint16_t i_perms)
{
posix_mode_t mode = 0;
if (i_perms & XA_PERM_RUSR) mode |= S_IRUSR;
if (i_perms & XA_PERM_XUSR) mode |= S_IXUSR;
#ifdef S_IRGRP
if (i_perms & XA_PERM_RGRP) mode |= S_IRGRP;
#endif
#ifdef S_IXGRP
if (i_perms & XA_PERM_XGRP) mode |= S_IXGRP;
#endif
#ifdef S_IROTH
if (i_perms & XA_PERM_ROTH) mode |= S_IROTH;
#endif
#ifdef S_IXOTH
if (i_perms & XA_PERM_XOTH) mode |= S_IXOTH;
#endif
if (i_perms & XA_ATTR_DIRECTORY) mode |= S_IFDIR;
return mode;
}

View File

@ -0,0 +1,57 @@
# Copyright (C) 2003, 2004, 2006, 2008, 2011
# Rocky Bernstein <rocky@gnu.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
########################################################
# Things to make the libudf library
########################################################
#
# From libtool documentation amended with guidance from N. Boullis:
#
# 1. Start with version information of `0:0:0' for each libtool library.
#
# 2. It is probably not a good idea to update the version information
# several times between public releases, but rather once per public
# release. (This seems to be more an aesthetic consideration than
# a hard technical one.)
#
# 3. If the library source code has changed at all since the last
# update, then increment REVISION (`C:R:A' becomes `C:R+1:A').
#
# 4. If any interfaces have been added, removed, or changed since the
# last update, increment CURRENT, and set REVISION to 0.
#
# 5. If any interfaces have been added since the last public release,
# then increment AGE.
#
# 6. If any interfaces have been removed or changed since the last
# public release, then set AGE to 0. A changed interface means an
# incompatibility with previous versions.
libudf_la_CURRENT = 1
libudf_la_REVISION = 0
libudf_la_AGE = 0
EXTRA_DIST = libudf.sym
noinst_HEADERS = udf_fs.h udf_private.h
lib_LTLIBRARIES = libudf.la
libudf_la_SOURCES = udf.c udf_file.c udf_fs.c udf_time.c filemode.c
libudf_la_LIBADD = @LIBCDIO_LIBS@ @LT_NO_UNDEFINED@
INCLUDES = $(LIBCDIO_CFLAGS)

291
src/libcdio/udf/filemode.c Normal file
View File

@ -0,0 +1,291 @@
/*
filemode.c -- make a string describing file modes
Copyright (C) 2005, 2008, 2011 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 1985, 1990, 1993, 1998-2000 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if HAVE_CONFIG_H
# include <config.h>
# define __CDIO_CONFIG_H__ 1
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#include <cdio/udf.h>
#if !S_IRUSR
# if S_IREAD
# define S_IRUSR S_IREAD
# else
# define S_IRUSR 00400
# endif
#endif
#if !S_IWUSR
# if S_IWRITE
# define S_IWUSR S_IWRITE
# else
# define S_IWUSR 00200
# endif
#endif
#if !S_IXUSR
# if S_IEXEC
# define S_IXUSR S_IEXEC
# else
# define S_IXUSR 00100
# endif
#endif
#if !S_IRGRP
# define S_IRGRP (S_IRUSR >> 3)
#endif
#if !S_IWGRP
# define S_IWGRP (S_IWUSR >> 3)
#endif
#if !S_IXGRP
# define S_IXGRP (S_IXUSR >> 3)
#endif
#if !S_IROTH
# define S_IROTH (S_IRUSR >> 6)
#endif
#if !S_IWOTH
# define S_IWOTH (S_IWUSR >> 6)
#endif
#if !S_IXOTH
# define S_IXOTH (S_IXUSR >> 6)
#endif
#ifdef STAT_MACROS_BROKEN
# undef S_ISBLK
# undef S_ISCHR
# undef S_ISDIR
# undef S_ISFIFO
# undef S_ISLNK
# undef S_ISMPB
# undef S_ISMPC
# undef S_ISNWK
# undef S_ISREG
# undef S_ISSOCK
#endif /* STAT_MACROS_BROKEN. */
#if !defined S_ISBLK && defined S_IFBLK
# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
#endif
#if !defined S_ISCHR && defined S_IFCHR
# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#endif
#if !defined S_ISDIR && defined S_IFDIR
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
#if !defined S_ISREG && defined S_IFREG
# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#endif
#if !defined S_ISFIFO && defined S_IFIFO
# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
#endif
#if !defined S_ISLNK && defined S_IFLNK
# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
#endif
#if !defined S_ISSOCK && defined S_IFSOCK
# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
#endif
#if !defined S_ISMPB && defined S_IFMPB /* V7 */
# define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
# define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
#endif
#if !defined S_ISNWK && defined S_IFNWK /* HP/UX */
# define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
#endif
#if !defined S_ISDOOR && defined S_IFDOOR /* Solaris 2.5 and up */
# define S_ISDOOR(m) (((m) & S_IFMT) == S_IFDOOR)
#endif
#if !defined S_ISCTG && defined S_IFCTG /* MassComp */
# define S_ISCTG(m) (((m) & S_IFMT) == S_IFCTG)
#endif
/* Set the 's' and 't' flags in file attributes string CHARS,
according to the file mode BITS. */
static void
setst (mode_t bits, char *chars)
{
#ifdef S_ISUID
if (bits & S_ISUID)
{
if (chars[3] != 'x')
/* Set-uid, but not executable by owner. */
chars[3] = 'S';
else
chars[3] = 's';
}
#endif
#ifdef S_ISGID
if (bits & S_ISGID)
{
if (chars[6] != 'x')
/* Set-gid, but not executable by group. */
chars[6] = 'S';
else
chars[6] = 's';
}
#endif
#ifdef S_ISVTX
if (bits & S_ISVTX)
{
if (chars[9] != 'x')
/* Sticky, but not executable by others. */
chars[9] = 'T';
else
chars[9] = 't';
}
#endif
}
/* Return a character indicating the type of file described by
file mode BITS:
'd' for directories
'D' for doors
'b' for block special files
'c' for character special files
'n' for network special files
'm' for multiplexor files
'M' for an off-line (regular) file
'l' for symbolic links
's' for sockets
'p' for fifos
'C' for contigous data files
'-' for regular files
'?' for any other file type. */
static char
ftypelet (mode_t bits)
{
#ifdef S_ISBLK
if (S_ISBLK (bits))
return 'b';
#endif
if (S_ISCHR (bits))
return 'c';
if (S_ISDIR (bits))
return 'd';
if (S_ISREG (bits))
return '-';
#ifdef S_ISFIFO
if (S_ISFIFO (bits))
return 'p';
#endif
#ifdef S_ISLNK
if (S_ISLNK (bits))
return 'l';
#endif
#ifdef S_ISSOCK
if (S_ISSOCK (bits))
return 's';
#endif
#ifdef S_ISMPC
if (S_ISMPC (bits))
return 'm';
#endif
#ifdef S_ISNWK
if (S_ISNWK (bits))
return 'n';
#endif
#ifdef S_ISDOOR
if (S_ISDOOR (bits))
return 'D';
#endif
#ifdef S_ISCTG
if (S_ISCTG (bits))
return 'C';
#endif
/* The following two tests are for Cray DMF (Data Migration
Facility), which is a HSM file system. A migrated file has a
`st_dm_mode' that is different from the normal `st_mode', so any
tests for migrated files should use the former. */
#ifdef S_ISOFD
if (S_ISOFD (bits))
/* off line, with data */
return 'M';
#endif
#ifdef S_ISOFL
/* off line, with no data */
if (S_ISOFL (bits))
return 'M';
#endif
return '?';
}
/*! udf_mode_string - fill in string STR with an ls-style ASCII
representation of the st_mode field of file stats block STATP.
10 characters are stored in STR; no terminating null is added.
The characters stored in STR are:
0 File type. 'd' for directory, 'c' for character
special, 'b' for block special, 'm' for multiplex,
'l' for symbolic link, 's' for socket, 'p' for fifo,
'-' for regular, '?' for any other file type
1 'r' if the owner may read, '-' otherwise.
2 'w' if the owner may write, '-' otherwise.
3 'x' if the owner may execute, 's' if the file is
set-user-id, '-' otherwise.
'S' if the file is set-user-id, but the execute
bit isn't set.
4 'r' if group members may read, '-' otherwise.
5 'w' if group members may write, '-' otherwise.
6 'x' if group members may execute, 's' if the file is
set-group-id, '-' otherwise.
'S' if it is set-group-id but not executable.
7 'r' if any user may read, '-' otherwise.
8 'w' if any user may write, '-' otherwise.
9 'x' if any user may execute, 't' if the file is "sticky"
(will be retained in swap space after execution), '-'
otherwise.
'T' if the file is sticky but not executable. */
char *
udf_mode_string (mode_t i_mode, char *psz_str)
{
psz_str[ 0] = ftypelet (i_mode);
psz_str[ 1] = i_mode & S_IRUSR ? 'r' : '-';
psz_str[ 2] = i_mode & S_IWUSR ? 'w' : '-';
psz_str[ 3] = i_mode & S_IXUSR ? 'x' : '-';
psz_str[ 4] = i_mode & S_IRGRP ? 'r' : '-';
psz_str[ 5] = i_mode & S_IWGRP ? 'w' : '-';
psz_str[ 6] = i_mode & S_IXGRP ? 'x' : '-';
psz_str[ 7] = i_mode & S_IROTH ? 'r' : '-';
psz_str[ 8] = i_mode & S_IWOTH ? 'w' : '-';
psz_str[ 9] = i_mode & S_IXOTH ? 'x' : '-';
psz_str[10] = '\0';
setst (i_mode, psz_str);
return psz_str;
}

124
src/libcdio/udf/udf.c Normal file
View File

@ -0,0 +1,124 @@
/*
Copyright (C) 2005, 2008, 2010 Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Access routines */
/* udf_private.h has to come first else _FILE_OFFSET_BITS are redefined in
say opensolaris. */
#include "udf_private.h"
#include <cdio/bytesex.h>
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
/** The below variables are trickery to force enum symbol values to be
recorded in debug symbol tables. They are used to allow one to refer
to the enumeration value names in the typedefs above in a debugger
and debugger expressions
*/
tag_id_t debug_tagid;
file_characteristics_t debug_file_characteristics;
icbtag_file_type_enum_t debug_icbtag_file_type_enum;
icbtag_flag_enum_t debug_flag_enum;
ecma_167_enum1_t debug_ecma_167_enum1;
ecma_167_timezone_enum_t debug_ecma_167_timezone_enum;
udf_enum1_t debug_udf_enum1;
/*!
Returns POSIX mode bitstring for a given file.
*/
mode_t
udf_get_posix_filemode(const udf_dirent_t *p_udf_dirent)
{
udf_file_entry_t udf_fe;
mode_t mode = 0;
if (udf_get_file_entry(p_udf_dirent, &udf_fe)) {
uint16_t i_flags;
uint32_t i_perms;
i_perms = uint32_from_le(udf_fe.permissions);
i_flags = uint16_from_le(udf_fe.icb_tag.flags);
if (i_perms & FE_PERM_U_READ) mode |= S_IRUSR;
if (i_perms & FE_PERM_U_WRITE) mode |= S_IWUSR;
if (i_perms & FE_PERM_U_EXEC) mode |= S_IXUSR;
#ifdef S_IRGRP
if (i_perms & FE_PERM_G_READ) mode |= S_IRGRP;
if (i_perms & FE_PERM_G_WRITE) mode |= S_IWGRP;
if (i_perms & FE_PERM_G_EXEC) mode |= S_IXGRP;
#endif
#ifdef S_IROTH
if (i_perms & FE_PERM_O_READ) mode |= S_IROTH;
if (i_perms & FE_PERM_O_WRITE) mode |= S_IWOTH;
if (i_perms & FE_PERM_O_EXEC) mode |= S_IXOTH;
#endif
switch (udf_fe.icb_tag.file_type) {
case ICBTAG_FILE_TYPE_DIRECTORY:
mode |= S_IFDIR;
break;
case ICBTAG_FILE_TYPE_REGULAR:
mode |= S_IFREG;
break;
#ifdef S_IFLNK
case ICBTAG_FILE_TYPE_SYMLINK:
mode |= S_IFLNK;
break;
#endif
case ICBTAG_FILE_TYPE_CHAR:
mode |= S_IFCHR;
break;
#ifdef S_IFSOCK
case ICBTAG_FILE_TYPE_SOCKET:
mode |= S_IFSOCK;
break;
#endif
case ICBTAG_FILE_TYPE_BLOCK:
mode |= S_IFBLK;
break;
default: ;
};
#ifdef S_ISUID
if (i_flags & ICBTAG_FLAG_SETUID) mode |= S_ISUID;
if (i_flags & ICBTAG_FLAG_SETGID) mode |= S_ISGID;
if (i_flags & ICBTAG_FLAG_STICKY) mode |= S_ISVTX;
#endif
}
return mode;
}
/*!
Return the partition number of the the opened udf handle. -1
Is returned if we have an error.
*/
int16_t udf_get_part_number(const udf_t *p_udf)
{
if (!p_udf) return -1;
return p_udf->i_partition;
}

257
src/libcdio/udf/udf_file.c Normal file
View File

@ -0,0 +1,257 @@
/*
Copyright (C) 2005, 2006, 2008, 2010 Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Access routines */
/* udf_private.h has to come first else _FILE_OFFSET_BITS are redefined in
say opensolaris. */
#include "udf_private.h"
#include <cdio/bytesex.h>
#include "udf_fs.h"
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#include <stdio.h> /* Remove when adding cdio/logging.h */
/* Useful defines */
#define MIN(a, b) (a<b) ? (a) : (b)
#define CEILING(x, y) ((x+(y-1))/y)
#define GETICB(offset) \
&p_udf_fe->alloc_descs[offset]
const char *
udf_get_filename(const udf_dirent_t *p_udf_dirent)
{
if (!p_udf_dirent) return NULL;
if (!p_udf_dirent->psz_name) return "..";
return p_udf_dirent->psz_name;
}
/* Get UDF File Entry. However we do NOT get the variable-length extended
attributes. */
bool
udf_get_file_entry(const udf_dirent_t *p_udf_dirent,
/*out*/ udf_file_entry_t *p_udf_fe)
{
if (!p_udf_dirent) return false;
memcpy(p_udf_fe, &p_udf_dirent->fe, sizeof(udf_file_entry_t));
return true;
}
/*!
Return the file id descriptor of the given file.
*/
bool udf_get_fileid_descriptor(const udf_dirent_t *p_udf_dirent,
/*out*/ udf_fileid_desc_t *p_udf_fid)
{
if (!p_udf_dirent) return false;
if (!p_udf_dirent->fid) {
/* FIXME do something about trying to get the descriptor. */
return false;
}
memcpy(p_udf_fid, p_udf_dirent->fid, sizeof(udf_fileid_desc_t));
return true;
}
/*!
Return the number of hard links of the file. Return 0 if error.
*/
uint16_t udf_get_link_count(const udf_dirent_t *p_udf_dirent)
{
if (p_udf_dirent) {
return uint16_from_le(p_udf_dirent->fe.link_count);
}
return 0; /* Error. Non-error case handled above. */
}
/*!
Return the file length the file. Return 2147483647L if error.
*/
uint64_t udf_get_file_length(const udf_dirent_t *p_udf_dirent)
{
if (p_udf_dirent) {
return uint64_from_le(p_udf_dirent->fe.info_len);
}
return 2147483647L; /* Error. Non-error case handled above. */
}
/*!
Return true if the file is a directory.
*/
bool
udf_is_dir(const udf_dirent_t *p_udf_dirent)
{
return p_udf_dirent->b_dir;
}
/*
* Translate a file offset into a logical block and then into a physical
* block.
*/
static lba_t
offset_to_lba(const udf_dirent_t *p_udf_dirent, off_t i_offset,
/*out*/ lba_t *pi_lba, /*out*/ uint32_t *pi_max_size)
{
udf_t *p_udf = p_udf_dirent->p_udf;
const udf_file_entry_t *p_udf_fe = (udf_file_entry_t *)
&p_udf_dirent->fe;
const udf_icbtag_t *p_icb_tag = &p_udf_fe->icb_tag;
const uint16_t strat_type= uint16_from_le(p_icb_tag->strat_type);
switch (strat_type) {
case 4096:
printf("Cannot deal with strategy4096 yet!\n");
return CDIO_INVALID_LBA;
break;
case ICBTAG_STRATEGY_TYPE_4:
{
uint32_t icblen = 0;
lba_t lsector;
int ad_offset, ad_num = 0;
uint16_t addr_ilk = uint16_from_le(p_icb_tag->flags&ICBTAG_FLAG_AD_MASK);
switch (addr_ilk) {
case ICBTAG_FLAG_AD_SHORT:
{
udf_short_ad_t *p_icb;
/*
* The allocation descriptor field is filled with short_ad's.
* If the offset is beyond the current extent, look for the
* next extent.
*/
do {
i_offset -= icblen;
ad_offset = sizeof(udf_short_ad_t) * ad_num;
if (ad_offset > uint32_from_le(p_udf_fe->i_alloc_descs)) {
printf("File offset out of bounds\n");
return CDIO_INVALID_LBA;
}
p_icb = (udf_short_ad_t *)
GETICB( uint32_from_le(p_udf_fe->i_extended_attr)
+ ad_offset );
icblen = p_icb->len;
ad_num++;
} while(i_offset >= icblen);
lsector = (i_offset / UDF_BLOCKSIZE) + p_icb->pos;
*pi_max_size = p_icb->len;
}
break;
case ICBTAG_FLAG_AD_LONG:
{
/*
* The allocation descriptor field is filled with long_ad's
* If the i_offset is beyond the current extent, look for the
* next extent.
*/
udf_long_ad_t *p_icb;
do {
i_offset -= icblen;
ad_offset = sizeof(udf_long_ad_t) * ad_num;
if (ad_offset > uint32_from_le(p_udf_fe->i_alloc_descs)) {
printf("File offset out of bounds\n");
return CDIO_INVALID_LBA;
}
p_icb = (udf_long_ad_t *)
GETICB( uint32_from_le(p_udf_fe->i_extended_attr)
+ ad_offset );
icblen = p_icb->len;
ad_num++;
} while(i_offset >= icblen);
lsector = (i_offset / UDF_BLOCKSIZE) +
uint32_from_le(((udf_long_ad_t *)(p_icb))->loc.lba);
*pi_max_size = p_icb->len;
}
break;
case ICBTAG_FLAG_AD_IN_ICB:
/*
* This type means that the file *data* is stored in the
* allocation descriptor field of the file entry.
*/
*pi_max_size = 0;
printf("Don't know how to data in ICB handle yet\n");
return CDIO_INVALID_LBA;
case ICBTAG_FLAG_AD_EXTENDED:
printf("Don't know how to handle extended addresses yet\n");
return CDIO_INVALID_LBA;
default:
printf("Unsupported allocation descriptor %d\n", addr_ilk);
return CDIO_INVALID_LBA;
}
*pi_lba = lsector + p_udf->i_part_start;
return *pi_lba;
}
default:
printf("Unknown strategy type %d\n", strat_type);
return DRIVER_OP_ERROR;
}
}
/**
Attempts to read up to count bytes from UDF directory entry
p_udf_dirent into the buffer starting at buf. buf should be a
multiple of UDF_BLOCKSIZE bytes. Reading continues after the point
at which we last read or from the beginning the first time.
If count is zero, read() returns zero and has no other results. If
count is greater than SSIZE_MAX, the result is unspecified.
It is the caller's responsibility to ensure that count is less
than the number of blocks recorded via p_udf_dirent.
If there is an error, cast the result to driver_return_code_t for
the specific error code.
*/
ssize_t
udf_read_block(const udf_dirent_t *p_udf_dirent, void * buf, size_t count)
{
if (count == 0) return 0;
else {
driver_return_code_t ret;
uint32_t i_max_size=0;
udf_t *p_udf = p_udf_dirent->p_udf;
lba_t i_lba = offset_to_lba(p_udf_dirent, p_udf->i_position, &i_lba,
&i_max_size);
if (i_lba != CDIO_INVALID_LBA) {
uint32_t i_max_blocks = CEILING(i_max_size, UDF_BLOCKSIZE);
if ( i_max_blocks < count ) {
fprintf(stderr, "Warning: read count %u is larger than %u extent size.\n",
count, i_max_blocks);
fprintf(stderr, "Warning: read count truncated to %u\n", count);
count = i_max_blocks;
}
ret = udf_read_sectors(p_udf, buf, i_lba, count);
if (DRIVER_OP_SUCCESS == ret) {
ssize_t i_read_len = MIN(i_max_size, count * UDF_BLOCKSIZE);
p_udf->i_position += i_read_len;
return i_read_len;
}
return ret;
} else {
return DRIVER_OP_ERROR;
}
}
}

694
src/libcdio/udf/udf_fs.c Normal file
View File

@ -0,0 +1,694 @@
/*
Copyright (C) 2005, 2006, 2008, 2011 Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Portions copyright (c) 2001, 2002 Scott Long <scottl@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
# define __CDIO_CONFIG_H__ 1
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
/* These definitions are also to make debugging easy. Note that they
have to come *before* #include <cdio/ecma_167.h> which sets
#defines for these.
*/
const char VSD_STD_ID_BEA01[] = {'B', 'E', 'A', '0', '1'};
const char VSD_STD_ID_BOOT2[] = {'B', 'O', 'O', 'T', '2'};
const char VSD_STD_ID_CD001[] = {'C', 'D', '0', '0', '1'};
const char VSD_STD_ID_CDW01[] = {'C', 'D', 'W', '0', '2'};
const char VSD_STD_ID_NSR03[] = {'N', 'S', 'R', '0', '3'};
const char VSD_STD_ID_TEA01[] = {'T', 'E', 'A', '0', '1'};
#include <cdio/bytesex.h>
#include "udf_private.h"
#include "udf_fs.h"
/*
* The UDF specs are pretty clear on how each data structure is made
* up, but not very clear on how they relate to each other. Here is
* the skinny... This demostrates a filesystem with one file in the
* root directory. Subdirectories are treated just as normal files,
* but they have File Id Descriptors of their children as their file
* data. As for the Anchor Volume Descriptor Pointer, it can exist in
* two of the following three places: sector 256, sector n (the max
* sector of the disk), or sector n - 256. It's a pretty good bet
* that one will exist at sector 256 though. One caveat is unclosed
* CD media. For that, sector 256 cannot be written, so the Anchor
* Volume Descriptor Pointer can exist at sector 512 until the media
* is closed.
*
* Sector:
* 256:
* n: Anchor Volume Descriptor Pointer
* n - 256: |
* |
* |-->Main Volume Descriptor Sequence
* | |
* | |
* | |-->Logical Volume Descriptor
* | |
* |-->Partition Descriptor |
* | |
* | |
* |-->Fileset Descriptor
* |
* |
* |-->Root Dir File Entry
* |
* |
* |-->File data:
* File Id Descriptor
* |
* |
* |-->File Entry
* |
* |
* |-->File data
*/
static udf_dirent_t *
udf_new_dirent(udf_file_entry_t *p_udf_fe, udf_t *p_udf,
const char *psz_name, bool b_dir, bool b_parent);
/**
* Check the descriptor tag for both the correct id and correct checksum.
* Return zero if all is good, -1 if not.
*/
int
udf_checktag(const udf_tag_t *p_tag, udf_Uint16_t tag_id)
{
uint8_t *itag;
uint8_t i;
uint8_t cksum = 0;
itag = (uint8_t *)p_tag;
if (p_tag->id != tag_id)
return -1;
for (i = 0; i < 15; i++)
cksum = cksum + itag[i];
cksum = cksum - itag[4];
if (cksum == p_tag->cksum)
return 0;
return -1;
}
bool
udf_get_lba(const udf_file_entry_t *p_udf_fe,
/*out*/ uint32_t *start, /*out*/ uint32_t *end)
{
if (! p_udf_fe->i_alloc_descs)
return false;
switch (p_udf_fe->icb_tag.flags & ICBTAG_FLAG_AD_MASK) {
case ICBTAG_FLAG_AD_SHORT:
{
/* The allocation descriptor field is filled with short_ad's. */
udf_short_ad_t *p_ad = (udf_short_ad_t *)
(p_udf_fe->ext_attr + p_udf_fe->i_extended_attr);
*start = uint32_from_le(p_ad->pos);
*end = *start +
((uint32_from_le(p_ad->len) & UDF_LENGTH_MASK) - 1) / UDF_BLOCKSIZE;
return true;
}
break;
case ICBTAG_FLAG_AD_LONG:
{
/* The allocation descriptor field is filled with long_ad's */
udf_long_ad_t *p_ad = (udf_long_ad_t *)
(p_udf_fe->ext_attr + p_udf_fe->i_extended_attr);
*start = uint32_from_le(p_ad->loc.lba); /* ignore partition number */
*end = *start +
((uint32_from_le(p_ad->len) & UDF_LENGTH_MASK) - 1) / UDF_BLOCKSIZE;
return true;
}
break;
case ICBTAG_FLAG_AD_EXTENDED:
{
udf_ext_ad_t *p_ad = (udf_ext_ad_t *)
(p_udf_fe->ext_attr + p_udf_fe->i_extended_attr);
*start = uint32_from_le(p_ad->ext_loc.lba); /* ignore partition number */
*end = *start +
((uint32_from_le(p_ad->len) & UDF_LENGTH_MASK) - 1) / UDF_BLOCKSIZE;
return true;
}
break;
default:
return false;
}
return false;
}
#define udf_PATH_DELIMITERS "/\\"
/* Searches p_udf_dirent a directory entry called psz_token.
Note p_udf_dirent is continuously updated. If the entry is
not found p_udf_dirent is useless and thus the caller should
not use it afterwards.
*/
static
udf_dirent_t *
udf_ff_traverse(udf_dirent_t *p_udf_dirent, char *psz_token)
{
while (udf_readdir(p_udf_dirent)) {
if (strcmp(psz_token, p_udf_dirent->psz_name) == 0) {
char *next_tok = strtok(NULL, udf_PATH_DELIMITERS);
if (!next_tok)
return p_udf_dirent; /* found */
else if (p_udf_dirent->b_dir) {
udf_dirent_t * p_udf_dirent2 = udf_opendir(p_udf_dirent);
if (p_udf_dirent2) {
udf_dirent_t * p_udf_dirent3 =
udf_ff_traverse(p_udf_dirent2, next_tok);
/* if p_udf_dirent3 is null p_udf_dirent2 is free'd. */
return p_udf_dirent3;
}
}
}
}
free(p_udf_dirent->psz_name);
return NULL;
}
/* FIXME! */
#define udf_MAX_PATHLEN 2048
udf_dirent_t *
udf_fopen(udf_dirent_t *p_udf_root, const char *psz_name)
{
udf_dirent_t *p_udf_file = NULL;
if (p_udf_root) {
char tokenline[udf_MAX_PATHLEN];
char *psz_token;
strncpy(tokenline, psz_name, udf_MAX_PATHLEN);
psz_token = strtok(tokenline, udf_PATH_DELIMITERS);
if (psz_token) {
/*** FIXME??? udf_dirent can be variable size due to the
extended attributes and descriptors. Given that, is this
correct?
*/
udf_dirent_t *p_udf_dirent =
udf_new_dirent(&p_udf_root->fe, p_udf_root->p_udf,
p_udf_root->psz_name, p_udf_root->b_dir,
p_udf_root->b_parent);
p_udf_file = udf_ff_traverse(p_udf_dirent, psz_token);
udf_dirent_free(p_udf_dirent);
}
else if ( 0 == strncmp("/", psz_name, sizeof("/")) ) {
return udf_new_dirent(&p_udf_root->fe, p_udf_root->p_udf,
p_udf_root->psz_name, p_udf_root->b_dir,
p_udf_root->b_parent);
}
}
return p_udf_file;
}
/* Convert unicode16 to 8-bit char by dripping MSB.
Wonder if iconv can be used here
*/
static int
unicode16_decode( const uint8_t *data, int i_len, char *target )
{
int p = 1, i = 0;
if( ( data[ 0 ] == 8 ) || ( data[ 0 ] == 16 ) ) do {
if( data[ 0 ] == 16 ) p++; /* Ignore MSB of unicode16 */
if( p < i_len ) {
target[ i++ ] = data[ p++ ];
}
} while( p < i_len );
target[ i ] = '\0';
return 0;
}
static udf_dirent_t *
udf_new_dirent(udf_file_entry_t *p_udf_fe, udf_t *p_udf,
const char *psz_name, bool b_dir, bool b_parent)
{
const unsigned int i_alloc_size = p_udf_fe->i_alloc_descs
+ p_udf_fe->i_extended_attr;
udf_dirent_t *p_udf_dirent = (udf_dirent_t *)
calloc(1, sizeof(udf_dirent_t) + i_alloc_size);
if (!p_udf_dirent) return NULL;
p_udf_dirent->psz_name = strdup(psz_name);
p_udf_dirent->b_dir = b_dir;
p_udf_dirent->b_parent = b_parent;
p_udf_dirent->p_udf = p_udf;
p_udf_dirent->i_part_start = p_udf->i_part_start;
p_udf_dirent->dir_left = uint64_from_le(p_udf_fe->info_len);
memcpy(&(p_udf_dirent->fe), p_udf_fe,
sizeof(udf_file_entry_t) + i_alloc_size);
udf_get_lba( p_udf_fe, &(p_udf_dirent->i_loc),
&(p_udf_dirent->i_loc_end) );
return p_udf_dirent;
}
/*!
Seek to a position i_start and then read i_blocks. Number of blocks read is
returned. One normally expects the return to be equal to i_blocks.
*/
driver_return_code_t
udf_read_sectors (const udf_t *p_udf, void *ptr, lsn_t i_start,
long int i_blocks)
{
driver_return_code_t ret;
long int i_read;
long int i_byte_offset;
if (!p_udf) return 0;
i_byte_offset = (i_start * UDF_BLOCKSIZE);
if (p_udf->b_stream) {
ret = cdio_stream_seek (p_udf->stream, i_byte_offset, SEEK_SET);
if (DRIVER_OP_SUCCESS != ret) return ret;
i_read = cdio_stream_read (p_udf->stream, ptr, UDF_BLOCKSIZE, i_blocks);
if (i_read) return DRIVER_OP_SUCCESS;
return DRIVER_OP_ERROR;
} else {
return cdio_read_data_sectors(p_udf->cdio, ptr, i_start, UDF_BLOCKSIZE,
i_blocks);
}
}
/*!
Open an UDF for reading. Maybe in the future we will have
a mode. NULL is returned on error.
Caller must free result - use udf_close for that.
*/
udf_t *
udf_open (const char *psz_path)
{
udf_t *p_udf = (udf_t *) calloc(1, sizeof(udf_t)) ;
uint8_t data[UDF_BLOCKSIZE];
if (!p_udf) return NULL;
p_udf->cdio = cdio_open(psz_path, DRIVER_UNKNOWN);
if (!p_udf->cdio) {
/* Not a CD-ROM drive or CD Image. Maybe it's a UDF file not
encapsulated as a CD-ROM Image (e.g. often .UDF or (sic) .ISO)
*/
p_udf->stream = cdio_stdio_new( psz_path );
if (!p_udf->stream)
goto error;
p_udf->b_stream = true;
}
/*
* Look for an Anchor Volume Descriptor Pointer at sector 256.
*/
if (DRIVER_OP_SUCCESS != udf_read_sectors (p_udf, &data, 256, 1) )
goto error;
memcpy(&(p_udf->anchor_vol_desc_ptr), &data, sizeof(anchor_vol_desc_ptr_t));
if (udf_checktag((udf_tag_t *)&(p_udf->anchor_vol_desc_ptr), TAGID_ANCHOR))
goto error;
/*
* Then try to find a reference to a Primary Volume Descriptor.
*/
{
const anchor_vol_desc_ptr_t *p_avdp = &p_udf->anchor_vol_desc_ptr;
const uint32_t mvds_start =
uint32_from_le(p_avdp->main_vol_desc_seq_ext.loc);
const uint32_t mvds_end = mvds_start +
(uint32_from_le(p_avdp->main_vol_desc_seq_ext.len) - 1) / UDF_BLOCKSIZE;
uint32_t i_lba;
for (i_lba = mvds_start; i_lba < mvds_end; i_lba++) {
udf_pvd_t *p_pvd = (udf_pvd_t *) &data;
if (DRIVER_OP_SUCCESS != udf_read_sectors (p_udf, p_pvd, i_lba, 1) )
goto error;
if (!udf_checktag(&p_pvd->tag, TAGID_PRI_VOL)) {
p_udf->pvd_lba = i_lba;
break;
}
}
/*
* If we couldn't find a reference, bail out.
*/
if (i_lba == mvds_end)
goto error;
}
return p_udf;
error:
free(p_udf);
return NULL;
}
/**
* Gets the Volume Identifier string, in 8bit unicode (latin-1)
* psz_volid, place to put the string
* i_volid_size, size of the buffer volid points to
* returns the size of buffer needed for all data
*/
int
udf_get_volume_id(udf_t *p_udf, /*out*/ char *psz_volid, unsigned int i_volid)
{
uint8_t data[UDF_BLOCKSIZE];
const udf_pvd_t *p_pvd = (udf_pvd_t *) &data;
unsigned int volid_len;
/* get primary volume descriptor */
if ( DRIVER_OP_SUCCESS != udf_read_sectors(p_udf, &data, p_udf->pvd_lba, 1) )
return 0;
volid_len = p_pvd->vol_ident[UDF_VOLID_SIZE-1];
if(volid_len > UDF_VOLID_SIZE-1) {
/* this field is only UDF_VOLID_SIZE bytes something is wrong */
volid_len = UDF_VOLID_SIZE-1;
}
if(i_volid > volid_len) {
i_volid = volid_len;
}
unicode16_decode((uint8_t *) p_pvd->vol_ident, i_volid, psz_volid);
return volid_len;
}
/**
* Gets the Volume Set Identifier, as a 128-byte dstring (not decoded)
* WARNING This is not a null terminated string
* volsetid, place to put the data
* volsetid_size, size of the buffer volsetid points to
* the buffer should be >=128 bytes to store the whole volumesetidentifier
* returns the size of the available volsetid information (128)
* or 0 on error
*/
int
udf_get_volumeset_id(udf_t *p_udf, /*out*/ uint8_t *volsetid,
unsigned int i_volsetid)
{
uint8_t data[UDF_BLOCKSIZE];
const udf_pvd_t *p_pvd = (udf_pvd_t *) &data;
/* get primary volume descriptor */
if ( DRIVER_OP_SUCCESS != udf_read_sectors(p_udf, &data, p_udf->pvd_lba, 1) )
return 0;
if (i_volsetid > UDF_VOLSET_ID_SIZE) {
i_volsetid = UDF_VOLSET_ID_SIZE;
}
memcpy(volsetid, p_pvd->volset_id, i_volsetid);
return UDF_VOLSET_ID_SIZE;
}
/*!
Get the root in p_udf. If b_any_partition is false then
the root must be in the given partition.
NULL is returned if the partition is not found or a root is not found or
there is on error.
Caller must free result - use udf_file_free for that.
*/
udf_dirent_t *
udf_get_root (udf_t *p_udf, bool b_any_partition, partition_num_t i_partition)
{
const anchor_vol_desc_ptr_t *p_avdp = &p_udf->anchor_vol_desc_ptr;
const uint32_t mvds_start =
uint32_from_le(p_avdp->main_vol_desc_seq_ext.loc);
const uint32_t mvds_end = mvds_start +
(uint32_from_le(p_avdp->main_vol_desc_seq_ext.len) - 1) / UDF_BLOCKSIZE;
uint32_t i_lba;
uint8_t data[UDF_BLOCKSIZE];
/*
Now we have the joy of finding the Partition Descriptor and the
Logical Volume Descriptor for the Main Volume Descriptor
Sequence. Once we've got that, we use the Logical Volume
Descriptor to get a Fileset Descriptor and that has the Root
Directory File Entry.
*/
for (i_lba = mvds_start; i_lba < mvds_end; i_lba++) {
uint8_t data[UDF_BLOCKSIZE];
partition_desc_t *p_partition = (partition_desc_t *) &data;
if (DRIVER_OP_SUCCESS != udf_read_sectors (p_udf, p_partition, i_lba, 1) )
return NULL;
if (!udf_checktag(&p_partition->tag, TAGID_PARTITION)) {
const partition_num_t i_partition_check
= uint16_from_le(p_partition->number);
if (b_any_partition || i_partition_check == i_partition) {
/* Squirrel away some data regarding partition */
p_udf->i_partition = uint16_from_le(p_partition->number);
p_udf->i_part_start = uint32_from_le(p_partition->start_loc);
if (p_udf->lvd_lba) break;
}
} else if (!udf_checktag(&p_partition->tag, TAGID_LOGVOL)) {
/* Get fileset descriptor */
logical_vol_desc_t *p_logvol = (logical_vol_desc_t *) &data;
bool b_valid =
UDF_BLOCKSIZE == uint32_from_le(p_logvol->logical_blocksize);
if (b_valid) {
p_udf->lvd_lba = i_lba;
p_udf->fsd_offset =
uint32_from_le(p_logvol->lvd_use.fsd_loc.loc.lba);
if (p_udf->i_part_start) break;
}
}
}
if (p_udf->lvd_lba && p_udf->i_part_start) {
udf_fsd_t *p_fsd = (udf_fsd_t *) &data;
driver_return_code_t ret =
udf_read_sectors(p_udf, p_fsd, p_udf->i_part_start + p_udf->fsd_offset,
1);
if (DRIVER_OP_SUCCESS == ret && !udf_checktag(&p_fsd->tag, TAGID_FSD)) {
udf_file_entry_t *p_udf_fe = (udf_file_entry_t *) &data;
const uint32_t parent_icb = uint32_from_le(p_fsd->root_icb.loc.lba);
/* Check partition numbers match of last-read block? */
ret = udf_read_sectors(p_udf, p_udf_fe,
p_udf->i_part_start + parent_icb, 1);
if (ret == DRIVER_OP_SUCCESS &&
!udf_checktag(&p_udf_fe->tag, TAGID_FILE_ENTRY)) {
/* Check partition numbers match of last-read block? */
/* We win! - Save root directory information. */
return udf_new_dirent(p_udf_fe, p_udf, "/", true, false );
}
}
}
return NULL;
}
#define free_and_null(x) \
free(x); \
x=NULL
/*!
Close UDF and free resources associated with p_udf.
*/
bool
udf_close (udf_t *p_udf)
{
if (!p_udf) return true;
if (p_udf->b_stream) {
cdio_stdio_destroy(p_udf->stream);
} else {
cdio_destroy(p_udf->cdio);
}
/* Get rid of root directory if allocated. */
free_and_null(p_udf);
return true;
}
udf_dirent_t *
udf_opendir(const udf_dirent_t *p_udf_dirent)
{
if (p_udf_dirent->b_dir && !p_udf_dirent->b_parent && p_udf_dirent->fid) {
udf_t *p_udf = p_udf_dirent->p_udf;
uint8_t data[UDF_BLOCKSIZE];
udf_file_entry_t *p_udf_fe = (udf_file_entry_t *) &data;
driver_return_code_t i_ret =
udf_read_sectors(p_udf, p_udf_fe, p_udf->i_part_start
+ p_udf_dirent->fid->icb.loc.lba, 1);
if (DRIVER_OP_SUCCESS == i_ret
&& !udf_checktag(&p_udf_fe->tag, TAGID_FILE_ENTRY)) {
if (ICBTAG_FILE_TYPE_DIRECTORY == p_udf_fe->icb_tag.file_type) {
udf_dirent_t *p_udf_dirent_new =
udf_new_dirent(p_udf_fe, p_udf, p_udf_dirent->psz_name, true, true);
return p_udf_dirent_new;
}
}
}
return NULL;
}
udf_dirent_t *
udf_readdir(udf_dirent_t *p_udf_dirent)
{
udf_t *p_udf;
if (p_udf_dirent->dir_left <= 0) {
udf_dirent_free(p_udf_dirent);
return NULL;
}
p_udf = p_udf_dirent->p_udf;
if (p_udf_dirent->fid) {
/* advance to next File Identifier Descriptor */
/* FIXME: need to advance file entry (fe) as well. */
uint32_t ofs = 4 *
((sizeof(*(p_udf_dirent->fid)) + p_udf_dirent->fid->i_imp_use
+ p_udf_dirent->fid->i_file_id + 3) / 4);
p_udf_dirent->fid =
(udf_fileid_desc_t *)((uint8_t *)p_udf_dirent->fid + ofs);
}
if (!p_udf_dirent->fid) {
uint32_t i_sectors =
(p_udf_dirent->i_loc_end - p_udf_dirent->i_loc + 1);
uint32_t size = UDF_BLOCKSIZE * i_sectors;
driver_return_code_t i_ret;
if (!p_udf_dirent->sector)
p_udf_dirent->sector = (uint8_t*) malloc(size);
i_ret = udf_read_sectors(p_udf, p_udf_dirent->sector,
p_udf_dirent->i_part_start+p_udf_dirent->i_loc,
i_sectors);
if (DRIVER_OP_SUCCESS == i_ret)
p_udf_dirent->fid = (udf_fileid_desc_t *) p_udf_dirent->sector;
else
p_udf_dirent->fid = NULL;
}
if (p_udf_dirent->fid && !udf_checktag(&(p_udf_dirent->fid->tag), TAGID_FID))
{
uint32_t ofs =
4 * ((sizeof(*p_udf_dirent->fid) + p_udf_dirent->fid->i_imp_use
+ p_udf_dirent->fid->i_file_id + 3) / 4);
p_udf_dirent->dir_left -= ofs;
p_udf_dirent->b_dir =
(p_udf_dirent->fid->file_characteristics & UDF_FILE_DIRECTORY) != 0;
p_udf_dirent->b_parent =
(p_udf_dirent->fid->file_characteristics & UDF_FILE_PARENT) != 0;
{
const unsigned int i_len = p_udf_dirent->fid->i_file_id;
uint8_t data[UDF_BLOCKSIZE] = {0};
udf_file_entry_t *p_udf_fe = (udf_file_entry_t *) &data;
if (DRIVER_OP_SUCCESS != udf_read_sectors(p_udf, p_udf_fe, p_udf->i_part_start
+ p_udf_dirent->fid->icb.loc.lba, 1))
return NULL;
memcpy(&(p_udf_dirent->fe), p_udf_fe,
sizeof(udf_file_entry_t) + p_udf_fe->i_alloc_descs
+ p_udf_fe->i_extended_attr );
if (strlen(p_udf_dirent->psz_name) < i_len)
p_udf_dirent->psz_name = (char *)
realloc(p_udf_dirent->psz_name, sizeof(char)*i_len+1);
unicode16_decode(p_udf_dirent->fid->imp_use
+ p_udf_dirent->fid->i_imp_use,
i_len, p_udf_dirent->psz_name);
}
return p_udf_dirent;
}
return NULL;
}
/*!
free free resources associated with p_udf_dirent.
*/
bool
udf_dirent_free(udf_dirent_t *p_udf_dirent)
{
if (p_udf_dirent) {
p_udf_dirent->fid = NULL;
free_and_null(p_udf_dirent->psz_name);
free_and_null(p_udf_dirent->sector);
free_and_null(p_udf_dirent);
}
return true;
}

39
src/libcdio/udf/udf_fs.h Normal file
View File

@ -0,0 +1,39 @@
/*
$Id: udf_fs.h,v 1.3 2008/04/18 16:02:10 karl Exp $
Copyright (C) 2006, 2008 Rocky Bernstein <rockyb@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CDIO_UDF_FS_H__
#define __CDIO_UDF_FS_H__
#include <cdio/ecma_167.h>
/**
* Check the descriptor tag for both the correct id and correct checksum.
* Return zero if all is good, -1 if not.
*/
int udf_checktag(const udf_tag_t *p_tag, udf_Uint16_t tag_id);
#endif /* __CDIO_UDF_FS_H__ */
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

View File

@ -0,0 +1,56 @@
/*
Copyright (C) 2005, 2006, 2008, 2011 Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CDIO_UDF_PRIVATE_H__
#define __CDIO_UDF_PRIVATE_H__
#if defined(HAVE_CONFIG_H) && !defined(LIBCDIO_CONFIG_H) && !defined(__CDIO_CONFIG_H__)
# include "config.h"
# define __CDIO_CONFIG_H__ 1
#endif
#include <cdio/types.h>
#include <cdio/ecma_167.h>
#include <cdio/udf.h>
#include "_cdio_stdio.h"
/* Implementation of opaque types */
struct udf_s {
bool b_stream; /* Use stream pointer, else use
p_cdio. */
ssize_t i_position; /* Position in file if positive. */
CdioDataSource_t *stream; /* Stream pointer if stream */
CdIo_t *cdio; /* Cdio pointer if read device */
anchor_vol_desc_ptr_t anchor_vol_desc_ptr;
uint32_t pvd_lba; /* sector of Primary Volume Descriptor */
partition_num_t i_partition; /* partition number */
uint32_t i_part_start; /* start of Partition Descriptor */
uint32_t lvd_lba; /* sector of Logical Volume Descriptor */
uint32_t fsd_offset; /* lba of fileset descriptor */
};
#endif /* __CDIO_UDF_PRIVATE_H__ */
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/

254
src/libcdio/udf/udf_time.c Normal file
View File

@ -0,0 +1,254 @@
/*
Copyright (C) 2005, 2008, 2011 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
Modified From part of the GNU C Library.
Contributed by Paul Eggert.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Some history from the GNU/Linux kernel from which this is also taken...
dgb 10/02/98: ripped this from glibc source to help convert
timestamps to unix time
10/04/98: added new table-based lookup after seeing how ugly the
gnu code is
blf 09/27/99: ripped out all the old code and inserted new table from
John Brockmeyer (without leap second corrections)
rewrote udf_stamp_to_time and fixed timezone
accounting in udf_timespec_to_stamp.
*/
/*
* We don't take into account leap seconds. This may be correct or incorrect.
* For more NIST information (especially dealing with leap seconds), see:
* http://www.boulder.nist.gov/timefreq/pubs/bulletin/leapsecond.htm
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
# define __CDIO_CONFIG_H__ 1
#endif
#ifdef NEED_TIMEZONEVAR
#define timezonevar 1
#endif
#include "udf_private.h"
#include <cdio/udf.h>
/**
Imagine the below enum values as #define'd or constant values
rather than distinct values of an enum.
*/
enum {
HOURS_PER_DAY = 24,
SECS_PER_MINUTE = 60,
MAX_YEAR_SECONDS = 69,
DAYS_PER_YEAR = 365, /* That is, in most of the years. */
EPOCH_YEAR = 1970,
SECS_PER_HOUR = (60 * SECS_PER_MINUTE),
SECS_PER_DAY = SECS_PER_HOUR * HOURS_PER_DAY
} debug_udf_time_enum;
#ifndef __isleap
/* Nonzero if YEAR is a leap year (every 4 years,
except every 100th isn't, and every 400th is). */
#define __isleap(year) \
((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
#endif
/* How many days come before each month (0-12). */
static const unsigned short int __mon_yday[2][13] =
{
/* Normal years. */
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, DAYS_PER_YEAR },
/* Leap years. */
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, DAYS_PER_YEAR+1 }
};
#define SPY(y,l,s) (SECS_PER_DAY * (DAYS_PER_YEAR*y+l)+s) /* Seconds per year */
static time_t year_seconds[MAX_YEAR_SECONDS]= {
/*1970*/ SPY( 0, 0,0), SPY( 1, 0,0), SPY( 2, 0,0), SPY( 3, 1,0),
/*1974*/ SPY( 4, 1,0), SPY( 5, 1,0), SPY( 6, 1,0), SPY( 7, 2,0),
/*1978*/ SPY( 8, 2,0), SPY( 9, 2,0), SPY(10, 2,0), SPY(11, 3,0),
/*1982*/ SPY(12, 3,0), SPY(13, 3,0), SPY(14, 3,0), SPY(15, 4,0),
/*1986*/ SPY(16, 4,0), SPY(17, 4,0), SPY(18, 4,0), SPY(19, 5,0),
/*1990*/ SPY(20, 5,0), SPY(21, 5,0), SPY(22, 5,0), SPY(23, 6,0),
/*1994*/ SPY(24, 6,0), SPY(25, 6,0), SPY(26, 6,0), SPY(27, 7,0),
/*1998*/ SPY(28, 7,0), SPY(29, 7,0), SPY(30, 7,0), SPY(31, 8,0),
/*2002*/ SPY(32, 8,0), SPY(33, 8,0), SPY(34, 8,0), SPY(35, 9,0),
/*2006*/ SPY(36, 9,0), SPY(37, 9,0), SPY(38, 9,0), SPY(39,10,0),
/*2010*/ SPY(40,10,0), SPY(41,10,0), SPY(42,10,0), SPY(43,11,0),
/*2014*/ SPY(44,11,0), SPY(45,11,0), SPY(46,11,0), SPY(47,12,0),
/*2018*/ SPY(48,12,0), SPY(49,12,0), SPY(50,12,0), SPY(51,13,0),
/*2022*/ SPY(52,13,0), SPY(53,13,0), SPY(54,13,0), SPY(55,14,0),
/*2026*/ SPY(56,14,0), SPY(57,14,0), SPY(58,14,0), SPY(59,15,0),
/*2030*/ SPY(60,15,0), SPY(61,15,0), SPY(62,15,0), SPY(63,16,0),
/*2034*/ SPY(64,16,0), SPY(65,16,0), SPY(66,16,0), SPY(67,17,0),
/*2038*/ SPY(68,17,0)
};
#ifdef HAVE_TIMEZONE_VAR
extern long timezone;
#endif
time_t *
udf_stamp_to_time(time_t *dest, long int *dest_usec,
const udf_timestamp_t src)
{
int yday;
uint8_t type = src.type_tz >> 12;
int16_t offset;
if (type == 1) {
offset = src.type_tz << 4;
/* sign extent offset */
offset = (offset >> 4);
if (offset == -2047) /* unspecified offset */
offset = 0;
}
else
offset = 0;
if ((src.year < EPOCH_YEAR) ||
(src.year >= EPOCH_YEAR+MAX_YEAR_SECONDS))
{
*dest = -1;
*dest_usec = -1;
return NULL;
}
*dest = year_seconds[src.year - EPOCH_YEAR];
*dest -= offset * SECS_PER_MINUTE;
yday = ((__mon_yday[__isleap (src.year)]
[src.month-1]) + (src.day-1));
*dest += src.second +
( SECS_PER_MINUTE *
( ( (yday* HOURS_PER_DAY) + src.hour ) * 60 + src.minute ) );
*dest_usec = src.microseconds
+ (src.centiseconds * 10000)
+ (src.hundreds_of_microseconds * 100);
return dest;
}
#ifdef HAVE_STRUCT_TIMESPEC
/*!
Convert a UDF timestamp to a time_t. If microseconds are desired,
use dest_usec. The return value is the same as dest. */
udf_timestamp_t *
udf_timespec_to_stamp(const struct timespec ts, udf_timestamp_t *dest)
{
long int days, rem, y;
const unsigned short int *ip;
int16_t offset = 0;
int16_t tv_sec;
#ifdef HAVE_TIMEZONE_VAR
offset = -timezone;
#endif
if (!dest)
return dest;
dest->type_tz = 0x1000 | (offset & 0x0FFF);
tv_sec = ts.tv_sec + (offset * SECS_PER_MINUTE);
days = tv_sec / SECS_PER_DAY;
rem = tv_sec % SECS_PER_DAY;
dest->hour = rem / SECS_PER_HOUR;
rem %= SECS_PER_HOUR;
dest->minute = rem / SECS_PER_MINUTE;
dest->second = rem % SECS_PER_MINUTE;
y = EPOCH_YEAR;
#define DIV(a,b) ((a) / (b) - ((a) % (b) < 0))
#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
while (days < 0 || days >= (__isleap(y) ? DAYS_PER_YEAR+1 : DAYS_PER_YEAR)) {
long int yg = y + days / DAYS_PER_YEAR - (days % DAYS_PER_YEAR < 0);
/* Adjust DAYS and Y to match the guessed year. */
days -= ((yg - y) * DAYS_PER_YEAR
+ LEAPS_THRU_END_OF (yg - 1)
- LEAPS_THRU_END_OF (y - 1));
y = yg;
}
dest->year = y;
ip = __mon_yday[__isleap(y)];
for (y = 11; days < (long int) ip[y]; --y)
continue;
days -= ip[y];
dest->month = y + 1;
dest->day = days + 1;
dest->centiseconds = ts.tv_nsec / 10000000;
dest->hundreds_of_microseconds = ( (ts.tv_nsec / 1000)
- (dest->centiseconds * 10000) ) / 100;
dest->microseconds = ( (ts.tv_nsec / 1000)
- (dest->centiseconds * 10000)
- (dest->hundreds_of_microseconds * 100) );
return dest;
}
#endif
/*!
Return the modification time of the file.
*/
time_t
udf_get_modification_time(const udf_dirent_t *p_udf_dirent)
{
if (p_udf_dirent) {
time_t ret_time;
long int usec;
udf_stamp_to_time(&ret_time, &usec, p_udf_dirent->fe.modification_time);
return ret_time;
}
return 0;
}
/*!
Return the access time of the file.
*/
time_t
udf_get_access_time(const udf_dirent_t *p_udf_dirent)
{
if (p_udf_dirent) {
time_t ret_time;
long int usec;
udf_stamp_to_time(&ret_time, &usec, p_udf_dirent->fe.access_time);
return ret_time;
}
return 0;
}
/*!
Return the attribute (most recent create or access) time of the file
*/
time_t
udf_get_attribute_time(const udf_dirent_t *p_udf_dirent)
{
if (p_udf_dirent) {
time_t ret_time;
long int usec;
udf_stamp_to_time(&ret_time, &usec, p_udf_dirent->fe.attribute_time);
return ret_time;
}
return 0;
}

View File

@ -1,26 +1,26 @@
#ifndef _MSC_VER
#error This header should only be used with Microsoft compilers
#endif
/* The addons below are not part of inttypes but required for syslinux */
#ifndef _SLTYPES_H_
#define _SLTYPES_H_
/* On MS environments, the inline keyword is available in C++ only */
#ifndef inline
#define inline __inline
#endif
/* ssize_t is also not available (copy/paste from MinGW) */
#ifndef _SSIZE_T_DEFINED
#define _SSIZE_T_DEFINED
#undef ssize_t
#ifdef _WIN64
typedef __int64 ssize_t;
#else
typedef int ssize_t;
#endif /* _WIN64 */
#endif /* _SSIZE_T_DEFINED */
#ifndef _MSC_VER
#error This header should only be used with Microsoft compilers
#endif
/* Workaround unisdt.h for MS compilers */
#ifndef _UNISTD_H_
#define _UNISTD_H_
/* On MS environments, the inline keyword is available in C++ only */
#ifndef inline
#define inline __inline
#endif
/* ssize_t is also not available (copy/paste from MinGW) */
#ifndef _SSIZE_T_DEFINED
#define _SSIZE_T_DEFINED
#undef ssize_t
#ifdef _WIN64
typedef __int64 ssize_t;
#else
typedef int ssize_t;
#endif /* _WIN64 */
#endif /* _SSIZE_T_DEFINED */
#endif

View File

@ -33,7 +33,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 206, 278
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "Rufus v1.0.7.118"
CAPTION "Rufus v1.0.7.119"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,94,236,50,14
@ -69,7 +69,7 @@ BEGIN
DEFPUSHBUTTON "OK",IDOK,231,175,50,14,WS_GROUP
CONTROL "<a href=""http://rufus.akeo.ie"">http://rufus.akeo.ie</a>",IDC_ABOUT_RUFUS_URL,
"SysLink",WS_TABSTOP,46,47,114,9
LTEXT "Version 1.0.7 (Build 118)",IDC_STATIC,46,19,78,8
LTEXT "Version 1.0.7 (Build 119)",IDC_STATIC,46,19,78,8
PUSHBUTTON "License...",IDC_ABOUT_LICENSE,46,175,50,14,WS_GROUP
EDITTEXT IDC_ABOUT_COPYRIGHTS,46,107,235,63,ES_MULTILINE | ES_READONLY | WS_VSCROLL
LTEXT "Report bugs or request enhancements at:",IDC_STATIC,46,66,187,8
@ -207,8 +207,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,7,118
PRODUCTVERSION 1,0,7,118
FILEVERSION 1,0,7,119
PRODUCTVERSION 1,0,7,119
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -225,13 +225,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "akeo.ie"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "1.0.7.118"
VALUE "FileVersion", "1.0.7.119"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "1.0.7.118"
VALUE "ProductVersion", "1.0.7.119"
END
END
BLOCK "VarFileInfo"

View File

@ -29,8 +29,8 @@
#define _INTTYPES_H_
#include <stdint.h>
/* SysLinux types addon */
#include <sltypes.h>
/* Workaround - TODO: move this include back into source */
#include <unistd.h>
#ifdef __cplusplus
extern "C" {

26
src/syslinux/unistd.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef _MSC_VER
#error This header should only be used with Microsoft compilers
#endif
/* Workaround unisdt.h for MS compilers */
#ifndef _UNISTD_H_
#define _UNISTD_H_
/* On MS environments, the inline keyword is available in C++ only */
#ifndef inline
#define inline __inline
#endif
/* ssize_t is also not available (copy/paste from MinGW) */
#ifndef _SSIZE_T_DEFINED
#define _SSIZE_T_DEFINED
#undef ssize_t
#ifdef _WIN64
typedef __int64 ssize_t;
#else
typedef int ssize_t;
#endif /* _WIN64 */
#endif /* _SSIZE_T_DEFINED */
#endif