|
|
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
|
|
|
|
|
|
|
#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. Not to use 64 bit file i/o will keep the
|
|
|
|
application from producing and processing ISO images 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-RAM/+RW: 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)
|
|
|
|
*/
|
|
|
|
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
|
|
|
|
*/
|
|
|
|
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 won't 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.
|
|
|
|
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;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** 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 finally call burn_finish().
|
|
|
|
You MUST calm down the busy drive 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 builtin signal handling:
|
|
|
|
burn_set_signal_handling("my_app_name : ", NULL, 0);
|
|
|
|
Else you may eventually call burn_drive_cancel() on the active drive and
|
|
|
|
wait for it to assume state BURN_DRIVE_IDLE.
|
|
|
|
@param patience Maximum number of seconds to wait for drives to finish
|
|
|
|
@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 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 Linux only:
|
|
|
|
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)
|
|
|
|
There are kernels which simply don't care about O_EXCL.
|
|
|
|
Some have it off, some have it on, some are switchable.
|
|
|
|
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 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:
|
|
|
|
|
|
|
|
Different than with burn_drive_scan() it is allowed to call
|
|
|
|
burn_drive_scan_and_grab() without giving up any other scanned drives. So
|
|
|
|
this call can be used to get a collection of more than one aquired drives.
|
|
|
|
The attempt to aquire the same drive twice will fail, though.
|
|
|
|
|
|
|
|
Pseudo-drives:
|
|
|
|
|
|
|
|
burn_drive_scan_and_grab() is able to aquire virtual drives which will
|
|
|
|
accept options much like a MMC burner drive. Many of those options will not
|
|
|
|
cause any effect, though. The address of a pseudo-drive begins with
|
|
|
|
prefix "stdio:" followed by a path.
|
|
|
|
Examples: "stdio:/tmp/pseudo_drive" , "stdio:/dev/null" , "stdio:-"
|
|
|
|
|
|
|
|
If the path is empty, the result is a null-drive = drive role 0.
|
|
|
|
It pretends to have loaded no media and supports no reading or writing.
|
|
|
|
|
|
|
|
If the path leads to an existing regular file, or to a not yet existing
|
|
|
|
file, or to an existing block device, then the result is a random access
|
|
|
|
stdio-drive capable of reading and writing = drive role 2.
|
|
|
|
|
|
|
|
If the path leads to an existing file of any type other than directory,
|
|
|
|
then the result is a sequential write-only stdio-drive = drive role 3.
|
|
|
|
|
|
|
|
The special address form "stdio:/dev/fd/<number>" is interpreted literally
|
|
|
|
as reference to open file descriptor <number>. This address form coincides
|
|
|
|
with real files on some systems, but it is in fact hardcoded in libburn.
|
|
|
|
Special address "stdio:-" means stdout = "stdio:/dev/fd/1".
|
|
|
|
The role of such a drive is determined by the file type obtained via
|
|
|
|
fstat(<number>).
|
|
|
|
|
|
|
|
Roles 2 and 3 perform all their eventual data transfer activities on a file
|
|
|
|
via standard i/o functions open(2), lseek(2), read(2), write(2), close(2).
|
|
|
|
The media profile is reported as 0xffff. Write space information from those
|
|
|
|
media is not necessarily realistic.
|
|
|
|
|
|
|
|
The capabilities of role 2 resemble DVD-RAM but it can simulate writing.
|
|
|
|
If the path does not exist in the filesystem yet, it is attempted to create
|
|
|
|
it as a regular file as soon as write operations are started.
|
|
|
|
|
|
|
|
The capabilities of role 3 resemble a blank DVD-R. Nevertheless each
|
|
|
|
burn_disc_write() run may only write a single track.
|
|
|
|
|
|
|
|
One may distinguish pseudo-drives from MMC drives by call
|
|
|
|
burn_drive_get_drive_role().
|
|
|
|
|
|
|
|
@param drive_infos On success returns a one element array with the drive
|
|
|
|
(cdrom/burner). Thus use with driveno 0 only. On failure
|
|
|
|
the array has no valid elements at all.
|
|
|
|
The returned array should be freed via burn_drive_info_free()
|
|
|
|
when it is no longer needed.
|
|
|
|
This is a result from call burn_drive_scan(). See there.
|
|
|
|
Use with driveno 0 only.
|
|
|
|
@param adr The persistent address of the desired drive. Either once
|
|
|
|
obtained by burn_drive_d_get_adr() or composed skillfully by
|
|
|
|
application resp. its user. E.g. "/dev/sr0".
|
|
|
|
Consider to preprocess it by burn_drive_convert_fs_adr().
|
|
|
|
@param load Nonzero to make the drive attempt to load a disc (close its
|
|
|
|
tray door, etc).
|
|
|
|
@return 1 = success , 0 = drive not found , -1 = other error
|
|
|
|
@since 0.2.2
|
|
|
|
*/
|
|