Play-/Source/ISO9660/ISO9660.cpp

89 lines
2.1 KiB
C++
Raw Normal View History

2015-07-31 14:06:45 -04:00
#include <string.h>
#include <limits.h>
#include "ISO9660.h"
#include "StdStream.h"
#include "File.h"
#include "DirectoryRecord.h"
#include "stricmp.h"
using namespace ISO9660;
CISO9660::CISO9660(const BlockProviderPtr& blockProvider)
2018-04-30 21:01:23 +01:00
: m_blockProvider(blockProvider)
, m_volumeDescriptor(blockProvider.get())
, m_pathTable(blockProvider.get(), m_volumeDescriptor.GetLPathTableAddress())
{
}
CISO9660::~CISO9660()
{
}
2014-07-12 21:59:58 -04:00
void CISO9660::ReadBlock(uint32 address, void* data)
{
//The buffer is needed to make sure exception handlers
//are properly called as some system calls (ie.: ReadFile)
//won't generate an exception when trying to write to
//a write protected area
m_blockProvider->ReadBlock(address, m_blockBuffer);
memcpy(data, m_blockBuffer, CBlockProvider::BLOCKSIZE);
}
2014-07-12 21:59:58 -04:00
bool CISO9660::GetFileRecord(CDirectoryRecord* record, const char* filename)
{
//Remove the first '/'
2014-07-12 21:59:58 -04:00
if(filename[0] == '/' || filename[0] == '\\') filename++;
2014-07-12 21:59:58 -04:00
unsigned int recordIndex = m_pathTable.FindRoot();
while(1)
{
//Find the next '/'
2014-07-12 21:59:58 -04:00
const char* next = strchr(filename, '/');
if(next == nullptr) break;
2014-07-12 21:59:58 -04:00
std::string dir(filename, next);
recordIndex = m_pathTable.FindDirectory(dir.c_str(), recordIndex);
if(recordIndex == 0)
{
return false;
}
2014-07-12 21:59:58 -04:00
filename = next + 1;
}
2014-07-12 21:59:58 -04:00
unsigned int address = m_pathTable.GetDirectoryAddress(recordIndex);
2014-07-12 21:59:58 -04:00
return GetFileRecordFromDirectory(record, address, filename);
}
2014-07-12 21:59:58 -04:00
bool CISO9660::GetFileRecordFromDirectory(CDirectoryRecord* record, uint32 address, const char* filename)
{
CFile directory(m_blockProvider.get(), address * CBlockProvider::BLOCKSIZE);
while(1)
{
2014-07-12 21:59:58 -04:00
CDirectoryRecord entry(&directory);
2014-07-12 21:59:58 -04:00
if(entry.GetLength() == 0) break;
if(strnicmp(entry.GetName(), filename, strlen(filename))) continue;
2014-07-12 21:59:58 -04:00
(*record) = entry;
return true;
}
return false;
}
2014-07-12 21:59:58 -04:00
Framework::CStream* CISO9660::Open(const char* filename)
{
2014-07-12 21:59:58 -04:00
CDirectoryRecord record;
2014-07-12 21:59:58 -04:00
if(GetFileRecord(&record, filename))
{
return new CFile(m_blockProvider.get(), static_cast<uint64>(record.GetPosition()) * CBlockProvider::BLOCKSIZE, record.GetDataLength());
}
2014-07-12 21:59:58 -04:00
return nullptr;
}