File: cdio_private.h

package info (click to toggle)
libcdio 2.1.0-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 16,564 kB
  • sloc: ansic: 38,843; sh: 5,501; cpp: 2,555; makefile: 777; ruby: 24; perl: 24
file content (596 lines) | stat: -rw-r--r-- 18,266 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
/*
  Copyright (C) 2003-2005, 2008-2009, 2011-2012, 2016-2017
  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_DRIVER_PRIVATE_H_
#define CDIO_DRIVER_PRIVATE_H_

#if defined(HAVE_CONFIG_H) && !defined(LIBCDIO_CONFIG_H)
# include "config.h"
#endif

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.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 */

#ifndef HAVE_STRNDUP
#undef  strndup
#define strndup libcdio_strndup
static inline char *libcdio_strndup(const char *s, size_t n)
{
    char *result;
    size_t len = strlen (s);
    if (n < len)
        len = n;
    result = (char *) malloc (len + 1);
    if (!result)
        return 0;
    result[len] = '\0';
    return (char *) strncpy (result, s, len);
}
#endif /*HAVE_STRNDUP*/

  /*!
    Get directory name from file name.

    Callers must free return value after use.
   */
  extern char *cdio_dirname(const char *fname);

  /*!
    Construct an absolute file name from path and file name.

    Callers must free return value after use.
   */
  extern 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_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_DRIVER_PRIVATE_H_ */