20 #include "Iso9660Filesystem.h" 21 #include "Iso9660Directory.h" 22 #include "Iso9660File.h" 24 #include "modules/Module.h" 25 #include "modules/system/vfs/File.h" 26 #include "modules/system/vfs/VFS.h" 27 #include "pedigree/kernel/Log.h" 28 #include "pedigree/kernel/machine/Disk.h" 29 #include "pedigree/kernel/utilities/StaticString.h" 30 #include "pedigree/kernel/utilities/utility.h" 32 String WideToMultiByteStr(uint8_t *in,
size_t inLen,
size_t maxLen)
37 while ((*in || in[1]) && (inLen > 0) && (maxLen > 0))
39 uint16_t c = (*in << 8) | in[1];
45 ret.append(static_cast<char>(c));
55 Iso9660Filesystem::Iso9660Filesystem()
56 : m_pDisk(0), m_PrimaryVolDesc(), m_SuppVolDesc(), m_VolDesc(),
57 m_RootDir(0), m_JolietLevel(0), m_BlockSize(0), m_BlockNumber(0),
58 m_VolumeLabel(
""), m_pRoot(0)
62 Iso9660Filesystem::~Iso9660Filesystem()
77 for (
size_t i = 16; i < 256; i++)
79 uintptr_t buff = m_pDisk->read(i * m_BlockSize);
85 reinterpret_cast<const char *>(vDesc->Ident),
"CD001", 5) != 0)
87 NOTICE(
"IDENT: " << reinterpret_cast<const char *>(vDesc->Ident));
92 if (vDesc->Type == PRIM_VOL_DESC)
95 &m_PrimaryVolDesc, reinterpret_cast<uint8_t *>(buff),
99 else if (vDesc->Type == SUPP_VOL_DESC)
102 &m_SuppVolDesc, reinterpret_cast<uint8_t *>(buff),
107 if (m_SuppVolDesc.Unused3_EscSequences[0] == 0x25 &&
108 m_SuppVolDesc.Unused3_EscSequences[1] == 0x2F)
110 if (m_SuppVolDesc.Unused3_EscSequences[2] == 0x40)
112 else if (m_SuppVolDesc.Unused3_EscSequences[2] == 0x43)
114 else if (m_SuppVolDesc.Unused3_EscSequences[2] == 0x45)
117 NOTICE(
"No Joliet level found");
120 NOTICE(
"Not handling Joliet level");
122 else if (vDesc->Type == TERM_VOL_DESC)
128 WARNING(
"ISO9660: Neither a primary or supplementary volume descriptor " 136 m_PrimaryVolDesc = m_SuppVolDesc;
140 char *volLabel =
new char[32];
141 MemoryCopy(volLabel, m_PrimaryVolDesc.VolIdent, 32);
145 WideToMultiByteStr(reinterpret_cast<uint8_t *>(volLabel), 32, 32);
147 str.append(volLabelString);
150 for (i = str.length() - 1;
static_cast<int32_t
>(i) >= 0; i--)
153 str = str.left(i + 1);
154 m_VolumeLabel =
String(str);
158 for (
size_t i = 31;
static_cast<int32_t
>(i) >= 0; i--)
160 if (volLabel[i] !=
' ')
166 m_VolumeLabel =
String(volLabel);
169 if (m_VolumeLabel.length() == 0)
173 str +=
"no-volume-label@";
174 str.append(reinterpret_cast<uintptr_t>(
this), 16);
175 m_VolumeLabel.assign(str, str.length(),
true);
182 m_pRoot = fileFromDirRecord(*m_RootDir, 1, 0,
true);
210 return m_VolumeLabel;
213 uintptr_t Iso9660Filesystem::readBlock(
File *pFile, uint64_t location)
223 if (location > pFile->getSize())
226 size_t blockSkip = location / m_BlockSize;
227 size_t blockNum = LITTLE_TO_HOST32(rec.ExtentLocation_LE) + blockSkip;
230 uintptr_t buff = m_pDisk->read(blockNum * m_BlockSize);
236 File *parent,
const String &filename, uint32_t mask)
242 File *parent,
const String &filename, uint32_t mask)
261 return parseJolietName(dirRecord);
267 uint8_t *fileIdent =
reinterpret_cast<uint8_t *
>(
268 adjust_pointer(&dirRecord,
sizeof(dirRecord)));
269 size_t len = (dirRecord.FileIdentLen < 31) ? dirRecord.FileIdentLen : 31;
271 for (i = 0; i < len; i++)
273 if (fileIdent[i] ==
';')
276 ret.append(toLower(static_cast<char>(fileIdent[i])));
279 if (i && (fileIdent[i - 1] ==
'.'))
289 reinterpret_cast<uint8_t *
>(adjust_pointer(&name,
sizeof(name)));
290 String s = WideToMultiByteStr(fileIdent, name.FileIdentLen >> 1, 64);
293 size_t len = str.length();
295 if ((len > 2) && (str[len - 2] ==
';') && (str[len - 1] ==
'1'))
298 while (len >= 2 && (str[len - 1] ==
'.'))
305 File *Iso9660Filesystem::fileFromDirRecord(
308 String fileName = parseName(dir);
309 Time::Timestamp t = timeToUnix(dir.Time);
313 fileName, inodeNum,
this, parent, dir, t, t, t);
319 fileName, t, t, t, inodeNum,
this, LITTLE_TO_HOST32(dir.DataLen_LE),
325 static bool initIso9660()
331 static void destroyIso9660()
335 MODULE_INFO(
"iso9660", &initIso9660, &destroyIso9660,
"vfs");
virtual bool createSymlink(File *parent, const String &filename, const String &value)
virtual bool createDirectory(File *parent, const String &filename, uint32_t mask)
Iso9660File(const Iso9660File &)
virtual String getVolumeLabel() const
virtual bool remove(File *parent, File *file)
void addProbeCallback(Filesystem::ProbeCallback callback)
virtual bool initialise(Disk *pDisk)
virtual bool createFile(File *parent, const String &filename, uint32_t mask)
virtual File * getRoot() const
virtual bool isDirectory()