IsoFile/IsoFS code conformance stuffs:

* Converted new code to use PCSX2/wxWidgets types and utility/helpers.
 * use u32 where appropriate (as defined by ISO 9660), and removed s64 stuff since it's not supported by the file format anyway.
 * general fixups to conform better to general C++ style error and object handling.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2165 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-11-08 17:29:12 +00:00
parent e0f455a57a
commit c6b14bd7f0
11 changed files with 665 additions and 698 deletions

View File

@ -71,13 +71,10 @@ static void CheckNullCDVD()
// //
static int CheckDiskTypeFS(int baseType) static int CheckDiskTypeFS(int baseType)
{ {
try {
IsoFSCDVD isofs; IsoFSCDVD isofs;
IsoDirectory fsroot(&isofs); IsoDirectory rootdir(isofs);
try { try {
// Will throw exception if the file was not found IsoFile file( rootdir, L"SYSTEM.CNF;1");
IsoFile file = fsroot.OpenFile("SYSTEM.CNF;1");
int size = file.getLength(); int size = file.getLength();
@ -95,29 +92,15 @@ static int CheckDiskTypeFS(int baseType)
return (baseType==CDVD_TYPE_DETCTCD) ? CDVD_TYPE_PS2CD : CDVD_TYPE_PS2DVD; return (baseType==CDVD_TYPE_DETCTCD) ? CDVD_TYPE_PS2CD : CDVD_TYPE_PS2DVD;
} }
catch( ... ) catch( Exception::FileNotFound& )
{ {
} }
try { if( rootdir.IsFile(L"PSX.EXE;1") )
fsroot.FindFile("PSX.EXE;1");
return CDVD_TYPE_PSCD; return CDVD_TYPE_PSCD;
}
catch( ... )
{
}
try { if( rootdir.IsFile(L"VIDEO_TS/VIDEO_TS.IFO;1") )
fsroot.FindFile("VIDEO_TS/VIDEO_TS.IFO;1");
return CDVD_TYPE_DVDV; return CDVD_TYPE_DVDV;
}
catch( ... )
{
}
}
catch( ... )
{
}
return CDVD_TYPE_ILLEGAL; // << Only for discs which aren't ps2 at all. return CDVD_TYPE_ILLEGAL; // << Only for discs which aren't ps2 at all.
} }

View File

@ -0,0 +1,30 @@
#pragma once
class IsoDirectory
{
public:
SectorSource& internalReader;
std::vector<IsoFileDescriptor> files;
public:
IsoDirectory(SectorSource& r);
IsoDirectory(SectorSource& r, IsoFileDescriptor directoryEntry);
~IsoDirectory() throw();
SectorSource& GetReader() const { return internalReader; }
bool Exists(const wxString& filePath) const;
bool IsFile(const wxString& filePath) const;
bool IsDir(const wxString& filePath) const;
u32 GetFileSize( const wxString& filePath ) const;
IsoFileDescriptor FindFile(const wxString& filePath) const;
protected:
const IsoFileDescriptor& GetEntry(const wxString& fileName) const;
const IsoFileDescriptor& GetEntry(int index) const;
void Init(const IsoFileDescriptor& directoryEntry);
int GetIndexOf(const wxString& fileName) const;
};

View File

