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,54 +71,37 @@ static void CheckNullCDVD()
//
static int CheckDiskTypeFS(int baseType)
{
IsoFSCDVD isofs;
IsoDirectory rootdir(isofs);
try {
IsoFSCDVD isofs;
IsoDirectory fsroot(&isofs);
try {
// Will throw exception if the file was not found
IsoFile file = fsroot.OpenFile("SYSTEM.CNF;1");
IsoFile file( rootdir, L"SYSTEM.CNF;1");
int size = file.getLength();
int size = file.getLength();
char buffer[256]; //if the file is longer...it should be shorter :D
file.read((u8*)buffer,size);
buffer[size]='\0';
char buffer[256]; //if the file is longer...it should be shorter :D
file.read((u8*)buffer,size);
buffer[size]='\0';
char* pos = strstr(buffer, "BOOT2");
if (pos == NULL)
{
pos = strstr(buffer, "BOOT");
if (pos == NULL) return CDVD_TYPE_ILLEGAL;
return CDVD_TYPE_PSCD;
}
return (baseType==CDVD_TYPE_DETCTCD) ? CDVD_TYPE_PS2CD : CDVD_TYPE_PS2DVD;
}
catch( ... )
char* pos = strstr(buffer, "BOOT2");
if (pos == NULL)
{
}
try {
fsroot.FindFile("PSX.EXE;1");
pos = strstr(buffer, "BOOT");
if (pos == NULL) return CDVD_TYPE_ILLEGAL;
return CDVD_TYPE_PSCD;
}
catch( ... )
{
}
try {
fsroot.FindFile("VIDEO_TS/VIDEO_TS.IFO;1");
return CDVD_TYPE_DVDV;
}
catch( ... )
{
}
return (baseType==CDVD_TYPE_DETCTCD) ? CDVD_TYPE_PS2CD : CDVD_TYPE_PS2DVD;
}
catch( ... )
catch( Exception::FileNotFound& )
{
}
if( rootdir.IsFile(L"PSX.EXE;1") )
return CDVD_TYPE_PSCD;
if( rootdir.IsFile(L"VIDEO_TS/VIDEO_TS.IFO;1") )
return CDVD_TYPE_DVDV;
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,188 +1,182 @@
#include "PrecompiledHeader.h"
#include "IsoFS.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(SectorSource* r)
{
byte sector[2048];
r->readSector(sector,16);
IsoFileDescriptor rootDirEntry(sector+156,38);
Init(r, rootDirEntry);
}
IsoDirectory::IsoDirectory(SectorSource* r, IsoFileDescriptor directoryEntry)
{
Init(r, directoryEntry);
}
void IsoDirectory::Init(SectorSource* r, IsoFileDescriptor directoryEntry)
{
// parse directory sector
IsoFile dataStream (r, directoryEntry);
internalReader = r;
files.clear();
int remainingSize = directoryEntry.size;
byte b[257];
while(remainingSize>=4) // hm hack :P
{
b[0] = dataStream.read<byte>();
if(b[0]==0)
{
break; // or continue?
}
remainingSize-=b[0];
dataStream.read(b+1, b[0]-1);
IsoFileDescriptor file(b,b[0]);
files.push_back(file);
}
b[0] = 0;
}
IsoFileDescriptor IsoDirectory::GetEntry(int index)
{
return files[index];
}
int IsoDirectory::GetIndexOf(string fileName)
{
for(unsigned int i=0;i<files.size();i++)
{
string file = files[i].name;
if(file.compare(fileName)==0)
{
return i;
}
}
throw Exception::FileNotFound( fileName.c_str() );
}
IsoFileDescriptor IsoDirectory::GetEntry(string fileName)
{
return GetEntry(GetIndexOf(fileName));
}
IsoFileDescriptor IsoDirectory::FindFile(string filePath)
{
IsoFileDescriptor info;
IsoDirectory dir = *this;
// this was supposed to be a vector<string>, but this damn hotfix kills stl
// if you have the Windows SDK 6.1 installed after vs2008 sp1
vector<string> path;
Tokenize(filePath,path,"\\/");
// 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(pathName);
if((info.flags&2)==2) // if it's a directory
{
dir = IsoDirectory(internalReader, info);
}
}
return info;
}
IsoFile IsoDirectory::OpenFile(string filePath)
{
IsoFileDescriptor info = FindFile(filePath);
if((info.flags&2)==2) // if it's a directory
{
throw Exception::InvalidArgument("Filename points to a directory.");
}
return IsoFile(internalReader, info);
}
IsoDirectory::~IsoDirectory(void)
{
}
//////////////////////////////////////////////////////////////////////////
// IsoFileDescriptor
//////////////////////////////////////////////////////////////////////////
IsoFileDescriptor::IsoFileDescriptor()
{
lba = 0;
size = 0;
flags = 0;
name = "";
}
IsoFileDescriptor::IsoFileDescriptor(const byte* data, int length)
{
lba = *(const int*)(data+2);
size = *(const int*)(data+10);
date.year = data[18] + 1900;
date.month = data[19];
date.day = data[20];
date.hour = data[21];
date.minute = data[22];
date.second = data[23];
date.gmtOffset = data[24];
flags = data[25];
if((lba<0)||(length<0))
{
// would be nice to have some exceptio nthis fits in
throw Exception::InvalidOperation("WTF?! Size or lba < 0?!");
}
int fileNameLength = data[32];
name.clear();
if(fileNameLength==1)
{
char c = *(const char*)(data+33);
switch(c)
{
case 0: name = "."; break;
case 1: name = ".."; break;
default: name.append(1,c);
}
}
else if (fileNameLength>0)
name.append((const char*)(data+33),fileNameLength);
}
#include "PrecompiledHeader.h"
#include "IsoFS.h"
#include "IsoFile.h"
//////////////////////////////////////////////////////////////////////////
// IsoDirectory
//////////////////////////////////////////////////////////////////////////
// Used to load the Root directory from an image
IsoDirectory::IsoDirectory(SectorSource& r) :
internalReader(r)
{
u8 sector[2048];
internalReader.readSector(sector,16);
IsoFileDescriptor rootDirEntry(sector+156,38);
Init(rootDirEntry);
}
// Used to load a specific directory from a file descriptor
IsoDirectory::IsoDirectory(SectorSource& r, IsoFileDescriptor directoryEntry) :
internalReader(r)
{
Init(directoryEntry);
}
IsoDirectory::~IsoDirectory() throw()
{
}
void IsoDirectory::Init(const IsoFileDescriptor& directoryEntry)
{
// parse directory sector
IsoFile dataStream (internalReader, directoryEntry);
files.clear();
int remainingSize = directoryEntry.size;
u8 b[257];
while(remainingSize>=4) // hm hack :P
{
b[0] = dataStream.read<u8>();
if(b[0]==0)
{
break; // or continue?
}
remainingSize -= b[0];
dataStream.read(b+1, b[0]-1);
files.push_back(IsoFileDescriptor(b, b[0]));
}
b[0] = 0;
}
const IsoFileDescriptor& IsoDirectory::GetEntry(int index) const
{
return files[index];
}
int IsoDirectory::GetIndexOf(const wxString& fileName) const
{
for(unsigned int i=0;i<files.size();i++)
{
if(files[i].name == fileName) return i;
}
throw Exception::FileNotFound( fileName );
}
const IsoFileDescriptor& IsoDirectory::GetEntry(const wxString& fileName) const
{
return GetEntry(GetIndexOf(fileName));
}
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;
const IsoDirectory* dir = this;
ScopedPtr<IsoDirectory> deleteme;
// walk through path ("." and ".." entries are in the directories themselves, so even if the
// path included . and/or .., it still works)
for(uint i=0; i<parts.GetDirCount(); ++i)
{
info = dir->GetEntry(parts.GetDirs()[i]);
if(info.IsFile()) throw Exception::FileNotFound( filePath );
dir = deleteme = new IsoDirectory(internalReader, info);
}
if( !parts.GetFullName().IsEmpty() )
info = dir->GetEntry(parts.GetFullName());
return info;
}
bool IsoDirectory::IsFile(const wxString& filePath) const
{
if( filePath.IsEmpty() ) return false;
return (FindFile(filePath).flags&2) != 2;
}
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
{
return FindFile( filePath ).size;
}
IsoFileDescriptor::IsoFileDescriptor()
{
lba = 0;
size = 0;
flags = 0;
}
IsoFileDescriptor::IsoFileDescriptor(const u8* data, int length)
{
lba = (u32&)data[2];
size = (u32&)data[10];
date.year = data[18] + 1900;
date.month = data[19];
date.day = data[20];
date.hour = data[21];
date.minute = data[22];
date.second = data[23];
date.gmtOffset = data[24];
flags = data[25];
// 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.
if( !pxAssertDev( (lba>=0) && (length>=0), "Invalid ISO file descriptor data encountered." ) )
throw Exception::BadStream();
int fileNameLength = data[32];
if(fileNameLength==1)
{
u8 c = data[33];
switch(c)
{
case 0: name = L"."; break;
case 1: name = L".."; break;
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;
}
}
}

