2
$Id: cd_types.c,v 1.3 2005/02/17 11:54:28 rocky Exp $
4
Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
This tries to determine what kind of CD-image or filesystems on a
42
#include <cdio/cdio.h>
43
#include <cdio/iso9660.h>
44
#include <cdio/logging.h>
45
#include <cdio/util.h>
46
#include <cdio/cd_types.h>
49
Subject: -65- How can I read an IRIX (EFS) CD-ROM on a machine which
51
Date: 18 Jun 1995 00:00:01 EST
53
You want 'efslook', at
54
ftp://viz.tamu.edu/pub/sgi/software/efslook.tar.gz.
57
! Robert E. Seastrom <rs@access4.digex.net>'s software (with source
58
! code) for using an SGI CD-ROM on a Macintosh is at
59
! ftp://bifrost.seastrom.com/pub/mac/CDROM-Jumpstart.sit151.hqx.
63
static char buffer[6][CDIO_CD_FRAMESIZE_RAW]; /* for CD-Data */
65
/* Some interesting sector numbers stored in the above buffer. */
66
#define ISO_SUPERBLOCK_SECTOR 16 /* buffer[0] */
67
#define UFS_SUPERBLOCK_SECTOR 4 /* buffer[2] */
68
#define BOOT_SECTOR 17 /* buffer[3] */
69
#define VCD_INFO_SECTOR 150 /* buffer[4] */
70
#define XISO_SECTOR 32 /* buffer[4] */
71
#define UDFX_SECTOR 32 /* buffer[4] */
72
#define UDF_ANCHOR_SECTOR 256 /* buffer[5] */
75
typedef struct signature
80
const char *description;
83
static signature_t sigs[] =
85
/*buffer[x] off look for description */
86
{0, 0, "MICROSOFT*XBOX*MEDIA", "XBOX CD"},
87
{0, 1, "BEA01", "UDF"},
88
{0, 1, ISO_STANDARD_ID, "ISO 9660"},
89
{0, 1, "CD-I", "CD-I"},
90
{0, 8, "CDTV", "CDTV"},
91
{0, 8, "CD-RTOS", "CD-RTOS"},
92
{0, 9, "CDROM", "HIGH SIERRA"},
93
{0, 16, "CD-BRIDGE", "BRIDGE"},
94
{0, ISO_XA_MARKER_OFFSET, ISO_XA_MARKER_STRING, "XA"},
95
{1, 64, "PPPPHHHHOOOOTTTTOOOO____CCCCDDDD", "PHOTO CD"},
96
{1, 0x438, "\x53\xef", "EXT2 FS"},
97
{2, 1372, "\x54\x19\x01\x0", "UFS"},
98
{3, 7, "EL TORITO", "BOOTABLE"},
99
{4, 0, "VIDEO_CD", "VIDEO CD"},
100
{4, 0, "SUPERVCD", "SVCD or Chaoji VCD"},
105
/* The below index into the above sigs array. Make sure things match. */
106
#define INDEX_XISO 0 /* Microsoft X-BOX filesystem */
108
#define INDEX_ISOFS 2
111
#define INDEX_CD_RTOS 5
113
#define INDEX_BRIDGE 7
115
#define INDEX_PHOTO_CD 9
116
#define INDEX_EXT2 10
118
#define INDEX_BOOTABLE 12
119
#define INDEX_VIDEO_CD 13 /* Video CD */
120
#define INDEX_SVCD 14 /* CVD *or* SVCD */
124
Read a particular block into the global array to be used for further
127
static driver_return_code_t
128
_cdio_read_block(const CdIo_t *p_cdio, int superblock, uint32_t offset,
129
uint8_t bufnum, track_t i_track)
131
unsigned int track_sec_count = cdio_get_track_sec_count(p_cdio, i_track);
132
memset(buffer[bufnum], 0, CDIO_CD_FRAMESIZE);
134
if ( track_sec_count < superblock) {
135
cdio_debug("reading block %u skipped track %d has only %u sectors\n",
136
superblock, i_track, track_sec_count);
137
return DRIVER_OP_ERROR;
140
cdio_debug("about to read sector %lu\n",
141
(long unsigned int) offset+superblock);
143
return cdio_read_data_sectors (p_cdio, buffer[bufnum], offset+superblock,
148
Return true if the previously read-in buffer contains a "signature" that
154
signature_t *sigp=&sigs[num];
155
int len=strlen(sigp->sig_str);
157
/* TODO: check that num < largest sig. */
158
return 0 == memcmp(&buffer[sigp->buf_num][sigp->offset], sigp->sig_str, len);
164
return (0 == memcmp(&buffer[1][512],"PM",2)) ||
165
(0 == memcmp(&buffer[1][512],"TS",2)) ||
166
(0 == memcmp(&buffer[1][1024], "BD",2));
172
return (0 == memcmp(&buffer[1][0],"\x01\x5a\x5a\x5a\x5a\x5a\x01", 7)) &&
173
(0 == memcmp(&buffer[1][40], "CD-ROM", 6));
177
_cdio_is_joliet(void)
179
return 2 == buffer[3][0] && buffer[3][88] == 0x25 && buffer[3][89] == 0x2f;
185
return 2 == ((uint16_t)buffer[5][0] | ((uint16_t)buffer[5][1] << 8));
188
/* ISO 9660 volume space in M2F1_SECTOR_SIZE byte units */
190
_cdio_get_iso9660_fs_sec_count(void)
192
return ((buffer[0][80] & 0xff) |
193
((buffer[0][81] & 0xff) << 8) |
194
((buffer[0][82] & 0xff) << 16) |
195
((buffer[0][83] & 0xff) << 24));
199
_cdio_get_joliet_level( void )
201
switch (buffer[3][90]) {
210
Try to determine what kind of CD-image and/or filesystem we
211
have at track i_track. Return information about the CD image
212
is returned in cdio_analysis and the return value.
215
cdio_guess_cd_type(const CdIo_t *p_cdio, int start_session, track_t i_track,
216
/*out*/ cdio_iso_analysis_t *iso_analysis)
218
int ret = CDIO_FS_UNKNOWN;
219
bool sector0_read_ok;
221
if (TRACK_FORMAT_AUDIO == cdio_get_track_format(p_cdio, i_track))
222
return CDIO_FS_AUDIO;
224
if ( DRIVER_OP_SUCCESS !=
225
_cdio_read_block(p_cdio, ISO_PVD_SECTOR, start_session, 0, i_track) )
226
return CDIO_FS_UNKNOWN;
228
if ( _cdio_is_it(INDEX_XISO) )
229
return CDIO_FS_ANAL_XISO;
231
if ( DRIVER_OP_SUCCESS != _cdio_read_block(p_cdio, ISO_SUPERBLOCK_SECTOR,
232
start_session, 0, i_track) )
235
if ( _cdio_is_it(INDEX_UDF) ) {
236
/* Detect UDF version
237
Test if we have a valid version of UDF the xbox can read natively */
238
if (_cdio_read_block(p_cdio, 35, start_session, 5, i_track) < 0)
239
return CDIO_FS_UNKNOWN;
241
iso_analysis->UDFVerMinor=(unsigned int)buffer[5][240];
242
iso_analysis->UDFVerMajor=(unsigned int)buffer[5][241];
243
/* Read disc label */
244
if (_cdio_read_block(p_cdio, 32, start_session, 5, i_track) < 0)
247
strncpy(iso_analysis->iso_label, buffer[5]+25, 33);
248
iso_analysis->iso_label[32] = '\0';
252
/* We have something that smells of a filesystem. */
253
if (_cdio_is_it(INDEX_CD_I) && _cdio_is_it(INDEX_CD_RTOS)
254
&& !_cdio_is_it(INDEX_BRIDGE) && !_cdio_is_it(INDEX_XA)) {
255
return CDIO_FS_INTERACTIVE;
257
/* read sector 0 ONLY, when NO greenbook CD-I !!!! */
260
_cdio_read_block(p_cdio, 0, start_session, 1, i_track) == 0;
262
if (_cdio_is_it(INDEX_HS))
263
ret |= CDIO_FS_HIGH_SIERRA;
264
else if (_cdio_is_it(INDEX_ISOFS)) {
265
if (_cdio_is_it(INDEX_CD_RTOS) && _cdio_is_it(INDEX_BRIDGE))
266
ret = CDIO_FS_ISO_9660_INTERACTIVE;
267
else if (_cdio_is_hfs())
268
ret = CDIO_FS_ISO_HFS;
270
ret = CDIO_FS_ISO_9660;
271
iso_analysis->isofs_size = _cdio_get_iso9660_fs_sec_count();
272
strncpy(iso_analysis->iso_label, buffer[0]+40,33);
273
iso_analysis->iso_label[32] = '\0';
275
if ( _cdio_read_block(p_cdio, UDF_ANCHOR_SECTOR, start_session, 5,
279
/* Maybe there is an UDF anchor in IOS session
280
so its ISO/UDF session and we prefere UDF */
281
if ( _cdio_is_UDF() ) {
282
/* Detect UDF version.
283
Test if we have a valid version of UDF the xbox can read natively */
284
if ( _cdio_read_block(p_cdio, 35, start_session, 5, i_track) < 0)
287
iso_analysis->UDFVerMinor=(unsigned int)buffer[5][240];
288
iso_analysis->UDFVerMajor=(unsigned int)buffer[5][241];
290
/* We are using ISO/UDF cd's as iso,
291
no need to get UDF disc label */
292
if (_cdio_read_block(p_cdio, 32, start_session, 5, i_track) < 0)
294
stnrcpy(iso_analysis->iso_label, buffer[5]+25, 33);
295
iso_analysis->iso_label[32] = '\0';
301
if (_cdio_is_rockridge())
302
ret |= CDIO_FS_ANAL_ROCKRIDGE;
305
if (_cdio_read_block(p_cdio, BOOT_SECTOR, start_session, 3, i_track) < 0)
308
if (_cdio_is_joliet()) {
309
iso_analysis->joliet_level = _cdio_get_joliet_level();
310
ret |= CDIO_FS_ANAL_JOLIET;
312
if (_cdio_is_it(INDEX_BOOTABLE))
313
ret |= CDIO_FS_ANAL_BOOTABLE;
315
if ( _cdio_is_it(INDEX_XA) && _cdio_is_it(INDEX_ISOFS)
316
&& !(sector0_read_ok && _cdio_is_it(INDEX_PHOTO_CD)) ) {
318
if ( _cdio_read_block(p_cdio, VCD_INFO_SECTOR, start_session, 4,
322
if (_cdio_is_it(INDEX_BRIDGE) && _cdio_is_it(INDEX_CD_RTOS)) {
323
if (_cdio_is_it(INDEX_VIDEO_CD)) ret |= CDIO_FS_ANAL_VIDEOCD;
324
else if (_cdio_is_it(INDEX_SVCD)) ret |= CDIO_FS_ANAL_SVCD;
325
} else if (_cdio_is_it(INDEX_SVCD)) ret |= CDIO_FS_ANAL_CVD;
329
else if (_cdio_is_hfs()) ret |= CDIO_FS_HFS;
330
else if (sector0_read_ok && _cdio_is_it(INDEX_EXT2)) ret |= CDIO_FS_EXT2;
331
else if (_cdio_is_3do()) ret |= CDIO_FS_3DO;
333
if ( _cdio_read_block(p_cdio, UFS_SUPERBLOCK_SECTOR, start_session, 2,
337
if (sector0_read_ok && _cdio_is_it(INDEX_UFS))
340
ret |= CDIO_FS_UNKNOWN;
345
if (_cdio_is_it(INDEX_XA)) ret |= CDIO_FS_ANAL_XA;
346
if (_cdio_is_it(INDEX_PHOTO_CD)) ret |= CDIO_FS_ANAL_PHOTO_CD;
347
if (_cdio_is_it(INDEX_CDTV)) ret |= CDIO_FS_ANAL_CDTV;