@ -1,157 +1,143 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "IsoFS.h" #include "IsoFS.h"
#include "IsoFile.h"
#include <vector>
using namespace std;
void Tokenize(const string& str, vector<string>& tokens, const string& delimiters = " ")
{
string::size_type lastPos = str.find_first_not_of(delimiters, 0);
string::size_type pos = str.find_first_of(delimiters, lastPos);
while (string::npos != pos || string::npos != lastPos)
{
tokens.push_back(str.substr(lastPos, pos - lastPos));
lastPos = str.find_first_not_of(delimiters, pos);
pos = str.find_first_of(delimiters, lastPos);
}
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// IsoDirectory // IsoDirectory
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
IsoDirectory::IsoDirectory(SectorSource* r) // Used to load the Root directory from an image
IsoDirectory::IsoDirectory(SectorSource& r) :
internalReader(r)
{ {
byte sector[2048]; u8 sector[2048];
r->readSector(sector,16); internalReader.readSector(sector,16);
IsoFileDescriptor rootDirEntry(sector+156,38); IsoFileDescriptor rootDirEntry(sector+156,38);
Init(r, rootDirEntry); Init(rootDirEntry);
} }
IsoDirectory::IsoDirectory(SectorSource* r, IsoFileDescriptor directoryEntry) // Used to load a specific directory from a file descriptor
IsoDirectory::IsoDirectory(SectorSource& r, IsoFileDescriptor directoryEntry) :
internalReader(r)
{ {
Init(r, directoryEntry); Init(directoryEntry);
} }
void IsoDirectory::Init(SectorSource* r, IsoFileDescriptor directoryEntry) IsoDirectory::~IsoDirectory() throw()
{
}
void IsoDirectory::Init(const IsoFileDescriptor& directoryEntry)
{ {
// parse directory sector // parse directory sector
IsoFile dataStream (r, directoryEntry); IsoFile dataStream (internalReader, directoryEntry);
internalReader = r;
files.clear(); files.clear();
int remainingSize = directoryEntry.size; int remainingSize = directoryEntry.size;
byte b[257]; u8 b[257];
while(remainingSize>=4) // hm hack :P while(remainingSize>=4) // hm hack :P
{ {
b[0] = dataStream.read<byte>(); b[0] = dataStream.read<u8>();
if(b[0]==0) if(b[0]==0)
{ {
break; // or continue? break; // or continue?
} }
remainingSize-=b[0]; remainingSize -= b[0];
dataStream.read(b+1, b[0]-1); dataStream.read(b+1, b[0]-1);
IsoFileDescriptor file(b,b[0]); files.push_back(IsoFileDescriptor(b, b[0]));
files.push_back(file);
} }
b[0] = 0; b[0] = 0;
} }
IsoFileDescriptor IsoDirectory::GetEntry(int index) const IsoFileDescriptor& IsoDirectory::GetEntry(int index) const
{ {
return files[index]; return files[index];
} }
int IsoDirectory::GetIndexOf(string fileName) int IsoDirectory::GetIndexOf(const wxString& fileName) const
{ {
for(unsigned int i=0;i<files.size();i++) for(unsigned int i=0;i<files.size();i++)
{ {
string file = files[i].name; if(files[i].name == fileName) return i;
if(file.compare(fileName)==0)
{
return i;
}
} }
throw Exception::FileNotFound( fileName.c_str() ); throw Exception::FileNotFound( fileName );
} }
IsoFileDescriptor IsoDirectory::GetEntry(string fileName) const IsoFileDescriptor& IsoDirectory::GetEntry(const wxString& fileName) const
{ {
return GetEntry(GetIndexOf(fileName)); return GetEntry(GetIndexOf(fileName));
} }
IsoFileDescriptor IsoDirectory::FindFile(string filePath) IsoFileDescriptor IsoDirectory::FindFile(const wxString& filePath) const
{ {
pxAssert( !filePath.IsEmpty() );
// wxWidgets DOS-style parser should work fine for ISO 9660 path names. Only practical difference
// is case sensitivity, and that won't matter for path splitting.
wxFileName parts( filePath, wxPATH_DOS );
IsoFileDescriptor info; IsoFileDescriptor info;
IsoDirectory dir = *this; const IsoDirectory* dir = this;
ScopedPtr<IsoDirectory> deleteme;
// this was supposed to be a vector<string>, but this damn hotfix kills stl // walk through path ("." and ".." entries are in the directories themselves, so even if the
// if you have the Windows SDK 6.1 installed after vs2008 sp1 // path included . and/or .., it still works)
vector<string> path;
Tokenize(filePath,path,"\\/"); for(uint i=0; i<parts.GetDirCount(); ++i)
// walk through path ("." and ".." entries are in the directories themselves, so even if the path included . and/or .., it should still work)
for(int i=0;i<path.size();i++)
{ {
string pathName = path[i]; info = dir->GetEntry(parts.GetDirs()[i]);
info = dir.GetEntry(pathName); if(info.IsFile()) throw Exception::FileNotFound( filePath );
if((info.flags&2)==2) // if it's a directory
{ dir = deleteme = new IsoDirectory(internalReader, info);
dir = IsoDirectory(internalReader, info);
}
} }
if( !parts.GetFullName().IsEmpty() )
info = dir->GetEntry(parts.GetFullName());
return info; return info;
} }
IsoFile IsoDirectory::OpenFile(string filePath) bool IsoDirectory::IsFile(const wxString& filePath) const
{ {
IsoFileDescriptor info = FindFile(filePath); if( filePath.IsEmpty() ) return false;
if((info.flags&2)==2) // if it's a directory return (FindFile(filePath).flags&2) != 2;
{
throw Exception::InvalidArgument("Filename points to a directory.");
}
return IsoFile(internalReader, info);
} }
IsoDirectory::~IsoDirectory(void) bool IsoDirectory::IsDir(const wxString& filePath) const
{ {
if( filePath.IsEmpty() ) return false;
return (FindFile(filePath).flags&2) == 2;
} }
////////////////////////////////////////////////////////////////////////// u32 IsoDirectory::GetFileSize( const wxString& filePath ) const
// IsoFileDescriptor {
////////////////////////////////////////////////////////////////////////// return FindFile( filePath ).size;
}
IsoFileDescriptor::IsoFileDescriptor() IsoFileDescriptor::IsoFileDescriptor()
{ {
lba = 0; lba = 0;
size = 0; size = 0;
flags = 0; flags = 0;
name = "";
} }
IsoFileDescriptor::IsoFileDescriptor(const byte* data, int length) IsoFileDescriptor::IsoFileDescriptor(const u8* data, int length)
{ {
lba = *(const int*)(data+2); lba = (u32&)data[2];
size = *(const int*)(data+10); size = (u32&)data[10];
date.year = data[18] + 1900; date.year = data[18] + 1900;
date.month = data[19]; date.month = data[19];
date.day = data[20]; date.day = data[20];
@ -162,27 +148,35 @@ IsoFileDescriptor::IsoFileDescriptor(const byte* data, int length)
flags = data[25]; flags = data[25];
if((lba<0)||(length<0)) // This assert probably means a coder error, but let's fall back on a runtime exception
{ // in release builds since, most likely, the error is "recoverable" form a user standpoint.
// would be nice to have some exceptio nthis fits in if( !pxAssertDev( (lba>=0) && (length>=0), "Invalid ISO file descriptor data encountered." ) )
throw Exception::InvalidOperation("WTF?! Size or lba < 0?!"); throw Exception::BadStream();
}
int fileNameLength = data[32]; int fileNameLength = data[32];
name.clear();
if(fileNameLength==1) if(fileNameLength==1)
{ {
char c = *(const char*)(data+33); u8 c = data[33];
switch(c) switch(c)
{ {
case 0: name = "."; break; case 0: name = L"."; break;
case 1: name = ".."; break; case 1: name = L".."; break;
default: name.append(1,c); default: name = (wxChar)c;
}
}
else
{
// copy string and up-convert from ascii to wxChar
const u8* fnsrc = data+33;
const u8* fnend = fnsrc+fileNameLength;
while( fnsrc != fnend )
{
name += (wxChar)*fnsrc;
++fnsrc;
} }
} }
else if (fileNameLength>0)
name.append((const char*)(data+33),fileNameLength);
} }

