Play-/Source/iop/ioman/HardDiskDumpDevice.cpp

143 lines
3.8 KiB
C++
Raw Permalink Normal View History

2023-01-03 21:18:18 -05:00
#include "HardDiskDumpDevice.h"
2023-01-06 13:47:25 -05:00
#include <cassert>
2023-01-29 18:11:17 -05:00
#include <cstring>
2023-01-03 21:18:18 -05:00
#include "HardDiskDevice.h"
#include "hdd/ApaReader.h"
#include "StringUtils.h"
#include "MemStream.h"
using namespace Iop;
using namespace Iop::Ioman;
CHardDiskDumpDevice::CHardDiskDumpDevice(std::unique_ptr<Framework::CStream> stream)
2023-01-06 12:26:39 -05:00
: m_stream(std::move(stream))
2023-01-03 21:18:18 -05:00
{
}
Framework::CStream* CHardDiskDumpDevice::GetFile(uint32 flags, const char* path)
{
assert(flags == OPEN_FLAG_RDONLY);
2023-01-04 19:36:29 -05:00
Hdd::APA_HEADER partitionHeader = {};
2023-01-03 21:18:18 -05:00
Hdd::CApaReader reader(*m_stream);
2023-01-04 19:36:29 -05:00
if(!reader.TryFindPartition(path, partitionHeader))
2023-01-03 21:18:18 -05:00
{
return nullptr;
}
return new CHardDiskPartition();
}
DirectoryIteratorPtr CHardDiskDumpDevice::GetDirectory(const char* path)
2023-01-03 21:18:18 -05:00
{
assert(strlen(path) == 0);
Hdd::CApaReader reader(*m_stream);
auto partitions = reader.GetPartitions();
return std::make_unique<CHardDiskDumpDirectoryIterator>(std::move(partitions));
2023-01-03 21:18:18 -05:00
}
DevicePtr CHardDiskDumpDevice::Mount(const char* path)
{
auto mountParams = StringUtils::Split(path, ',', true);
2023-01-04 19:36:29 -05:00
Hdd::APA_HEADER partitionHeader = {};
2023-01-03 21:18:18 -05:00
Hdd::CApaReader reader(*m_stream);
2023-01-04 19:36:29 -05:00
if(!reader.TryFindPartition(mountParams[0].c_str(), partitionHeader))
2023-01-03 21:18:18 -05:00
{
assert(false);
return DevicePtr();
}
2023-01-04 19:36:29 -05:00
return std::make_shared<CHardDiskDumpPartitionDevice>(*m_stream, partitionHeader);
2023-01-03 21:18:18 -05:00
}
2023-01-05 20:07:15 -05:00
bool CHardDiskDumpDevice::TryGetStat(const char* path, bool& succeeded, STAT& stat)
{
auto mountParams = StringUtils::Split(path, ',', true);
Hdd::APA_HEADER partitionHeader = {};
Hdd::CApaReader reader(*m_stream);
if(!reader.TryFindPartition(mountParams[0].c_str(), partitionHeader))
{
succeeded = false;
return true;
}
succeeded = true;
stat = {};
stat.mode = partitionHeader.type;
stat.attr = partitionHeader.flags;
stat.loSize = partitionHeader.length;
return true;
}
CHardDiskDumpDirectoryIterator::CHardDiskDumpDirectoryIterator(std::vector<Hdd::APA_HEADER> partitions)
2023-03-04 16:15:29 -05:00
: m_partitions(std::move(partitions))
{
}
void CHardDiskDumpDirectoryIterator::ReadEntry(DIRENTRY* entry)
{
*entry = {};
while(!IsDone())
{
const auto& partition = m_partitions[m_index++];
if(strlen(partition.id) == 0) continue;
static_assert(sizeof(entry->name) >= sizeof(partition.id));
strncpy(entry->name, partition.id, Hdd::APA_HEADER::ID_SIZE);
entry->name[Hdd::APA_HEADER::ID_SIZE - 1] = 0;
break;
}
}
bool CHardDiskDumpDirectoryIterator::IsDone()
{
return (m_index == m_partitions.size());
}
2023-01-04 19:36:29 -05:00
CHardDiskDumpPartitionDevice::CHardDiskDumpPartitionDevice(Framework::CStream& stream, const Hdd::APA_HEADER& partitionHeader)
2023-01-06 12:26:39 -05:00
: m_pfsReader(stream, partitionHeader)
2023-01-03 21:18:18 -05:00
{
}
Framework::CStream* CHardDiskDumpPartitionDevice::GetFile(uint32 accessType, const char* path)
2023-01-03 21:18:18 -05:00
{
accessType &= ~OPEN_FLAG_NOWAIT;
assert(accessType == OPEN_FLAG_RDONLY);
std::string absPath = path;
assert(!absPath.empty());
if(absPath[0] != '/')
{
//TODO: Append current directory
absPath = '/' + absPath;
}
return m_pfsReader.GetFileStream(absPath.c_str());
2023-01-03 21:18:18 -05:00
}
DirectoryIteratorPtr CHardDiskDumpPartitionDevice::GetDirectory(const char* path)
2023-01-03 21:18:18 -05:00
{
auto reader = m_pfsReader.GetDirectoryReader(path);
return std::make_unique<CHardDiskDumpPartitionDirectoryIterator>(reader);
}
CHardDiskDumpPartitionDirectoryIterator::CHardDiskDumpPartitionDirectoryIterator(Hdd::CPfsDirectoryReader* reader)
2023-04-14 10:08:11 -04:00
: m_reader(reader)
{
}
CHardDiskDumpPartitionDirectoryIterator::~CHardDiskDumpPartitionDirectoryIterator()
{
delete m_reader;
}
void CHardDiskDumpPartitionDirectoryIterator::ReadEntry(DIRENTRY* entry)
{
std::string entryName;
Hdd::PFS_INODE entryInode = {};
m_reader->ReadEntry(entryName, entryInode);
*entry = {};
strncpy(entry->name, entryName.c_str(), DIRENTRY::NAME_SIZE);
entry->stat.mode = entryInode.mode;
entry->stat.loSize = entryInode.size;
entry->stat.attr = entryInode.attr;
}
bool CHardDiskDumpPartitionDirectoryIterator::IsDone()
{
return m_reader->IsDone();
2023-01-03 21:18:18 -05:00
}