mirror of https://github.com/AxioDL/nod.git
WIP context
This commit is contained in:
parent
8cd695c229
commit
f4c606c4eb
|
@ -29,13 +29,19 @@ int main(int argc, char* argv[])
|
||||||
/* Enable logging to console */
|
/* Enable logging to console */
|
||||||
LogVisor::RegisterConsoleLogger();
|
LogVisor::RegisterConsoleLogger();
|
||||||
|
|
||||||
|
NOD::ExtractionContext ctx = { true, true, [&](const std::string& str){
|
||||||
|
fprintf(stderr, "%s\n", str.c_str());
|
||||||
|
}};
|
||||||
const NOD::SystemChar* inDir = nullptr;
|
const NOD::SystemChar* inDir = nullptr;
|
||||||
const NOD::SystemChar* outDir = _S(".");
|
const NOD::SystemChar* outDir = _S(".");
|
||||||
bool force = false;
|
|
||||||
for (int a=2 ; a<argc ; ++a)
|
for (int a=2 ; a<argc ; ++a)
|
||||||
{
|
{
|
||||||
if (argv[a][0] == '-' && argv[a][1] == 'f')
|
if (argv[a][0] == '-' && argv[a][1] == 'f')
|
||||||
force = true;
|
ctx.force = true;
|
||||||
|
else if (argv[a][0] == '-' && argv[a][1] == 'v')
|
||||||
|
ctx.verbose = true;
|
||||||
|
|
||||||
else if (!inDir)
|
else if (!inDir)
|
||||||
inDir = argv[a];
|
inDir = argv[a];
|
||||||
else
|
else
|
||||||
|
@ -52,7 +58,7 @@ int main(int argc, char* argv[])
|
||||||
if (!dataPart)
|
if (!dataPart)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!dataPart->extractToDirectory(outDir, force))
|
if (!dataPart->extractToDirectory(outDir, ctx))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else if (!strcasecmp(argv[1], _S("make")))
|
else if (!strcasecmp(argv[1], _S("make")))
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
namespace NOD
|
namespace NOD
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class ExtractionContext;
|
||||||
class DiscBase
|
class DiscBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -163,7 +164,7 @@ public:
|
||||||
return end();
|
return end();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool extractToDirectory(const SystemString& basePath, bool force=false) const;
|
bool extractToDirectory(const SystemString& basePath, const ExtractionContext& ctx) const;
|
||||||
};
|
};
|
||||||
protected:
|
protected:
|
||||||
uint64_t m_dolOff;
|
uint64_t m_dolOff;
|
||||||
|
@ -193,7 +194,7 @@ public:
|
||||||
{return beginReadStream(0x2440 + offset);}
|
{return beginReadStream(0x2440 + offset);}
|
||||||
inline const Node& getFSTRoot() const {return m_nodes[0];}
|
inline const Node& getFSTRoot() const {return m_nodes[0];}
|
||||||
inline Node& getFSTRoot() {return m_nodes[0];}
|
inline Node& getFSTRoot() {return m_nodes[0];}
|
||||||
bool extractToDirectory(const SystemString& path, bool force=false);
|
bool extractToDirectory(const SystemString& path, const ExtractionContext& ctx);
|
||||||
|
|
||||||
inline uint64_t getDOLSize() const {return m_dolSz;}
|
inline uint64_t getDOLSize() const {return m_dolSz;}
|
||||||
inline std::unique_ptr<uint8_t[]> getDOLBuf() const
|
inline std::unique_ptr<uint8_t[]> getDOLBuf() const
|
||||||
|
@ -245,10 +246,10 @@ public:
|
||||||
return part.get();
|
return part.get();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
inline void extractToDirectory(const SystemString& path, bool force=false)
|
inline void extractToDirectory(const SystemString& path, const ExtractionContext& ctx)
|
||||||
{
|
{
|
||||||
for (std::unique_ptr<IPartition>& part : m_partitions)
|
for (std::unique_ptr<IPartition>& part : m_partitions)
|
||||||
part->extractToDirectory(path, force);
|
part->extractToDirectory(path, ctx);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define __NOD_LIB__
|
#define __NOD_LIB__
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <functional>
|
||||||
#include <LogVisor/LogVisor.hpp>
|
#include <LogVisor/LogVisor.hpp>
|
||||||
#include "Util.hpp"
|
#include "Util.hpp"
|
||||||
|
|
||||||
|
@ -10,6 +11,13 @@ namespace NOD
|
||||||
|
|
||||||
class DiscBase;
|
class DiscBase;
|
||||||
|
|
||||||
|
struct ExtractionContext final
|
||||||
|
{
|
||||||
|
bool verbose : 1;
|
||||||
|
bool force : 1;
|
||||||
|
std::function<void(const std::string&)> progressCB;
|
||||||
|
};
|
||||||
|
|
||||||
std::unique_ptr<DiscBase> OpenDiscFromImage(const SystemChar* path);
|
std::unique_ptr<DiscBase> OpenDiscFromImage(const SystemChar* path);
|
||||||
std::unique_ptr<DiscBase> OpenDiscFromImage(const SystemChar* path, bool& isWii);
|
std::unique_ptr<DiscBase> OpenDiscFromImage(const SystemChar* path, bool& isWii);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "NOD/DiscBase.hpp"
|
#include "NOD/DiscBase.hpp"
|
||||||
#include "NOD/IFileIO.hpp"
|
#include "NOD/IFileIO.hpp"
|
||||||
|
#include "NOD/NOD.hpp"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
@ -60,25 +61,33 @@ void DiscBase::IPartition::parseDOL(IPartReadStream& s)
|
||||||
m_dolSz = dolSize;
|
m_dolSz = dolSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DiscBase::IPartition::Node::extractToDirectory(const SystemString& basePath, bool force) const
|
bool DiscBase::IPartition::Node::extractToDirectory(const SystemString& basePath, const ExtractionContext& ctx) const
|
||||||
{
|
{
|
||||||
SystemStringView nameView(getName());
|
SystemStringView nameView(getName());
|
||||||
SystemString path = basePath + _S("/") + nameView.sys_str();
|
SystemString path = basePath + _S("/") + nameView.sys_str();
|
||||||
|
|
||||||
if (m_kind == NODE_DIRECTORY)
|
if (m_kind == NODE_DIRECTORY)
|
||||||
{
|
{
|
||||||
|
if (ctx.verbose && ctx.progressCB && !getName().empty())
|
||||||
|
ctx.progressCB(getName());
|
||||||
if (Mkdir(path.c_str(), 0755) && errno != EEXIST)
|
if (Mkdir(path.c_str(), 0755) && errno != EEXIST)
|
||||||
{
|
{
|
||||||
LogModule.report(LogVisor::Error, _S("unable to mkdir '%s'"), path.c_str());
|
LogModule.report(LogVisor::Error, _S("unable to mkdir '%s'"), path.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (Node& subnode : *this)
|
for (Node& subnode : *this)
|
||||||
if (!subnode.extractToDirectory(path, force))
|
if (!subnode.extractToDirectory(path, ctx))
|
||||||
return false;
|
return false;
|
||||||
|
if (ctx.verbose && ctx.progressCB)
|
||||||
|
ctx.progressCB(getName());
|
||||||
}
|
}
|
||||||
else if (m_kind == NODE_FILE)
|
else if (m_kind == NODE_FILE)
|
||||||
{
|
{
|
||||||
Sstat theStat;
|
Sstat theStat;
|
||||||
if (force || Stat(path.c_str(), &theStat))
|
if (ctx.verbose && ctx.progressCB)
|
||||||
|
ctx.progressCB(getName());
|
||||||
|
|
||||||
|
if (ctx.force || Stat(path.c_str(), &theStat))
|
||||||
{
|
{
|
||||||
std::unique_ptr<IPartReadStream> rs = beginReadStream();
|
std::unique_ptr<IPartReadStream> rs = beginReadStream();
|
||||||
std::unique_ptr<IFileIO::IWriteStream> ws = NewFileIO(path)->beginWriteStream();
|
std::unique_ptr<IFileIO::IWriteStream> ws = NewFileIO(path)->beginWriteStream();
|
||||||
|
@ -88,7 +97,7 @@ bool DiscBase::IPartition::Node::extractToDirectory(const SystemString& basePath
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DiscBase::IPartition::extractToDirectory(const SystemString& path, bool force)
|
bool DiscBase::IPartition::extractToDirectory(const SystemString& path, const ExtractionContext& ctx)
|
||||||
{
|
{
|
||||||
Sstat theStat;
|
Sstat theStat;
|
||||||
if (Mkdir(path.c_str(), 0755) && errno != EEXIST)
|
if (Mkdir(path.c_str(), 0755) && errno != EEXIST)
|
||||||
|
@ -99,22 +108,26 @@ bool DiscBase::IPartition::extractToDirectory(const SystemString& path, bool for
|
||||||
|
|
||||||
/* Extract Apploader */
|
/* Extract Apploader */
|
||||||
SystemString apploaderPath = path + _S("/apploader.bin");
|
SystemString apploaderPath = path + _S("/apploader.bin");
|
||||||
if (force || Stat(apploaderPath.c_str(), &theStat))
|
if (ctx.force || Stat(apploaderPath.c_str(), &theStat))
|
||||||
{
|
{
|
||||||
|
if (ctx.verbose && ctx.progressCB)
|
||||||
|
ctx.progressCB("apploader.bin");
|
||||||
std::unique_ptr<uint8_t[]> buf = getApploaderBuf();
|
std::unique_ptr<uint8_t[]> buf = getApploaderBuf();
|
||||||
NewFileIO(apploaderPath)->beginWriteStream()->write(buf.get(), m_apploaderSz);
|
NewFileIO(apploaderPath)->beginWriteStream()->write(buf.get(), m_apploaderSz);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extract Dol */
|
/* Extract Dol */
|
||||||
SystemString dolPath = path + _S("/main.dol");
|
SystemString dolPath = path + _S("/main.dol");
|
||||||
if (force || Stat(dolPath.c_str(), &theStat))
|
if (ctx.force || Stat(dolPath.c_str(), &theStat))
|
||||||
{
|
{
|
||||||
|
if (ctx.verbose && ctx.progressCB)
|
||||||
|
ctx.progressCB("main.dol");
|
||||||
std::unique_ptr<uint8_t[]> buf = getDOLBuf();
|
std::unique_ptr<uint8_t[]> buf = getDOLBuf();
|
||||||
NewFileIO(dolPath)->beginWriteStream()->write(buf.get(), m_dolSz);
|
NewFileIO(dolPath)->beginWriteStream()->write(buf.get(), m_dolSz);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extract Filesystem */
|
/* Extract Filesystem */
|
||||||
return m_nodes[0].extractToDirectory(path, force);
|
return m_nodes[0].extractToDirectory(path, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue