Replaced the old isofs code with a new simpler and cleaner isofs handler.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2152 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gigaherz 2009-11-07 23:03:03 +00:00
parent 3b0f524417
commit f598fb8362
22 changed files with 764 additions and 1289 deletions

View File

@ -19,7 +19,6 @@
#include <wx/datetime.h> #include <wx/datetime.h>
#include "IopCommon.h" #include "IopCommon.h"
#include "IsoFStools.h"
#include "CDVD_internal.h" #include "CDVD_internal.h"
#include "CDVDisoReader.h" #include "CDVDisoReader.h"
#include "GS.h" // for gsRegionMode #include "GS.h" // for gsRegionMode

View File

@ -27,10 +27,12 @@
#include <wx/datetime.h> #include <wx/datetime.h>
#include "IopCommon.h" #include "IopCommon.h"
#include "IsoFStools.h"
#include "IsoFSdrv.h"
#include "CDVDisoReader.h" #include "CDVDisoReader.h"
#include "IsoFS/IsoFS.h"
#include "IsoFS/IsoFSCDVD.h"
#include <exception>
const wxChar* CDVD_SourceLabels[] = const wxChar* CDVD_SourceLabels[] =
{ {
L"Iso", L"Iso",
@ -69,41 +71,52 @@ static void CheckNullCDVD()
// //
static int CheckDiskTypeFS(int baseType) static int CheckDiskTypeFS(int baseType)
{ {
int f; try {
char buffer[256];//if a file is longer...it should be shorter :D IsoFSCDVD isofs;
char *pos; IsoDirectory fsroot(&isofs);
static struct TocEntry tocEntry;
IsoFS_init(); try {
// Will throw exception if the file was not found
IsoFile file = fsroot.OpenFile("SYSTEM.CNF;1");
f = IsoFS_open("SYSTEM.CNF;1", 1); int size = file.getLength();
// check if the file exists char buffer[256]; //if the file is longer...it should be shorter :D
if (f >= 0) file.read((u8*)buffer,size);
{ buffer[size]='\0';
int size = IsoFS_read(f, buffer, 256);
IsoFS_close(f);
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;
}
pos = strstr(buffer, "BOOT2"); return (baseType==CDVD_TYPE_DETCTCD) ? CDVD_TYPE_PS2CD : CDVD_TYPE_PS2DVD;
if (pos == NULL) }
catch( ... )
{ {
pos = strstr(buffer, "BOOT"); }
if (pos == NULL) return CDVD_TYPE_ILLEGAL;
try {
fsroot.FindFile("PSX.EXE;1");
return CDVD_TYPE_PSCD; return CDVD_TYPE_PSCD;
} }
return (baseType==CDVD_TYPE_DETCTCD) ? CDVD_TYPE_PS2CD : CDVD_TYPE_PS2DVD; catch( ... )
} {
}
if (IsoFS_findFile("PSX.EXE;1", &tocEntry) == TRUE) try {
{ fsroot.FindFile("VIDEO_TS/VIDEO_TS.IFO;1");
return CDVD_TYPE_PSCD; return CDVD_TYPE_DVDV;
}
catch( ... )
{
}
} }
catch( ... )
if (IsoFS_findFile("VIDEO_TS/VIDEO_TS.IFO;1", &tocEntry) == TRUE)
{ {
return CDVD_TYPE_DVDV;
} }
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.
@ -136,8 +149,9 @@ static int FindDiskType(int mType)
{ {
if (DoCDVDreadSector(bleh, 16, CDVD_MODE_2048) == 0) if (DoCDVDreadSector(bleh, 16, CDVD_MODE_2048) == 0)
{ {
const cdVolDesc& volDesc = (cdVolDesc&)bleh; //const cdVolDesc& volDesc = (cdVolDesc&)bleh;
if(volDesc.rootToc.tocSize == 2048) //if(volDesc.rootToc.tocSize == 2048)
if(*(u16*)(bleh+166) == 2048)
iCDType = CDVD_TYPE_DETCTCD; iCDType = CDVD_TYPE_DETCTCD;
else else
iCDType = CDVD_TYPE_DETCTDVDS; iCDType = CDVD_TYPE_DETCTDVDS;

View File

@ -96,6 +96,7 @@ s32 CALLBACK ISOreadSubQ(u32 lsn, cdvdSubQ* subq)
subq->discM = itob(min); subq->discM = itob(min);
subq->discS = itob(sec); subq->discS = itob(sec);
subq->discF = itob(frm); subq->discF = itob(frm);
return 0; return 0;
} }

View File

@ -23,7 +23,6 @@
#include <stdio.h> #include <stdio.h>
#include "IopCommon.h" #include "IopCommon.h"
#include "IsoFStools.h"
#include "IsoFileFormats.h" #include "IsoFileFormats.h"
#endif #endif

188
pcsx2/CDVD/IsoFS/IsoFS.cpp Normal file
View File

@ -0,0 +1,188 @@
#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);
}

38
pcsx2/CDVD/IsoFS/IsoFS.h Normal file
View File

@ -0,0 +1,38 @@
#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);
};

View File

@ -0,0 +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)
{
}

View File

@ -0,0 +1,17 @@
#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);
};

View File

@ -0,0 +1,213 @@
#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(__int64 offset)
{
__int64 endOffset = offset;
if(offset<0)
throw new exception("Seek offset out of bounds.");
int oldSectorNumber = currentSectorNumber;
__int64 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(__int64 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);
}
__int64 IsoFile::skip(__int64 n)
{
__int64 oldOffset = currentOffset;
if(n<0)
return n;
seek(currentOffset+n);
return currentOffset-oldOffset;
}
__int64 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;
}
__int64 IsoFile::getLength()
{
return maxOffset;
}
const IsoFileDescriptor& IsoFile::getEntry()
{
return fileEntry;
}
IsoFile::~IsoFile(void)
{
}

View File

@ -0,0 +1,63 @@
#pragma once
#include "IsoFileDescriptor.h"
#include "SectorSource.h"
class IsoFile
{
public:
static const int sectorLength = 2048;
private:
IsoFileDescriptor fileEntry;
__int64 currentOffset;
__int64 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(__int64 offset);
void seek(__int64 offset, int ref_position);
void reset();
__int64 skip(__int64 n);
__int64 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)
__int64 getLength();
const IsoFileDescriptor& getEntry();
~IsoFile(void);
};

View File

@ -0,0 +1,32 @@
#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) {}
};

View File

@ -0,0 +1,10 @@
#include "PrecompiledHeader.h"
#include "SectorSource.h"
SectorSource::SectorSource(void)
{
}
SectorSource::~SectorSource(void)
{
}

View File

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

View File

@ -1,47 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 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 PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Original code from libcdvd by Hiryu & Sjeep (C) 2002
* Linux kernel headers
* Modified by Florin for PCSX2 emu
*/
#ifndef _ISOFSCDVD_H
#define _ISOFSCDVD_H
#include "Common.h"
#ifdef _MSC_VER
# pragma pack(1)
#endif
struct TocEntry
{
u32 fileLBA;
u32 fileSize;
u8 fileProperties;
u8 padding1[3];
char filename[128+1];
u8 date[7];
} __packed;
#ifdef _MSC_VER
# pragma pack()
#endif
extern int IsoFS_findFile(const char* fname, struct TocEntry* tocEntry);
extern int IsoFS_readSectors(u32 lsn, u32 sectors, void *buf);
#endif // _ISOFSCDVD_H

View File

@ -1,238 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 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 PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Original code from libcdvd by Hiryu & Sjeep (C) 2002
* Modified by Florin for PCSX2 emu
*/
#include "PrecompiledHeader.h"
#include "IsoFStools.h"
#include "IsoFSdrv.h"
struct fdtable{
// int fd;
int fileSize;
int LBA;
int filePos;
};
static struct fdtable fd_table[16];
static int fd_used[16];
static int files_open=0;
static int inited=FALSE;
/*************************************************************
* The functions below are the normal file-system operations, *
* used to provide a standard filesystem interface *
*************************************************************/
//////////////////////////////////////////////////////////////////////
// CDVDFS_init
//////////////////////////////////////////////////////////////////////
void IsoFS_init()
{
if (inited) return; //might change in the future as a param; forceInit/Reset
ISOFS_LOG("[IsoFSdrv:init] Initializing '%s' file driver.", "IsoFS");
memzero( fd_table );
memzero( fd_used );
inited = TRUE;
return;
}
//////////////////////////////////////////////////////////////////////
// CDVDFS_open
//////////////////////////////////////////////////////////////////////
int IsoFS_open(const char *name, int mode){
int j;
static struct TocEntry tocEntry;
// check if the file exists
if (IsoFS_findFile(name, &tocEntry) != TRUE) return -1;
if(mode != 1) return -2; //SCE_RDONLY
// set up a new file descriptor
for(j=0; j < 16; j++) if(fd_used[j] == 0) break;
if(j >= 16) return -3;
fd_used[j] = 1;
files_open++;
ISOFS_LOG("[IsoFSdrv:open] internal fd=%d", j);
fd_table[j].fileSize = tocEntry.fileSize;
fd_table[j].LBA = tocEntry.fileLBA;
fd_table[j].filePos = 0;
ISOFS_LOG("[IsoFSdrv:open] tocEntry.fileSize = %d",tocEntry.fileSize);
return j;
}
//////////////////////////////////////////////////////////////////////
// CDVDFS_lseek
//////////////////////////////////////////////////////////////////////
int IsoFS_lseek(int fd, int offset, int whence){
if ((fd >= 16) || (fd_used[fd]==0)){
ISOFS_LOG("[IsoFSdrv:lseek] ERROR: File does not appear to be open!");
return -1;
}
switch(whence){
case SEEK_SET:
fd_table[fd].filePos = offset;
break;
case SEEK_CUR:
fd_table[fd].filePos += offset;
break;
case SEEK_END:
fd_table[fd].filePos = fd_table[fd].fileSize + offset;
break;
default:
return -1;
}
if (fd_table[fd].filePos < 0) fd_table[fd].filePos = 0;
if (fd_table[fd].filePos > fd_table[fd].fileSize)
{
fd_table[fd].filePos = fd_table[fd].fileSize;
}
return fd_table[fd].filePos;
}
//////////////////////////////////////////////////////////////////////
// CDVDFS_read
//////////////////////////////////////////////////////////////////////
int IsoFS_read( int fd, char *buffer, int size )
{
int off_sector;
static char lb[2048]; //2KB
//Start, Aligned, End
int ssector, asector, esector;
int ssize=0, asize, esize;
if ((fd >= 16) || (fd_used[fd]==0))
{
ISOFS_LOG("[IsoFSdrv:read] ERROR: File does not appear to be open!");
return -1;
}
// A few sanity checks
if (fd_table[fd].filePos > fd_table[fd].fileSize)
{
// We cant start reading from past the beginning of the file
return 0; // File exists but we couldn't read anything from it
}
if ((fd_table[fd].filePos + size) > fd_table[fd].fileSize)
{
size = fd_table[fd].fileSize - fd_table[fd].filePos;
}
// Now work out where we want to start reading from
asector = ssector = fd_table[fd].LBA + (fd_table[fd].filePos >> 11);
off_sector = (fd_table[fd].filePos & 0x7FF);
if (off_sector)
{
ssize = std::min(2048 - off_sector, size);
size -= ssize;
asector++;
}
asize = size & 0xFFFFF800;
esize = size & 0x000007FF;
esector=asector + (asize >> 11);
size += ssize;
ISOFS_LOG("[IsoFSdrv:read] read sectors 0x%08X to 0x%08X", ssector, esector-(esize==0));
if (ssize)
{
if (IsoFS_readSectors(ssector, 1, lb) != TRUE)
{
ISOFS_LOG("[IsoFSdrv:read] Couldn't Read from file for some reason");
return 0;
}
memcpy_fast(buffer, lb + off_sector, ssize);
}
if (asize && (IsoFS_readSectors(asector, asize >> 11, buffer+ssize) != TRUE))
{
ISOFS_LOG("[IsoFSdrv:read] Couldn't Read from file for some reason");
return 0;
}
if (esize)
{
if (IsoFS_readSectors(esector, 1, lb) != TRUE)
{
ISOFS_LOG("[IsoFSdrv:read] Couldn't Read from file for some reason");
return 0;
}
memcpy_fast(buffer+ssize+asize, lb, esize);
}
/***********************
// Now work out where we want to start reading from
start_sector = fd_table[fd].LBA + (fd_table[fd].filePos >> 11);
off_sector = (fd_table[fd].filePos & 0x7FF);
num_sectors = ((off_sector + size) >> 11) + 1;
RPC_LOG("[IsoFSdrv:read] read sectors 0x%08X to 0x%08X",start_sector,start_sector+num_sectors);
// Read the data (we only ever get 16KB max request at once)
if (CdRead(start_sector, num_sectors, local_buffer, &cdReadMode) != TRUE){
//RPC_LOG("sector = %d, start sector = %d",sector,start_sector);
RPC_LOG("[IsoFSdrv: ] Couldn't Read from file for some reason");
return 0;
}
//CdSync(0); hm, a wait function maybe...
memcpy_fast(buffer,local_buffer+off_sector,size);
**************************/
fd_table[fd].filePos += size;
return (size);
}
//////////////////////////////////////////////////////////////////////
// CDVDFS_close
//////////////////////////////////////////////////////////////////////
int IsoFS_close( int fd)
{
if ((fd >= 16) || (fd_used[fd]==0))
{
ISOFS_LOG("[IsoFSdrv:close] ERROR: File does not appear to be open!");
return -1;
}
ISOFS_LOG("[IsoFSdrv:close] internal fd %d", fd);
fd_used[fd] = 0;
files_open--;
return 0;
}

View File

@ -1,30 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 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 PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Original code from libcdvd by Hiryu & Sjeep (C) 2002
* Modified by Florin for PCSX2 emu
*/
#pragma once
#include "IsoFScdvd.h"
/* Filing-system exported functions */
extern void IsoFS_init();
extern int IsoFS_open(const char *name, int mode);
extern int IsoFS_lseek(int fd, int offset, int whence);
extern int IsoFS_read( int fd, char * buffer, int size );
extern int IsoFS_close(int fd);

View File

@ -1,730 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 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 PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Original code from libcdvd by Hiryu & Sjeep (C) 2002
* Modified by Florin for PCSX2 emu
* Fixed CdRead by linuzappz
*/
#include "PrecompiledHeader.h"
#include <ctype.h>
#include "IsoFStools.h"
#include "IsoFSdrv.h"
#include "CDVDaccess.h"
struct dir_toc_data
{
u32 start_LBA;
u32 num_sectors;
u32 num_entries;
u32 current_entry;
u32 current_sector;
u32 current_sector_offset;
u32 inc_dirs;
char extension_list[128+1];
};
//static u8 cdVolDescriptor[2048];
static dir_toc_data getDirTocData;
static cdVolDesc CDVolDesc;
static const int JolietMaxPath = 1024;
void _splitpath2(const char *constpath, char *dir, char *fname){
// 255 char max path-length is an ISO9660 restriction
// we must change this for Joliet or relaxed iso restriction support
char pathcopy[JolietMaxPath+1];
char* slash;
strncpy(pathcopy, constpath, 1024);
slash = strrchr (pathcopy, '/');
// if the path doesn't contain a '/' then look for a '\'
if (!slash)
slash = strrchr (pathcopy, (int)'\\');
// if a slash was found
if (slash != NULL)
{
// null terminate the path
slash[0] = 0;
// and copy the path into 'dir'
strncpy(dir, pathcopy, 1024);
dir[255]=0;
// copy the filename into 'fname'
strncpy(fname, slash+1, 128);
fname[128]=0;
}
else
{
dir[0] = 0;
strncpy(fname, pathcopy, 128);
fname[128]=0;
}
}
// Used in findfile
//int tolower(int c);
int strcasecmp(const char *s1, const char *s2){
while (*s1 != '\0' && tolower(*s1) == tolower(*s2))
{
s1++;
s2++;
}
return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2);
}
// Copy a TOC Entry from the CD native format to our tidier format
void TocEntryCopy(TocEntry* tocEntry, const dirTocEntry* internalTocEntry){
int i;
int filenamelen;
tocEntry->fileSize = internalTocEntry->fileSize;
tocEntry->fileLBA = internalTocEntry->fileLBA;
tocEntry->fileProperties = internalTocEntry->fileProperties;
memcpy(tocEntry->date, internalTocEntry->dateStamp, 7); //TODO: Buffer read overrun, dateStamp is 6 bytes
if (CDVolDesc.filesystemType == 2){
// This is a Joliet Filesystem, so use Unicode to ISO string copy
filenamelen = internalTocEntry->filenameLength/2;
// if (!(tocEntry->fileProperties & 0x02)){
// strip the ;1 from the filename
// filenamelen -= 2;//(Florin) nah, do not strip ;1
// }
for (i=0; i < filenamelen; i++)
tocEntry->filename[i] = internalTocEntry->filename[(i<<1)+1];
tocEntry->filename[filenamelen] = 0;
}
else{
filenamelen = internalTocEntry->filenameLength;
// if (!(tocEntry->fileProperties & 0x02)){
// strip the ;1 from the filename
// filenamelen -= 2;//(Florin) nah, do not strip ;1
// }
// use normal string copy
strncpy(tocEntry->filename,internalTocEntry->filename,128);
tocEntry->filename[filenamelen] = 0;
}
}
// Check if a TOC Entry matches our extension list
int TocEntryCompare(char* filename, char* extensions){
static char ext_list[129];
char* token;
char* ext_point;
strncpy(ext_list,extensions,128);
ext_list[128]=0;
token = strtok( ext_list, " ," );
while( token != NULL )
{
// if 'token' matches extension of 'filename'
// then return a match
ext_point = strrchr(filename,'.');
if (strnicmp(ext_point, token, strlen(token)) == 0)
return (TRUE);
/* Get next token: */
token = strtok( NULL, " ," );
}
// If not match found then return FALSE
return (FALSE);
}
int IsoFS_readSectors(u32 lsn, u32 sectors, void *buf)
{
for (u32 i=0; i<sectors; i++)
{
if (DoCDVDreadSector((u8*)((uptr)buf+2048*i), lsn+i, CDVD_MODE_2048) == -1) return 0;
}
return 1;
}
/**************************************************************
* The functions below are not exported for normal file-system *
* operations, but are used by the file-system operations, and *
* may also be exported for use via RPC *
**************************************************************/
int IsoFS_getVolumeDescriptor(void)
{
// Read until we find the last valid Volume Descriptor
s32 volDescSector;
cdVolDesc localVolDesc;
DbgCon.WriteLn("IsoFS_GetVolumeDescriptor called");
for (volDescSector = 16; volDescSector<20; volDescSector++)
{
IsoFS_readSectors(volDescSector,1,&localVolDesc);
// CdSync(0x00);
// If this is still a volume Descriptor
if (strncmp((char*)localVolDesc.volID, "CD001", 5) == 0)
{
if ((localVolDesc.filesystemType == 1) ||
(localVolDesc.filesystemType == 2))
{
memcpy_fast(&CDVolDesc, &localVolDesc, sizeof(cdVolDesc));
}
}
else
break;
}
if (CDVolDesc.filesystemType == 1)
DbgCon.WriteLn( Color_Green, "CD FileSystem is ISO9660" );
else if (CDVolDesc.filesystemType == 2)
DbgCon.WriteLn( Color_Green, "CD FileSystem is Joliet");
else
DbgCon.Warning("Could not detect CD FileSystem type");
// CdStop();
return TRUE;
}
int IsoFS_findFile(const char* fname, TocEntry* tocEntry){
char filename[g_MaxPath+1], pathname[JolietMaxPath+1], toc[2048];
char* dirname;
s32 found_dir, num_dir_sectors, current_sector, dir_lba;
dirTocEntry* tocEntryPointer;
TocEntry localTocEntry; // used for internal checking only
DbgCon.WriteLn("IsoFS_findfile(\"%s\") called", fname);
_splitpath2(fname, pathname, filename);
// Find the TOC for a specific directory
if (IsoFS_getVolumeDescriptor() != TRUE)
{
ISOFS_LOG("Could not get CD Volume Descriptor");
return -1;
}
// Read the TOC of the root directory
if (IsoFS_readSectors(CDVolDesc.rootToc.tocLBA,1,toc) != TRUE){
ISOFS_LOG("Couldn't Read from CD !");
return -1;
}
//CdSync(0x00);
// point the tocEntryPointer at the first real toc entry
tocEntryPointer = (dirTocEntry*)toc;
num_dir_sectors = (tocEntryPointer->fileSize+2047) >> 11; //round up fix
current_sector = tocEntryPointer->fileLBA;
tocEntryPointer = (dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length);
tocEntryPointer = (dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length);
localTocEntry.fileLBA = CDVolDesc.rootToc.tocLBA;
// while (there are more dir names in the path)
dirname = strtok( pathname, "\\/" );
while( dirname != NULL )
{
found_dir = FALSE;
/*
while(tocEntryPointer->length > 0)
{
// while there are still more directory entries then search through
// for the one we want
if (tocEntryPointer->fileProperties & 0x02)
{
// Copy the CD format TOC Entry to our format
TocEntryCopy(&localTocEntry, tocEntryPointer);
// If this TOC Entry is a directory,
// then see if it has the right name
if (strcasecmp(dirname,localTocEntry.filename) == 0)
{
// if the name matches then we've found the directory
found_dir = TRUE;
break;
}
}
// point to the next entry
(char*)tocEntryPointer += tocEntryPointer->length;
}
*/
while(1)
{
if ((tocEntryPointer->length == 0) || (((char*)tocEntryPointer-toc)>=2048))
{
num_dir_sectors--;
if (num_dir_sectors > 0)
{
// If we've run out of entries, but arent on the last sector
// then load another sector
current_sector++;
if (IsoFS_readSectors(current_sector,1,toc) != TRUE)
{
Console.Error("Couldn't Read from CD !");
return -1;
}
// CdSync(0x00);
tocEntryPointer = (dirTocEntry*)toc;
}
else
{
// Couldnt find the directory, and got to end of directory
return -1;
}
}
if (tocEntryPointer->fileProperties & 0x02)
{
TocEntryCopy(&localTocEntry, tocEntryPointer);
// If this TOC Entry is a directory,
// then see if it has the right name
if (strcmp(dirname,localTocEntry.filename) == 0)
{
// if the name matches then we've found the directory
found_dir = TRUE;
break;
}
}
// point to the next entry
tocEntryPointer = (dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length);
}
// If we havent found the directory name we wanted then fail
if (found_dir != TRUE)
{
Console.Warning( "IsoFS_findfile: could not find dir" );
return -1;
}
// Get next directory name
dirname = strtok( NULL, "\\/" );
// Read the TOC of the found subdirectory
if (IsoFS_readSectors(localTocEntry.fileLBA,1,toc) != TRUE)
{
Console.Error("Couldn't Read from CD !");
return -1;
}
// CdSync(0x00);
num_dir_sectors = (localTocEntry.fileSize+2047) >> 11; //round up fix
current_sector = localTocEntry.fileLBA;
// and point the tocEntryPointer at the first real toc entry
tocEntryPointer = (dirTocEntry*)toc;
tocEntryPointer = (dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length);
tocEntryPointer = (dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length);
}
ISOFS_LOG("[IsoFStools] findfile: found dir, now looking for file");
tocEntryPointer = (dirTocEntry*)toc;
num_dir_sectors = (tocEntryPointer->fileSize+2047) >> 11; //round up fix
dir_lba = tocEntryPointer->fileLBA;
tocEntryPointer = (dirTocEntry*)toc;
tocEntryPointer = (dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length);
tocEntryPointer = (dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length);
while (num_dir_sectors > 0)
{
while(tocEntryPointer->length != 0)
{
// Copy the CD format TOC Entry to our format
TocEntryCopy(&localTocEntry, tocEntryPointer);
if ((strnicmp(localTocEntry.filename, filename, strlen(filename)) == 0) ||
((filename[strlen(filename)-2] == ';') &&
(localTocEntry.filename[strlen(localTocEntry.filename)-2] == ';') &&
(strnicmp(localTocEntry.filename, filename, strlen(filename)-2) == 0)))
{
// if the filename matches then copy the toc Entry
tocEntry->fileLBA = localTocEntry.fileLBA;
tocEntry->fileProperties = localTocEntry.fileProperties;
tocEntry->fileSize = localTocEntry.fileSize;
strcpy(tocEntry->filename, localTocEntry.filename);
memcpy(tocEntry->date, localTocEntry.date, 7);
DbgCon.WriteLn("IsoFS_findfile: found file");
return TRUE;
}
tocEntryPointer = (dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length);
}
num_dir_sectors--;
if (num_dir_sectors > 0)
{
dir_lba++;
if (IsoFS_readSectors(dir_lba,1,toc) != TRUE){
Console.Error("Couldn't Read from CD !");
return -1;
}
// CdSync(0x00);
tocEntryPointer = (dirTocEntry*)toc;
}
}
DbgCon.Warning("IsoFS_findfile: could not find file");
return FALSE;
}
// This is the RPC-ready function which takes the request to start the tocEntry retrieval
int IsoFS_initDirectoryList(char* pathname, char* extensions, unsigned int inc_dirs){
char toc[2048];
char* dirname;
s32 found_dir, num_dir_sectors, current_sector;
u32 toc_entry_num;
dirTocEntry* tocEntryPointer;
TocEntry localTocEntry;
// store the extension list statically for the retrieve function
strncpy(getDirTocData.extension_list, extensions, 128);
getDirTocData.extension_list[128]=0;
getDirTocData.inc_dirs = inc_dirs;
// Find the TOC for a specific directory
if (IsoFS_getVolumeDescriptor() != TRUE){
ISOFS_LOG("[IsoFStools] Could not get CD Volume Descriptor");
return -1;
}
ISOFS_LOG("[IsoFStools] Getting Directory Listing for: \"%s\"", pathname);
// Read the TOC of the root directory
if (IsoFS_readSectors(CDVolDesc.rootToc.tocLBA,1,toc) != TRUE){
ISOFS_LOG("[IsoFStools] Couldn't Read from CD !");
return -1;
}
//CdSync(0x00);
// point the tocEntryPointer at the first real toc entry
tocEntryPointer = (dirTocEntry*)toc;
num_dir_sectors = (tocEntryPointer->fileSize+2047) >> 11;
current_sector = tocEntryPointer->fileLBA;
tocEntryPointer = (dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length);
tocEntryPointer = (dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length);
// use strtok to get the next dir name
// if there isn't one, then assume we want the LBA
// for the current one, and exit the while loop
// if there is another dir name then increment dir_depth
// and look through dir table entries until we find the right name
// if we don't find the right name
// before finding an entry at a higher level (lower num), then return nothing
localTocEntry.fileLBA = CDVolDesc.rootToc.tocLBA;
// while (there are more dir names in the path)
dirname = strtok( pathname, "\\/" );
while( dirname != NULL ){
found_dir = FALSE;
while(1){
if ((tocEntryPointer->length == 0) || (((char*)tocEntryPointer-toc)>=2048)) {
num_dir_sectors--;
if (num_dir_sectors > 0){
// If we've run out of entries, but arent on the last sector
// then load another sector
current_sector++;
if (IsoFS_readSectors(current_sector,1,toc) != TRUE){
ISOFS_LOG("[IsoFStools] Couldn't Read from CD !");
return -1;
}
//CdSync(0x00);
tocEntryPointer = (dirTocEntry*)toc;
}
else{
// Couldnt find the directory, and got to end of directory
return -1;
}
}
if (tocEntryPointer->fileProperties & 0x02){
TocEntryCopy(&localTocEntry, tocEntryPointer);
// If this TOC Entry is a directory,
// then see if it has the right name
if (strcmp(dirname,localTocEntry.filename) == 0){
// if the name matches then we've found the directory
found_dir = TRUE;
ISOFS_LOG("[IsoFStools] Found directory %s in subdir at sector %d",dirname,current_sector);
ISOFS_LOG("[IsoFStools] LBA of found subdirectory = %d",localTocEntry.fileLBA);
break;
}
}
// point to the next entry
tocEntryPointer = (dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length);
}
// If we havent found the directory name we wanted then fail
if (found_dir != TRUE) return -1;
// Get next directory name
dirname = strtok( NULL, "\\/" );
// Read the TOC of the found subdirectory
if (IsoFS_readSectors(localTocEntry.fileLBA,1,toc) != TRUE){
ISOFS_LOG("[IsoFStools] Couldn't Read from CD !");
return -1;
}
//CdSync(0x00);
num_dir_sectors = (localTocEntry.fileSize+2047) >> 11;
current_sector = localTocEntry.fileLBA;
// and point the tocEntryPointer at the first real toc entry
tocEntryPointer = (dirTocEntry*)toc;
tocEntryPointer = (dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length);
tocEntryPointer = (dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length);
}
// We know how much data we need to read in from the DirTocHeader
// but we need to read in at least 1 sector before we can get this value
// Now we need to COUNT the number of entries (dont do anything with info at this point)
// so set the tocEntryPointer to point to the first actual file entry
// This is a bit of a waste of reads since we're not actually copying the data out yet,
// but we dont know how big this TOC might be, so we cant allocate a specific size
tocEntryPointer = (dirTocEntry*)toc;
// Need to STORE the start LBA and number of Sectors, for use by the retrieve func.
getDirTocData.start_LBA = localTocEntry.fileLBA;
getDirTocData.num_sectors = (tocEntryPointer->fileSize+2047) >> 11;
getDirTocData.num_entries = 0;
getDirTocData.current_entry = 0;
getDirTocData.current_sector = getDirTocData.start_LBA;
getDirTocData.current_sector_offset = 0;
num_dir_sectors = getDirTocData.num_sectors;
tocEntryPointer = (dirTocEntry*)toc;
tocEntryPointer = (dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length);
tocEntryPointer = (dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length);
toc_entry_num=0;
while(1){
if ((tocEntryPointer->length == 0) || (((char*)tocEntryPointer-toc)>=2048)){
// decrease the number of dirs remaining
num_dir_sectors--;
if (num_dir_sectors > 0){
// If we've run out of entries, but arent on the last sector
// then load another sector
getDirTocData.current_sector++;
if (IsoFS_readSectors(getDirTocData.current_sector,1,toc) != TRUE){
ISOFS_LOG("[IsoFStools] Couldn't Read from CD !");
return -1;
}
//CdSync(0x00);
tocEntryPointer = (dirTocEntry*)toc;
// continue;
}
else{
getDirTocData.num_entries = toc_entry_num;
getDirTocData.current_sector = getDirTocData.start_LBA;
return (toc_entry_num);
}
}
// We've found a file/dir in this directory
// now check if it matches our extension list (if there is one)
TocEntryCopy(&localTocEntry, tocEntryPointer);
if (localTocEntry.fileProperties & 0x02){
// If this is a subdir, then check if we want to include subdirs
if (getDirTocData.inc_dirs){
toc_entry_num++;
}
}
else{
if (strlen(getDirTocData.extension_list) > 0){
if (TocEntryCompare(localTocEntry.filename, getDirTocData.extension_list) == TRUE){
// increment the number of matching entries counter
toc_entry_num++;
}
}
else{
toc_entry_num++;
}
}
tocEntryPointer = (dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length);
}
// THIS SHOULD BE UNREACHABLE -
// since we are trying to count ALL matching entries, rather than upto a limit
// STORE total number of TOC entries
getDirTocData.num_entries = toc_entry_num;
getDirTocData.current_sector = getDirTocData.start_LBA;
// we've reached the toc entry limit, so return how many we've done
return (toc_entry_num);
}
// This function can be called repeatedly after CDVD_GetDir_RPC_request to get the actual entries
// buffer (tocEntry) must be 18KB in size, and this will be filled with a maximum of 128 entries in one go
int IsoFS_getDirectories(TocEntry tocEntry[], int req_entries){
char toc[2048];
s32 toc_entry_num;
dirTocEntry* tocEntryPointer;
if (IsoFS_readSectors(getDirTocData.current_sector,1,toc) != TRUE){
ISOFS_LOG("[IsoFStools] Couldn't Read from CD !");
return -1;
}
//CdSync(0x00);
if (getDirTocData.current_entry == 0){
// if this is the first read then make sure we point to the first real entry
tocEntryPointer = (dirTocEntry*)toc;
tocEntryPointer = (dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length);
tocEntryPointer = (dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length);
getDirTocData.current_sector_offset = (char*)tocEntryPointer - toc;
}
else{
tocEntryPointer = (dirTocEntry*)(toc + getDirTocData.current_sector_offset);
}
if (req_entries > 128) req_entries = 128;
for (toc_entry_num=0; toc_entry_num < req_entries;)
{
if ((tocEntryPointer->length == 0) || (getDirTocData.current_sector_offset >= 2048))
{
// decrease the number of dirs remaining
getDirTocData.num_sectors--;
if (getDirTocData.num_sectors > 0)
{
// If we've run out of entries, but arent on the last sector
// then load another sector
getDirTocData.current_sector++;
if (IsoFS_readSectors(getDirTocData.current_sector,1,toc) != TRUE){
ISOFS_LOG("[IsoFStools] Couldn't Read from CD !");
return -1;
}
//CdSync(0x00);
getDirTocData.current_sector_offset = 0;
tocEntryPointer = (dirTocEntry*)(toc + getDirTocData.current_sector_offset);
// continue;
}
else
{
return (toc_entry_num);
}
}
// This must be incremented even if the filename doesnt match extension list
getDirTocData.current_entry++;
// We've found a file in this directory
// now check if it matches our extension list (if there is one)
// Copy the entry regardless, as it makes the comparison easier
// if it doesn't match then it will just be overwritten
TocEntryCopy(&tocEntry[toc_entry_num], tocEntryPointer);
if (tocEntry[toc_entry_num].fileProperties & 0x02){
// If this is a subdir, then check if we want to include subdirs
if (getDirTocData.inc_dirs) {
toc_entry_num++;
}
getDirTocData.current_sector_offset += tocEntryPointer->length;
tocEntryPointer = (dirTocEntry*)(toc + getDirTocData.current_sector_offset);
}
else{
if (strlen(getDirTocData.extension_list) > 0){
if (TocEntryCompare(tocEntry[toc_entry_num].filename, getDirTocData.extension_list) == TRUE){
// increment the number of matching entries counter
toc_entry_num++;
}
getDirTocData.current_sector_offset += tocEntryPointer->length;
tocEntryPointer = (dirTocEntry*)(toc + getDirTocData.current_sector_offset);
}
else{
toc_entry_num++;
getDirTocData.current_sector_offset += tocEntryPointer->length;
tocEntryPointer = (dirTocEntry*)(toc + getDirTocData.current_sector_offset);
}
}
}
return (toc_entry_num);
}

View File

@ -1,137 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 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 PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Original code from libcdvd by Hiryu & Sjeep (C) 2002
* Modified by Florin for PCSX2 emu
*/
#pragma once
#include "IsoFScdvd.h"
int IsoFS_initDirectoryList(char* pathname, char* extensions, unsigned int inc_dirs);
int IsoFS_getDirectories(TocEntry tocEntry[], int req_entries);
static const int CD_SECS = 60; // seconds per minute
static const int CD_FRAMES = 75; // frames per second
static const int CD_MSF_OFFSET = 150; // MSF numbering offset of first frame
#ifdef _MSC_VER
# pragma pack(1)
#endif
struct rootDirTocHeader
{
u16 length; //+00
u32 tocLBA; //+02
u32 tocLBA_bigend; //+06
u32 tocSize; //+0A
u32 tocSize_bigend; //+0E
u8 dateStamp[8]; //+12
u8 reserved[6]; //+1A
u8 reserved2; //+20
u8 reserved3; //+21
} __packed; //+22
struct asciiDate
{
char year[4];
char month[2];
char day[2];
char hours[2];
char minutes[2];
char seconds[2];
char hundreths[2];
char terminator[1];
} __packed;
struct cdVolDesc
{
u8 filesystemType; // 0x01 = ISO9660, 0x02 = Joliet, 0xFF = NULL
u8 volID[5]; // "CD001"
u8 reserved2;
u8 reserved3;
u8 sysIdName[32];
u8 volName[32]; // The ISO9660 Volume Name
u8 reserved5[8];
u32 volSize; // Volume Size
u32 volSizeBig; // Volume Size Big-Endian
u8 reserved6[32];
u32 unknown1;
u32 unknown1_bigend;
u16 volDescSize; //+80
u16 volDescSize_bigend; //+82
u32 unknown3; //+84
u32 unknown3_bigend; //+88
u32 priDirTableLBA; // LBA of Primary Dir Table //+8C
u32 reserved7; //+90
u32 secDirTableLBA; // LBA of Secondary Dir Table //+94
u32 reserved8; //+98
rootDirTocHeader rootToc;
s8 volSetName[128];
s8 publisherName[128];
s8 preparerName[128];
s8 applicationName[128];
s8 copyrightFileName[37];
s8 abstractFileName[37];
s8 bibliographyFileName[37];
asciiDate creationDate;
asciiDate modificationDate;
asciiDate effectiveDate;
asciiDate expirationDate;
u8 reserved10;
u8 reserved11[1166];
} __packed;
struct dirTableEntry
{
u8 dirNameLength;
u8 reserved;
u32 dirTOCLBA;
u16 dirDepth;
u8 dirName[32];
} __packed;
// --------------------------------------------------------------------------------------
// dirTocEntry
// --------------------------------------------------------------------------------------
// This is the internal Table of Contents, as found on the CD
// TocEntry structure contains only the important stuff needed for export.
struct dirTocEntry
{
s16 length;
u32 fileLBA;
u32 fileLBA_bigend;
u32 fileSize;
u32 fileSize_bigend;
u8 dateStamp[6];
u8 reserved1;
u8 fileProperties;
u8 reserved2[6];
u8 filenameLength;
char filename[128];
} __packed;
#ifdef _MSC_VER
# pragma pack()
#endif

View File

@ -16,8 +16,8 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "IopCommon.h" #include "IopCommon.h"
#include "IsoFStools.h" //#include "IsoFStools.h"
#include "IsoFSdrv.h" //#include "IsoFSdrv.h"
#include "IsoFileFormats.h" #include "IsoFileFormats.h"
#include <stdio.h> #include <stdio.h>
@ -27,15 +27,15 @@
int detect(isoFile *iso) int detect(isoFile *iso)
{ {
u8 buf[2448]; u8 buf[2448];
cdVolDesc *volDesc; u8* pbuf;
if (isoReadBlock(iso, buf, 16) == -1) return -1; if (isoReadBlock(iso, buf, 16) == -1) return -1;
volDesc = (cdVolDesc *) (( iso->flags & ISOFLAGS_BLOCKDUMP_V3 ) ? buf : (buf + 24)); pbuf = (( iso->flags & ISOFLAGS_BLOCKDUMP_V3 ) ? buf : (buf + 24));
if (strncmp((char*)volDesc->volID, "CD001", 5)) return 0; if (strncmp((char*)(pbuf+1), "CD001", 5)) return 0;
if (volDesc->rootToc.tocSize == 2048) if (*(u16*)(pbuf+166) == 2048)
iso->type = ISOTYPE_CD; iso->type = ISOTYPE_CD;
else else
iso->type = ISOTYPE_DVD; iso->type = ISOTYPE_DVD;

View File

@ -16,9 +16,11 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "Common.h" #include "Common.h"
#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/isofs.h"
using namespace std; using namespace std;
extern void InitPatch(wxString crc); extern void InitPatch(wxString crc);
@ -326,13 +328,18 @@ struct ElfObject
if ((strnicmp( work, "cdrom0:", strlen("cdromN:")) == 0) || if ((strnicmp( work, "cdrom0:", strlen("cdromN:")) == 0) ||
(strnicmp( work, "cdrom1:", strlen("cdromN:")) == 0)) (strnicmp( work, "cdrom1:", strlen("cdromN:")) == 0))
{ {
int fi = IsoFS_open(work + strlen("cdromN:"), 1);//RDONLY IsoFSCDVD isofs;
IsoDirectory fsroot(&isofs);
if (fi < 0) throw Exception::FileNotFound( filename ); // Will throw exception if the file was not found
IsoFile file = fsroot.OpenFile(work + strlen("cdromN:"));
IsoFS_lseek( fi, 0, SEEK_SET ); int size = file.getLength();
rsize = IsoFS_read( fi, (char*)data.GetPtr(), data.GetSizeInBytes() );
IsoFS_close( fi ); char buffer[256]; //if the file is longer...it should be shorter :D
rsize = file.read((u8*)data.GetPtr(), data.GetSizeInBytes());
//if (fi < 0) throw Exception::FileNotFound( filename );
} }
else else
{ {
@ -503,18 +510,24 @@ 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 )
{ {
TocEntry toc; IsoFSCDVD isofs;
IsoDirectory fsroot(&isofs);
IsoFS_init( ); IsoFileDescriptor desc;
u32 crcval = 0;
Console.WriteLn("loadElfCRC: %s", filename); Console.WriteLn("loadElfCRC: %s", filename);
int mylen = strlen( "cdromN:" ); try {
if ( IsoFS_findFile( filename + mylen, &toc ) == -1 ) return 0; int mylen = strlen( "cdromN:" );
desc = fsroot.FindFile( filename + mylen );
DevCon.WriteLn( "loadElfFile: %d bytes", toc.fileSize ); DevCon.WriteLn( "loadElfFile: %d bytes", desc.size );
u32 crcval = ElfObject( fromUTF8( filename ), toc.fileSize ).GetCRC(); crcval = ElfObject( fromUTF8( filename ), desc.size ).GetCRC();
Console.WriteLn( "loadElfFile: %s; CRC = %8.8X", filename, crcval ); Console.WriteLn( "loadElfFile: %s; CRC = %8.8X", filename, crcval );
}
catch( ... )
{
}
return crcval; return crcval;
} }
@ -549,11 +562,23 @@ 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;
TocEntry toc;
IsoFS_init( ); IsoFileDescriptor desc;
if ( IsoFS_findFile( fnptr + strlen( "cdromN:" ), &toc ) == -1 ) try
{
IsoFSCDVD isofs;
IsoDirectory fsroot(&isofs);
u32 crcval = 0;
Console.WriteLn("loadElfCRC: %s", filename);
desc = fsroot.FindFile(fnptr + strlen( "cdromN:" ));
}
catch( ... )
{
throw Exception::FileNotFound( filename, wxLt("ELF file was not found on the CDVD source media.") ); throw Exception::FileNotFound( filename, wxLt("ELF file was not found on the CDVD source media.") );
elfsize = toc.fileSize; }
elfsize = desc.size;
} }
if( elfsize > 0xfffffff ) if( elfsize > 0xfffffff )
@ -612,42 +637,51 @@ int GetPS2ElfName( wxString& name )
int f; int f;
char buffer[g_MaxPath];//if a file is longer...it should be shorter :D char buffer[g_MaxPath];//if a file is longer...it should be shorter :D
char *pos; char *pos;
TocEntry tocEntry;
IsoFS_init(); try {
IsoFSCDVD isofs;
IsoDirectory fsroot(&isofs);
// check if the file exists try {
if (IsoFS_findFile("SYSTEM.CNF;1", &tocEntry) != TRUE){ // Will throw exception if the file was not found
Console.Warning("GetElfName: SYSTEM.CNF not found; invalid cd image or no disc present."); IsoFile file = fsroot.OpenFile("SYSTEM.CNF;1");
return 0;//could not find; not a PS/PS2 cdvd
}
f=IsoFS_open("SYSTEM.CNF;1", 1); int size = file.getLength();
IsoFS_read(f, buffer, g_MaxPath);
IsoFS_close(f);
buffer[tocEntry.fileSize]='\0'; char buffer[256]; //if the file is longer...it should be shorter :D
file.read((u8*)buffer,size);
buffer[size]='\0';
pos=strstr(buffer, "BOOT2"); char* pos = strstr(buffer, "BOOT2");
if (pos==NULL){ if (pos == NULL)
pos=strstr(buffer, "BOOT"); {
if (pos==NULL) { pos = strstr(buffer, "BOOT");
Console.Error("PCSX2 Boot Error: This is not a Playstation or PS2 game!"); if (pos==NULL) {
return 0; Console.Error("PCSX2 Boot Error: This is not a Playstation or PS2 game!");
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( ... )
{
} }
return 1;
} }
pos+=strlen("BOOT2"); catch( ... )
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();
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
FILE *fp; FILE *fp;

View File

@ -19,7 +19,7 @@
#include "IopCommon.h" #include "IopCommon.h"
#include "SaveState.h" #include "SaveState.h"
#include "CDVD/IsoFSdrv.h" //#include "CDVD/IsoFSdrv.h"
#include "ps2/BiosTools.h" #include "ps2/BiosTools.h"
#include "VUmicro.h" #include "VUmicro.h"

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="windows-1253"?> <?xml version="1.0" encoding="windows-1253"?>
<VisualStudioProject <VisualStudioProject
ProjectType="Visual C++" ProjectType="Visual C++"
Version="9.00" Version="9,00"
Name="pcsx2" Name="pcsx2"
ProjectGUID="{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}" ProjectGUID="{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}"
RootNamespace="pcsx2" RootNamespace="pcsx2"
@ -415,26 +415,6 @@
RelativePath="..\..\CDVD\IsoFileFormats.h" RelativePath="..\..\CDVD\IsoFileFormats.h"
> >
</File> </File>
<File
RelativePath="..\..\CDVD\IsoFScdvd.h"
>
</File>
<File
RelativePath="..\..\CDVD\IsoFSdrv.cpp"
>
</File>
<File
RelativePath="..\..\CDVD\IsoFSdrv.h"
>
</File>
<File
RelativePath="..\..\CDVD\IsoFStools.cpp"
>
</File>
<File
RelativePath="..\..\CDVD\IsoFStools.h"
>
</File>
</Filter> </Filter>
<Filter <Filter
Name="Include" Name="Include"
@ -1776,6 +1756,42 @@
> >
</File> </File>
</Filter> </Filter>
<Filter
Name="IsoFS"
>
<File
RelativePath="..\..\CDVD\IsoFS\IsoFile.cpp"
>
</File>
<File
RelativePath="..\..\CDVD\IsoFS\IsoFile.h"
>
</File>
<File
RelativePath="..\..\CDVD\IsoFS\IsoFileDescriptor.h"
>
</File>
<File
RelativePath="..\..\CDVD\IsoFS\IsoFS.cpp"
>
</File>
<File
RelativePath="..\..\CDVD\IsoFS\IsoFS.h"
>
</File>
<File
RelativePath="..\..\CDVD\IsoFS\IsoFSCDVD.cpp"
>
</File>
<File
RelativePath="..\..\CDVD\IsoFS\IsoFSCDVD.h"
>
</File>
<File
RelativePath="..\..\CDVD\IsoFS\SectorSource.h"
>
</File>
</Filter>
</Filter> </Filter>
<Filter <Filter
Name="AppHost" Name="AppHost"