View File

@ -1,38 +1,11 @@
#pragma once #pragma once
#include <vector> class IsoFile;
#include <string> class IsoDirectory;
struct ISoFileDescriptor;
#include "SectorSource.h"
#include "IsoFileDescriptor.h" #include "IsoFileDescriptor.h"
#include "IsoFile.h" #include "IsoDirectory.h"
#include "ISoFile.h"
class IsoDirectory
{
public:
std::vector<IsoFileDescriptor> files;
SectorSource* internalReader;
protected:
void Init(SectorSource* r, IsoFileDescriptor directoryEntry);
public:
// Used to load the Root directory from an image
IsoDirectory(SectorSource* r);
// Used to load a specific directory from a file descriptor
IsoDirectory(SectorSource* r, IsoFileDescriptor directoryEntry);
IsoFileDescriptor GetEntry(std::string fileName);
IsoFileDescriptor GetEntry(int index);
int GetIndexOf(std::string fileName);
// Tool. For OpenFile.
IsoFileDescriptor FindFile(std::string filePath);
IsoFile OpenFile(std::string filePath);
~IsoDirectory(void);
};

View File

@ -8,10 +8,9 @@ class IsoFSCDVD: public SectorSource
{ {
public: public:
IsoFSCDVD(); IsoFSCDVD();
virtual ~IsoFSCDVD() throw();
virtual bool readSector(unsigned char* buffer, int lba); virtual bool readSector(unsigned char* buffer, int lba);
virtual int getNumSectors(); virtual int getNumSectors();
virtual ~IsoFSCDVD(void);
}; };

