20#include "Iso9660Filesystem.h"
21#include "pedigree/kernel/Log.h"
22#include "pedigree/kernel/TargetInfo.h"
23#include "pedigree/kernel/machine/Disk.h"
24#include "pedigree/kernel/utilities/StaticString.h"
25#include "pedigree/kernel/utilities/utility.h"
27#include "Iso9660Directory.h"
28#include "Iso9660File.h"
30#include "modules/Module.h"
31#include "modules/system/vfs/File.h"
32#include "modules/system/vfs/VFS.h"
35constexpr size_t IsoSectorSize = 2048;
36constexpr size_t IsoSectorViewCapacity =
40String WideToMultiByteStr(uint8_t* in,
size_t inLen,
size_t maxLen) {
44 while (inLen > 0 && maxLen > 0 && (*in || in[1])) {
45 uint16_t c = (*in << 8) | in[1];
49 ret.append(
static_cast<char>(c));
61Iso9660Filesystem::Iso9660Filesystem()
73Iso9660Filesystem::~Iso9660Filesystem() {}
85 for (
size_t i = 16; i < 256; i++) {
91 const BufferView buffer(sector,
sizeof(sector));
95 if (StringCompareN(
reinterpret_cast<const char*
>(vDesc->Ident),
"CD001", 5) != 0) {
96 NOTICE(
"IDENT: " <<
reinterpret_cast<const char*
>(vDesc->Ident));
100 const uint8_t descriptorType = vDesc->Type;
103 if (descriptorType == PRIM_VOL_DESC) {
106 }
else if (descriptorType == SUPP_VOL_DESC) {
111 if (m_SuppVolDesc.Unused3_EscSequences[0] == 0x25 &&
112 m_SuppVolDesc.Unused3_EscSequences[1] == 0x2F) {
113 if (m_SuppVolDesc.Unused3_EscSequences[2] == 0x40)
115 else if (m_SuppVolDesc.Unused3_EscSequences[2] == 0x43)
117 else if (m_SuppVolDesc.Unused3_EscSequences[2] == 0x45)
120 NOTICE(
"No Joliet level found");
122 NOTICE(
"Not handling Joliet level");
124 if (descriptorType == TERM_VOL_DESC)
130 "ISO9660: Neither a primary or supplementary volume descriptor "
141 char volLabel[33] = {};
144 String volLabelString = WideToMultiByteStr(
reinterpret_cast<uint8_t*
>(volLabel), 16, 32);
146 str.append(volLabelString);
149 for (i = str.length() - 1;
static_cast<int32_t
>(i) >= 0; i--)
152 str = str.left(i + 1);
155 size_t labelLength = 32;
156 while (labelLength && volLabel[labelLength - 1] ==
' ')
158 volLabel[labelLength] = 0;
165 str +=
"no-volume-label@";
166 str.append(
reinterpret_cast<uintptr_t
>(
this), 16);
171 m_pRoot = fileFromDirRecord(*m_RootDir, 1, 0,
true);
197 if (!
m_pDisk || !destination) {
207 const bool copied = views.copyTo(destination, IsoSectorSize);
212uintptr_t Iso9660Filesystem::readBlock(
File* pFile, uint64_t location) {
221 if (location >= pFile->getSize())
224 const size_t viewLength =
226 const uint64_t diskLocation =
227 (
static_cast<uint64_t
>(LITTLE_TO_HOST32(rec.ExtentLocation_LE)) *
m_BlockSize) + location;
229 if (!buffer || buffer.size() < viewLength) {
236 return buffer.address();
257 return parseJolietName(dirRecord);
263 uint8_t* fileIdent =
reinterpret_cast<uint8_t*
>(adjust_pointer(&dirRecord,
sizeof(dirRecord)));
264 size_t len = (dirRecord.FileIdentLen < 31) ? dirRecord.FileIdentLen : 31;
266 for (i = 0; i < len; i++) {
267 if (fileIdent[i] ==
';')
270 ret.append(toLower(
static_cast<char>(fileIdent[i])));
273 if (i && (fileIdent[i - 1] ==
'.'))
281 uint8_t* fileIdent =
reinterpret_cast<uint8_t*
>(adjust_pointer(&name,
sizeof(name)));
282 String s = WideToMultiByteStr(fileIdent, name.FileIdentLen >> 1, 64);
285 size_t len = str.length();
287 if ((len > 2) && (str[len - 2] ==
';') && (str[len - 1] ==
'1'))
290 while (len >= 2 && (str[len - 1] ==
'.'))
299 String fileName = parseName(dir);
300 Time::Timestamp t = timeToUnix(dir.Time);
306 LITTLE_TO_HOST32(dir.DataLen_LE), dir, parent);
311#ifndef ISO9660_STANDALONE
312static bool initIso9660() {
317static void destroyIso9660() {
318 if (!
VFS::instance().removeProbeCallback(&Iso9660Filesystem::probe)) {
319 FATAL(
"ISO9660 probe callback was not registered during unload");
323MODULE_INFO(
"iso9660", &initIso9660, &destroyIso9660,
"vfs");
void unpinViews(uint64_t location, BufferViewSequence &views)
virtual BufferView read(uint64_t location)
virtual void unpin(uint64_t location)=0
MUST_USE_RESULT bool readViews(uint64_t location, size_t length, BufferViewSequence &views)
virtual bool isDirectory()
virtual const String & getVolumeLabel() const
virtual bool createFile(File *parent, const String &filename, uint32_t mask)
virtual bool createSymlink(File *parent, const String &filename, const String &value)
bool readSector(uint64_t location, void *destination)
virtual bool removeNode(File *parent, const String &filename, File *file)
virtual File * getRoot() const
virtual bool initialise(Disk *pDisk)
Iso9660VolumeDescriptorPrimary m_PrimaryVolDesc
virtual bool createDirectory(File *parent, const String &filename, uint32_t mask)
static constexpr size_t getPageSize() noexcept
void addProbeCallback(Filesystem::ProbeCallback callback)