View File

@ -1,38 +1,11 @@
#pragma once
#include <vector>
#include <string>
#include "IsoFileDescriptor.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);
};
#pragma once
class IsoFile;
class IsoDirectory;
struct ISoFileDescriptor;
#include "SectorSource.h"
#include "IsoFileDescriptor.h"
#include "IsoDirectory.h"
#include "ISoFile.h"

View File

@ -1,24 +1,24 @@
#include "PrecompiledHeader.h"
#include "IsoFSCDVD.h"
#include "../CDVDaccess.h"
IsoFSCDVD::IsoFSCDVD()
{
}
bool IsoFSCDVD::readSector(unsigned char* buffer, int lba)
{
return DoCDVDreadSector(buffer,lba,CDVD_MODE_2048)>=0;
}
int IsoFSCDVD::getNumSectors()
{
cdvdTD td;
CDVD->getTD(0,&td);
return td.lsn;
}
IsoFSCDVD::~IsoFSCDVD(void)
{
}
#include "PrecompiledHeader.h"
#include "IsoFSCDVD.h"
#include "../CDVDaccess.h"
IsoFSCDVD::IsoFSCDVD()
{
}
bool IsoFSCDVD::readSector(unsigned char* buffer, int lba)
{
return DoCDVDreadSector(buffer,lba,CDVD_MODE_2048)>=0;
}
int IsoFSCDVD::getNumSectors()
{
cdvdTD td;
CDVD->getTD(0,&td);
return td.lsn;
}
IsoFSCDVD::~IsoFSCDVD(void)
{
}

View File

@ -1,17 +1,16 @@
#pragma once
#include <stdio.h>
#include "SectorSource.h"
class IsoFSCDVD: public SectorSource
{
public:
IsoFSCDVD();
virtual bool readSector(unsigned char* buffer, int lba);
virtual int getNumSectors();
virtual ~IsoFSCDVD(void);
};
#pragma once
#include <stdio.h>
#include "SectorSource.h"
class IsoFSCDVD: public SectorSource
{
public:
IsoFSCDVD();
virtual ~IsoFSCDVD() throw();
virtual bool readSector(unsigned char* buffer, int lba);
virtual int getNumSectors();
};

View File

@ -1,217 +1,225 @@
#include "PrecompiledHeader.h"
#include "IsoFile.h"
using namespace std;
IsoFile::IsoFile(SectorSource* reader, IsoFileDescriptor fileEntry)
: fileEntry(fileEntry)
{
internalReader = reader;
currentSectorNumber=fileEntry.lba;
currentOffset = 0;
sectorOffset = 0;
maxOffset = fileEntry.size;
if(maxOffset>0)
reader->readSector(currentSector,currentSectorNumber);
}
void IsoFile::seek(s64 offset)
{
s64 endOffset = offset;
#include "PrecompiledHeader.h"
#ifdef __LINUX__
if (offset<0) throw "Seek offset out of bounds.";
#else
if(offset<0)
throw new exception("Seek offset out of bounds.");
#endif
int oldSectorNumber = currentSectorNumber;
s64 newOffset = endOffset;
int newSectorNumber = fileEntry.lba + (int)(newOffset / sectorLength);
if(oldSectorNumber != newSectorNumber)
{
internalReader->readSector(currentSector, newSectorNumber);
}
currentOffset = newOffset;
currentSectorNumber = newSectorNumber;
sectorOffset = (int)(currentOffset % sectorLength);
}
void IsoFile::seek(s64 offset, int ref_position)
{
if(ref_position == SEEK_SET)
seek(offset);
if(ref_position == SEEK_CUR)
seek(currentOffset+offset);
if(ref_position == SEEK_END)
seek(fileEntry.size+offset);
}
void IsoFile::reset()
{
seek(0);
}
s64 IsoFile::skip(s64 n)
{
s64 oldOffset = currentOffset;
if(n<0)
return n;
seek(currentOffset+n);
return currentOffset-oldOffset;
}
s64 IsoFile::getFilePointer()
{
return currentOffset;
}
bool IsoFile::eof()
{
return (currentOffset == maxOffset);
}
void IsoFile::makeDataAvailable()
{
if (sectorOffset >= sectorLength) {
currentSectorNumber++;
internalReader->readSector(currentSector, currentSectorNumber);
sectorOffset -= sectorLength;
}
}
int IsoFile::read()
{
if(currentOffset >= maxOffset)
throw Exception::EndOfStream();
makeDataAvailable();
currentOffset++;
return currentSector[sectorOffset++];
}
int IsoFile::internalRead(byte* b, int off, int len)
{
if (len > 0)
{
if (len > (maxOffset - currentOffset))
{
len = (int) (maxOffset - currentOffset);
}
memcpy(b + off, currentSector + sectorOffset, len);
sectorOffset += len;
currentOffset += len;
}
return len;
}
int IsoFile::read(byte* b, int len)
{
if (b == NULL)
{
throw Exception::ObjectIsNull("b");
}
if (len < 0)
{
throw Exception::InvalidOperation("off<0 or len<0.");
}
int off=0;
int totalLength = 0;
int firstSector = internalRead(b, off, min(len, sectorLength - sectorOffset));
off += firstSector;
len -= firstSector;
totalLength += firstSector;
// Read whole sectors
while ((len >= sectorLength) && (currentOffset < maxOffset))
{
makeDataAvailable();
int n = internalRead(b, off, sectorLength);
off += n;
len -= n;
totalLength += n;
}
// Read remaining, if any
if (len > 0) {
makeDataAvailable();
int lastSector = internalRead(b, off, len);
totalLength += lastSector;
}
return totalLength;
}
string IsoFile::readLine()
{
string s;
char c;
s.clear();
do {
if(eof())
break;
c = read();
if((c=='\n')||(c=='\r')||(c==0))
break;
s.append(1,c);
} while(true);
return s;
}
wstring IsoFile::readLineW()
{
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;
}
const IsoFileDescriptor& IsoFile::getEntry()
{
return fileEntry;
}
IsoFile::~IsoFile(void)
{
}
#include "IsoFS.h"
#include "IsoFile.h"
IsoFile::IsoFile(SectorSource& reader, const wxString& filename)
: internalReader(reader)
, fileEntry(IsoDirectory(reader).FindFile(filename))
{
Init();
}
IsoFile::IsoFile(const IsoDirectory& dir, const wxString& filename)
: internalReader(dir.GetReader())
, fileEntry(dir.FindFile(filename))
{
Init();
}
IsoFile::IsoFile(SectorSource& reader, const IsoFileDescriptor& fileEntry)
: internalReader(reader)
, fileEntry(fileEntry)
{
Init();
}
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;
u32 newOffset = endOffset;
int newSectorNumber = fileEntry.lba + (int)(newOffset / sectorLength);
if(oldSectorNumber != newSectorNumber)
{
internalReader.readSector(currentSector, newSectorNumber);
}
currentOffset = newOffset;
currentSectorNumber = newSectorNumber;
sectorOffset = (int)(currentOffset % sectorLength);
return currentOffset;
}
u32 IsoFile::seek(s32 offset, wxSeekMode ref_position)
{
switch( ref_position )
{
case wxFromStart:
pxAssertDev( offset > 0, "Invalid seek position from start." );
return seek(offset);
case wxFromCurrent:
// truncate negative values to zero
return seek( std::max<u32>(0, currentOffset+offset) );
case wxFromEnd:
// truncate negative values to zero
return seek( std::max<u32>(0, fileEntry.size+offset) );
jNO_DEFAULT;
}
return 0; // unreachable
}
void IsoFile::reset()
{
seek(0);
}
// Returns the number of bytes actually skipped.
s32 IsoFile::skip(s32 n)
{
s32 oldOffset = currentOffset;
if(n<0)
return 0;
seek(currentOffset+n);
return currentOffset-oldOffset;
}
u32 IsoFile::getSeekPos() const
{
return currentOffset;
}
bool IsoFile::eof() const
{
return (currentOffset == maxOffset);
}
// loads the current sector index into the CurrentSector buffer.
void IsoFile::makeDataAvailable()
{
if (sectorOffset >= sectorLength)
{
currentSectorNumber++;
internalReader.readSector(currentSector, currentSectorNumber);
sectorOffset -= sectorLength;
}
}
u8 IsoFile::readByte()
{
if(currentOffset >= maxOffset)
throw Exception::EndOfStream();
makeDataAvailable();
currentOffset++;
return currentSector[sectorOffset++];
}
// 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)
{
size_t slen = len;
if (slen > (maxOffset - currentOffset))
{
slen = (int) (maxOffset - currentOffset);
}
memcpy_fast((u8*)dest + off, currentSector + sectorOffset, slen);
sectorOffset += slen;
currentOffset += slen;
return slen;
}
return 0;
}
// returns the number of bytes actually read.
s32 IsoFile::read(void* dest, s32 len)
{
pxAssert( dest != NULL );
pxAssert( len >= 0 ); // should we silent-fail on negative length reads? prolly not...
if( len <= 0 ) return 0;
int off = 0;
int totalLength = 0;
int firstSector = internalRead(dest, off, std::min(len, sectorLength - sectorOffset));
off += firstSector;
len -= firstSector;
totalLength += firstSector;
// Read whole sectors
while ((len >= sectorLength) && (currentOffset < maxOffset))
{
makeDataAvailable();
int n = internalRead(dest, off, sectorLength);
off += n;
len -= n;
totalLength += n;
}
// Read remaining, if any
if (len > 0) {
makeDataAvailable();
int lastSector = internalRead(dest, off, len);
totalLength += lastSector;
}
return totalLength;
}
// 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()
{
std::string s;
s.reserve( 512 );
while( !eof() )
{
u8 c = read<u8>();
if((c=='\n') || (c=='\r') || (c==0))
break;
s += c;
}
return s;
}
u32 IsoFile::getLength()
{
return maxOffset;
}
const IsoFileDescriptor& IsoFile::getEntry()
{
return fileEntry;
}

View File

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

View File

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

View File

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

View File

@ -19,11 +19,12 @@
//#include "CDVD/IsoFSdrv.h"
#include "DebugTools/Debug.h"
#include "GS.h" // for sending game crc to mtgs
#include "CDVD/IsoFS/IsoFSCDVD.h"
#include "CDVD/IsoFS/IsoFS.h"
using namespace std;
extern void InitPatch(wxString crc);
extern void InitPatch(const wxString& crc);
u32 ElfCRC;
@ -329,16 +330,10 @@ struct ElfObject
(strnicmp( work, "cdrom1:", strlen("cdromN:")) == 0))
{
IsoFSCDVD isofs;
IsoDirectory fsroot(&isofs);
IsoFile file( isofs, fromUTF8(work) );
// Will throw exception if the file was not found
IsoFile file = fsroot.OpenFile(work + strlen("cdromN:"));
int size = file.getLength();
rsize = file.read((u8*)data.GetPtr(), data.GetSizeInBytes());
//if (fi < 0) throw Exception::FileNotFound( filename );
//int size = file.getLength();
rsize = file.read(data.GetPtr(), data.GetSizeInBytes());
}
else
{
@ -509,24 +504,16 @@ void ElfApplyPatches()
// Fetches the CRC of the game bound to the CDVD plugin.
u32 loadElfCRC( const char* filename )
{
IsoFSCDVD isofs;
IsoDirectory fsroot(&isofs);
IsoFileDescriptor desc;
u32 crcval = 0;
Console.WriteLn("loadElfCRC: %s", filename);
int mylen = strlen( "cdromN:" );
try {
int mylen = strlen( "cdromN:" );
desc = fsroot.FindFile( filename + mylen );
IsoFSCDVD isofs;
const int filesize = IsoDirectory(isofs).GetFileSize( fromUTF8(filename) );
DevCon.WriteLn( "loadElfFile: %d bytes", desc.size );
crcval = ElfObject( fromUTF8( filename ), desc.size ).GetCRC();
Console.WriteLn( "loadElfFile: %s; CRC = %8.8X", filename, crcval );
}
catch( ... )
{
}
DevCon.WriteLn( "loadElfFile: %d bytes", filesize );
crcval = ElfObject( fromUTF8(filename), filesize ).GetCRC();
Console.WriteLn( "loadElfFile: %s; CRC = %8.8X", filename, crcval );
return crcval;
}
@ -548,9 +535,8 @@ void loadElfFile(const wxString& filename)
s64 elfsize;
Console.WriteLn( L"loadElfFile: " + filename );
const wxCharBuffer buffer( filename.ToUTF8() );
const char* fnptr = buffer.data();
bool useCdvdSource=false;
const wxCharBuffer fnptr( filename.ToUTF8() );
bool useCdvdSource = false;
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");
useCdvdSource = true;
IsoFileDescriptor desc;
try
{
IsoFSCDVD isofs;
IsoDirectory fsroot(&isofs);
Console.WriteLn(L"loadElfCRC: " + filename);
desc = fsroot.FindFile(fnptr + strlen( "cdromN:" ));
}
catch( ... )
{
throw Exception::FileNotFound( filename, wxLt("ELF file was not found on the CDVD source media.") );
}
elfsize = desc.size;
Console.WriteLn(L"loadElfCRC: " + filename);
IsoFSCDVD isofs;
elfsize = IsoDirectory( isofs ).GetFileSize( fromUTF8(fnptr) );
}
if( elfsize > 0xfffffff )
@ -632,51 +606,64 @@ void loadElfFile(const wxString& filename)
// 2 - PS2 CD
int GetPS2ElfName( wxString& name )
{
char buffer[g_MaxPath];//if a file is longer...it should be shorter :D
char buffer[512];
try {
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();
if( size == 0 ) return 0;
int size = file.getLength();
file.read( buffer, size );
buffer[size] = '\0';
}
catch( Exception::FileNotFound& )
{
return 0; // no SYSTEM.CNF, not a PS1/PS2 disc.
}
char buffer[256]; //if the file is longer...it should be shorter :D
file.read((u8*)buffer,size);
buffer[size]='\0';
int retype = 0;
wxArrayString lines;
SplitString( lines, fromUTF8((char*)buffer), L"\n" );
char* pos = strstr(buffer, "BOOT2");
if (pos == NULL)
{
pos = strstr(buffer, "BOOT");
if (pos==NULL) {
Console.Error("PCSX2 Boot Error: This is not a Playstation or PS2 game!");
return 0;
}
return 1;
}
for( uint i=0; i<lines.GetCount(); ++i )
{
ParsedAssignmentString parts( lines[i] );
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( ... )
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 );
}
}
catch( ... )
if( retype == 0 )
{
Console.Error("(GetElfName) Disc image is *not* a Playstation or PS2 game!");
return 0;
}
#ifdef PCSX2_DEVBUILD