|
|
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
|
|
|
|
|
|
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
|
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
|
|
Provided under GPL version 2 or later.
|
|
|
|
|
|
|
|
This is the official API definition of libburn.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef LIBBURN_H
|
|
|
|
#define LIBBURN_H
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
Applications must use 64 bit off_t. E.g. by defining
|
|
|
|
#define _LARGEFILE_SOURCE
|
|
|
|
#define _FILE_OFFSET_BITS 64
|
|
|
|
or take special precautions to interface with the library by 64 bit integers
|
|
|
|
where this .h files prescribe off_t.
|
|
|
|
|
|
|
|
To prevent 64 bit file i/o in the library would keep the application from
|
|
|
|
processing tracks of more than 2 GB size.
|
|
|
|
|
|
|
|
*/
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
|
|
|
#ifndef DOXYGEN
|
|
|
|
|
|
|
|
#if defined(__cplusplus)
|
|
|
|
#define BURN_BEGIN_DECLS \
|
|
|
|
namespace burn { \
|
|
|
|
extern "C" {
|
|
|
|
#define BURN_END_DECLS \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#define BURN_BEGIN_DECLS
|
|
|
|
#define BURN_END_DECLS
|
|
|
|
#endif
|
|
|
|
|
|
|
|
BURN_BEGIN_DECLS
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/** References a physical drive in the system */
|
|
|
|
struct burn_drive;
|
|
|
|
|
|
|
|
/** References a whole disc */
|
|
|
|
struct burn_disc;
|
|
|
|
|
|
|
|
/** References a single session on a disc */
|
|
|
|
struct burn_session;
|
|
|
|
|
|
|
|
/** References a single track on a disc */
|
|
|
|
struct burn_track;
|
|
|
|
|
|
|
|
/* ts A61111 */
|
|
|
|
/** References a set of write parameters */
|
|
|
|
struct burn_write_opts;
|
|
|
|
|
|
|
|
/** Session format for normal audio or data discs */
|
|
|
|
#define BURN_CDROM 0
|
|
|
|
/** Session format for obsolete CD-I discs */
|
|
|
|
#define BURN_CDI 0x10
|
|
|
|
/** Session format for CDROM-XA discs */
|
|
|
|
#define BURN_CDXA 0x20
|
|
|
|
|
|
|
|
#define BURN_POS_END 100
|
|
|
|
|
|
|
|
/** Mask for mode bits */
|
|
|
|
#define BURN_MODE_BITS 127
|
|
|
|
|
|
|
|
/** Track mode - mode 0 data
|
|
|
|
0 bytes of user data. it's all 0s. mode 0. get it? HAH
|
|
|
|
*/
|
|
|
|
#define BURN_MODE0 (1 << 0)
|
|
|
|
/** Track mode - mode "raw" - all 2352 bytes supplied by app
|
|
|
|
FOR DATA TRACKS ONLY!
|
|
|
|
*/
|
|
|
|
#define BURN_MODE_RAW (1 << 1)
|
|
|
|
/** Track mode - mode 1 data
|
|
|
|
2048 bytes user data, and all the LEC money can buy
|
|
|
|
*/
|
|
|
|
#define BURN_MODE1 (1 << 2)
|
|
|
|
/** Track mode - mode 2 data
|
|
|
|
defaults to formless, 2336 bytes of user data, unprotected
|
|
|
|
| with a data form if required.
|
|
|
|
*/
|
|
|
|
#define BURN_MODE2 (1 << 3)
|
|
|
|
/** Track mode modifier - Form 1, | with MODE2 for reasonable results
|
|
|
|
2048 bytes of user data, 4 bytes of subheader
|
|
|
|
*/
|
|
|
|
#define BURN_FORM1 (1 << 4)
|
|
|
|
/** Track mode modifier - Form 2, | with MODE2 for reasonable results
|
|
|
|
lots of user data. not much LEC.
|
|
|
|
*/
|
|
|
|
#define BURN_FORM2 (1 << 5)
|
|
|
|
/** Track mode - audio
|
|
|
|
2352 bytes per sector. may be | with 4ch or preemphasis.
|
|
|
|
NOT TO BE CONFUSED WITH BURN_MODE_RAW
|
|
|
|
Audio data must be 44100Hz 16bit stereo with no riff or other header at
|
|
|
|
beginning. Extra header data will cause pops or clicks. Audio data should
|
|
|
|
also be in little-endian byte order. Big-endian audio data causes static.
|
|
|
|
*/
|
|
|
|
#define BURN_AUDIO (1 << 6)
|
|
|
|
/** Track mode modifier - 4 channel audio. */
|
|
|
|
#define BURN_4CH (1 << 7)
|
|
|
|
/** Track mode modifier - Digital copy permitted, can be set on any track.*/
|
|
|
|
#define BURN_COPY (1 << 8)
|
|
|
|
/** Track mode modifier - 50/15uS pre-emphasis */
|
|
|
|
#define BURN_PREEMPHASIS (1 << 9)
|
|
|
|
/** Input mode modifier - subcodes present packed 16 */
|
|
|
|
#define BURN_SUBCODE_P16 (1 << 10)
|
|
|
|
/** Input mode modifier - subcodes present packed 96 */
|
|
|
|
#define BURN_SUBCODE_P96 (1 << 11)
|
|
|
|
/** Input mode modifier - subcodes present raw 96 */
|
|
|
|
#define BURN_SUBCODE_R96 (1 << 12)
|
|
|
|
|
|
|
|
/** Possible disc writing style/modes */
|
|
|
|
enum burn_write_types
|
|
|
|
{
|
|
|
|
/** Packet writing.
|
|
|
|
currently unsupported, (for DVD Incremental Streaming use TAO)
|
|
|
|
*/
|
|
|
|
BURN_WRITE_PACKET,
|
|
|
|
|
|
|
|
/** With CD: Track At Once recording
|
|
|
|
2s gaps between tracks, no fonky lead-ins
|
|
|
|
|
|
|
|
With sequential DVD-R[W]: Incremental Streaming
|
|
|
|
With DVD+R and BD-R: Track of open size
|
|
|
|
With DVD-RAM, DVD+RW, BD-RE: Random Writeable (used sequentially)
|
|
|
|
With overwriteable DVD-RW: Rigid Restricted Overwrite
|
|
|
|
*/
|
|
|
|
BURN_WRITE_TAO,
|
|
|
|
|
|
|
|
/** With CD: Session At Once
|
|
|
|
Block type MUST be BURN_BLOCK_SAO
|
|
|
|
ts A70122: Currently not capable of mixing data and audio tracks.
|
|
|
|
|
|
|
|
With sequential DVD-R[W]: Disc-at-once, DAO
|
|
|
|
Single session, single track, fixed size mandatory, (-dvd-compat)
|
|
|
|
With other DVD or BD media: same as BURN_WRITE_TAO but may demand
|
|
|
|
that track size is known in advance.
|
|
|
|
*/
|
|
|
|
BURN_WRITE_SAO,
|
|
|
|
|
|
|
|
/** With CD: Raw disc at once recording.
|
|
|
|
all subcodes must be provided by lib or user
|
|
|
|
only raw block types are supported
|
|
|
|
With DVD and BD media: not supported.
|
|
|
|
|
|
|
|
ts A90901: This had been disabled because its implementation
|
|
|
|
relied on code from cdrdao which is not understood
|
|
|
|
currently.
|
|
|
|
A burn run will abort with "FATAL" error message
|
|
|
|
if this mode is attempted.
|
|
|
|
@since 0.7.2
|
|
|
|
ts A91016: Re-implemented according to ECMA-130 Annex A and B.
|
|
|
|
Now understood, explained and not stemming from cdrdao.
|
|
|
|
@since 0.7.4
|
|
|
|
*/
|
|
|
|
BURN_WRITE_RAW,
|
|
|
|
|
|
|
|
/** In replies this indicates that not any writing will work.
|
|
|
|
As parameter for inquiries it indicates that no particular write
|
|
|
|
mode shall is specified.
|
|
|
|
Do not use for setting a write mode for burning. It will not work.
|
|
|
|
*/
|
|
|
|
BURN_WRITE_NONE
|
|
|
|
};
|
|
|
|
|
|
|
|
/** Data format to send to the drive */
|
|
|
|
enum burn_block_types
|
|
|
|
{
|
|
|
|
/** sync, headers, edc/ecc provided by lib/user */
|
|
|
|
BURN_BLOCK_RAW0 = 1,
|
|
|
|
/** sync, headers, edc/ecc and p/q subs provided by lib/user */
|
|
|
|
BURN_BLOCK_RAW16 = 2,
|
|
|
|
/** sync, headers, edc/ecc and packed p-w subs provided by lib/user */
|
|
|
|
BURN_BLOCK_RAW96P = 4,
|
|
|
|
/** sync, headers, edc/ecc and raw p-w subs provided by lib/user */
|
|
|
|
BURN_BLOCK_RAW96R = 8,
|
|
|
|
/** only 2048 bytes of user data provided by lib/user */
|
|
|
|
BURN_BLOCK_MODE1 = 256,
|
|
|
|
/** 2336 bytes of user data provided by lib/user */
|
|
|
|
BURN_BLOCK_MODE2R = 512,
|
|
|
|
/** 2048 bytes of user data provided by lib/user
|
|
|
|
subheader provided in write parameters
|
|
|
|
are we ever going to support this shit? I vote no.
|
|
|
|
(supposed to be supported on all drives...)
|
|
|
|
*/
|
|
|
|
BURN_BLOCK_MODE2_PATHETIC = 1024,
|
|
|
|
/** 2048 bytes of data + 8 byte subheader provided by lib/user
|
|
|
|
hey, this is also dumb
|
|
|
|
*/
|
|
|
|
BURN_BLOCK_MODE2_LAME = 2048,
|
|
|
|
/** 2324 bytes of data provided by lib/user
|
|
|
|
subheader provided in write parameters
|
|
|
|
no sir, I don't like it.
|
|
|
|
*/
|
|
|
|
BURN_BLOCK_MODE2_OBSCURE = 4096,
|
|
|
|
/** 2332 bytes of data supplied by lib/user
|
|
|
|
8 bytes sub header provided in write parameters
|
|
|
|
this is the second least suck mode2, and is mandatory for
|
|
|
|
all drives to support.
|
|
|
|
*/
|
|
|
|
BURN_BLOCK_MODE2_OK = 8192,
|
|
|
|
/** SAO block sizes are based on cue sheet, so use this. */
|
|
|
|
BURN_BLOCK_SAO = 16384
|
|
|
|
};
|
|
|
|
|
|
|
|
/** Possible status of the drive in regard to the disc in it. */
|
|
|
|
enum burn_disc_status
|
|
|
|
{
|
|
|
|
/** The current status is not yet known */
|
|
|
|
BURN_DISC_UNREADY,
|
|
|
|
|
|
|
|
/** The drive holds a blank disc. It is ready for writing from scratch.
|
|
|
|
Unused multi-session media:
|
|
|
|
CD-R, CD-RW, DVD-R, DVD-RW, DVD+R, BD-R
|
|
|
|
Blanked multi-session media (i.e. treated by burn_disc_erase())
|
|
|
|
CD-RW, DVD-RW
|
|
|
|
Overwriteable media with or without valid data
|
|
|
|
DVD-RAM, DVD+RW, formatted DVD-RW, BD-RE
|
|
|
|
*/
|
|
|
|
BURN_DISC_BLANK,
|
|
|
|
|
|
|
|
/** There is no disc at all in the drive */
|
|
|
|
BURN_DISC_EMPTY,
|
|
|
|
|
|
|
|
/** There is an incomplete disc in the drive. It is ready for appending
|
|
|
|
another session.
|
|
|
|
Written but not yet closed multi-session media
|
|
|
|
CD-R, CD-RW, DVD-R, DVD-RW, DVD+R, BD-R
|
|
|
|
*/
|
|
|
|
BURN_DISC_APPENDABLE,
|
|
|
|
|
|
|
|
/** There is a disc with data on it in the drive. It is usable only for
|
|
|
|
reading.
|
|
|
|
Written and closed multi-session media
|
|
|
|
CD-R, CD-RW, DVD-R, DVD-RW, DVD+R, BD-R
|
|
|
|
Read-Only media
|
|
|
|
CD-ROM, DVD-ROM, BD-ROM
|
|
|
|
Note that many DVD-ROM drives report any written media
|
|
|
|
as Read-Only media and not by their real media types.
|
|
|
|
*/
|
|
|
|
BURN_DISC_FULL,
|
|
|
|
|
|
|
|
/* ts A61007 */
|
|
|
|
/* @since 0.2.4 */
|
|
|
|
/** The drive was not grabbed when the status was inquired */
|
|
|
|
BURN_DISC_UNGRABBED,
|
|
|
|
|
|
|
|
/* ts A61020 */
|
|
|
|
/* @since 0.2.6 */
|
|
|
|
/** The media seems to be unsuitable for reading and for writing */
|
|
|
|
BURN_DISC_UNSUITABLE
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** Possible data source return values */
|
|
|
|
enum burn_source_status
|
|
|
|
{
|
|
|
|
/** The source is ok */
|
|
|
|
BURN_SOURCE_OK,
|
|
|
|
/** The source is at end of file */
|
|
|
|
BURN_SOURCE_EOF,
|
|
|
|
/** The source is unusable */
|
|
|
|
BURN_SOURCE_FAILED
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** Possible busy states for a drive */
|
|
|
|
enum burn_drive_status
|
|
|
|
{
|
|
|
|
/** The drive is not in an operation */
|
|
|
|
BURN_DRIVE_IDLE,
|
|
|
|
/** The library is spawning the processes to handle a pending
|
|
|
|
operation (A read/write/etc is about to start but hasn't quite
|
|
|
|
yet) */
|
|
|
|
BURN_DRIVE_SPAWNING,
|
|
|
|
/** The drive is reading data from a disc */
|
|
|
|
BURN_DRIVE_READING,
|
|
|
|
/** The drive is writing data to a disc */
|
|
|
|
BURN_DRIVE_WRITING,
|
|
|
|
/** The drive is writing Lead-In */
|
|
|
|
BURN_DRIVE_WRITING_LEADIN,
|
|
|
|
/** The drive is writing Lead-Out */
|
|
|
|
BURN_DRIVE_WRITING_LEADOUT,
|
|
|
|
/** The drive is erasing a disc */
|
|
|
|
BURN_DRIVE_ERASING,
|
|
|
|
/** The drive is being grabbed */
|
|
|
|
BURN_DRIVE_GRABBING,
|
|
|
|
|
|
|
|
/* ts A61102 */
|
|
|
|
/* @since 0.2.6 */
|
|
|
|
/** The drive gets written zeroes before the track payload data */
|
|
|
|
BURN_DRIVE_WRITING_PREGAP,
|
|
|
|
/** The drive is told to close a track (TAO only) */
|
|
|
|
BURN_DRIVE_CLOSING_TRACK,
|
|
|
|
/** The drive is told to close a session (TAO only) */
|
|
|
|
BURN_DRIVE_CLOSING_SESSION,
|
|
|
|
|
|
|
|
/* ts A61223 */
|
|
|
|
/* @since 0.3.0 */
|
|
|
|
/** The drive is formatting media */
|
|
|
|
BURN_DRIVE_FORMATTING,
|
|
|
|
|
|
|
|
/* ts A70822 */
|
|
|
|
/* @since 0.4.0 */
|
|
|
|
/** The drive is busy in synchronous read (if you see this then it
|
|
|
|
has been interrupted) */
|
|
|
|
BURN_DRIVE_READING_SYNC,
|
|
|
|
/** The drive is busy in synchronous write (if you see this then it
|
|
|
|
has been interrupted) */
|
|
|
|
BURN_DRIVE_WRITING_SYNC
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** Information about a track on a disc - this is from the q sub channel of the
|
|
|
|
lead-in area of a disc. The documentation here is very terse.
|
|
|
|
See a document such as mmc3 for proper information.
|
|
|
|
|
|
|
|
CAUTION : This structure is prone to future extension !
|
|
|
|
|
|
|
|
Do not restrict your application to unsigned char with any counter like
|
|
|
|
"session", "point", "pmin", ...
|
|
|
|
Do not rely on the current size of a burn_toc_entry.
|
|
|
|
|
|
|
|
ts A70201 : DVD extension, see below
|
|
|
|
*/
|
|
|
|
struct burn_toc_entry
|
|
|
|
{
|
|
|
|
/** Session the track is in */
|
|
|
|
unsigned char session;
|
|
|
|
/** Type of data. for this struct to be valid, it must be 1 */
|
|
|
|
unsigned char adr;
|
|
|
|
/** Type of data in the track */
|
|
|
|
unsigned char control;
|
|
|
|
/** Zero. Always. Really. */
|
|
|
|
unsigned char tno;
|
|
|
|
/** Track number or special information */
|
|
|
|
unsigned char point;
|
|
|
|
unsigned char min;
|
|
|
|
unsigned char sec;
|
|
|
|
unsigned char frame;
|
|
|
|
unsigned char zero;
|
|
|
|
/** Track start time minutes for normal tracks */
|
|
|
|
unsigned char pmin;
|
|
|
|
/** Track start time seconds for normal tracks */
|
|
|
|
unsigned char psec;
|
|
|
|
/** Track start time frames for normal tracks */
|
|
|
|
unsigned char pframe;
|
|
|
|
|
|
|
|
/* Indicates whether extension data are valid and eventually override
|
|
|
|
older elements in this structure:
|
|
|
|
bit0= DVD extension is valid @since 0.3.2
|
|
|
|
@since 0.5.2 : DVD extensions are made valid for CD too
|
|
|
|
*/
|
|
|
|
unsigned char extensions_valid;
|
|
|
|
|
|
|
|
/* ts A70201 : DVD extension. extensions_valid:bit0
|
|
|
|
If invalid the members are guaranteed to be 0. */
|
|
|
|
/* @since 0.3.2 */
|
|
|
|
/* Tracks and session numbers are 16 bit. Here are the high bytes. */
|
|
|
|
unsigned char session_msb;
|
|
|
|
unsigned char point_msb;
|
|
|
|
/* pmin, psec, and pframe may be too small if DVD extension is valid */
|
|
|
|
int start_lba;
|
|
|
|
/* min, sec, and frame may be too small if DVD extension is valid */
|
|
|
|
int track_blocks;
|
|
|
|
|
|
|
|
/* ts A90909 : LRA extension. extensions_valid:bit1 */
|
|
|
|
/* @since 0.7.2 */
|
|
|
|
/* MMC-5 6.27.3.18 : The Last Recorded Address is valid for DVD-R,
|
|
|
|
DVD-R DL when LJRS = 00b, DVD-RW, HD DVD-R, and BD-R.
|
|
|
|
This would mean profiles: 0x11, 0x15, 0x13, 0x14, 0x51, 0x41, 0x42
|
|
|
|
*/
|
|
|
|
int last_recorded_address;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** Data source interface for tracks.
|
|
|
|
This allows to use arbitrary program code as provider of track input data.
|
|
|
|
|
|
|
|
Objects compliant to this interface are either provided by the application
|
|
|
|
or by API calls of libburn: burn_fd_source_new() , burn_file_source_new(),
|
|
|
|
and burn_fifo_source_new().
|
|
|
|
|
|
|
|
The API calls allow to use any file object as data source. Consider to feed
|
|
|
|
an eventual custom data stream asynchronously into a pipe(2) and to let
|
|
|
|
libburn handle the rest.
|
|
|
|
In this case the following rule applies:
|
|
|
|
Call burn_source_free() exactly once for every source obtained from
|
|
|
|
libburn API. You MUST NOT otherwise use or manipulate its components.
|
|
|
|
|
|
|
|
In general, burn_source objects can be freed as soon as they are attached
|
|
|
|
to track objects. The track objects will keep them alive and dispose them
|
|
|
|
when they are no longer needed. With a fifo burn_source it makes sense to
|
|
|
|
keep the own reference for inquiring its state while burning is in
|
|
|
|
progress.
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
The following description of burn_source applies only to application
|
|
|
|
implemented burn_source objects. You need not to know it for API provided
|
|
|
|
ones.
|
|
|
|
|
|
|
|
If you really implement an own passive data producer by this interface,
|
|
|
|
then beware: it can do anything and it can spoil everything.
|
|
|
|
|
|
|
|
In this case the functions (*read), (*get_size), (*set_size), (*free_data)
|
|
|
|
MUST be implemented by the application and attached to the object at
|
|
|
|
creation time.
|
|
|
|
Function (*read_sub) is allowed to be NULL or it MUST be implemented and
|
|
|
|
attached.
|
|
|
|
|
|
|
|
burn_source.refcount MUST be handled properly: If not exactly as many
|
|
|
|
references are freed as have been obtained, then either memory leaks or
|
|
|
|
corrupted memory are the consequence.
|
|
|
|
All objects which are referred to by *data must be kept existent until
|
|
|
|
(*free_data) is called via burn_source_free() by the last referer.
|
|
|
|
*/
|
|
|
|
struct burn_source {
|
|
|
|
|
|
|
|
/** Reference count for the data source. MUST be 1 when a new source
|
|
|
|
is created and thus the first reference is handed out. Increment
|
|
|
|
it to take more references for yourself. Use burn_source_free()
|
|
|
|
to destroy your references to it. */
|
|
|
|
int refcount;
|
|
|
|
|
|
|
|
|
|
|
|
/** Read data from the source. Semantics like with read(2), but MUST
|
|
|
|
either deliver the full buffer as defined by size or MUST deliver
|
|
|
|
EOF (return 0) or failure (return -1) at this call or at the
|
|
|
|
next following call. I.e. the only incomplete buffer may be the
|
|
|
|
last one from that source.
|
|
|
|
libburn will read a single sector by each call to (*read).
|
|
|
|
The size of a sector depends on BURN_MODE_*. The known range is
|
|
|
|
2048 to 2352.
|
|
|
|
|
|
|
|
If this call is reading from a pipe then it will learn
|
|
|
|
about the end of data only when that pipe gets closed on the
|
|
|
|
feeder side. So if the track size is not fixed or if the pipe
|
|
|
|
delivers less than the predicted amount or if the size is not
|
|
|
|
block aligned, then burning will halt until the input process
|
|
|
|
closes the pipe.
|
|
|
|
|
|
|
|
IMPORTANT:
|
|
|
|
If this function pointer is NULL, then the struct burn_source is of
|
|
|
|
version >= 1 and the job of .(*read)() is done by .(*read_xt)().
|
|
|
|
See below, member .version.
|
|
|
|
*/
|
|
|
|
int (*read)(struct burn_source *, unsigned char *buffer, int size);
|
|
|
|
|
|
|
|
|
|
|
|
/** Read subchannel data from the source (NULL if lib generated)
|
|
|
|
WARNING: This is an obscure feature with CD raw write modes.
|
|
|
|
Unless you checked the libburn code for correctness in that aspect
|
|
|
|
you should not rely on raw writing with own subchannels.
|
|
|
|
ADVICE: Set this pointer to NULL.
|
|
|
|
*/
|
|
|
|
int (*read_sub)(struct burn_source *, unsigned char *buffer, int size);
|
|
|
|
|
|
|
|
|
|
|
|
/** Get the size of the source's data. Return 0 means unpredictable
|
|
|
|
size. If application provided (*get_size) allows return 0, then
|
|
|
|
the application MUST provide a fully functional (*set_size).
|
|
|
|
*/
|
|
|
|
off_t (*get_size)(struct burn_source *);
|
|
|
|
|
|
|
|
|
|
|
|
/* ts A70125 : BROKE BINARY BACKWARD COMPATIBILITY AT libburn-0.3.1. */
|
|
|
|
/* @since 0.3.2 */
|
|
|
|
/** Program the reply of (*get_size) to a fixed value. It is advised
|
|
|
|
to implement this by a attribute off_t fixed_size; in *data .
|
|
|
|
The read() function does not have to take into respect this fake
|
|
|
|
setting. It is rather a note of libburn to itself. Eventually
|
|
|
|
necessary truncation or padding is done in libburn. Truncation
|
|
|
|
is usually considered a misburn. Padding is considered ok.
|
|
|
|
|
|
|
|
libburn is supposed to work even if (*get_size) ignores the
|
|
|
|
setting by (*set_size). But your application will not be able to
|
|
|
|
enforce fixed track sizes by burn_track_set_size() and possibly
|
|
|
|
even padding might be left out.
|
|
|
|
*/
|
|
|
|
int (*set_size)(struct burn_source *source, off_t size);
|
|
|
|
|
|
|
|
|
|
|
|
/** Clean up the source specific data. This function will be called
|
|
|
|
once by burn_source_free() when the last referer disposes the
|
|
|
|
source.
|
|
|
|
*/
|
|
|
|
void (*free_data)(struct burn_source *);
|
|
|
|
|
|
|
|
|
|
|
|
/** Next source, for when a source runs dry and padding is disabled
|
|
|
|
WARNING: This is an obscure feature. Set to NULL at creation and
|
|
|
|
from then on leave untouched and uninterpreted.
|
|
|
|
*/
|
|
|
|
struct burn_source *next;
|
|
|
|
|
|
|
|
|
|
|
|
/** Source specific data. Here the various source classes express their
|
|
|
|
specific properties and the instance objects store their individual
|
|
|
|
management data.
|
|
|
|
E.g. data could point to a struct like this:
|
|
|
|
struct app_burn_source
|
|
|
|
{
|
|
|
|
struct my_app *app_handle;
|
|
|
|
... other individual source parameters ...
|
|
|
|
off_t fixed_size;
|
|
|
|
};
|
|
|
|
|
|
|
|
Function (*free_data) has to be prepared to clean up and free
|
|
|
|
the struct.
|
|
|
|
*/
|
|
|
|
void *data;
|
|
|
|
|
|
|
|
|
|
|
|
/* ts A71222 : Supposed to be binary backwards compatible extension. */
|
|
|
|
/* @since 0.4.2 */
|
|
|
|
/** Valid only if above member .(*read)() is NULL. This indicates a
|
|
|
|
version of struct burn_source younger than 0.
|
|
|
|
From then on, member .version tells which further members exist
|
|
|
|
in the memory layout of struct burn_source. libburn will only touch
|
|
|
|
those announced extensions.
|
|
|
|
|
|
|
|
Versions:
|
|
|
|
0 has .(*read)() != NULL, not even .version is present.
|
|
|
|
1 has .version, .(*read_xt)(), .(*cancel)()
|
|
|
|
*/
|
|
|
|
int version;
|
|
|
|
|
|
|
|
/** This substitutes for (*read)() in versions above 0. */
|
|
|
|
int (*read_xt)(struct burn_source *, unsigned char *buffer, int size);
|
|
|
|
|
|
|
|
/** Informs the burn_source that the consumer of data prematurely
|
|
|
|
ended reading. This call may or may not be issued by libburn
|
|
|
|
before (*free_data)() is called.
|
|
|
|
*/
|
|
|
|
int (*cancel)(struct burn_source *source);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** Information on a drive in the system */
|
|
|
|
struct burn_drive_info
|
|
|
|
{
|
|
|
|
/** Name of the vendor of the drive */
|
|
|
|
char vendor[9];
|
|
|
|
/** Name of the drive */
|
|
|
|
char product[17];
|
|
|
|
/** Revision of the drive */
|
|
|
|
char revision[5];
|
|
|
|
|
|
|
|
/** Invalid: Was: "Location of the drive in the filesystem." */
|
|
|
|
/** This string has no meaning any more. Once it stored the persistent
|
|
|
|
drive address. Now always use function burn_drive_d_get_adr() to
|
|
|
|
inquire a persistent address. ^^^^^^ ALWAYS ^^^^^^^^ */
|
|
|
|
char location[17];
|
|
|
|
|
|
|
|
/** Can the drive read DVD-RAM discs */
|
|
|
|
unsigned int read_dvdram:1;
|
|
|
|
/** Can the drive read DVD-R discs */
|
|
|
|
unsigned int read_dvdr:1;
|
|
|
|
/** Can the drive read DVD-ROM discs */
|
|
|
|
unsigned int read_dvdrom:1;
|
|
|
|
/** Can the drive read CD-R discs */
|
|
|
|
unsigned int read_cdr:1;
|
|
|
|
/** Can the drive read CD-RW discs */
|
|
|
|
unsigned int read_cdrw:1;
|
|
|
|
|
|
|
|
/** Can the drive write DVD-RAM discs */
|
|
|
|
unsigned int write_dvdram:1;
|
|
|
|
/** Can the drive write DVD-R discs */
|
|
|
|
unsigned int write_dvdr:1;
|
|
|
|
/** Can the drive write CD-R discs */
|
|
|
|
unsigned int write_cdr:1;
|
|
|
|
/** Can the drive write CD-RW discs */
|
|
|
|
unsigned int write_cdrw:1;
|
|
|
|
|
|
|
|
/** Can the drive simulate a write */
|
|
|
|
unsigned int write_simulate:1;
|
|
|
|
|
|
|
|
/** Can the drive report C2 errors */
|
|
|
|
unsigned int c2_errors:1;
|
|
|
|
|
|
|
|
/** The size of the drive's buffer (in kilobytes) */
|
|
|
|
int buffer_size;
|
|
|
|
/**
|
|
|
|
* The supported block types in tao mode.
|
|
|
|
* They should be tested with the desired block type.
|
|
|
|
* See also burn_block_types.
|
|
|
|
*/
|
|
|
|
int tao_block_types;
|
|
|
|
/**
|
|
|
|
* The supported block types in sao mode.
|
|
|
|
* They should be tested with the desired block type.
|
|
|
|
* See also burn_block_types.
|
|
|
|
*/
|
|
|
|
int sao_block_types;
|
|
|
|
/**
|
|
|
|
* The supported block types in raw mode.
|
|
|
|
* They should be tested with the desired block type.
|
|
|
|
* See also burn_block_types.
|
|
|
|
*/
|
|
|
|
int raw_block_types;
|
|
|
|
/**
|
|
|
|
* The supported block types in packet mode.
|
|
|
|
* They should be tested with the desired block type.
|
|
|
|
* See also burn_block_types.
|
|
|
|
*/
|
|
|
|
int packet_block_types;
|
|
|
|
|
|
|
|
/** The value by which this drive can be indexed when using functions
|
|
|
|
in the library. This is the value to pass to all libbburn functions
|
|
|
|
that operate on a drive. */
|
|
|
|
struct burn_drive *drive;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** Operation progress report. All values are 0 based indices.
|
|
|
|
* */
|
|
|
|
struct burn_progress {
|
|
|
|
/** The total number of sessions */
|
|
|
|
int sessions;
|
|
|
|
/** Current session.*/
|
|
|
|
int session;
|
|
|
|
/** The total number of tracks */
|
|
|
|
int tracks;
|
|
|
|
/** Current track. */
|
|
|
|
int track;
|
|
|
|
/** The total number of indices */
|
|
|
|
int indices;
|
|
|
|
/** Curent index. */
|
|
|
|
int index;
|
|
|
|
/** The starting logical block address */
|
|
|
|
int start_sector;
|
|
|
|
/** On write: The number of sectors.
|
|
|
|
On blank: 0x10000 as upper limit for relative progress steps */
|
|
|
|
int sectors;
|
|
|
|
/** On write: The current sector being processed.
|
|
|
|
On blank: Relative progress steps 0 to 0x10000 */
|
|
|
|
int sector;
|
|
|
|
|
|
|
|
/* ts A61023 */
|
|
|
|
/* @since 0.2.6 */
|
|
|
|
/** The capacity of the drive buffer */
|
|
|
|
unsigned buffer_capacity;
|
|
|
|
/** The free space in the drive buffer (might be slightly outdated) */
|
|
|
|
unsigned buffer_available;
|
|
|
|
|
|
|
|
/* ts A61119 */
|
|
|
|
/* @since 0.2.6 */
|
|
|
|
/** The number of bytes sent to the drive buffer */
|
|
|
|
off_t buffered_bytes;
|
|
|
|
/** The minimum number of bytes stored in buffer during write.
|
|
|
|
(Caution: Before surely one buffer size of bytes was processed,
|
|
|
|
this value is 0xffffffff.)
|
|
|
|
*/
|
|
|
|
unsigned buffer_min_fill;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* ts A61226 */
|
|
|
|
/* @since 0.3.0 */
|
|
|
|
/** Description of a speed capability as reported by the drive in conjunction
|
|
|
|
with eventually loaded media. There can be more than one such object per
|
|
|
|
drive. So they are chained via .next and .prev , where NULL marks the end
|
|
|
|
of the chain. This list is set up by burn_drive_scan() and gets updated
|
|
|
|
by burn_drive_grab().
|
|
|
|
A copy may be obtained by burn_drive_get_speedlist() and disposed by
|
|
|
|
burn_drive_free_speedlist().
|
|
|
|
For technical background info see SCSI specs MMC and SPC:
|
|
|
|
mode page 2Ah (from SPC 5Ah MODE SENSE) , mmc3r10g.pdf , 6.3.11 Table 364
|
|
|
|
ACh GET PERFORMANCE, Type 03h , mmc5r03c.pdf , 6.8.5.3 Table 312
|
|
|
|
*/
|
|
|
|
struct burn_speed_descriptor {
|
|
|
|
|
|
|
|
/** Where this info comes from :
|
|
|
|
0 = misc , 1 = mode page 2Ah , 2 = ACh GET PERFORMANCE */
|
|
|
|
int source;
|
|
|
|
|
|
|
|
/** The media type that was current at the time of report
|
|
|
|
-2 = state unknown, -1 = no media was loaded , else see
|
|
|
|
burn_disc_get_profile() */
|
|
|
|
int profile_loaded;
|
|
|
|
char profile_name[80];
|
|
|
|
|
|
|
|
/** The attributed capacity of appropriate media in logical block units
|
|
|
|
i.e. 2352 raw bytes or 2048 data bytes. -1 = capacity unknown. */
|
|
|
|
int end_lba;
|
|
|
|
|
|
|
|
/** Speed is given in 1000 bytes/s , 0 = invalid. The numbers
|
|
|
|
are supposed to be usable with burn_drive_set_speed() */
|
|
|
|
int write_speed;
|
|
|
|
int read_speed;
|
|
|
|
|
|
|
|
/** Expert info from ACh GET PERFORMANCE and/or mode page 2Ah.
|
|
|
|
Expect values other than 0 or 1 to get a meaning in future.*/
|
|
|
|
/* Rotational control: 0 = CLV/default , 1 = CAV */
|
|
|
|
int wrc;
|
|
|
|
/* 1 = drive promises reported performance over full media */
|
|
|
|
int exact;
|
|
|
|
/* 1 = suitable for mixture of read and write */
|
|
|
|
int mrw;
|
|
|
|
|
|
|
|
/** List chaining. Use .next until NULL to iterate over the list */
|
|
|
|
struct burn_speed_descriptor *prev;
|
|
|
|
struct burn_speed_descriptor *next;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** Initialize the library.
|
|
|
|
This must be called before using any other functions in the library. It
|
|
|
|
may be called more than once with no effect.
|
|
|
|
It is possible to 'restart' the library by shutting it down and
|
|
|
|
re-initializing it. Once this was necessary if you follow the older and
|
|
|
|
more general way of accessing a drive via burn_drive_scan() and
|
|
|
|
burn_drive_grab(). See burn_drive_scan_and_grab() with its strong
|
|
|
|
urges and its explanations.
|
|
|
|
@return Nonzero if the library was able to initialize; zero if
|
|
|
|
initialization failed.
|
|
|
|
*/
|
|
|
|
int burn_initialize(void);
|
|
|
|
|
|
|
|
/** Shutdown the library.
|
|
|
|
This should be called before exiting your application. Make sure that all
|
|
|
|
drives you have grabbed are released <i>before</i> calling this.
|
|
|
|
*/
|
|
|
|
void burn_finish(void);
|
|
|
|
|
|
|
|
|
|
|
|
/* ts A61002 */
|
|
|
|
/** Abort any running drive operation and eventually call burn_finish().
|
|
|
|
|
|
|
|
You MUST shut down the busy drives if an aborting event occurs during a
|
|
|
|
burn run. For that you may call this function either from your own signal
|
|
|
|
handling code or indirectly by activating the built-in signal handling:
|
|
|
|
burn_set_signal_handling("my_app_name : ", NULL, 0);
|
|
|
|
Else you may eventually call burn_drive_cancel() on the active drives and
|
|
|
|
wait for them to assume state BURN_DRIVE_IDLE.
|
|
|
|
@param patience Maximum number of seconds to wait for drives to
|
|
|
|
finish.
|
|
|
|
@since 0.7.8 :
|
|
|
|
If this is -1, then only the cancel operations will
|
|
|
|
be performed and no burn_finish() will happen.
|
|
|
|
@param pacifier_func If not NULL: a function to produce appeasing messages.
|
|
|
|
See burn_abort_pacifier() for an example.
|
|
|
|
@param handle Opaque handle to be used with pacifier_func
|
|
|
|
@return 1 ok, all went well
|
|
|
|
0 had to leave a drive in unclean state
|
|
|
|
<0 severe error, do no use libburn again
|
|
|
|
@since 0.2.6
|
|
|
|
*/
|
|
|
|
int burn_abort(int patience,
|
|
|
|
int (*pacifier_func)(void *handle, int patience, int elapsed),
|
|
|
|
void *handle);
|
|
|
|
|
|
|
|
/** A pacifier function suitable for burn_abort.
|
|
|
|
@param handle If not NULL, a pointer to a text suitable for printf("%s")
|
|
|
|
@param patience Maximum number of seconds to wait
|
|
|
|
@param elapsed Elapsed number of seconds
|
|
|
|
*/
|
|
|
|
int burn_abort_pacifier(void *handle, int patience, int elapsed);
|
|
|
|
|
|
|
|
|
|
|
|
/** ts A61006 : This is for development only. Not suitable for applications.
|
|
|
|
Set the verbosity level of the library. The default value is 0, which means
|
|
|
|
that nothing is output on stderr. The more you increase this, the more
|
|
|
|
debug output should be displayed on stderr for you.
|
|
|
|
@param level The verbosity level desired. 0 for nothing, higher positive
|
|
|
|
values for more information output.
|
|
|
|
*/
|
|
|
|
void burn_set_verbosity(int level);
|
|
|
|
|
|
|
|
/* ts A91111 */
|
|
|
|
/** Enable resp. disable logging of SCSI commands (currently GNU/Linux only).
|
|
|
|
This call can be made at any time - even before burn_initialize().
|
|
|
|
It is in effect for all active drives and currently not very thread
|
|
|
|
safe for multiple drives.
|
|
|
|
@param flag Bitfield for control purposes. The default is 0.
|
|
|
|
bit0= log to file /tmp/libburn_sg_command_log
|
|
|
|
bit1= log to stderr
|
|
|
|
bit2= flush output after each line
|
|
|
|
@since 0.7.4
|
|
|
|
*/
|
|
|
|
void burn_set_scsi_logging(int flag);
|
|
|
|
|
|
|
|
/* ts A60813 */
|
|
|
|
/** Set parameters for behavior on opening device files. To be called early
|
|
|
|
after burn_initialize() and before any bus scan. But not mandatory at all.
|
|
|
|
Parameter value 1 enables a feature, 0 disables.
|
|
|
|
Default is (1,0,0). Have a good reason before you change it.
|
|
|
|
@param exclusive
|
|
|
|
0 = no attempt to make drive access exclusive.
|
|
|
|
1 = Try to open only devices which are not marked as busy
|
|
|
|
and try to mark them busy if opened sucessfully. (O_EXCL
|
|
|
|
on GNU/Linux , flock(LOCK_EX) on FreeBSD.)
|
|
|
|
2 = in case of a SCSI device, also try to open exclusively
|
|
|
|
the matching /dev/sr, /dev/scd and /dev/st .
|
|
|
|
One may select a device SCSI file family by adding
|
|
|
|
0 = default family
|
|
|
|
4 = /dev/sr%d
|
|
|
|
8 = /dev/scd%d
|
|
|
|
16 = /dev/sg%d
|
|
|
|
Do not use other values !
|
|
|
|
Add 32 to demand on GNU/Linux an exclusive lock by
|
|
|
|
fcntl(,F_SETLK,) after open() has succeeded.
|
|
|
|
@param blocking Try to wait for drives which do not open immediately but
|
|
|
|
also do not return an error as well. (O_NONBLOCK)
|
|
|
|
This might stall indefinitely with /dev/hdX hard disks.
|
|
|
|
@param abort_on_busy Unconditionally abort process when a non blocking
|
|
|
|
exclusive opening attempt indicates a busy drive.
|
|
|
|
Use this only after thorough tests with your app.
|
|
|
|
@since 0.2.2
|
|
|
|
*/
|
|
|
|
void burn_preset_device_open(int exclusive, int blocking, int abort_on_busy);
|
|
|
|
|
|
|
|
|
|
|
|
/* ts A70223 */
|
|
|
|
/** Allows the use of media types which are implemented in libburn but not yet
|
|
|
|
tested. The list of those untested profiles is subject to change.
|
|
|
|
Currently it contains: 0x15 "DVD-R/DL sequential recording",
|
|
|
|
If you really test such media, then please report the outcome on
|
|
|
|
libburn-hackers@pykix.org
|
|
|
|
If ever then this call should be done soon after burn_initialize() before
|
|
|
|
any drive scanning.
|
|
|
|
@param yes 1=allow all implemented profiles, 0=only tested media (default)
|
|
|
|
@since 0.3.4
|
|
|
|
*/
|
|
|
|
void burn_allow_untested_profiles(int yes);
|
|
|
|
|
|
|
|
|
|
|
|
/* ts A60823 */
|
|
|
|
/** Aquire a drive with known persistent address.
|
|
|
|
|
|
|
|
This is the sysadmin friendly way to open one drive and to leave all
|
|
|
|
others untouched. It bundles the following API calls to form a
|
|
|
|
non-obtrusive way to use libburn:
|
|
|
|
burn_drive_add_whitelist() , burn_drive_scan() , burn_drive_grab()
|
|
|
|
You are *strongly urged* to use this call whenever you know the drive
|
|
|
|
address in advance.
|
|
|
|
|
|
|
|
If not, then you have to use directly above calls. In that case, you are
|
|
|
|
*strongly urged* to drop any unintended drive which will be exclusively
|
|
|
|
occupied and not closed by burn_drive_scan().
|
|
|
|
This can be done by shutting down the library including a call to
|
|
|
|
burn_finish(). You may later start a new libburn session and should then
|
|
|
|
use the function described here with an address obtained after
|
|
|
|
burn_drive_scan() via burn_drive_d_get_adr(drive_infos[driveno].drive,adr).
|
|
|
|
Another way is to drop the unwanted drives by burn_drive_info_forget().
|
|
|
|
|
|
|
|
Operating on multiple drives:
|
|
|
|
|
|
|