mirror of https://github.com/AxioDL/nod.git
Proper extract structure for GCN images
This commit is contained in:
parent
41148a1368
commit
2a472651ae
|
@ -24,6 +24,14 @@ enum class EBuildResult
|
||||||
DiskFull
|
DiskFull
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class PartitionKind : uint32_t
|
||||||
|
{
|
||||||
|
Data,
|
||||||
|
Update,
|
||||||
|
Channel
|
||||||
|
};
|
||||||
|
const char* getKindString(PartitionKind kind);
|
||||||
|
|
||||||
class FSTNode
|
class FSTNode
|
||||||
{
|
{
|
||||||
uint32_t typeAndNameOffset;
|
uint32_t typeAndNameOffset;
|
||||||
|
@ -187,12 +195,6 @@ public:
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~IPartition() = default;
|
virtual ~IPartition() = default;
|
||||||
enum class Kind : uint32_t
|
|
||||||
{
|
|
||||||
Data,
|
|
||||||
Update,
|
|
||||||
Channel
|
|
||||||
};
|
|
||||||
struct DOLHeader
|
struct DOLHeader
|
||||||
{
|
{
|
||||||
uint32_t textOff[7];
|
uint32_t textOff[7];
|
||||||
|
@ -317,8 +319,9 @@ public:
|
||||||
void parseDOL(IPartReadStream& s);
|
void parseDOL(IPartReadStream& s);
|
||||||
|
|
||||||
const DiscBase& m_parent;
|
const DiscBase& m_parent;
|
||||||
Kind m_kind;
|
PartitionKind m_kind;
|
||||||
uint64_t m_offset;
|
uint64_t m_offset;
|
||||||
|
bool m_isWii;
|
||||||
public:
|
public:
|
||||||
mutable size_t m_curNodeIdx = 0;
|
mutable size_t m_curNodeIdx = 0;
|
||||||
float getProgressFactor() const { return getNodeCount() ? m_curNodeIdx / float(getNodeCount()) : 0.f; }
|
float getProgressFactor() const { return getNodeCount() ? m_curNodeIdx / float(getNodeCount()) : 0.f; }
|
||||||
|
@ -333,10 +336,11 @@ public:
|
||||||
return m_curNodeIdx / float(getNodeCount());
|
return m_curNodeIdx / float(getNodeCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
IPartition(const DiscBase& parent, Kind kind, uint64_t offset)
|
IPartition(const DiscBase& parent, PartitionKind kind, bool isWii, uint64_t offset)
|
||||||
: m_parent(parent), m_kind(kind), m_offset(offset) {}
|
: m_parent(parent), m_kind(kind), m_offset(offset), m_isWii(isWii) {}
|
||||||
virtual uint64_t normalizeOffset(uint64_t anOffset) const {return anOffset;}
|
virtual uint64_t normalizeOffset(uint64_t anOffset) const {return anOffset;}
|
||||||
inline Kind getKind() const {return m_kind;}
|
inline PartitionKind getKind() const {return m_kind;}
|
||||||
|
inline bool isWii() const {return m_isWii;}
|
||||||
inline uint64_t getDiscOffset() const {return m_offset;}
|
inline uint64_t getDiscOffset() const {return m_offset;}
|
||||||
virtual std::unique_ptr<IPartReadStream> beginReadStream(uint64_t offset=0) const=0;
|
virtual std::unique_ptr<IPartReadStream> beginReadStream(uint64_t offset=0) const=0;
|
||||||
inline std::unique_ptr<IPartReadStream> beginDOLReadStream(uint64_t offset=0) const
|
inline std::unique_ptr<IPartReadStream> beginDOLReadStream(uint64_t offset=0) const
|
||||||
|
@ -399,7 +403,7 @@ public:
|
||||||
inline IPartition* getDataPartition()
|
inline IPartition* getDataPartition()
|
||||||
{
|
{
|
||||||
for (const std::unique_ptr<IPartition>& part : m_partitions)
|
for (const std::unique_ptr<IPartition>& part : m_partitions)
|
||||||
if (part->getKind() == IPartition::Kind::Data)
|
if (part->getKind() == PartitionKind::Data)
|
||||||
return part.get();
|
return part.get();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -407,7 +411,7 @@ public:
|
||||||
inline IPartition* getUpdatePartition()
|
inline IPartition* getUpdatePartition()
|
||||||
{
|
{
|
||||||
for (const std::unique_ptr<IPartition>& part : m_partitions)
|
for (const std::unique_ptr<IPartition>& part : m_partitions)
|
||||||
if (part->getKind() == IPartition::Kind::Update)
|
if (part->getKind() == PartitionKind::Update)
|
||||||
return part.get();
|
return part.get();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -429,12 +433,6 @@ public:
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~PartitionBuilderBase() = default;
|
virtual ~PartitionBuilderBase() = default;
|
||||||
enum class Kind : uint32_t
|
|
||||||
{
|
|
||||||
Data,
|
|
||||||
Update,
|
|
||||||
Channel
|
|
||||||
};
|
|
||||||
protected:
|
protected:
|
||||||
std::unordered_map<SystemString, std::pair<uint64_t,uint64_t>> m_fileOffsetsSizes;
|
std::unordered_map<SystemString, std::pair<uint64_t,uint64_t>> m_fileOffsetsSizes;
|
||||||
std::vector<FSTNode> m_buildNodes;
|
std::vector<FSTNode> m_buildNodes;
|
||||||
|
@ -469,17 +467,19 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
DiscBuilderBase& m_parent;
|
DiscBuilderBase& m_parent;
|
||||||
Kind m_kind;
|
PartitionKind m_kind;
|
||||||
uint64_t m_dolOffset = 0;
|
uint64_t m_dolOffset = 0;
|
||||||
uint64_t m_dolSize = 0;
|
uint64_t m_dolSize = 0;
|
||||||
|
bool m_isWii;
|
||||||
public:
|
public:
|
||||||
PartitionBuilderBase(DiscBuilderBase& parent, Kind kind)
|
PartitionBuilderBase(DiscBuilderBase& parent, PartitionKind kind, bool isWii)
|
||||||
: m_parent(parent), m_kind(kind)
|
: m_parent(parent), m_kind(kind), m_isWii(isWii)
|
||||||
{}
|
{}
|
||||||
virtual std::unique_ptr<IPartWriteStream> beginWriteStream(uint64_t offset)=0;
|
virtual std::unique_ptr<IPartWriteStream> beginWriteStream(uint64_t offset)=0;
|
||||||
bool buildFromDirectory(IPartWriteStream& ws,
|
bool buildFromDirectory(IPartWriteStream& ws,
|
||||||
const SystemChar* dirIn);
|
const SystemChar* dirIn);
|
||||||
static uint64_t CalculateTotalSizeBuild(const SystemChar* dirIn);
|
static uint64_t CalculateTotalSizeBuild(const SystemChar* dirIn,
|
||||||
|
PartitionKind kind, bool isWii);
|
||||||
bool mergeFromDirectory(IPartWriteStream& ws,
|
bool mergeFromDirectory(IPartWriteStream& ws,
|
||||||
const DiscBase::IPartition* partIn,
|
const DiscBase::IPartition* partIn,
|
||||||
const SystemChar* dirIn);
|
const SystemChar* dirIn);
|
||||||
|
|
|
@ -38,6 +38,21 @@ static void* memmem(const void *haystack, size_t hlen, const void *needle, size_
|
||||||
namespace nod
|
namespace nod
|
||||||
{
|
{
|
||||||
|
|
||||||
|
const char* getKindString(PartitionKind kind)
|
||||||
|
{
|
||||||
|
switch (kind)
|
||||||
|
{
|
||||||
|
case PartitionKind::Data:
|
||||||
|
return "DATA";
|
||||||
|
case PartitionKind::Update:
|
||||||
|
return "UPDATE";
|
||||||
|
case PartitionKind::Channel:
|
||||||
|
return "CHANNEL";
|
||||||
|
default:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DiscBase::IPartition::parseFST(IPartReadStream& s)
|
void DiscBase::IPartition::parseFST(IPartReadStream& s)
|
||||||
{
|
{
|
||||||
std::unique_ptr<uint8_t[]> fst(new uint8_t[m_fstSz]);
|
std::unique_ptr<uint8_t[]> fst(new uint8_t[m_fstSz]);
|
||||||
|
@ -144,20 +159,24 @@ bool DiscBase::IPartition::extractToDirectory(const SystemString& path,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Mkdir((path + _S("/DATA")).c_str(), 0755) && errno != EEXIST)
|
SystemString basePath = m_isWii ? path + _S("/") + getKindString(m_kind) : path;
|
||||||
|
if (m_isWii)
|
||||||
{
|
{
|
||||||
LogModule.report(logvisor::Error, _S("unable to mkdir '%s/DATA'"), path.c_str());
|
if (Mkdir(basePath.c_str(), 0755) && errno != EEXIST)
|
||||||
|
{
|
||||||
|
LogModule.report(logvisor::Error, _S("unable to mkdir '%s'"), basePath.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Mkdir((path + _S("/DATA/sys")).c_str(), 0755) && errno != EEXIST)
|
if (Mkdir((basePath + _S("/sys")).c_str(), 0755) && errno != EEXIST)
|
||||||
{
|
{
|
||||||
LogModule.report(logvisor::Error, _S("unable to mkdir '%s/DATA/sys'"), path.c_str());
|
LogModule.report(logvisor::Error, _S("unable to mkdir '%s/sys'"), basePath.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extract Disc Files */
|
/* Extract Disc Files */
|
||||||
if (!m_parent.extractDiscHeaderFiles(path, ctx))
|
if (!m_parent.extractDiscHeaderFiles(basePath, ctx))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Extract Crypto Files */
|
/* Extract Crypto Files */
|
||||||
|
@ -165,7 +184,7 @@ bool DiscBase::IPartition::extractToDirectory(const SystemString& path,
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Extract Apploader */
|
/* Extract Apploader */
|
||||||
SystemString apploaderPath = path + _S("/DATA/sys/apploader.img");
|
SystemString apploaderPath = basePath + _S("/sys/apploader.img");
|
||||||
if (ctx.force || Stat(apploaderPath.c_str(), &theStat))
|
if (ctx.force || Stat(apploaderPath.c_str(), &theStat))
|
||||||
{
|
{
|
||||||
if (ctx.progressCB)
|
if (ctx.progressCB)
|
||||||
|
@ -178,7 +197,7 @@ bool DiscBase::IPartition::extractToDirectory(const SystemString& path,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extract Dol */
|
/* Extract Dol */
|
||||||
SystemString dolPath = path + _S("/DATA/sys/main.dol");
|
SystemString dolPath = basePath + _S("/sys/main.dol");
|
||||||
if (ctx.force || Stat(dolPath.c_str(), &theStat))
|
if (ctx.force || Stat(dolPath.c_str(), &theStat))
|
||||||
{
|
{
|
||||||
if (ctx.progressCB)
|
if (ctx.progressCB)
|
||||||
|
@ -191,7 +210,7 @@ bool DiscBase::IPartition::extractToDirectory(const SystemString& path,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extract Boot info */
|
/* Extract Boot info */
|
||||||
SystemString bootPath = path + _S("/DATA/sys/boot.bin");
|
SystemString bootPath = basePath + _S("/sys/boot.bin");
|
||||||
if (ctx.force || Stat(bootPath.c_str(), &theStat))
|
if (ctx.force || Stat(bootPath.c_str(), &theStat))
|
||||||
{
|
{
|
||||||
if (ctx.progressCB)
|
if (ctx.progressCB)
|
||||||
|
@ -203,7 +222,7 @@ bool DiscBase::IPartition::extractToDirectory(const SystemString& path,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extract BI2 info */
|
/* Extract BI2 info */
|
||||||
SystemString bi2Path = path + _S("/DATA/sys/bi2.bin");
|
SystemString bi2Path = basePath + _S("/sys/bi2.bin");
|
||||||
if (ctx.force || Stat(bi2Path.c_str(), &theStat))
|
if (ctx.force || Stat(bi2Path.c_str(), &theStat))
|
||||||
{
|
{
|
||||||
if (ctx.progressCB)
|
if (ctx.progressCB)
|
||||||
|
@ -216,7 +235,7 @@ bool DiscBase::IPartition::extractToDirectory(const SystemString& path,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extract Filesystem */
|
/* Extract Filesystem */
|
||||||
SystemString fsPath = path + _S("/DATA/files");
|
SystemString fsPath = basePath + _S("/files");
|
||||||
if (Mkdir(fsPath.c_str(), 0755) && errno != EEXIST)
|
if (Mkdir(fsPath.c_str(), 0755) && errno != EEXIST)
|
||||||
{
|
{
|
||||||
LogModule.report(logvisor::Error, _S("unable to mkdir '%s'"), fsPath.c_str());
|
LogModule.report(logvisor::Error, _S("unable to mkdir '%s'"), fsPath.c_str());
|
||||||
|
@ -799,8 +818,9 @@ bool DiscBuilderBase::PartitionBuilderBase::buildFromDirectory(IPartWriteStream&
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemString dirStr(dirIn);
|
SystemString dirStr(dirIn);
|
||||||
SystemString dolIn = dirStr + _S("/DATA/sys/main.dol");
|
SystemString basePath = m_isWii ? dirStr + _S("/") + getKindString(m_kind) : dirStr;
|
||||||
SystemString filesIn = dirStr + _S("/DATA/files");
|
SystemString dolIn = basePath + _S("/sys/main.dol");
|
||||||
|
SystemString filesIn = basePath + _S("/files");
|
||||||
|
|
||||||
/* 1st pass - Tally up total progress steps */
|
/* 1st pass - Tally up total progress steps */
|
||||||
m_parent.m_progressTotal += 2; /* Prep and DOL */
|
m_parent.m_progressTotal += 2; /* Prep and DOL */
|
||||||
|
@ -851,11 +871,13 @@ bool DiscBuilderBase::PartitionBuilderBase::buildFromDirectory(IPartWriteStream&
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeBuild(const SystemChar* dirIn)
|
uint64_t DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeBuild(const SystemChar* dirIn,
|
||||||
|
PartitionKind kind, bool isWii)
|
||||||
{
|
{
|
||||||
SystemString dirStr(dirIn);
|
SystemString dirStr(dirIn);
|
||||||
SystemString dolIn = dirStr + _S("/DATA/sys/main.dol");
|
SystemString basePath = isWii ? dirStr + _S("/") + getKindString(kind) : dirStr;
|
||||||
SystemString filesIn = dirStr + _S("/DATA/files");
|
SystemString dolIn = basePath + _S("/sys/main.dol");
|
||||||
|
SystemString filesIn = basePath + _S("/files");
|
||||||
|
|
||||||
Sstat dolStat;
|
Sstat dolStat;
|
||||||
if (Stat(dolIn.c_str(), &dolStat))
|
if (Stat(dolIn.c_str(), &dolStat))
|
||||||
|
@ -880,7 +902,8 @@ bool DiscBuilderBase::PartitionBuilderBase::mergeFromDirectory(IPartWriteStream&
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemString dirStr(dirIn);
|
SystemString dirStr(dirIn);
|
||||||
SystemString filesIn = dirStr + _S("/DATA/files");
|
SystemString basePath = m_isWii ? dirStr + _S("/") + getKindString(m_kind) : dirStr;
|
||||||
|
SystemString filesIn = basePath + _S("/files");
|
||||||
|
|
||||||
/* 1st pass - Tally up total progress steps */
|
/* 1st pass - Tally up total progress steps */
|
||||||
m_parent.m_progressTotal += 2; /* Prep and DOL */
|
m_parent.m_progressTotal += 2; /* Prep and DOL */
|
||||||
|
@ -930,7 +953,8 @@ uint64_t DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeMerge(const Di
|
||||||
const SystemChar* dirIn)
|
const SystemChar* dirIn)
|
||||||
{
|
{
|
||||||
SystemString dirStr(dirIn);
|
SystemString dirStr(dirIn);
|
||||||
SystemString filesIn = dirStr + _S("/DATA/files");
|
SystemString basePath = partIn->isWii() ? dirStr + _S("/") + getKindString(partIn->getKind()) : dirStr;
|
||||||
|
SystemString filesIn = basePath + _S("/files");
|
||||||
|
|
||||||
uint64_t totalSz = ROUND_UP_32(partIn->getDOLSize());
|
uint64_t totalSz = ROUND_UP_32(partIn->getDOLSize());
|
||||||
if (!RecursiveCalculateTotalSize(totalSz, &partIn->getFSTRoot(), filesIn.c_str()))
|
if (!RecursiveCalculateTotalSize(totalSz, &partIn->getFSTRoot(), filesIn.c_str()))
|
||||||
|
|
|
@ -9,8 +9,8 @@ namespace nod
|
||||||
class PartitionGCN : public DiscBase::IPartition
|
class PartitionGCN : public DiscBase::IPartition
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PartitionGCN(const DiscGCN& parent, Kind kind, uint64_t offset, bool& err)
|
PartitionGCN(const DiscGCN& parent, uint64_t offset, bool& err)
|
||||||
: IPartition(parent, kind, offset)
|
: IPartition(parent, PartitionKind::Data, false, offset)
|
||||||
{
|
{
|
||||||
/* GCN-specific header reads */
|
/* GCN-specific header reads */
|
||||||
std::unique_ptr<IPartReadStream> s = beginReadStream(0x0);
|
std::unique_ptr<IPartReadStream> s = beginReadStream(0x0);
|
||||||
|
@ -126,7 +126,7 @@ DiscGCN::DiscGCN(std::unique_ptr<IDiscIO>&& dio, bool& err)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* One lone partition for GCN */
|
/* One lone partition for GCN */
|
||||||
m_partitions.emplace_back(new PartitionGCN(*this, IPartition::Kind::Data, 0, err));
|
m_partitions.emplace_back(new PartitionGCN(*this, 0, err));
|
||||||
}
|
}
|
||||||
|
|
||||||
DiscBuilderGCN DiscGCN::makeMergeBuilder(const SystemChar* outPath, FProgress progressCB)
|
DiscBuilderGCN DiscGCN::makeMergeBuilder(const SystemChar* outPath, FProgress progressCB)
|
||||||
|
@ -136,31 +136,6 @@ DiscBuilderGCN DiscGCN::makeMergeBuilder(const SystemChar* outPath, FProgress pr
|
||||||
|
|
||||||
bool DiscGCN::extractDiscHeaderFiles(const SystemString& path, const ExtractionContext& ctx) const
|
bool DiscGCN::extractDiscHeaderFiles(const SystemString& path, const ExtractionContext& ctx) const
|
||||||
{
|
{
|
||||||
if (Mkdir((path + _S("/DATA/disc")).c_str(), 0755) && errno != EEXIST)
|
|
||||||
{
|
|
||||||
LogModule.report(logvisor::Error, _S("unable to mkdir '%s/DATA/disc'"), path.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sstat theStat;
|
|
||||||
|
|
||||||
/* Extract Header */
|
|
||||||
SystemString headerPath = path + _S("/DATA/disc/header.bin");
|
|
||||||
if (ctx.force || Stat(headerPath.c_str(), &theStat))
|
|
||||||
{
|
|
||||||
if (ctx.progressCB)
|
|
||||||
ctx.progressCB("header.bin", 0.f);
|
|
||||||
std::unique_ptr<IReadStream> rs = getDiscIO().beginReadStream(0x0);
|
|
||||||
if (!rs)
|
|
||||||
return false;
|
|
||||||
Header header;
|
|
||||||
header.read(*rs);
|
|
||||||
auto ws = NewFileIO(headerPath)->beginWriteStream();
|
|
||||||
if (!ws)
|
|
||||||
return false;
|
|
||||||
header.write(*ws);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +174,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
PartitionBuilderGCN(DiscBuilderBase& parent)
|
PartitionBuilderGCN(DiscBuilderBase& parent)
|
||||||
: DiscBuilderBase::PartitionBuilderBase(parent, Kind::Data) {}
|
: DiscBuilderBase::PartitionBuilderBase(parent, PartitionKind::Data, false) {}
|
||||||
|
|
||||||
uint64_t userAllocate(uint64_t reqSz, IPartWriteStream& ws)
|
uint64_t userAllocate(uint64_t reqSz, IPartWriteStream& ws)
|
||||||
{
|
{
|
||||||
|
@ -281,7 +256,7 @@ public:
|
||||||
SystemString dirStr(dirIn);
|
SystemString dirStr(dirIn);
|
||||||
|
|
||||||
/* Check Apploader */
|
/* Check Apploader */
|
||||||
SystemString apploaderIn = dirStr + _S("/DATA/sys/apploader.img");
|
SystemString apploaderIn = dirStr + _S("/sys/apploader.img");
|
||||||
Sstat apploaderStat;
|
Sstat apploaderStat;
|
||||||
if (Stat(apploaderIn.c_str(), &apploaderStat))
|
if (Stat(apploaderIn.c_str(), &apploaderStat))
|
||||||
{
|
{
|
||||||
|
@ -290,7 +265,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check Boot */
|
/* Check Boot */
|
||||||
SystemString bootIn = dirStr + _S("/DATA/sys/boot.bin");
|
SystemString bootIn = dirStr + _S("/sys/boot.bin");
|
||||||
Sstat bootStat;
|
Sstat bootStat;
|
||||||
if (Stat(bootIn.c_str(), &bootStat))
|
if (Stat(bootIn.c_str(), &bootStat))
|
||||||
{
|
{
|
||||||
|
@ -299,7 +274,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check BI2 */
|
/* Check BI2 */
|
||||||
SystemString bi2In = dirStr + _S("/DATA/sys/bi2.bin");
|
SystemString bi2In = dirStr + _S("/sys/bi2.bin");
|
||||||
Sstat bi2Stat;
|
Sstat bi2Stat;
|
||||||
if (Stat(bi2In.c_str(), &bi2Stat))
|
if (Stat(bi2In.c_str(), &bi2Stat))
|
||||||
{
|
{
|
||||||
|
@ -431,7 +406,7 @@ EBuildResult DiscBuilderGCN::buildFromDirectory(const SystemChar* dirIn)
|
||||||
|
|
||||||
uint64_t DiscBuilderGCN::CalculateTotalSizeRequired(const SystemChar* dirIn)
|
uint64_t DiscBuilderGCN::CalculateTotalSizeRequired(const SystemChar* dirIn)
|
||||||
{
|
{
|
||||||
uint64_t sz = DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeBuild(dirIn);
|
uint64_t sz = DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeBuild(dirIn, PartitionKind::Data, false);
|
||||||
if (sz == -1)
|
if (sz == -1)
|
||||||
return -1;
|
return -1;
|
||||||
sz += 0x30000;
|
sz += 0x30000;
|
||||||
|
|
|
@ -272,8 +272,8 @@ class PartitionWii : public DiscBase::IPartition
|
||||||
uint8_t m_decKey[16];
|
uint8_t m_decKey[16];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PartitionWii(const DiscWii& parent, Kind kind, uint64_t offset, bool& err)
|
PartitionWii(const DiscWii& parent, PartitionKind kind, uint64_t offset, bool& err)
|
||||||
: IPartition(parent, kind, offset)
|
: IPartition(parent, kind, true, offset)
|
||||||
{
|
{
|
||||||
std::unique_ptr<IReadStream> s = parent.getDiscIO().beginReadStream(offset);
|
std::unique_ptr<IReadStream> s = parent.getDiscIO().beginReadStream(offset);
|
||||||
if (!s)
|
if (!s)
|
||||||
|
@ -545,7 +545,7 @@ DiscWii::DiscWii(std::unique_ptr<IDiscIO>&& dio, bool& err)
|
||||||
struct Part
|
struct Part
|
||||||
{
|
{
|
||||||
uint32_t partDataOff;
|
uint32_t partDataOff;
|
||||||
IPartition::Kind partType;
|
PartitionKind partType;
|
||||||
} parts[4];
|
} parts[4];
|
||||||
PartInfo(IDiscIO& dio, bool& err)
|
PartInfo(IDiscIO& dio, bool& err)
|
||||||
{
|
{
|
||||||
|
@ -565,7 +565,7 @@ DiscWii::DiscWii(std::unique_ptr<IDiscIO>&& dio, bool& err)
|
||||||
{
|
{
|
||||||
s->read(&parts[p], 8);
|
s->read(&parts[p], 8);
|
||||||
parts[p].partDataOff = SBig(parts[p].partDataOff);
|
parts[p].partDataOff = SBig(parts[p].partDataOff);
|
||||||
parts[p].partType = IPartition::Kind(SBig(uint32_t(parts[p].partType)));
|
parts[p].partType = PartitionKind(SBig(uint32_t(parts[p].partType)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} partInfo(*m_discIO, err);
|
} partInfo(*m_discIO, err);
|
||||||
|
@ -577,12 +577,12 @@ DiscWii::DiscWii(std::unique_ptr<IDiscIO>&& dio, bool& err)
|
||||||
for (uint32_t p=0 ; p<partInfo.partCount && p<4 ; ++p)
|
for (uint32_t p=0 ; p<partInfo.partCount && p<4 ; ++p)
|
||||||
{
|
{
|
||||||
PartInfo::Part& part = partInfo.parts[p];
|
PartInfo::Part& part = partInfo.parts[p];
|
||||||
IPartition::Kind kind;
|
PartitionKind kind;
|
||||||
switch (part.partType)
|
switch (part.partType)
|
||||||
{
|
{
|
||||||
case IPartition::Kind::Data:
|
case PartitionKind::Data:
|
||||||
case IPartition::Kind::Update:
|
case PartitionKind::Update:
|
||||||
case IPartition::Kind::Channel:
|
case PartitionKind::Channel:
|
||||||
kind = part.partType;
|
kind = part.partType;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -601,18 +601,18 @@ DiscBuilderWii DiscWii::makeMergeBuilder(const SystemChar* outPath, bool dualLay
|
||||||
return DiscBuilderWii(outPath, dualLayer, progressCB);
|
return DiscBuilderWii(outPath, dualLayer, progressCB);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DiscWii::extractDiscHeaderFiles(const SystemString& path, const ExtractionContext& ctx) const
|
bool DiscWii::extractDiscHeaderFiles(const SystemString& basePath, const ExtractionContext& ctx) const
|
||||||
{
|
{
|
||||||
if (Mkdir((path + _S("/DATA/disc")).c_str(), 0755) && errno != EEXIST)
|
if (Mkdir((basePath + _S("/disc")).c_str(), 0755) && errno != EEXIST)
|
||||||
{
|
{
|
||||||
LogModule.report(logvisor::Error, _S("unable to mkdir '%s/DATA/disc'"), path.c_str());
|
LogModule.report(logvisor::Error, _S("unable to mkdir '%s/disc'"), basePath.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sstat theStat;
|
Sstat theStat;
|
||||||
|
|
||||||
/* Extract Header */
|
/* Extract Header */
|
||||||
SystemString headerPath = path + _S("/DATA/disc/header.bin");
|
SystemString headerPath = basePath + _S("/disc/header.bin");
|
||||||
if (ctx.force || Stat(headerPath.c_str(), &theStat))
|
if (ctx.force || Stat(headerPath.c_str(), &theStat))
|
||||||
{
|
{
|
||||||
if (ctx.progressCB)
|
if (ctx.progressCB)
|
||||||
|
@ -629,7 +629,7 @@ bool DiscWii::extractDiscHeaderFiles(const SystemString& path, const ExtractionC
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extract Region info */
|
/* Extract Region info */
|
||||||
SystemString regionPath = path + _S("/DATA/disc/region.bin");
|
SystemString regionPath = basePath + _S("/disc/region.bin");
|
||||||
if (ctx.force || Stat(regionPath.c_str(), &theStat))
|
if (ctx.force || Stat(regionPath.c_str(), &theStat))
|
||||||
{
|
{
|
||||||
if (ctx.progressCB)
|
if (ctx.progressCB)
|
||||||
|
@ -816,8 +816,8 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
PartitionBuilderWii(DiscBuilderBase& parent, Kind kind, uint64_t baseOffset)
|
PartitionBuilderWii(DiscBuilderBase& parent, PartitionKind kind, uint64_t baseOffset)
|
||||||
: DiscBuilderBase::PartitionBuilderBase(parent, kind),
|
: DiscBuilderBase::PartitionBuilderBase(parent, kind, true),
|
||||||
m_baseOffset(baseOffset), m_aes(NewAES()) {}
|
m_baseOffset(baseOffset), m_aes(NewAES()) {}
|
||||||
|
|
||||||
uint64_t getCurUserEnd() const {return m_curUser;}
|
uint64_t getCurUserEnd() const {return m_curUser;}
|
||||||
|
@ -1019,6 +1019,7 @@ public:
|
||||||
uint64_t buildFromDirectory(const SystemChar* dirIn)
|
uint64_t buildFromDirectory(const SystemChar* dirIn)
|
||||||
{
|
{
|
||||||
SystemString dirStr(dirIn);
|
SystemString dirStr(dirIn);
|
||||||
|
SystemString basePath = dirStr + _S("/") + getKindString(m_kind);
|
||||||
|
|
||||||
/* Check Ticket */
|
/* Check Ticket */
|
||||||
SystemString ticketIn = dirStr + _S("/ticket.bin");
|
SystemString ticketIn = dirStr + _S("/ticket.bin");
|
||||||
|
@ -1048,7 +1049,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check Apploader */
|
/* Check Apploader */
|
||||||
SystemString apploaderIn = dirStr + _S("/DATA/sys/apploader.img");
|
SystemString apploaderIn = basePath + _S("/sys/apploader.img");
|
||||||
Sstat apploaderStat;
|
Sstat apploaderStat;
|
||||||
if (Stat(apploaderIn.c_str(), &apploaderStat))
|
if (Stat(apploaderIn.c_str(), &apploaderStat))
|
||||||
{
|
{
|
||||||
|
@ -1057,7 +1058,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check Boot */
|
/* Check Boot */
|
||||||
SystemString bootIn = dirStr + _S("/DATA/sys/boot.bin");
|
SystemString bootIn = basePath + _S("/sys/boot.bin");
|
||||||
Sstat bootStat;
|
Sstat bootStat;
|
||||||
if (Stat(bootIn.c_str(), &bootStat))
|
if (Stat(bootIn.c_str(), &bootStat))
|
||||||
{
|
{
|
||||||
|
@ -1066,7 +1067,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check BI2 */
|
/* Check BI2 */
|
||||||
SystemString bi2In = dirStr + _S("/DATA/sys/bi2.bin");
|
SystemString bi2In = basePath + _S("/sys/bi2.bin");
|
||||||
Sstat bi2Stat;
|
Sstat bi2Stat;
|
||||||
if (Stat(bi2In.c_str(), &bi2Stat))
|
if (Stat(bi2In.c_str(), &bi2Stat))
|
||||||
{
|
{
|
||||||
|
@ -1254,6 +1255,7 @@ public:
|
||||||
EBuildResult DiscBuilderWii::buildFromDirectory(const SystemChar* dirIn)
|
EBuildResult DiscBuilderWii::buildFromDirectory(const SystemChar* dirIn)
|
||||||
{
|
{
|
||||||
SystemString dirStr(dirIn);
|
SystemString dirStr(dirIn);
|
||||||
|
SystemString basePath = dirStr + _S("/") + getKindString(PartitionKind::Data);
|
||||||
|
|
||||||
PartitionBuilderWii& pb = static_cast<PartitionBuilderWii&>(*m_partitions[0]);
|
PartitionBuilderWii& pb = static_cast<PartitionBuilderWii&>(*m_partitions[0]);
|
||||||
uint64_t filledSz = pb.m_baseOffset;
|
uint64_t filledSz = pb.m_baseOffset;
|
||||||
|
@ -1289,7 +1291,7 @@ EBuildResult DiscBuilderWii::buildFromDirectory(const SystemChar* dirIn)
|
||||||
ws = m_fileIO->beginWriteStream(0);
|
ws = m_fileIO->beginWriteStream(0);
|
||||||
if (!ws)
|
if (!ws)
|
||||||
return EBuildResult::Failed;
|
return EBuildResult::Failed;
|
||||||
SystemString headerPath = dirStr + _S("/DATA/disc/header.bin");
|
SystemString headerPath = basePath + _S("/disc/header.bin");
|
||||||
std::unique_ptr<IFileIO::IReadStream> rs = NewFileIO(headerPath.c_str())->beginReadStream();
|
std::unique_ptr<IFileIO::IReadStream> rs = NewFileIO(headerPath.c_str())->beginReadStream();
|
||||||
if (!rs)
|
if (!rs)
|
||||||
return EBuildResult::Failed;
|
return EBuildResult::Failed;
|
||||||
|
@ -1311,7 +1313,7 @@ EBuildResult DiscBuilderWii::buildFromDirectory(const SystemChar* dirIn)
|
||||||
ws->write(vals, 4);
|
ws->write(vals, 4);
|
||||||
|
|
||||||
/* Populate region info */
|
/* Populate region info */
|
||||||
SystemString regionPath = dirStr + _S("/DATA/disc/region.bin");
|
SystemString regionPath = basePath + _S("/disc/region.bin");
|
||||||
rs = NewFileIO(regionPath.c_str())->beginReadStream();
|
rs = NewFileIO(regionPath.c_str())->beginReadStream();
|
||||||
if (!rs)
|
if (!rs)
|
||||||
return EBuildResult::Failed;
|
return EBuildResult::Failed;
|
||||||
|
@ -1345,7 +1347,7 @@ EBuildResult DiscBuilderWii::buildFromDirectory(const SystemChar* dirIn)
|
||||||
|
|
||||||
uint64_t DiscBuilderWii::CalculateTotalSizeRequired(const SystemChar* dirIn, bool& dualLayer)
|
uint64_t DiscBuilderWii::CalculateTotalSizeRequired(const SystemChar* dirIn, bool& dualLayer)
|
||||||
{
|
{
|
||||||
uint64_t sz = DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeBuild(dirIn);
|
uint64_t sz = DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeBuild(dirIn, PartitionKind::Data, true);
|
||||||
if (sz == -1)
|
if (sz == -1)
|
||||||
return -1;
|
return -1;
|
||||||
auto szDiv = std::lldiv(sz, 0x1F0000);
|
auto szDiv = std::lldiv(sz, 0x1F0000);
|
||||||
|
@ -1364,7 +1366,7 @@ uint64_t DiscBuilderWii::CalculateTotalSizeRequired(const SystemChar* dirIn, boo
|
||||||
DiscBuilderWii::DiscBuilderWii(const SystemChar* outPath, bool dualLayer, FProgress progressCB)
|
DiscBuilderWii::DiscBuilderWii(const SystemChar* outPath, bool dualLayer, FProgress progressCB)
|
||||||
: DiscBuilderBase(outPath, dualLayer ? 0x1FB4E0000 : 0x118240000, progressCB), m_dualLayer(dualLayer)
|
: DiscBuilderBase(outPath, dualLayer ? 0x1FB4E0000 : 0x118240000, progressCB), m_dualLayer(dualLayer)
|
||||||
{
|
{
|
||||||
PartitionBuilderWii* partBuilder = new PartitionBuilderWii(*this, PartitionBuilderBase::Kind::Data, 0x200000);
|
PartitionBuilderWii* partBuilder = new PartitionBuilderWii(*this, PartitionKind::Data, 0x200000);
|
||||||
m_partitions.emplace_back(partBuilder);
|
m_partitions.emplace_back(partBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue