diff --git a/include/NOD/DiscBase.hpp b/include/NOD/DiscBase.hpp index fb4364d..1494692 100644 --- a/include/NOD/DiscBase.hpp +++ b/include/NOD/DiscBase.hpp @@ -101,14 +101,14 @@ public: m_name(name) {} inline Kind getKind() const {return m_kind;} inline const std::string& getName() const {return m_name;} - std::unique_ptr beginReadStream() const + std::unique_ptr beginReadStream(uint64_t offset=0) const { if (m_kind != NODE_FILE) { throw std::runtime_error("unable to stream a non-file"); return std::unique_ptr(); } - return m_parent.beginReadStream(m_discOffset); + return m_parent.beginReadStream(m_discOffset + offset); } inline std::vector::iterator rawBegin() const {return m_childrenBegin;} inline std::vector::iterator rawEnd() const {return m_childrenEnd;} @@ -144,6 +144,10 @@ public: std::vector m_nodes; void parseFST(IPartReadStream& s); + DOLHeader m_dolHead; + uint64_t m_dolSz; + void parseDOL(IPartReadStream& s); + const DiscBase& m_parent; Kind m_kind; uint64_t m_offset; @@ -153,9 +157,39 @@ public: virtual uint64_t normalizeOffset(uint64_t anOffset) const {return anOffset;} inline Kind getKind() const {return m_kind;} virtual std::unique_ptr beginReadStream(uint64_t offset=0) const=0; + inline std::unique_ptr beginDOLReadStream(uint64_t offset=0) const + {return beginReadStream(m_dolOff + offset);} + inline std::unique_ptr beginFSTReadStream(uint64_t offset=0) const + {return beginReadStream(m_fstOff + offset);} + inline std::unique_ptr beginApploaderReadStream(uint64_t offset=0) const + {return beginReadStream(0x2440 + offset);} inline const Node& getFSTRoot() const {return m_nodes[0];} inline Node& getFSTRoot() {return m_nodes[0];} void extractToDirectory(const SystemString& path, bool force=false); + + inline uint64_t getDOLSize() const {return m_dolSz;} + inline std::unique_ptr getDOLBuf() const + { + std::unique_ptr buf(new uint8_t[m_dolSz]); + beginDOLReadStream()->read(buf.get(), m_dolSz); + return buf; + } + + inline uint64_t getFSTSize() const {return m_fstSz;} + inline std::unique_ptr getFSTBuf() const + { + std::unique_ptr buf(new uint8_t[m_fstSz]); + beginFSTReadStream()->read(buf.get(), m_fstSz); + return buf; + } + + inline uint64_t getApploaderSize() const {return m_apploaderSz;} + inline std::unique_ptr getApploaderBuf() const + { + std::unique_ptr buf(new uint8_t[m_apploaderSz]); + beginApploaderReadStream()->read(buf.get(), m_apploaderSz); + return buf; + } }; protected: diff --git a/lib/DiscBase.cpp b/lib/DiscBase.cpp index 9d68ca2..0ae76f5 100644 --- a/lib/DiscBase.cpp +++ b/lib/DiscBase.cpp @@ -43,6 +43,20 @@ void DiscBase::IPartition::parseFST(IPartReadStream& s) } } +void DiscBase::IPartition::parseDOL(IPartReadStream& s) +{ + /* Read Dol header */ + s.read(&m_dolHead, sizeof(DOLHeader)); + + /* Calculate Dol size */ + uint32_t dolSize = SBig(m_dolHead.textOff[0]) - sizeof(DOLHeader); + for (uint32_t i = 0 ; i < 7 ; i++) + dolSize += SBig(m_dolHead.textSizes[i]); + for (uint32_t i = 0 ; i < 11 ; i++) + dolSize += SBig(m_dolHead.dataSizes[i]); + m_dolSz = dolSize; +} + void DiscBase::IPartition::Node::extractToDirectory(const SystemString& basePath, bool force) { SystemStringView nameView(getName()); @@ -83,32 +97,16 @@ void DiscBase::IPartition::extractToDirectory(const SystemString& path, bool for SystemString apploaderPath = path + _S("/apploader.bin"); if (force || Stat(apploaderPath.c_str(), &theStat)) { - std::unique_ptr buf(new uint8_t[m_apploaderSz]); - std::unique_ptr rs = beginReadStream(0x2440); - rs->read(buf.get(), m_apploaderSz); - std::unique_ptr ws = NewFileIO(apploaderPath)->beginWriteStream(); - ws->write(buf.get(), m_apploaderSz); + std::unique_ptr buf = getApploaderBuf(); + NewFileIO(apploaderPath)->beginWriteStream()->write(buf.get(), m_apploaderSz); } /* Extract Dol */ SystemString dolPath = path + _S("/main.dol"); if (force || Stat(dolPath.c_str(), &theStat)) { - std::unique_ptr rs = beginReadStream(m_dolOff); - /* Read Dol header */ - DOLHeader hdr; - rs->read(&hdr, sizeof(DOLHeader)); - std::unique_ptr ws = NewFileIO(dolPath)->beginWriteStream(); - ws->write(&hdr, sizeof(DOLHeader)); - /* Calculate Dol size */ - uint32_t dolSize = SBig(hdr.textOff[0]) - sizeof(DOLHeader); - for (uint32_t i = 0 ; i < 7 ; i++) - dolSize += SBig(hdr.textSizes[i]); - for (uint32_t i = 0 ; i < 11 ; i++) - dolSize += SBig(hdr.dataSizes[i]); - std::unique_ptr buf(new uint8_t[dolSize]); - rs->read(buf.get(), dolSize); - ws->write(buf.get(), dolSize); + std::unique_ptr buf = getDOLBuf(); + NewFileIO(dolPath)->beginWriteStream()->write(buf.get(), m_dolSz); } /* Extract Filesystem */ diff --git a/lib/DiscGCN.cpp b/lib/DiscGCN.cpp index 2b5eeb2..75f7df1 100644 --- a/lib/DiscGCN.cpp +++ b/lib/DiscGCN.cpp @@ -22,6 +22,10 @@ public: /* Yay files!! */ parseFST(*s.get()); + + /* Also make DOL header and size handy */ + s->seek(m_dolOff); + parseDOL(*s.get()); } class PartReadStream : public IPartReadStream diff --git a/lib/DiscWii.cpp b/lib/DiscWii.cpp index 346f81f..81d14de 100644 --- a/lib/DiscWii.cpp +++ b/lib/DiscWii.cpp @@ -249,6 +249,10 @@ public: /* Yay files!! */ parseFST(*ds.get()); + + /* Also make DOL header and size handy */ + ds->seek(m_dolOff); + parseDOL(*ds.get()); } class PartReadStream : public IPartReadStream