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
|
/*
* Copyright (C) 2005-2018 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
* See LICENSES/README.md for more information.
*/
#pragma once
// CCdInfo - Information about media type of an inserted cd
// CCdIoSupport - Wrapper class for libcdio with the interface of CIoSupport
// and detecting the filesystem on the Disc.
//
// by Bobbin007 in 2003
// CD-Text support by Mog - Oct 2004
#include "threads/CriticalSection.h"
#include <map>
#include <memory>
#include <string>
#include <utility>
#include "PlatformDefs.h" // for ssize_t typedef, used by cdio
#include <cdio/cdio.h>
namespace MEDIA_DETECT
{
#define STRONG "__________________________________\n"
//#define NORMAL ""
#define FS_NO_DATA 0 /* audio only */
#define FS_HIGH_SIERRA 1
#define FS_ISO_9660 2
#define FS_INTERACTIVE 3
#define FS_HFS 4
#define FS_UFS 5
#define FS_EXT2 6
#define FS_ISO_HFS 7 /* both hfs & isofs filesystem */
#define FS_ISO_9660_INTERACTIVE 8 /* both CD-RTOS and isofs filesystem */
#define FS_3DO 9
#define FS_UDF 11
#define FS_ISO_UDF 12
#define FS_UNKNOWN 15
#define FS_MASK 15
#define XA 16
#define MULTISESSION 32
#define PHOTO_CD 64
#define HIDDEN_TRACK 128
#define CDTV 256
#define BOOTABLE 512
#define VIDEOCDI 1024
#define ROCKRIDGE 2048
#define JOLIET 4096
#define CVD 8192 /* Choiji Video CD */
#define IS_ISOFS 0
#define IS_CD_I 1
#define IS_CDTV 2
#define IS_CD_RTOS 3
#define IS_HS 4
#define IS_BRIDGE 5
#define IS_XA 6
#define IS_PHOTO_CD 7
#define IS_EXT2 8
#define IS_UFS 9
#define IS_BOOTABLE 10
#define IS_VIDEO_CD 11 /* Video CD */
#define IS_CVD 12 /* Chinese Video CD - slightly incompatible with SVCD */
#define IS_UDF 14
typedef struct signature
{
unsigned int buf_num;
unsigned int offset;
const char *sig_str;
const char *description;
}
signature_t;
typedef std::map<cdtext_field_t, std::string> xbmc_cdtext_t;
typedef struct TRACKINFO
{
int nfsInfo; // Information of the Tracks Filesystem
int nJolietLevel; // Jouliet Level
int ms_offset; // Multisession Offset
int isofs_size; // Size of the ISO9660 Filesystem
int nFrames; // Can be used for cddb query
int nMins; // minutes playtime part of Track
int nSecs; // seconds playtime part of Track
xbmc_cdtext_t cdtext; // CD-Text for this track
}
trackinfo;
/*! \brief Helper enum class for the MMC tray state
*/
enum class CdioTrayStatus
{
/* The MMC tray state is reported closed */
CLOSED,
/* The MMC tray state is reported open */
OPEN,
/* The MMC tray status operation is not supported */
UNKNOWN,
/* Generic driver error */
DRIVER_ERROR
};
class CCdInfo
{
public:
CCdInfo()
{
m_bHasCDDBInfo = true;
m_nLength = m_nFirstTrack = m_nNumTrack = m_nNumAudio = m_nFirstAudio = m_nNumData = m_nFirstData = 0;
}
trackinfo GetTrackInformation( int nTrack ) { return m_ti[nTrack -1]; }
xbmc_cdtext_t GetDiscCDTextInformation() { return m_cdtext; }
bool HasDataTracks() { return (m_nNumData > 0); }
bool HasAudioTracks() { return (m_nNumAudio > 0); }
int GetFirstTrack() { return m_nFirstTrack; }
int GetTrackCount() { return m_nNumTrack; }
int GetFirstAudioTrack() { return m_nFirstAudio; }
int GetFirstDataTrack() { return m_nFirstData; }
int GetDataTrackCount() { return m_nNumData; }
int GetAudioTrackCount() { return m_nNumAudio; }
uint32_t GetCddbDiscId() { return m_ulCddbDiscId; }
int GetDiscLength() { return m_nLength; }
std::string GetDiscLabel(){ return m_strDiscLabel; }
// CD-ROM with ISO 9660 filesystem
bool IsIso9660( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_ISO_9660); }
// CD-ROM with joliet extension
bool IsJoliet( int nTrack ) { return (m_ti[nTrack - 1].nfsInfo & JOLIET) ? false : true; }
// Joliet extension level
int GetJolietLevel( int nTrack ) { return m_ti[nTrack - 1].nJolietLevel; }
// ISO filesystem size
int GetIsoSize( int nTrack ) { return m_ti[nTrack - 1].isofs_size; }
// CD-ROM with rockridge extensions
bool IsRockridge( int nTrack ) { return (m_ti[nTrack - 1].nfsInfo & ROCKRIDGE) ? false : true; }
// CD-ROM with CD-RTOS and ISO 9660 filesystem
bool IsIso9660Interactive( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_ISO_9660_INTERACTIVE); }
// CD-ROM with High Sierra filesystem
bool IsHighSierra( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_HIGH_SIERRA); }
// CD-Interactive, with audiotracks > 0 CD-Interactive/Ready
bool IsCDInteractive( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_INTERACTIVE); }
// CD-ROM with Macintosh HFS
bool IsHFS( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_HFS); }
// CD-ROM with both Macintosh HFS and ISO 9660 filesystem
bool IsISOHFS( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_ISO_HFS); }
// CD-ROM with both UDF and ISO 9660 filesystem
bool IsISOUDF( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_ISO_UDF); }
// CD-ROM with Unix UFS
bool IsUFS( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_UFS); }
// CD-ROM with Linux second extended filesystem
bool IsEXT2( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_EXT2); }
// CD-ROM with Panasonic 3DO filesystem
bool Is3DO( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_3DO); }
// Mixed Mode CD-ROM
bool IsMixedMode( int nTrack ) { return (m_nFirstData == 1 && m_nNumAudio > 0); }
// CD-ROM with XA sectors
bool IsXA( int nTrack ) { return (m_ti[nTrack - 1].nfsInfo & XA) ? false : true; }
// Multisession CD-ROM
bool IsMultiSession( int nTrack ) { return (m_ti[nTrack - 1].nfsInfo & MULTISESSION) ? false : true; }
// Gets multisession offset
int GetMultisessionOffset( int nTrack ) { return m_ti[nTrack - 1].ms_offset; }
// Hidden Track on Audio CD
bool IsHiddenTrack( int nTrack ) { return (m_ti[nTrack - 1].nfsInfo & HIDDEN_TRACK) ? false : true; }
// Photo CD, with audiotracks > 0 Portfolio Photo CD
bool IsPhotoCd( int nTrack ) { return (m_ti[nTrack - 1].nfsInfo & PHOTO_CD) ? false : true; }
// CD-ROM with Commodore CDTV
bool IsCdTv( int nTrack ) { return (m_ti[nTrack - 1].nfsInfo & CDTV) ? false : true; }
// CD-Plus/Extra
bool IsCDExtra( int nTrack ) { return (m_nFirstData > 1); }
// Bootable CD
bool IsBootable( int nTrack ) { return (m_ti[nTrack - 1].nfsInfo & BOOTABLE) ? false : true; }
// Video CD
bool IsVideoCd( int nTrack ) { return (m_ti[nTrack - 1].nfsInfo & VIDEOCDI && m_nNumAudio == 0); }
// Chaoji Video CD
bool IsChaojiVideoCD( int nTrack ) { return (m_ti[nTrack - 1].nfsInfo & CVD) ? false : true; }
// Audio Track
bool IsAudio( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_NO_DATA); }
// UDF filesystem
bool IsUDF( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_UDF); }
// Has the cd a filesystem that is readable by the xbox
bool IsValidFs() { return (IsISOHFS(1) || IsIso9660(1) || IsIso9660Interactive(1) || IsISOUDF(1) || IsUDF(1) || IsAudio(1)); }
void SetFirstTrack( int nTrack ) { m_nFirstTrack = nTrack; }
void SetTrackCount( int nCount ) { m_nNumTrack = nCount; }
void SetFirstAudioTrack( int nTrack ) { m_nFirstAudio = nTrack; }
void SetFirstDataTrack( int nTrack ) { m_nFirstData = nTrack; }
void SetDataTrackCount( int nCount ) { m_nNumData = nCount; }
void SetAudioTrackCount( int nCount ) { m_nNumAudio = nCount; }
void SetTrackInformation(int nTrack, trackinfo nInfo)
{
if (nTrack > 0 && nTrack <= 99)
m_ti[nTrack - 1] = std::move(nInfo);
}
void SetDiscCDTextInformation(xbmc_cdtext_t cdtext) { m_cdtext = std::move(cdtext); }
void SetCddbDiscId( uint32_t ulCddbDiscId ) { m_ulCddbDiscId = ulCddbDiscId; }
void SetDiscLength( int nLength ) { m_nLength = nLength; }
bool HasCDDBInfo() { return m_bHasCDDBInfo; }
void SetNoCDDBInfo() { m_bHasCDDBInfo = false; }
void SetDiscLabel(const std::string& strDiscLabel){ m_strDiscLabel = strDiscLabel; }
private:
int m_nFirstData; /* # of first data track */
int m_nNumData; /* # of data tracks */
int m_nFirstAudio; /* # of first audio track */
int m_nNumAudio; /* # of audio tracks */
int m_nNumTrack;
int m_nFirstTrack;
trackinfo m_ti[100];
uint32_t m_ulCddbDiscId;
int m_nLength; // Disclength can be used for cddb query, also see trackinfo.nFrames
bool m_bHasCDDBInfo;
std::string m_strDiscLabel;
xbmc_cdtext_t m_cdtext; // CD-Text for this disc
};
class CLibcdio : public CCriticalSection
{
private:
CLibcdio();
public:
virtual ~CLibcdio();
static void ReleaseInstance();
static std::shared_ptr<CLibcdio> GetInstance();
// libcdio is not thread safe so these are wrappers to libcdio routines
CdIo_t* cdio_open(const char *psz_source, driver_id_t driver_id);
CdIo_t* cdio_open_win32(const char *psz_source);
void cdio_destroy(CdIo_t *p_cdio);
discmode_t cdio_get_discmode(CdIo_t *p_cdio);
CdioTrayStatus mmc_get_tray_status(const CdIo_t* p_cdio);
driver_return_code_t cdio_eject_media(CdIo_t** p_cdio);
track_t cdio_get_last_track_num(const CdIo_t *p_cdio);
lsn_t cdio_get_track_lsn(const CdIo_t *p_cdio, track_t i_track);
lsn_t cdio_get_track_last_lsn(const CdIo_t *p_cdio, track_t i_track);
driver_return_code_t cdio_read_audio_sectors(const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, uint32_t i_blocks);
driver_return_code_t cdio_close_tray(const char* psz_source, driver_id_t* driver_id);
const char* cdio_driver_errmsg(driver_return_code_t drc);
char* GetDeviceFileName();
private:
char* s_defaultDevice;
CCriticalSection m_critSection;
static std::shared_ptr<CLibcdio> m_pInstance;
};
class CCdIoSupport
{
public:
CCdIoSupport();
virtual ~CCdIoSupport();
bool EjectTray();
bool CloseTray();
HANDLE OpenCDROM();
HANDLE OpenIMAGE( std::string& strFilename );
int ReadSector(HANDLE hDevice, DWORD dwSector, char* lpczBuffer);
int ReadSectorMode2(HANDLE hDevice, DWORD dwSector, char* lpczBuffer);
int ReadSectorCDDA(HANDLE hDevice, DWORD dwSector, char* lpczBuffer);
void CloseCDROM(HANDLE hDevice);
void PrintAnalysis(int fs, int num_audio);
CCdInfo* GetCdInfo(char* cDeviceFileName=NULL);
void GetCdTextInfo(xbmc_cdtext_t &xcdt, int trackNum);
protected:
int ReadBlock(int superblock, uint32_t offset, uint8_t bufnum, track_t track_num);
bool IsIt(int num);
int IsHFS(void);
int Is3DO(void);
int IsJoliet(void);
int IsUDF(void);
int GetSize(void);
int GetJolietLevel( void );
int GuessFilesystem(int start_session, track_t track_num);
uint32_t CddbDiscId();
int CddbDecDigitSum(int n);
unsigned int MsfSeconds(msf_t *msf);
private:
char buffer[7][CDIO_CD_FRAMESIZE_RAW]; /* for CD-Data */
static signature_t sigs[17];
int i = 0, j = 0; /* index */
int m_nStartTrack; /* first sector of track */
int m_nIsofsSize; /* size of session */
int m_nJolietLevel;
int m_nMsOffset; /* multisession offset found by track-walking */
int m_nDataStart; /* start of data area */
int m_nFs;
int m_nUDFVerMinor;
int m_nUDFVerMajor;
CdIo* cdio;
track_t m_nNumTracks = CDIO_INVALID_TRACK;
track_t m_nFirstTrackNum = CDIO_INVALID_TRACK;
std::string m_strDiscLabel;
int m_nFirstData; /* # of first data track */
int m_nNumData; /* # of data tracks */
int m_nFirstAudio; /* # of first audio track */
int m_nNumAudio; /* # of audio tracks */
std::shared_ptr<CLibcdio> m_cdio;
};
}
|