View File

@ -1,55 +1,84 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "IsoFS.h"
#include "IsoFile.h" #include "IsoFile.h"
using namespace std; IsoFile::IsoFile(SectorSource& reader, const wxString& filename)
: internalReader(reader)
IsoFile::IsoFile(SectorSource* reader, IsoFileDescriptor fileEntry) , fileEntry(IsoDirectory(reader).FindFile(filename))
: fileEntry(fileEntry)
{ {
internalReader = reader; Init();
currentSectorNumber=fileEntry.lba;
currentOffset = 0;
sectorOffset = 0;
maxOffset = fileEntry.size;
if(maxOffset>0)
reader->readSector(currentSector,currentSectorNumber);
} }
void IsoFile::seek(s64 offset) IsoFile::IsoFile(const IsoDirectory& dir, const wxString& filename)
: internalReader(dir.GetReader())
, fileEntry(dir.FindFile(filename))
{ {
s64 endOffset = offset; Init();
}
#ifdef __LINUX__ IsoFile::IsoFile(SectorSource& reader, const IsoFileDescriptor& fileEntry)
if (offset<0) throw "Seek offset out of bounds."; : internalReader(reader)
#else , fileEntry(fileEntry)
if(offset<0) {
throw new exception("Seek offset out of bounds."); Init();
#endif }
void IsoFile::Init()
{
//pxAssertDev( fileEntry.IsFile(), "IsoFile Error: Filename points to a directory." );
currentSectorNumber = fileEntry.lba;
currentOffset = 0;
sectorOffset = 0;
maxOffset = std::max<u32>( 0, fileEntry.size );
if(maxOffset > 0)
internalReader.readSector(currentSector, currentSectorNumber);
}
IsoFile::~IsoFile() throw()
{
}
u32 IsoFile::seek(u32 absoffset)
{
u32 endOffset = absoffset;
int oldSectorNumber = currentSectorNumber; int oldSectorNumber = currentSectorNumber;
s64 newOffset = endOffset; u32 newOffset = endOffset;
int newSectorNumber = fileEntry.lba + (int)(newOffset / sectorLength); int newSectorNumber = fileEntry.lba + (int)(newOffset / sectorLength);
if(oldSectorNumber != newSectorNumber) if(oldSectorNumber != newSectorNumber)
{ {
internalReader->readSector(currentSector, newSectorNumber); internalReader.readSector(currentSector, newSectorNumber);
} }
currentOffset = newOffset; currentOffset = newOffset;
currentSectorNumber = newSectorNumber; currentSectorNumber = newSectorNumber;
sectorOffset = (int)(currentOffset % sectorLength); sectorOffset = (int)(currentOffset % sectorLength);
return currentOffset;
} }
void IsoFile::seek(s64 offset, int ref_position) u32 IsoFile::seek(s32 offset, wxSeekMode ref_position)
{ {
if(ref_position == SEEK_SET) switch( ref_position )
seek(offset); {
case wxFromStart:
pxAssertDev( offset > 0, "Invalid seek position from start." );
return seek(offset);
if(ref_position == SEEK_CUR) case wxFromCurrent:
seek(currentOffset+offset); // truncate negative values to zero
return seek( std::max<u32>(0, currentOffset+offset) );
if(ref_position == SEEK_END) case wxFromEnd:
seek(fileEntry.size+offset); // truncate negative values to zero
return seek( std::max<u32>(0, fileEntry.size+offset) );
jNO_DEFAULT;
}
return 0; // unreachable
} }
void IsoFile::reset() void IsoFile::reset()
@ -57,38 +86,41 @@ void IsoFile::reset()
seek(0); seek(0);
} }
s64 IsoFile::skip(s64 n) // Returns the number of bytes actually skipped.
s32 IsoFile::skip(s32 n)
{ {
s64 oldOffset = currentOffset; s32 oldOffset = currentOffset;
if(n<0) if(n<0)
return n; return 0;
seek(currentOffset+n); seek(currentOffset+n);
return currentOffset-oldOffset; return currentOffset-oldOffset;
} }
s64 IsoFile::getFilePointer() u32 IsoFile::getSeekPos() const
{ {
return currentOffset; return currentOffset;
} }
bool IsoFile::eof() bool IsoFile::eof() const
{ {
return (currentOffset == maxOffset); return (currentOffset == maxOffset);
} }
// loads the current sector index into the CurrentSector buffer.
void IsoFile::makeDataAvailable() void IsoFile::makeDataAvailable()
{ {
if (sectorOffset >= sectorLength) { if (sectorOffset >= sectorLength)
{
currentSectorNumber++; currentSectorNumber++;
internalReader->readSector(currentSector, currentSectorNumber); internalReader.readSector(currentSector, currentSectorNumber);
sectorOffset -= sectorLength; sectorOffset -= sectorLength;
} }
} }
int IsoFile::read() u8 IsoFile::readByte()
{ {
if(currentOffset >= maxOffset) if(currentOffset >= maxOffset)
throw Exception::EndOfStream(); throw Exception::EndOfStream();
@ -100,41 +132,39 @@ int IsoFile::read()
return currentSector[sectorOffset++]; return currentSector[sectorOffset++];
} }
int IsoFile::internalRead(byte* b, int off, int len) // Reads data from a single sector at a time. Reads cannot cross sector boundaries.
int IsoFile::internalRead(void* dest, int off, int len)
{ {
if (len > 0) if (len > 0)
{ {
if (len > (maxOffset - currentOffset)) size_t slen = len;
if (slen > (maxOffset - currentOffset))
{ {
len = (int) (maxOffset - currentOffset); slen = (int) (maxOffset - currentOffset);
} }
memcpy(b + off, currentSector + sectorOffset, len); memcpy_fast((u8*)dest + off, currentSector + sectorOffset, slen);
sectorOffset += len; sectorOffset += slen;
currentOffset += len; currentOffset += slen;
return slen;
} }
return 0;
return len;
} }
int IsoFile::read(byte* b, int len) // returns the number of bytes actually read.
s32 IsoFile::read(void* dest, s32 len)
{ {
if (b == NULL) pxAssert( dest != NULL );
{ pxAssert( len >= 0 ); // should we silent-fail on negative length reads? prolly not...
throw Exception::ObjectIsNull("b");
}
if (len < 0) if( len <= 0 ) return 0;
{
throw Exception::InvalidOperation("off<0 or len<0.");
}
int off=0; int off = 0;
int totalLength = 0; int totalLength = 0;
int firstSector = internalRead(b, off, min(len, sectorLength - sectorOffset)); int firstSector = internalRead(dest, off, std::min(len, sectorLength - sectorOffset));
off += firstSector; off += firstSector;
len -= firstSector; len -= firstSector;
totalLength += firstSector; totalLength += firstSector;
@ -143,7 +173,7 @@ int IsoFile::read(byte* b, int len)
while ((len >= sectorLength) && (currentOffset < maxOffset)) while ((len >= sectorLength) && (currentOffset < maxOffset))
{ {
makeDataAvailable(); makeDataAvailable();
int n = internalRead(b, off, sectorLength); int n = internalRead(dest, off, sectorLength);
off += n; off += n;
len -= n; len -= n;
totalLength += n; totalLength += n;
@ -152,56 +182,39 @@ int IsoFile::read(byte* b, int len)
// Read remaining, if any // Read remaining, if any
if (len > 0) { if (len > 0) {
makeDataAvailable(); makeDataAvailable();
int lastSector = internalRead(b, off, len); int lastSector = internalRead(dest, off, len);
totalLength += lastSector; totalLength += lastSector;
} }
return totalLength; return totalLength;
} }
string IsoFile::readLine() // Reads data until it reaches a newline character (either \n, \r, or ASCII-Z). The caller is
// responsible for handling files with DOS-style newlines (CR/LF pairs), if needed. The resulting
// string has no newlines.
//
// Read data is unformatted 8 bit / Ascii. If the source file is known to be UTF8, use the fromUTF8()
// conversion helper provided by PCSX2 utility classes.
//
std::string IsoFile::readLine()
{ {
string s; std::string s;
char c; s.reserve( 512 );
s.clear(); while( !eof() )
do { {
if(eof()) u8 c = read<u8>();
if((c=='\n') || (c=='\r') || (c==0))
break; break;
c = read(); s += c;
}
if((c=='\n')||(c=='\r')||(c==0))
break;
s.append(1,c);
} while(true);
return s; return s;
} }
wstring IsoFile::readLineW() u32 IsoFile::getLength()
{
wstring s;
wchar_t c;
s.clear();
do {
if(eof())
break;
c = read<wchar_t>();
if((c==L'\n')||(c==L'\r')||(c==0))
break;
s.append(1,c);
} while(true);
return s;
}
s64 IsoFile::getLength()
{ {
return maxOffset; return maxOffset;
} }
@ -210,8 +223,3 @@ const IsoFileDescriptor& IsoFile::getEntry()
{ {
return fileEntry; return fileEntry;
} }
IsoFile::~IsoFile(void)
{
}

View File

@ -8,56 +8,54 @@ class IsoFile
public: public:
static const int sectorLength = 2048; static const int sectorLength = 2048;
private: protected:
SectorSource& internalReader;
IsoFileDescriptor fileEntry; IsoFileDescriptor fileEntry;
s64 currentOffset; u32 currentOffset;
s64 maxOffset; u32 maxOffset;
int currentSectorNumber; int currentSectorNumber;
byte currentSector[sectorLength]; u8 currentSector[sectorLength];
int sectorOffset; int sectorOffset;
SectorSource* internalReader;
void makeDataAvailable();
int internalRead(byte* b, int off, int len);
public: public:
IsoFile(const IsoDirectory& dir, const wxString& filename);
IsoFile(SectorSource& reader, const wxString& filename);
IsoFile(SectorSource& reader, const IsoFileDescriptor& fileEntry);
virtual ~IsoFile() throw();
IsoFile(SectorSource* reader, IsoFileDescriptor fileEntry); u32 seek(u32 absoffset);
u32 seek(s32 offset, wxSeekMode ref_position);
void seek(s64 offset);
void seek(s64 offset, int ref_position);
void reset(); void reset();
s64 skip(s64 n); s32 skip(s32 n);
s64 getFilePointer(); u32 getSeekPos() const;
u32 getLength();
bool eof() const;
bool eof(); const IsoFileDescriptor& getEntry();
int read();
int read(byte* b, int len); u8 readByte();
s32 read(void* dest, s32 len);
std::string readLine();
// Tool to read a specific value type, including structs. // Tool to read a specific value type, including structs.
template<class T> template< class T >
T read() T read()
{ {
if(sizeof(T)==1) if(sizeof(T)==1)
return (T)read(); return (T)readByte();
else else
{ {
T t; T t;
read((byte*)&t,sizeof(t)); read((u8*)&t,sizeof(t));
return t; return t;
} }
} }
std::string readLine(); // Assume null-termination protected:
std::wstring readLineW(); // (this one too) void makeDataAvailable();
int internalRead(void* dest, int off, int len);
s64 getLength(); void Init();
const IsoFileDescriptor& getEntry();
~IsoFile(void);
}; };

