Skip to content

Commit

Permalink
isofs: fix long directory listing
Browse files Browse the repository at this point in the history
Directory entries can't cross a sector boundary, so reading must
continue on the next one.
Add list() method
  • Loading branch information
flyinghead committed Feb 25, 2024
1 parent 4f1512d commit ff91d11
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 36 deletions.
102 changes: 72 additions & 30 deletions core/imgread/isofs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,41 +61,69 @@ IsoFs::Directory *IsoFs::getRoot()
return root;
}

IsoFs::Entry *IsoFs::Directory::getEntry(const std::string& name)
void IsoFs::Directory::reset()
{
std::string isoname = name + ';';
for (u32 i = 0; i < data.size(); )
index = 0;
if (data.empty() && len != 0)
{
data.resize(len);
fs->disc->ReadSectors(startFad, len / 2048, data.data(), 2048);
}
}

IsoFs::Entry *IsoFs::Directory::nextEntry()
{
if (index >= data.size())
return nullptr;
const iso9660_dir_t *dir = (const iso9660_dir_t *)&data[index];
if (dir->length == 0)
{
const iso9660_dir_t *dir = (const iso9660_dir_t *)&data[i];
if ((index & 2047) == 0)
return nullptr;
index = ((index + 2047) / 2048) * 2048;
if (index >= data.size())
return nullptr;
dir = (const iso9660_dir_t *)&data[index];
if (dir->length == 0)
break;
return nullptr;
}
std::string name(dir->filename.str + 1, dir->filename.str[0]);

if ((u8)dir->filename.str[0] > isoname.size()
&& memcmp(dir->filename.str + 1, isoname.c_str(), isoname.size()) == 0)
{
DEBUG_LOG(GDROM, "Found %s at offset %X", name.c_str(), i);
u32 startFad = decode_iso733(dir->extent) + 150;
u32 len = decode_iso733(dir->size);
if ((dir->file_flags & ISO_DIRECTORY) == 0)
{
File *file = new File(fs);
file->startFad = startFad;
file->len = len;

return file;
}
else
{
Directory *directory = new Directory(fs);
directory->data.resize(len);
fs->disc->ReadSectors(startFad, len / 2048, directory->data.data(), 2048);

return directory;
}
}
i += dir->length;
u32 startFad = decode_iso733(dir->extent) + 150;
u32 len = decode_iso733(dir->size);
Entry *entry;
if ((dir->file_flags & ISO_DIRECTORY) == 0)
{
File *file = new File(fs);
entry = file;
}
else
{
Directory *directory = new Directory(fs);
len = ((len + 2047) / 2048) * 2048;
entry = directory;
}
entry->startFad = startFad;
entry->len = len;
entry->name = name;
index += dir->length;

return entry;
}

IsoFs::Entry *IsoFs::Directory::getEntry(const std::string& name)
{
std::string isoname = name + ';';
reset();
while (true)
{
Entry *entry = nextEntry();
if (entry == nullptr)
return nullptr;
if (entry->getName().substr(0, isoname.size()) == isoname)
return entry;
delete entry;
}
return nullptr;
}

u32 IsoFs::File::read(u8 *buf, u32 size, u32 offset) const
Expand All @@ -112,3 +140,17 @@ u32 IsoFs::File::read(u8 *buf, u32 size, u32 offset) const
}
return sectors * 2048 + size;
}

std::vector<IsoFs::Entry*> IsoFs::Directory::list()
{
std::vector<IsoFs::Entry*> v;
reset();
while (true)
{
Entry *entry = nextEntry();
if (entry == nullptr)
break;
v.push_back(entry);
}
return v;
}
16 changes: 10 additions & 6 deletions core/imgread/isofs.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,33 @@ class IsoFs
public:
virtual bool isDirectory() const = 0;
virtual ~Entry() = default;
const std::string& getName() const { return name; }

protected:
Entry(IsoFs *fs) : fs(fs) {}

IsoFs *fs;
std::string name;
u32 startFad = 0;
u32 len = 0;

friend class IsoFs;
};

class Directory final : public Entry
{
public:
bool isDirectory() const override { return true; }

Entry *getEntry(const std::string& name);
std::vector<Entry*> list();

private:
Directory(IsoFs *fs) : Entry(fs) {}
void reset();
Entry *nextEntry();

std::vector<u8> data;
u32 index = 0;

friend class IsoFs;
};
Expand All @@ -53,17 +62,12 @@ class IsoFs
{
public:
bool isDirectory() const override { return false; }

u32 getSize() const { return len; }

u32 read(u8 *buf, u32 size, u32 offset = 0) const;

private:
File(IsoFs *fs) : Entry(fs) {}

u32 startFad = 0;
u32 len = 0;

friend class IsoFs;
};

Expand Down

0 comments on commit ff91d11

Please sign in to comment.