mirror of
https://github.com/Team-Resurgent/XBMC4Xbox.git
synced 2026-08-15 11:18:13 -07:00
If ever adding the XBMC4Xbox source to GitHub use "git add -f -A" or it wont add all the files.
354 lines
12 KiB
C++
354 lines
12 KiB
C++
/*
|
|
* Copyright (C) 2005-2013 Team XBMC
|
|
* http://xbmc.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 2, 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 XBMC; see the file COPYING. If not, see
|
|
* <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
// 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
|
|
//
|
|
//
|
|
//
|
|
|
|
#pragma once
|
|
|
|
#include "xbox/IoSupport.h"
|
|
|
|
#include "lib/libcdio/intTypes.h"
|
|
#include "lib/libcdio/Types.h"
|
|
#include "lib/libcdio/cdio.h"
|
|
#include "lib/libcdio/cd_Types.h"
|
|
#include "lib/libcdio/cdtext.h"
|
|
#include "../utils/CriticalSection.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_UDFX 10
|
|
#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_UDFX 13
|
|
#define IS_UDF 14
|
|
|
|
typedef struct signature
|
|
{
|
|
unsigned int buf_num;
|
|
unsigned int offset;
|
|
const char *sig_str;
|
|
const char *description;
|
|
}
|
|
signature_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
|
|
cdtext_t cdtext; // CD-Text for this track
|
|
}
|
|
trackinfo;
|
|
|
|
|
|
class CCdInfo
|
|
{
|
|
public:
|
|
CCdInfo()
|
|
{
|
|
m_bHasCDDBInfo = true;
|
|
cdtext_init(&m_cdtext);
|
|
for (int i = 0; i < 100; i++)
|
|
cdtext_init(&m_ti[i].cdtext);
|
|
|
|
m_nLength = m_nFirstTrack = m_nNumTrack = m_nNumAudio = m_nFirstAudio = m_nNumData = m_nFirstData = 0;
|
|
}
|
|
virtual ~CCdInfo()
|
|
{
|
|
cdtext_destroy(&m_cdtext);
|
|
for (int i = 0; i < 100; i++)
|
|
cdtext_destroy(&m_ti[i].cdtext);
|
|
}
|
|
|
|
trackinfo GetTrackInformation( int nTrack ) { return m_ti[nTrack -1]; }
|
|
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; }
|
|
ULONG GetCddbDiscId() { return m_ulCddbDiscId; }
|
|
int GetDiscLength() { return m_nLength; }
|
|
CStdString 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); }
|
|
|
|
// CD-ROM with XBOX UDFX filesystem
|
|
bool IsUDFX( int nTrack ) { return ((m_ti[nTrack - 1].nfsInfo & FS_MASK) == FS_UDFX); }
|
|
|
|
// 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) || IsUDFX(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] = nInfo; }
|
|
void SetDiscCDTextInformation( cdtext_t cdtext ) { m_cdtext = cdtext; }
|
|
|
|
void SetCddbDiscId( ULONG ulCddbDiscId ) { m_ulCddbDiscId = ulCddbDiscId; }
|
|
void SetDiscLength( int nLength ) { m_nLength = nLength; }
|
|
bool HasCDDBInfo() { return m_bHasCDDBInfo; }
|
|
void SetNoCDDBInfo() { m_bHasCDDBInfo = false; }
|
|
|
|
void SetDiscLabel(const CStdString& 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];
|
|
ULONG m_ulCddbDiscId;
|
|
int m_nLength; // Disclength can be used for cddb query, also see trackinfo.nFrames
|
|
bool m_bHasCDDBInfo;
|
|
CStdString m_strDiscLabel;
|
|
cdtext_t m_cdtext; // CD-Text for this disc
|
|
};
|
|
|
|
class CLibcdio : public CCriticalSection
|
|
{
|
|
private:
|
|
CLibcdio();
|
|
public:
|
|
virtual ~CLibcdio();
|
|
|
|
static void RemoveInstance();
|
|
static 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);
|
|
int mmc_get_tray_status(const CdIo_t *p_cdio);
|
|
int 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);
|
|
|
|
char* GetDeviceFileName();
|
|
|
|
private:
|
|
CCriticalSection m_critSection;
|
|
static CLibcdio* m_pInstance;
|
|
};
|
|
|
|
class CCdIoSupport
|
|
{
|
|
public:
|
|
CCdIoSupport();
|
|
virtual ~CCdIoSupport();
|
|
|
|
HRESULT EjectTray();
|
|
HRESULT CloseTray();
|
|
|
|
HANDLE OpenCDROM();
|
|
HANDLE OpenIMAGE( CStdString& strFilename );
|
|
INT ReadSector(HANDLE hDevice, DWORD dwSector, LPSTR lpczBuffer);
|
|
INT ReadSectorMode2(HANDLE hDevice, DWORD dwSector, LPSTR lpczBuffer);
|
|
INT ReadSectorCDDA(HANDLE hDevice, DWORD dwSector, LPSTR lpczBuffer);
|
|
VOID CloseCDROM(HANDLE hDevice);
|
|
|
|
void PrintAnalysis(int fs, int num_audio);
|
|
|
|
CCdInfo* GetCdInfo();
|
|
void GetCdTextInfo(trackinfo *pti, 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);
|
|
|
|
ULONG CddbDiscId();
|
|
int CddbDecDigitSum(int n);
|
|
UINT MsfSeconds(msf_t *msf);
|
|
|
|
private:
|
|
char buffer[7][CDIO_CD_FRAMESIZE_RAW]; /* for CD-Data */
|
|
static signature_t sigs[17];
|
|
int i, j; /* 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;
|
|
track_t m_nFirstTrackNum;
|
|
|
|
CStdString 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 */
|
|
|
|
CLibcdio* m_cdio;
|
|
};
|
|
|
|
}
|