View File

@ -1,32 +1,27 @@
#pragma once #pragma once
#include <string> struct IsoFileDescriptor
typedef unsigned char byte;
class IsoFileDescriptor
{ {
public:
struct FileDate // not 1:1 with iso9660 date struct struct FileDate // not 1:1 with iso9660 date struct
{ {
int year; s32 year;
byte month; u8 month;
byte day; u8 day;
byte hour; u8 hour;
byte minute; u8 minute;
byte second; u8 second;
byte gmtOffset; // Offset from Greenwich Mean Time in number of 15 min intervals from -48 (West) to + 52 (East) u8 gmtOffset; // Offset from Greenwich Mean Time in number of 15 min intervals from -48 (West) to + 52 (East)
} date; } date;
int lba; u32 lba;
int size; u32 size;
int flags; int flags;
std::string name; //[128+1]; wxString name;
IsoFileDescriptor(); IsoFileDescriptor();
IsoFileDescriptor(const u8* data, int length);
IsoFileDescriptor(const byte* data, int length); bool IsFile() const { return !(flags & 2); }
bool IsDir() const { return !IsFile(); }
~IsoFileDescriptor(void) {}
}; };

View File

@ -5,5 +5,5 @@ class SectorSource
public: public:
virtual int getNumSectors()=0; virtual int getNumSectors()=0;
virtual bool readSector(unsigned char* buffer, int lba)=0; virtual bool readSector(unsigned char* buffer, int lba)=0;
virtual ~SectorSource(void) {}; virtual ~SectorSource() throw() {}
}; };

View File

@ -19,11 +19,12 @@
//#include "CDVD/IsoFSdrv.h" //#include "CDVD/IsoFSdrv.h"
#include "DebugTools/Debug.h" #include "DebugTools/Debug.h"
#include "GS.h" // for sending game crc to mtgs #include "GS.h" // for sending game crc to mtgs
#include "CDVD/IsoFS/IsoFSCDVD.h" #include "CDVD/IsoFS/IsoFSCDVD.h"
#include "CDVD/IsoFS/IsoFS.h" #include "CDVD/IsoFS/IsoFS.h"
using namespace std; using namespace std;
extern void InitPatch(wxString crc); extern void InitPatch(const wxString& crc);
u32 ElfCRC; u32 ElfCRC;
@ -329,16 +330,10 @@ struct ElfObject
(strnicmp( work, "cdrom1:", strlen("cdromN:")) == 0)) (strnicmp( work, "cdrom1:", strlen("cdromN:")) == 0))
{ {
IsoFSCDVD isofs; IsoFSCDVD isofs;
IsoDirectory fsroot(&isofs); IsoFile file( isofs, fromUTF8(work) );
// Will throw exception if the file was not found //int size = file.getLength();
IsoFile file = fsroot.OpenFile(work + strlen("cdromN:")); rsize = file.read(data.GetPtr(), data.GetSizeInBytes());
int size = file.getLength();
rsize = file.read((u8*)data.GetPtr(), data.GetSizeInBytes());
//if (fi < 0) throw Exception::FileNotFound( filename );
} }
else else
{ {
@ -509,24 +504,16 @@ void ElfApplyPatches()
// Fetches the CRC of the game bound to the CDVD plugin. // Fetches the CRC of the game bound to the CDVD plugin.
u32 loadElfCRC( const char* filename ) u32 loadElfCRC( const char* filename )
{ {
IsoFSCDVD isofs;
IsoDirectory fsroot(&isofs);
IsoFileDescriptor desc;
u32 crcval = 0; u32 crcval = 0;
Console.WriteLn("loadElfCRC: %s", filename); Console.WriteLn("loadElfCRC: %s", filename);
try {
int mylen = strlen( "cdromN:" ); int mylen = strlen( "cdromN:" );
desc = fsroot.FindFile( filename + mylen );
DevCon.WriteLn( "loadElfFile: %d bytes", desc.size ); IsoFSCDVD isofs;
crcval = ElfObject( fromUTF8( filename ), desc.size ).GetCRC(); const int filesize = IsoDirectory(isofs).GetFileSize( fromUTF8(filename) );
DevCon.WriteLn( "loadElfFile: %d bytes", filesize );
crcval = ElfObject( fromUTF8(filename), filesize ).GetCRC();
Console.WriteLn( "loadElfFile: %s; CRC = %8.8X", filename, crcval ); Console.WriteLn( "loadElfFile: %s; CRC = %8.8X", filename, crcval );
}
catch( ... )
{
}
return crcval; return crcval;
} }
@ -548,9 +535,8 @@ void loadElfFile(const wxString& filename)
s64 elfsize; s64 elfsize;
Console.WriteLn( L"loadElfFile: " + filename ); Console.WriteLn( L"loadElfFile: " + filename );
const wxCharBuffer buffer( filename.ToUTF8() ); const wxCharBuffer fnptr( filename.ToUTF8() );
const char* fnptr = buffer.data(); bool useCdvdSource = false;
bool useCdvdSource=false;
if( !filename.StartsWith( L"cdrom0:" ) && !filename.StartsWith( L"cdrom1:" ) ) if( !filename.StartsWith( L"cdrom0:" ) && !filename.StartsWith( L"cdrom1:" ) )
{ {
@ -562,21 +548,9 @@ void loadElfFile(const wxString& filename)
DevCon.WriteLn("Loading from a CD rom or CD image"); DevCon.WriteLn("Loading from a CD rom or CD image");
useCdvdSource = true; useCdvdSource = true;
IsoFileDescriptor desc;
try
{
IsoFSCDVD isofs;
IsoDirectory fsroot(&isofs);
Console.WriteLn(L"loadElfCRC: " + filename); Console.WriteLn(L"loadElfCRC: " + filename);
IsoFSCDVD isofs;
desc = fsroot.FindFile(fnptr + strlen( "cdromN:" )); elfsize = IsoDirectory( isofs ).GetFileSize( fromUTF8(fnptr) );
}
catch( ... )
{
throw Exception::FileNotFound( filename, wxLt("ELF file was not found on the CDVD source media.") );
}
elfsize = desc.size;
} }
if( elfsize > 0xfffffff ) if( elfsize > 0xfffffff )
@ -632,52 +606,65 @@ void loadElfFile(const wxString& filename)
// 2 - PS2 CD // 2 - PS2 CD
int GetPS2ElfName( wxString& name ) int GetPS2ElfName( wxString& name )
{ {
char buffer[g_MaxPath];//if a file is longer...it should be shorter :D char buffer[512];
try { try {
IsoFSCDVD isofs; IsoFSCDVD isofs;
IsoDirectory fsroot(&isofs); IsoFile file( isofs, L"SYSTEM.CNF;1");
try {
// Will throw exception if the file was not found
IsoFile file = fsroot.OpenFile("SYSTEM.CNF;1");
int size = file.getLength(); int size = file.getLength();
if( size == 0 ) return 0;
char buffer[256]; //if the file is longer...it should be shorter :D file.read( buffer, size );
file.read((u8*)buffer,size); buffer[size] = '\0';
buffer[size]='\0'; }
catch( Exception::FileNotFound& )
char* pos = strstr(buffer, "BOOT2");
if (pos == NULL)
{ {
pos = strstr(buffer, "BOOT"); return 0; // no SYSTEM.CNF, not a PS1/PS2 disc.
if (pos==NULL) { }
Console.Error("PCSX2 Boot Error: This is not a Playstation or PS2 game!");
int retype = 0;
wxArrayString lines;
SplitString( lines, fromUTF8((char*)buffer), L"\n" );
for( uint i=0; i<lines.GetCount(); ++i )
{
ParsedAssignmentString parts( lines[i] );
if( parts.rvalue.IsEmpty() )
{
Console.Error( "(GetElfName) Unusual or malformed entry in SYSTEM.CNF ignored:" );
Console.WriteLn( L"\t" + lines[i] );
continue;
}
if( parts.lvalue == L"BOOT2" )
{
Console.WriteLn( Color_StrongBlue, L"(GetElfName) Detected PS2 Disc = " + name );
name = parts.rvalue;
retype = 2;
}
else if( parts.lvalue == L"BOOT" )
{
Console.WriteLn( Color_StrongBlue, L"(GetElfName) Detected PSX/PSone Disc = " + name );
name = parts.rvalue;
retype = 1;
}
else if( parts.lvalue == L"VMODE" )
{
Console.WriteLn( Color_StrongBlue, L"(GetElfName) Disc region type = " + parts.rvalue );
}
else if( parts.lvalue == L"VER" )
{
Console.WriteLn( Color_StrongBlue, L"(GetElfName) Software version = " + parts.rvalue );
}
}
if( retype == 0 )
{
Console.Error("(GetElfName) Disc image is *not* a Playstation or PS2 game!");
return 0; return 0;
} }
return 1;
}
pos+=strlen("BOOT2");
while (pos && *pos && pos<&buffer[g_MaxPath]
&& (*pos<'A' || (*pos>'Z' && *pos<'a') || *pos>'z'))
pos++;
if (!pos || *pos==0)
return 0;
// the filename is everything up to the first CR/LF/tab.. ?
// Or up to any whitespace? (I'm opting for first CRLF/tab, although the old code
// apparently stopped on spaces too) --air
name = wxStringTokenizer( fromUTF8( pos ) ).GetNextToken();
}
catch( ... )
{
}
}
catch( ... )
{
}
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
FILE *fp; FILE *fp;