mirror of
https://github.com/AxioDL/nod.git
synced 2025-12-08 21:17:51 +00:00
Compare commits
15 Commits
v1.0
...
3d70a568dc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d70a568dc | ||
| 63ae60a967 | |||
|
|
e20fce1e6f | ||
|
|
b5916af702 | ||
|
|
58ceb47b25 | ||
|
|
69e96e3b3c | ||
|
|
27a2cb5998 | ||
|
|
c374038103 | ||
|
|
db1a6f13a2 | ||
|
|
fb2a5c91d2 | ||
| 42ef3a7958 | |||
|
|
d597400f4a | ||
| e99290e3c3 | |||
| 72169e8e77 | |||
| a7c19799e1 |
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -1,3 +1,3 @@
|
|||||||
[submodule "logvisor"]
|
[submodule "logvisor"]
|
||||||
path = logvisor
|
path = logvisor
|
||||||
url = https://github.com/AxioDL/logvisor.git
|
url = ../logvisor.git
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||||
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR) # because of CMAKE_CXX_STANDARD
|
cmake_minimum_required(VERSION 3.10 FATAL_ERROR) # because of c++17
|
||||||
project(nod)
|
project(nod)
|
||||||
set(CMAKE_CXX_STANDARD 14)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
# Shaddup MSVC
|
||||||
|
add_definitions(-DUNICODE=1 -D_UNICODE=1 -D__SSE__=1 -D_CRT_SECURE_NO_WARNINGS=1 -DD_SCL_SECURE_NO_WARNINGS=1
|
||||||
|
/IGNORE:4221 /wd4018 /wd4800 /wd4005 /wd4311 /wd4267 /wd4244 /wd4200 /wd4305 /wd4067 /wd4146 ${VS_DEFINES})
|
||||||
|
endif()
|
||||||
|
|
||||||
if (NOT TARGET logvisor)
|
if (NOT TARGET logvisor)
|
||||||
add_subdirectory(logvisor)
|
add_subdirectory(logvisor)
|
||||||
set(LOGVISOR_INCLUDE_DIR logvisor/include)
|
set(LOGVISOR_INCLUDE_DIR logvisor/include)
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
nod::ExtractionContext ctx = {true,
|
nod::ExtractionContext ctx = {true,
|
||||||
[&](const std::string& str, float c) {
|
[&](std::string_view str, float c) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
fprintf(stderr, "Current node: %s, Extraction %g%% Complete\n", str.c_str(), c * 100.f);
|
fprintf(stderr, "Current node: %s, Extraction %g%% Complete\n", str.data(), c * 100.f);
|
||||||
}};
|
}};
|
||||||
const nod::SystemChar* inDir = nullptr;
|
const nod::SystemChar* inDir = nullptr;
|
||||||
const nod::SystemChar* outDir = _S(".");
|
const nod::SystemChar* outDir = _S(".");
|
||||||
@@ -61,13 +61,13 @@ int main(int argc, char* argv[])
|
|||||||
outDir = argv[a];
|
outDir = argv[a];
|
||||||
}
|
}
|
||||||
|
|
||||||
auto progFunc = [&](float prog, const nod::SystemString& name, size_t bytes)
|
auto progFunc = [&](float prog, nod::SystemStringView name, size_t bytes)
|
||||||
{
|
{
|
||||||
nod::Printf(_S("\r "));
|
nod::Printf(_S("\r "));
|
||||||
if (bytes != -1)
|
if (bytes != -1)
|
||||||
nod::Printf(_S("\r%g%% %s %" PRISize " B"), prog * 100.f, name.c_str(), bytes);
|
nod::Printf(_S("\r%g%% %s %" PRISize " B"), prog * 100.f, name.data(), bytes);
|
||||||
else
|
else
|
||||||
nod::Printf(_S("\r%g%% %s"), prog * 100.f, name.c_str());
|
nod::Printf(_S("\r%g%% %s"), prog * 100.f, name.data());
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ int main(int argc, char* argv[])
|
|||||||
{
|
{
|
||||||
nod::SystemString outPath(argv[2]);
|
nod::SystemString outPath(argv[2]);
|
||||||
outPath.append(_S(".iso"));
|
outPath.append(_S(".iso"));
|
||||||
nod::DiscBuilderGCN b(outPath.c_str(), progFunc);
|
nod::DiscBuilderGCN b(outPath, progFunc);
|
||||||
ret = b.buildFromDirectory(argv[2]);
|
ret = b.buildFromDirectory(argv[2]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -8,21 +8,21 @@ namespace nod
|
|||||||
|
|
||||||
struct CaseInsensitiveCompare
|
struct CaseInsensitiveCompare
|
||||||
{
|
{
|
||||||
bool operator()(const std::string& lhs, const std::string& rhs) const
|
bool operator()(std::string_view lhs, std::string_view rhs) const
|
||||||
{
|
{
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
if (_stricmp(lhs.c_str(), rhs.c_str()) < 0)
|
if (_stricmp(lhs.data(), rhs.data()) < 0)
|
||||||
#else
|
#else
|
||||||
if (strcasecmp(lhs.c_str(), rhs.c_str()) < 0)
|
if (strcasecmp(lhs.data(), rhs.data()) < 0)
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
bool operator()(const std::wstring& lhs, const std::wstring& rhs) const
|
bool operator()(std::wstring_view lhs, std::wstring_view rhs) const
|
||||||
{
|
{
|
||||||
if (_wcsicmp(lhs.c_str(), rhs.c_str()) < 0)
|
if (_wcsicmp(lhs.data(), rhs.data()) < 0)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -56,10 +56,7 @@ private:
|
|||||||
std::vector<Entry> m_entries;
|
std::vector<Entry> m_entries;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DirectoryEnumerator(const SystemString& path, Mode mode=Mode::DirsThenFilesSorted,
|
DirectoryEnumerator(SystemStringView path, Mode mode=Mode::DirsThenFilesSorted,
|
||||||
bool sizeSort=false, bool reverse=false, bool noHidden=false)
|
|
||||||
: DirectoryEnumerator(path.c_str(), mode, sizeSort, reverse, noHidden) {}
|
|
||||||
DirectoryEnumerator(const SystemChar* path, Mode mode=Mode::DirsThenFilesSorted,
|
|
||||||
bool sizeSort=false, bool reverse=false, bool noHidden=false);
|
bool sizeSort=false, bool reverse=false, bool noHidden=false);
|
||||||
|
|
||||||
operator bool() const {return m_entries.size() != 0;}
|
operator bool() const {return m_entries.size() != 0;}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
namespace nod
|
namespace nod
|
||||||
{
|
{
|
||||||
|
|
||||||
using FProgress = std::function<void(float totalProg, const SystemString& fileName, size_t fileBytesXfered)>;
|
using FProgress = std::function<void(float totalProg, SystemStringView fileName, size_t fileBytesXfered)>;
|
||||||
|
|
||||||
enum class EBuildResult
|
enum class EBuildResult
|
||||||
{
|
{
|
||||||
@@ -229,14 +229,14 @@ public:
|
|||||||
std::vector<Node>::iterator m_childrenEnd;
|
std::vector<Node>::iterator m_childrenEnd;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Node(const IPartition& parent, const FSTNode& node, const char* name)
|
Node(const IPartition& parent, const FSTNode& node, std::string_view name)
|
||||||
: m_parent(parent),
|
: m_parent(parent),
|
||||||
m_kind(node.isDir() ? Kind::Directory : Kind::File),
|
m_kind(node.isDir() ? Kind::Directory : Kind::File),
|
||||||
m_discOffset(parent.normalizeOffset(node.getOffset())),
|
m_discOffset(parent.normalizeOffset(node.getOffset())),
|
||||||
m_discLength(node.getLength()),
|
m_discLength(node.getLength()),
|
||||||
m_name(name) {}
|
m_name(name) {}
|
||||||
inline Kind getKind() const {return m_kind;}
|
inline Kind getKind() const {return m_kind;}
|
||||||
inline const std::string& getName() const {return m_name;}
|
inline std::string_view getName() const {return m_name;}
|
||||||
inline uint64_t size() const {return m_discLength;}
|
inline uint64_t size() const {return m_discLength;}
|
||||||
std::unique_ptr<IPartReadStream> beginReadStream(uint64_t offset=0) const
|
std::unique_ptr<IPartReadStream> beginReadStream(uint64_t offset=0) const
|
||||||
{
|
{
|
||||||
@@ -283,7 +283,7 @@ public:
|
|||||||
};
|
};
|
||||||
inline DirectoryIterator begin() const {return DirectoryIterator(m_childrenBegin);}
|
inline DirectoryIterator begin() const {return DirectoryIterator(m_childrenBegin);}
|
||||||
inline DirectoryIterator end() const {return DirectoryIterator(m_childrenEnd);}
|
inline DirectoryIterator end() const {return DirectoryIterator(m_childrenEnd);}
|
||||||
inline DirectoryIterator find(const std::string& name) const
|
inline DirectoryIterator find(std::string_view name) const
|
||||||
{
|
{
|
||||||
if (m_kind == Kind::Directory)
|
if (m_kind == Kind::Directory)
|
||||||
{
|
{
|
||||||
@@ -298,7 +298,7 @@ public:
|
|||||||
return end();
|
return end();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool extractToDirectory(const SystemString& basePath, const ExtractionContext& ctx) const;
|
bool extractToDirectory(SystemStringView basePath, const ExtractionContext& ctx) const;
|
||||||
};
|
};
|
||||||
protected:
|
protected:
|
||||||
Header m_header;
|
Header m_header;
|
||||||
@@ -313,7 +313,6 @@ public:
|
|||||||
std::vector<FSTNode> m_buildNodes;
|
std::vector<FSTNode> m_buildNodes;
|
||||||
std::vector<std::string> m_buildNames;
|
std::vector<std::string> m_buildNames;
|
||||||
size_t m_buildNameOff = 0;
|
size_t m_buildNameOff = 0;
|
||||||
void recursiveBuildNodes(const SystemChar* dirIn, std::function<void(void)> incParents);
|
|
||||||
|
|
||||||
uint64_t m_dolSz;
|
uint64_t m_dolSz;
|
||||||
void parseDOL(IPartReadStream& s);
|
void parseDOL(IPartReadStream& s);
|
||||||
@@ -351,7 +350,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, const ExtractionContext& ctx);
|
bool extractToDirectory(SystemStringView 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
|
||||||
@@ -380,7 +379,8 @@ public:
|
|||||||
inline size_t getNodeCount() const { return m_nodes.size(); }
|
inline size_t getNodeCount() const { return m_nodes.size(); }
|
||||||
inline const Header& getHeader() const { return m_header; }
|
inline const Header& getHeader() const { return m_header; }
|
||||||
inline const BI2Header& getBI2() const { return m_bi2Header; }
|
inline const BI2Header& getBI2() const { return m_bi2Header; }
|
||||||
virtual bool extractCryptoFiles(const SystemString& path, const ExtractionContext& ctx) const { return true; }
|
virtual bool extractCryptoFiles(SystemStringView path, const ExtractionContext& ctx) const { return true; }
|
||||||
|
bool extractSysFiles(SystemStringView path, const ExtractionContext& ctx) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -416,13 +416,13 @@ public:
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void extractToDirectory(const SystemString& path, const ExtractionContext& ctx)
|
inline void extractToDirectory(SystemStringView path, const ExtractionContext& ctx)
|
||||||
{
|
{
|
||||||
for (std::unique_ptr<IPartition>& part : m_partitions)
|
for (std::unique_ptr<IPartition>& part : m_partitions)
|
||||||
part->extractToDirectory(path, ctx);
|
part->extractToDirectory(path, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool extractDiscHeaderFiles(const SystemString& path, const ExtractionContext& ctx) const=0;
|
virtual bool extractDiscHeaderFiles(SystemStringView path, const ExtractionContext& ctx) const=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DiscBuilderBase
|
class DiscBuilderBase
|
||||||
@@ -441,28 +441,29 @@ public:
|
|||||||
virtual uint64_t userAllocate(uint64_t reqSz, IPartWriteStream& ws)=0;
|
virtual uint64_t userAllocate(uint64_t reqSz, IPartWriteStream& ws)=0;
|
||||||
virtual uint32_t packOffset(uint64_t offset) const=0;
|
virtual uint32_t packOffset(uint64_t offset) const=0;
|
||||||
|
|
||||||
void recursiveBuildNodesPre(const SystemChar* dirIn);
|
void recursiveBuildNodesPre(SystemStringView dirIn);
|
||||||
bool recursiveBuildNodes(IPartWriteStream& ws, bool system, const SystemChar* dirIn);
|
bool recursiveBuildNodes(IPartWriteStream& ws, bool system, SystemStringView dirIn);
|
||||||
|
|
||||||
bool recursiveBuildFST(const SystemChar* dirIn,
|
bool recursiveBuildFST(SystemStringView dirIn,
|
||||||
std::function<void(void)> incParents);
|
std::function<void(void)> incParents,
|
||||||
|
size_t parentDirIdx);
|
||||||
|
|
||||||
void recursiveMergeNodesPre(const DiscBase::IPartition::Node* nodeIn, const SystemChar* dirIn);
|
void recursiveMergeNodesPre(const DiscBase::IPartition::Node* nodeIn, SystemStringView dirIn);
|
||||||
bool recursiveMergeNodes(IPartWriteStream& ws, bool system,
|
bool recursiveMergeNodes(IPartWriteStream& ws, bool system,
|
||||||
const DiscBase::IPartition::Node* nodeIn, const SystemChar* dirIn,
|
const DiscBase::IPartition::Node* nodeIn, SystemStringView dirIn,
|
||||||
const SystemString& keyPath);
|
SystemStringView keyPath);
|
||||||
bool recursiveMergeFST(const DiscBase::IPartition::Node* nodeIn,
|
bool recursiveMergeFST(const DiscBase::IPartition::Node* nodeIn,
|
||||||
const SystemChar* dirIn, std::function<void(void)> incParents,
|
SystemStringView dirIn, std::function<void(void)> incParents,
|
||||||
const SystemString& keyPath);
|
SystemStringView keyPath);
|
||||||
|
|
||||||
static bool RecursiveCalculateTotalSize(uint64_t& totalSz,
|
static bool RecursiveCalculateTotalSize(uint64_t& totalSz,
|
||||||
const DiscBase::IPartition::Node* nodeIn,
|
const DiscBase::IPartition::Node* nodeIn,
|
||||||
const SystemChar* dirIn);
|
SystemStringView dirIn);
|
||||||
|
|
||||||
void addBuildName(const SystemString& str)
|
void addBuildName(SystemStringView str)
|
||||||
{
|
{
|
||||||
SystemUTF8View utf8View(str);
|
SystemUTF8Conv utf8View(str);
|
||||||
m_buildNames.push_back(utf8View.utf8_str());
|
m_buildNames.emplace_back(utf8View.utf8_str());
|
||||||
m_buildNameOff += str.size() + 1;
|
m_buildNameOff += str.size() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,15 +477,10 @@ public:
|
|||||||
: m_parent(parent), m_kind(kind), m_isWii(isWii)
|
: 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, SystemStringView dirIn);
|
||||||
const SystemChar* dirIn);
|
static uint64_t CalculateTotalSizeBuild(SystemStringView dirIn, PartitionKind kind, bool isWii);
|
||||||
static uint64_t CalculateTotalSizeBuild(const SystemChar* dirIn,
|
bool mergeFromDirectory(IPartWriteStream& ws, const DiscBase::IPartition* partIn, SystemStringView dirIn);
|
||||||
PartitionKind kind, bool isWii);
|
static uint64_t CalculateTotalSizeMerge(const DiscBase::IPartition* partIn, SystemStringView dirIn);
|
||||||
bool mergeFromDirectory(IPartWriteStream& ws,
|
|
||||||
const DiscBase::IPartition* partIn,
|
|
||||||
const SystemChar* dirIn);
|
|
||||||
static uint64_t CalculateTotalSizeMerge(const DiscBase::IPartition* partIn,
|
|
||||||
const SystemChar* dirIn);
|
|
||||||
};
|
};
|
||||||
protected:
|
protected:
|
||||||
SystemString m_outPath;
|
SystemString m_outPath;
|
||||||
@@ -511,7 +507,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual ~DiscBuilderBase() = default;
|
virtual ~DiscBuilderBase() = default;
|
||||||
DiscBuilderBase(const SystemChar* outPath,
|
DiscBuilderBase(SystemStringView outPath,
|
||||||
int64_t discCapacity, FProgress progressCB)
|
int64_t discCapacity, FProgress progressCB)
|
||||||
: m_outPath(outPath), m_fileIO(NewFileIO(outPath, discCapacity)),
|
: m_outPath(outPath), m_fileIO(NewFileIO(outPath, discCapacity)),
|
||||||
m_discCapacity(discCapacity), m_progressCB(progressCB) {}
|
m_discCapacity(discCapacity), m_progressCB(progressCB) {}
|
||||||
|
|||||||
@@ -10,19 +10,19 @@ class DiscBuilderGCN;
|
|||||||
class DiscGCN : public DiscBase
|
class DiscGCN : public DiscBase
|
||||||
{
|
{
|
||||||
friend class DiscMergerGCN;
|
friend class DiscMergerGCN;
|
||||||
DiscBuilderGCN makeMergeBuilder(const SystemChar* outPath, FProgress progressCB);
|
DiscBuilderGCN makeMergeBuilder(SystemStringView outPath, FProgress progressCB);
|
||||||
public:
|
public:
|
||||||
DiscGCN(std::unique_ptr<IDiscIO>&& dio, bool& err);
|
DiscGCN(std::unique_ptr<IDiscIO>&& dio, bool& err);
|
||||||
bool extractDiscHeaderFiles(const SystemString& path, const ExtractionContext& ctx) const;
|
bool extractDiscHeaderFiles(SystemStringView path, const ExtractionContext& ctx) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DiscBuilderGCN : public DiscBuilderBase
|
class DiscBuilderGCN : public DiscBuilderBase
|
||||||
{
|
{
|
||||||
friend class DiscMergerGCN;
|
friend class DiscMergerGCN;
|
||||||
public:
|
public:
|
||||||
DiscBuilderGCN(const SystemChar* outPath, FProgress progressCB);
|
DiscBuilderGCN(SystemStringView outPath, FProgress progressCB);
|
||||||
EBuildResult buildFromDirectory(const SystemChar* dirIn);
|
EBuildResult buildFromDirectory(SystemStringView dirIn);
|
||||||
static uint64_t CalculateTotalSizeRequired(const SystemChar* dirIn);
|
static uint64_t CalculateTotalSizeRequired(SystemStringView dirIn);
|
||||||
};
|
};
|
||||||
|
|
||||||
class DiscMergerGCN
|
class DiscMergerGCN
|
||||||
@@ -30,9 +30,9 @@ class DiscMergerGCN
|
|||||||
DiscGCN& m_sourceDisc;
|
DiscGCN& m_sourceDisc;
|
||||||
DiscBuilderGCN m_builder;
|
DiscBuilderGCN m_builder;
|
||||||
public:
|
public:
|
||||||
DiscMergerGCN(const SystemChar* outPath, DiscGCN& sourceDisc, FProgress progressCB);
|
DiscMergerGCN(SystemStringView outPath, DiscGCN& sourceDisc, FProgress progressCB);
|
||||||
EBuildResult mergeFromDirectory(const SystemChar* dirIn);
|
EBuildResult mergeFromDirectory(SystemStringView dirIn);
|
||||||
static uint64_t CalculateTotalSizeRequired(DiscGCN& sourceDisc, const SystemChar* dirIn);
|
static uint64_t CalculateTotalSizeRequired(DiscGCN& sourceDisc, SystemStringView dirIn);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,17 +11,17 @@ class DiscWii : public DiscBase
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DiscWii(std::unique_ptr<IDiscIO>&& dio, bool& err);
|
DiscWii(std::unique_ptr<IDiscIO>&& dio, bool& err);
|
||||||
DiscBuilderWii makeMergeBuilder(const SystemChar* outPath, bool dualLayer, FProgress progressCB);
|
DiscBuilderWii makeMergeBuilder(SystemStringView outPath, bool dualLayer, FProgress progressCB);
|
||||||
bool extractDiscHeaderFiles(const SystemString& path, const ExtractionContext& ctx) const;
|
bool extractDiscHeaderFiles(SystemStringView path, const ExtractionContext& ctx) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DiscBuilderWii : public DiscBuilderBase
|
class DiscBuilderWii : public DiscBuilderBase
|
||||||
{
|
{
|
||||||
bool m_dualLayer;
|
bool m_dualLayer;
|
||||||
public:
|
public:
|
||||||
DiscBuilderWii(const SystemChar* outPath, bool dualLayer, FProgress progressCB);
|
DiscBuilderWii(SystemStringView outPath, bool dualLayer, FProgress progressCB);
|
||||||
EBuildResult buildFromDirectory(const SystemChar* dirIn);
|
EBuildResult buildFromDirectory(SystemStringView dirIn);
|
||||||
static uint64_t CalculateTotalSizeRequired(const SystemChar* dirIn, bool& dualLayer);
|
static uint64_t CalculateTotalSizeRequired(SystemStringView dirIn, bool& dualLayer);
|
||||||
};
|
};
|
||||||
|
|
||||||
class DiscMergerWii
|
class DiscMergerWii
|
||||||
@@ -29,10 +29,10 @@ class DiscMergerWii
|
|||||||
DiscWii& m_sourceDisc;
|
DiscWii& m_sourceDisc;
|
||||||
DiscBuilderWii m_builder;
|
DiscBuilderWii m_builder;
|
||||||
public:
|
public:
|
||||||
DiscMergerWii(const SystemChar* outPath, DiscWii& sourceDisc,
|
DiscMergerWii(SystemStringView outPath, DiscWii& sourceDisc,
|
||||||
bool dualLayer, FProgress progressCB);
|
bool dualLayer, FProgress progressCB);
|
||||||
EBuildResult mergeFromDirectory(const SystemChar* dirIn);
|
EBuildResult mergeFromDirectory(SystemStringView dirIn);
|
||||||
static uint64_t CalculateTotalSizeRequired(DiscWii& sourceDisc, const SystemChar* dirIn,
|
static uint64_t CalculateTotalSizeRequired(DiscWii& sourceDisc, SystemStringView dirIn,
|
||||||
bool& dualLayer);
|
bool& dualLayer);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -79,8 +79,7 @@ public:
|
|||||||
virtual std::unique_ptr<IReadStream> beginReadStream(uint64_t offset) const=0;
|
virtual std::unique_ptr<IReadStream> beginReadStream(uint64_t offset) const=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<IFileIO> NewFileIO(const SystemString& path, int64_t maxWriteSize=-1);
|
std::unique_ptr<IFileIO> NewFileIO(SystemStringView path, int64_t maxWriteSize=-1);
|
||||||
std::unique_ptr<IFileIO> NewFileIO(const SystemChar* path, int64_t maxWriteSize=-1);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,11 @@
|
|||||||
#define NOMINMAX
|
#define NOMINMAX
|
||||||
#endif
|
#endif
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#if defined(WINAPI_FAMILY) && WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP
|
||||||
|
#define WINDOWS_STORE 1
|
||||||
|
#else
|
||||||
|
#define WINDOWS_STORE 0
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
@@ -23,6 +28,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "logvisor/logvisor.hpp"
|
#include "logvisor/logvisor.hpp"
|
||||||
@@ -74,34 +80,37 @@ static inline int Stat(const char* path, Sstat* statout) {return stat(path, stat
|
|||||||
#if NOD_UCS2
|
#if NOD_UCS2
|
||||||
typedef wchar_t SystemChar;
|
typedef wchar_t SystemChar;
|
||||||
typedef std::wstring SystemString;
|
typedef std::wstring SystemString;
|
||||||
|
typedef std::wstring_view SystemStringView;
|
||||||
static inline void ToLower(SystemString& str)
|
static inline void ToLower(SystemString& str)
|
||||||
{std::transform(str.begin(), str.end(), str.begin(), towlower);}
|
{std::transform(str.begin(), str.end(), str.begin(), towlower);}
|
||||||
static inline void ToUpper(SystemString& str)
|
static inline void ToUpper(SystemString& str)
|
||||||
{std::transform(str.begin(), str.end(), str.begin(), towupper);}
|
{std::transform(str.begin(), str.end(), str.begin(), towupper);}
|
||||||
static inline size_t StrLen(const SystemChar* str) {return wcslen(str);}
|
static inline size_t StrLen(const SystemChar* str) {return wcslen(str);}
|
||||||
class SystemUTF8View
|
class SystemUTF8Conv
|
||||||
{
|
{
|
||||||
std::string m_utf8;
|
std::string m_utf8;
|
||||||
public:
|
public:
|
||||||
explicit SystemUTF8View(const SystemString& str)
|
explicit SystemUTF8Conv(SystemStringView str)
|
||||||
{
|
{
|
||||||
int len = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), str.size(), nullptr, 0, nullptr, nullptr);
|
int len = WideCharToMultiByte(CP_UTF8, 0, str.data(), str.size(), nullptr, 0, nullptr, nullptr);
|
||||||
m_utf8.assign(len, '\0');
|
m_utf8.assign(len, '\0');
|
||||||
WideCharToMultiByte(CP_UTF8, 0, str.c_str(), str.size(), &m_utf8[0], len, nullptr, nullptr);
|
WideCharToMultiByte(CP_UTF8, 0, str.data(), str.size(), &m_utf8[0], len, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
inline const std::string& utf8_str() {return m_utf8;}
|
inline std::string_view utf8_str() const {return m_utf8;}
|
||||||
|
inline const char* c_str() const {return m_utf8.c_str();}
|
||||||
};
|
};
|
||||||
class SystemStringView
|
class SystemStringConv
|
||||||
{
|
{
|
||||||
std::wstring m_sys;
|
std::wstring m_sys;
|
||||||
public:
|
public:
|
||||||
explicit SystemStringView(const std::string& str)
|
explicit SystemStringConv(std::string_view str)
|
||||||
{
|
{
|
||||||
int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.size(), nullptr, 0);
|
int len = MultiByteToWideChar(CP_UTF8, 0, str.data(), str.size(), nullptr, 0);
|
||||||
m_sys.assign(len, L'\0');
|
m_sys.assign(len, L'\0');
|
||||||
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.size(), &m_sys[0], len);
|
MultiByteToWideChar(CP_UTF8, 0, str.data(), str.size(), &m_sys[0], len);
|
||||||
}
|
}
|
||||||
inline const std::wstring& sys_str() {return m_sys;}
|
inline SystemStringView sys_str() const {return m_sys;}
|
||||||
|
inline const SystemChar* c_str() const {return m_sys.c_str();}
|
||||||
};
|
};
|
||||||
#ifndef _S
|
#ifndef _S
|
||||||
#define _S(val) L ## val
|
#define _S(val) L ## val
|
||||||
@@ -109,26 +118,29 @@ public:
|
|||||||
#else
|
#else
|
||||||
typedef char SystemChar;
|
typedef char SystemChar;
|
||||||
typedef std::string SystemString;
|
typedef std::string SystemString;
|
||||||
|
typedef std::string_view SystemStringView;
|
||||||
static inline void ToLower(SystemString& str)
|
static inline void ToLower(SystemString& str)
|
||||||
{std::transform(str.begin(), str.end(), str.begin(), tolower);}
|
{std::transform(str.begin(), str.end(), str.begin(), tolower);}
|
||||||
static inline void ToUpper(SystemString& str)
|
static inline void ToUpper(SystemString& str)
|
||||||
{std::transform(str.begin(), str.end(), str.begin(), toupper);}
|
{std::transform(str.begin(), str.end(), str.begin(), toupper);}
|
||||||
static inline size_t StrLen(const SystemChar* str) {return strlen(str);}
|
static inline size_t StrLen(const SystemChar* str) {return strlen(str);}
|
||||||
class SystemUTF8View
|
class SystemUTF8Conv
|
||||||
{
|
{
|
||||||
const std::string& m_utf8;
|
std::string_view m_utf8;
|
||||||
public:
|
public:
|
||||||
explicit SystemUTF8View(const SystemString& str)
|
explicit SystemUTF8Conv(SystemStringView str)
|
||||||
: m_utf8(str) {}
|
: m_utf8(str) {}
|
||||||
inline const std::string& utf8_str() {return m_utf8;}
|
inline std::string_view utf8_str() const {return m_utf8;}
|
||||||
|
inline const char* c_str() const {return m_utf8.data();}
|
||||||
};
|
};
|
||||||
class SystemStringView
|
class SystemStringConv
|
||||||
{
|
{
|
||||||
const std::string& m_sys;
|
SystemStringView m_sys;
|
||||||
public:
|
public:
|
||||||
explicit SystemStringView(const std::string& str)
|
explicit SystemStringConv(std::string_view str)
|
||||||
: m_sys(str) {}
|
: m_sys(str) {}
|
||||||
inline const std::string& sys_str() {return m_sys;}
|
inline SystemStringView sys_str() const {return m_sys;}
|
||||||
|
inline const SystemChar* c_str() const {return m_sys.data();}
|
||||||
};
|
};
|
||||||
#ifndef _S
|
#ifndef _S
|
||||||
#define _S(val) val
|
#define _S(val) val
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ class DiscBase;
|
|||||||
struct ExtractionContext final
|
struct ExtractionContext final
|
||||||
{
|
{
|
||||||
bool force : 1;
|
bool force : 1;
|
||||||
std::function<void(const std::string&, float)> progressCB;
|
std::function<void(std::string_view, float)> progressCB;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<DiscBase> OpenDiscFromImage(const SystemChar* path);
|
std::unique_ptr<DiscBase> OpenDiscFromImage(SystemStringView path);
|
||||||
std::unique_ptr<DiscBase> OpenDiscFromImage(const SystemChar* path, bool& isWii);
|
std::unique_ptr<DiscBase> OpenDiscFromImage(SystemStringView path, bool& isWii);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ add_library(nod
|
|||||||
DiscWii.cpp
|
DiscWii.cpp
|
||||||
DirectoryEnumerator.cpp
|
DirectoryEnumerator.cpp
|
||||||
nod.cpp
|
nod.cpp
|
||||||
${PLAT_SRCS}
|
${PLAT_SRCS}
|
||||||
${NOD_HEADERS})
|
${NOD_HEADERS})
|
||||||
if(NOT MSVC)
|
if(NOT MSVC)
|
||||||
set_source_files_properties(aes.cpp PROPERTIES COMPILE_FLAGS -maes)
|
set_source_files_properties(aes.cpp PROPERTIES COMPILE_FLAGS -maes)
|
||||||
|
|||||||
@@ -12,11 +12,11 @@
|
|||||||
namespace nod
|
namespace nod
|
||||||
{
|
{
|
||||||
|
|
||||||
DirectoryEnumerator::DirectoryEnumerator(const SystemChar* path, Mode mode,
|
DirectoryEnumerator::DirectoryEnumerator(SystemStringView path, Mode mode,
|
||||||
bool sizeSort, bool reverse, bool noHidden)
|
bool sizeSort, bool reverse, bool noHidden)
|
||||||
{
|
{
|
||||||
Sstat theStat;
|
Sstat theStat;
|
||||||
if (Stat(path, &theStat) || !S_ISDIR(theStat.st_mode))
|
if (Stat(path.data(), &theStat) || !S_ISDIR(theStat.st_mode))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
@@ -151,7 +151,7 @@ DirectoryEnumerator::DirectoryEnumerator(const SystemChar* path, Mode mode,
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
DIR* dir = opendir(path);
|
DIR* dir = opendir(path.data());
|
||||||
if (!dir)
|
if (!dir)
|
||||||
return;
|
return;
|
||||||
const dirent* d;
|
const dirent* d;
|
||||||
|
|||||||
253
lib/DiscBase.cpp
253
lib/DiscBase.cpp
@@ -104,11 +104,11 @@ void DiscBase::IPartition::parseDOL(IPartReadStream& s)
|
|||||||
m_dolSz = dolSize;
|
m_dolSz = dolSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DiscBase::IPartition::Node::extractToDirectory(const SystemString& basePath,
|
bool DiscBase::IPartition::Node::extractToDirectory(SystemStringView basePath,
|
||||||
const ExtractionContext& ctx) const
|
const ExtractionContext& ctx) const
|
||||||
{
|
{
|
||||||
SystemStringView nameView(getName());
|
SystemStringConv nameView(getName());
|
||||||
SystemString path = basePath + _S("/") + nameView.sys_str();
|
SystemString path = SystemString(basePath) + _S('/') + nameView.sys_str().data();
|
||||||
|
|
||||||
if (m_kind == Kind::Directory)
|
if (m_kind == Kind::Directory)
|
||||||
{
|
{
|
||||||
@@ -148,18 +148,17 @@ bool DiscBase::IPartition::Node::extractToDirectory(const SystemString& basePath
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DiscBase::IPartition::extractToDirectory(const SystemString& path,
|
bool DiscBase::IPartition::extractToDirectory(SystemStringView path,
|
||||||
const ExtractionContext& ctx)
|
const ExtractionContext& ctx)
|
||||||
{
|
{
|
||||||
m_curNodeIdx = 0;
|
m_curNodeIdx = 0;
|
||||||
Sstat theStat;
|
if (Mkdir(path.data(), 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.data());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemString basePath = m_isWii ? path + _S("/") + getKindString(m_kind) : path;
|
SystemString basePath = m_isWii ? SystemString(path) + _S("/") + getKindString(m_kind) : SystemString(path);
|
||||||
if (m_isWii)
|
if (m_isWii)
|
||||||
{
|
{
|
||||||
if (Mkdir(basePath.c_str(), 0755) && errno != EEXIST)
|
if (Mkdir(basePath.c_str(), 0755) && errno != EEXIST)
|
||||||
@@ -169,12 +168,6 @@ bool DiscBase::IPartition::extractToDirectory(const SystemString& path,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Mkdir((basePath + _S("/sys")).c_str(), 0755) && errno != EEXIST)
|
|
||||||
{
|
|
||||||
LogModule.report(logvisor::Error, _S("unable to mkdir '%s/sys'"), basePath.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Extract Disc Files */
|
/* Extract Disc Files */
|
||||||
if (!m_parent.extractDiscHeaderFiles(basePath, ctx))
|
if (!m_parent.extractDiscHeaderFiles(basePath, ctx))
|
||||||
return false;
|
return false;
|
||||||
@@ -183,56 +176,8 @@ bool DiscBase::IPartition::extractToDirectory(const SystemString& path,
|
|||||||
if (!extractCryptoFiles(basePath, ctx))
|
if (!extractCryptoFiles(basePath, ctx))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Extract Apploader */
|
if (!extractSysFiles(basePath, ctx))
|
||||||
SystemString apploaderPath = basePath + _S("/sys/apploader.img");
|
return false;
|
||||||
if (ctx.force || Stat(apploaderPath.c_str(), &theStat))
|
|
||||||
{
|
|
||||||
if (ctx.progressCB)
|
|
||||||
ctx.progressCB("apploader.bin", 0.f);
|
|
||||||
std::unique_ptr<uint8_t[]> buf = getApploaderBuf();
|
|
||||||
auto ws = NewFileIO(apploaderPath)->beginWriteStream();
|
|
||||||
if (!ws)
|
|
||||||
return false;
|
|
||||||
ws->write(buf.get(), m_apploaderSz);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Extract Dol */
|
|
||||||
SystemString dolPath = basePath + _S("/sys/main.dol");
|
|
||||||
if (ctx.force || Stat(dolPath.c_str(), &theStat))
|
|
||||||
{
|
|
||||||
if (ctx.progressCB)
|
|
||||||
ctx.progressCB("main.dol", 0.f);
|
|
||||||
std::unique_ptr<uint8_t[]> buf = getDOLBuf();
|
|
||||||
auto ws = NewFileIO(dolPath)->beginWriteStream();
|
|
||||||
if (!ws)
|
|
||||||
return false;
|
|
||||||
ws->write(buf.get(), m_dolSz);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Extract Boot info */
|
|
||||||
SystemString bootPath = basePath + _S("/sys/boot.bin");
|
|
||||||
if (ctx.force || Stat(bootPath.c_str(), &theStat))
|
|
||||||
{
|
|
||||||
if (ctx.progressCB)
|
|
||||||
ctx.progressCB("boot.bin", 0.f);
|
|
||||||
auto ws = NewFileIO(bootPath)->beginWriteStream();
|
|
||||||
if (!ws)
|
|
||||||
return false;
|
|
||||||
m_header.write(*ws.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Extract BI2 info */
|
|
||||||
SystemString bi2Path = basePath + _S("/sys/bi2.bin");
|
|
||||||
if (ctx.force || Stat(bi2Path.c_str(), &theStat))
|
|
||||||
{
|
|
||||||
if (ctx.progressCB)
|
|
||||||
ctx.progressCB("bi2.bin", 0.f);
|
|
||||||
|
|
||||||
auto ws = NewFileIO(bi2Path)->beginWriteStream();
|
|
||||||
if (!ws)
|
|
||||||
return false;
|
|
||||||
m_bi2Header.write(*ws);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Extract Filesystem */
|
/* Extract Filesystem */
|
||||||
SystemString fsPath = basePath + _S("/files");
|
SystemString fsPath = basePath + _S("/files");
|
||||||
@@ -245,44 +190,71 @@ bool DiscBase::IPartition::extractToDirectory(const SystemString& path,
|
|||||||
return m_nodes[0].extractToDirectory(fsPath, ctx);
|
return m_nodes[0].extractToDirectory(fsPath, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t GetInode(const SystemChar* path)
|
bool DiscBase::IPartition::extractSysFiles(SystemStringView basePath, const ExtractionContext& ctx) const
|
||||||
{
|
{
|
||||||
uint64_t inode;
|
SystemString basePathStr(basePath);
|
||||||
#if _WIN32
|
if (Mkdir((basePathStr + _S("/sys")).c_str(), 0755) && errno != EEXIST)
|
||||||
HANDLE fp = CreateFileW(path,
|
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
||||||
nullptr,
|
|
||||||
OPEN_EXISTING,
|
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
|
||||||
nullptr);
|
|
||||||
if (!fp)
|
|
||||||
{
|
{
|
||||||
LogModule.report(logvisor::Error, _S("unable to open %s"), path);
|
LogModule.report(logvisor::Error, _S("unable to mkdir '%s/sys'"), basePath.data());
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
BY_HANDLE_FILE_INFORMATION info;
|
|
||||||
if (!GetFileInformationByHandle(fp, &info))
|
Sstat theStat;
|
||||||
|
/* Extract Apploader */
|
||||||
|
SystemString apploaderPath = basePathStr + _S("/sys/apploader.img");
|
||||||
|
if (ctx.force || Stat(apploaderPath.c_str(), &theStat))
|
||||||
{
|
{
|
||||||
LogModule.report(logvisor::Error, _S("unable to GetFileInformationByHandle %s"), path);
|
if (ctx.progressCB)
|
||||||
return 0;
|
ctx.progressCB("apploader.bin", 0.f);
|
||||||
|
std::unique_ptr<uint8_t[]> buf = getApploaderBuf();
|
||||||
|
auto ws = NewFileIO(apploaderPath)->beginWriteStream();
|
||||||
|
if (!ws)
|
||||||
|
return false;
|
||||||
|
ws->write(buf.get(), m_apploaderSz);
|
||||||
}
|
}
|
||||||
inode = uint64_t(info.nFileIndexHigh) << 32;
|
|
||||||
inode |= uint64_t(info.nFileIndexLow);
|
/* Extract Dol */
|
||||||
CloseHandle(fp);
|
SystemString dolPath = basePathStr + _S("/sys/main.dol");
|
||||||
#else
|
if (ctx.force || Stat(dolPath.c_str(), &theStat))
|
||||||
struct stat st;
|
|
||||||
if (stat(path, &st))
|
|
||||||
{
|
{
|
||||||
LogModule.report(logvisor::Error, _S("unable to stat %s"), path);
|
if (ctx.progressCB)
|
||||||
return 0;
|
ctx.progressCB("main.dol", 0.f);
|
||||||
|
std::unique_ptr<uint8_t[]> buf = getDOLBuf();
|
||||||
|
auto ws = NewFileIO(dolPath)->beginWriteStream();
|
||||||
|
if (!ws)
|
||||||
|
return false;
|
||||||
|
ws->write(buf.get(), m_dolSz);
|
||||||
}
|
}
|
||||||
inode = uint64_t(st.st_ino);
|
|
||||||
#endif
|
/* Extract Boot info */
|
||||||
return inode;
|
SystemString bootPath = basePathStr + _S("/sys/boot.bin");
|
||||||
|
if (ctx.force || Stat(bootPath.c_str(), &theStat))
|
||||||
|
{
|
||||||
|
if (ctx.progressCB)
|
||||||
|
ctx.progressCB("boot.bin", 0.f);
|
||||||
|
auto ws = NewFileIO(bootPath)->beginWriteStream();
|
||||||
|
if (!ws)
|
||||||
|
return false;
|
||||||
|
m_header.write(*ws.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extract BI2 info */
|
||||||
|
SystemString bi2Path = basePathStr + _S("/sys/bi2.bin");
|
||||||
|
if (ctx.force || Stat(bi2Path.c_str(), &theStat))
|
||||||
|
{
|
||||||
|
if (ctx.progressCB)
|
||||||
|
ctx.progressCB("bi2.bin", 0.f);
|
||||||
|
|
||||||
|
auto ws = NewFileIO(bi2Path)->beginWriteStream();
|
||||||
|
if (!ws)
|
||||||
|
return false;
|
||||||
|
m_bi2Header.write(*ws);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsSystemFile(const SystemString& name, bool& isDol)
|
static bool IsSystemFile(SystemStringView name, bool& isDol)
|
||||||
{
|
{
|
||||||
isDol = false;
|
isDol = false;
|
||||||
if (name.size() < 4)
|
if (name.size() < 4)
|
||||||
@@ -332,7 +304,7 @@ static size_t PatchDOL(IFileIO::IReadStream& in, IPartWriteStream& out, size_t s
|
|||||||
return out.write(buf.get(), sz);
|
return out.write(buf.get(), sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiscBuilderBase::PartitionBuilderBase::recursiveBuildNodesPre(const SystemChar* filesIn)
|
void DiscBuilderBase::PartitionBuilderBase::recursiveBuildNodesPre(SystemStringView filesIn)
|
||||||
{
|
{
|
||||||
DirectoryEnumerator dEnum(filesIn, DirectoryEnumerator::Mode::DirsThenFilesSorted, false, false, true);
|
DirectoryEnumerator dEnum(filesIn, DirectoryEnumerator::Mode::DirsThenFilesSorted, false, false, true);
|
||||||
for (const DirectoryEnumerator::Entry& e : dEnum)
|
for (const DirectoryEnumerator::Entry& e : dEnum)
|
||||||
@@ -346,7 +318,7 @@ void DiscBuilderBase::PartitionBuilderBase::recursiveBuildNodesPre(const SystemC
|
|||||||
|
|
||||||
bool DiscBuilderBase::PartitionBuilderBase::recursiveBuildNodes(IPartWriteStream& ws,
|
bool DiscBuilderBase::PartitionBuilderBase::recursiveBuildNodes(IPartWriteStream& ws,
|
||||||
bool system,
|
bool system,
|
||||||
const SystemChar* filesIn)
|
SystemStringView filesIn)
|
||||||
{
|
{
|
||||||
DirectoryEnumerator dEnum(filesIn, DirectoryEnumerator::Mode::DirsThenFilesSorted, false, false, true);
|
DirectoryEnumerator dEnum(filesIn, DirectoryEnumerator::Mode::DirsThenFilesSorted, false, false, true);
|
||||||
for (const DirectoryEnumerator::Entry& e : dEnum)
|
for (const DirectoryEnumerator::Entry& e : dEnum)
|
||||||
@@ -401,8 +373,9 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveBuildNodes(IPartWriteStream
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DiscBuilderBase::PartitionBuilderBase::recursiveBuildFST(const SystemChar* filesIn,
|
bool DiscBuilderBase::PartitionBuilderBase::recursiveBuildFST(SystemStringView filesIn,
|
||||||
std::function<void(void)> incParents)
|
std::function<void(void)> incParents,
|
||||||
|
size_t parentDirIdx)
|
||||||
{
|
{
|
||||||
DirectoryEnumerator dEnum(filesIn, DirectoryEnumerator::Mode::DirsThenFilesSorted, false, false, true);
|
DirectoryEnumerator dEnum(filesIn, DirectoryEnumerator::Mode::DirsThenFilesSorted, false, false, true);
|
||||||
for (const DirectoryEnumerator::Entry& e : dEnum)
|
for (const DirectoryEnumerator::Entry& e : dEnum)
|
||||||
@@ -410,10 +383,12 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveBuildFST(const SystemChar*
|
|||||||
if (e.m_isDir)
|
if (e.m_isDir)
|
||||||
{
|
{
|
||||||
size_t dirNodeIdx = m_buildNodes.size();
|
size_t dirNodeIdx = m_buildNodes.size();
|
||||||
m_buildNodes.emplace_back(true, m_buildNameOff, 0, dirNodeIdx+1);
|
m_buildNodes.emplace_back(true, m_buildNameOff, parentDirIdx, dirNodeIdx+1);
|
||||||
addBuildName(e.m_name);
|
addBuildName(e.m_name);
|
||||||
incParents();
|
incParents();
|
||||||
if (!recursiveBuildFST(e.m_path.c_str(), [&](){m_buildNodes[dirNodeIdx].incrementLength(); incParents();}))
|
if (!recursiveBuildFST(e.m_path.c_str(),
|
||||||
|
[&](){m_buildNodes[dirNodeIdx].incrementLength(); incParents();},
|
||||||
|
dirNodeIdx))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -429,7 +404,7 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveBuildFST(const SystemChar*
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DiscBuilderBase::PartitionBuilderBase::recursiveMergeNodesPre(const DiscBase::IPartition::Node* nodeIn,
|
void DiscBuilderBase::PartitionBuilderBase::recursiveMergeNodesPre(const DiscBase::IPartition::Node* nodeIn,
|
||||||
const SystemChar* dirIn)
|
SystemStringView dirIn)
|
||||||
{
|
{
|
||||||
/* Build map of existing nodes to write-through later */
|
/* Build map of existing nodes to write-through later */
|
||||||
std::unordered_map<std::string, const Partition::Node*> fileNodes;
|
std::unordered_map<std::string, const Partition::Node*> fileNodes;
|
||||||
@@ -448,16 +423,16 @@ void DiscBuilderBase::PartitionBuilderBase::recursiveMergeNodesPre(const DiscBas
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Merge this directory's files */
|
/* Merge this directory's files */
|
||||||
if (dirIn)
|
if (!dirIn.empty())
|
||||||
{
|
{
|
||||||
DirectoryEnumerator dEnum(dirIn, DirectoryEnumerator::Mode::DirsThenFilesSorted, false, false, true);
|
DirectoryEnumerator dEnum(dirIn, DirectoryEnumerator::Mode::DirsThenFilesSorted, false, false, true);
|
||||||
for (const DirectoryEnumerator::Entry& e : dEnum)
|
for (const DirectoryEnumerator::Entry& e : dEnum)
|
||||||
{
|
{
|
||||||
SystemUTF8View nameView(e.m_name);
|
SystemUTF8Conv nameView(e.m_name);
|
||||||
|
|
||||||
if (e.m_isDir)
|
if (e.m_isDir)
|
||||||
{
|
{
|
||||||
auto search = dirNodes.find(nameView.utf8_str());
|
auto search = dirNodes.find(nameView.utf8_str().data());
|
||||||
if (search != dirNodes.cend())
|
if (search != dirNodes.cend())
|
||||||
{
|
{
|
||||||
recursiveMergeNodesPre(search->second, e.m_path.c_str());
|
recursiveMergeNodesPre(search->second, e.m_path.c_str());
|
||||||
@@ -470,7 +445,7 @@ void DiscBuilderBase::PartitionBuilderBase::recursiveMergeNodesPre(const DiscBas
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fileNodes.erase(nameView.utf8_str());
|
fileNodes.erase(nameView.utf8_str().data());
|
||||||
++m_parent.m_progressTotal;
|
++m_parent.m_progressTotal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -489,8 +464,8 @@ void DiscBuilderBase::PartitionBuilderBase::recursiveMergeNodesPre(const DiscBas
|
|||||||
bool DiscBuilderBase::PartitionBuilderBase::recursiveMergeNodes(IPartWriteStream& ws,
|
bool DiscBuilderBase::PartitionBuilderBase::recursiveMergeNodes(IPartWriteStream& ws,
|
||||||
bool system,
|
bool system,
|
||||||
const DiscBase::IPartition::Node* nodeIn,
|
const DiscBase::IPartition::Node* nodeIn,
|
||||||
const SystemChar* dirIn,
|
SystemStringView dirIn,
|
||||||
const SystemString& keyPath)
|
SystemStringView keyPath)
|
||||||
{
|
{
|
||||||
/* Build map of existing nodes to write-through later */
|
/* Build map of existing nodes to write-through later */
|
||||||
std::unordered_map<std::string, const Partition::Node*> fileNodes;
|
std::unordered_map<std::string, const Partition::Node*> fileNodes;
|
||||||
@@ -509,17 +484,17 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveMergeNodes(IPartWriteStream
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Merge this directory's files */
|
/* Merge this directory's files */
|
||||||
if (dirIn)
|
if (!dirIn.empty())
|
||||||
{
|
{
|
||||||
DirectoryEnumerator dEnum(dirIn, DirectoryEnumerator::Mode::DirsThenFilesSorted, false, false, true);
|
DirectoryEnumerator dEnum(dirIn, DirectoryEnumerator::Mode::DirsThenFilesSorted, false, false, true);
|
||||||
for (const DirectoryEnumerator::Entry& e : dEnum)
|
for (const DirectoryEnumerator::Entry& e : dEnum)
|
||||||
{
|
{
|
||||||
SystemUTF8View nameView(e.m_name);
|
SystemUTF8Conv nameView(e.m_name);
|
||||||
SystemString chKeyPath = keyPath + _S('/') + e.m_name;
|
SystemString chKeyPath = SystemString(keyPath) + _S('/') + e.m_name;
|
||||||
|
|
||||||
if (e.m_isDir)
|
if (e.m_isDir)
|
||||||
{
|
{
|
||||||
auto search = dirNodes.find(nameView.utf8_str());
|
auto search = dirNodes.find(nameView.utf8_str().data());
|
||||||
if (search != dirNodes.cend())
|
if (search != dirNodes.cend())
|
||||||
{
|
{
|
||||||
if (!recursiveMergeNodes(ws, system, search->second, e.m_path.c_str(), chKeyPath))
|
if (!recursiveMergeNodes(ws, system, search->second, e.m_path.c_str(), chKeyPath))
|
||||||
@@ -539,7 +514,7 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveMergeNodes(IPartWriteStream
|
|||||||
if (system ^ isSys)
|
if (system ^ isSys)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
fileNodes.erase(nameView.utf8_str());
|
fileNodes.erase(nameView.utf8_str().data());
|
||||||
|
|
||||||
size_t fileSz = ROUND_UP_32(e.m_fileSz);
|
size_t fileSz = ROUND_UP_32(e.m_fileSz);
|
||||||
uint64_t fileOff = userAllocate(fileSz, ws);
|
uint64_t fileOff = userAllocate(fileSz, ws);
|
||||||
@@ -581,8 +556,8 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveMergeNodes(IPartWriteStream
|
|||||||
/* Write-through remaining dir nodes */
|
/* Write-through remaining dir nodes */
|
||||||
for (const auto& p : dirNodes)
|
for (const auto& p : dirNodes)
|
||||||
{
|
{
|
||||||
SystemStringView sysName(p.second->getName());
|
SystemStringConv sysName(p.second->getName());
|
||||||
SystemString chKeyPath = keyPath + _S('/') + sysName.sys_str();
|
SystemString chKeyPath = SystemString(keyPath) + _S('/') + sysName.c_str();
|
||||||
if (!recursiveMergeNodes(ws, system, p.second, nullptr, chKeyPath))
|
if (!recursiveMergeNodes(ws, system, p.second, nullptr, chKeyPath))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -591,8 +566,8 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveMergeNodes(IPartWriteStream
|
|||||||
for (const auto& p : fileNodes)
|
for (const auto& p : fileNodes)
|
||||||
{
|
{
|
||||||
const Partition::Node& ch = *p.second;
|
const Partition::Node& ch = *p.second;
|
||||||
SystemStringView sysName(ch.getName());
|
SystemStringConv sysName(ch.getName());
|
||||||
SystemString chKeyPath = keyPath + _S('/') + sysName.sys_str();
|
SystemString chKeyPath = SystemString(keyPath) + _S('/') + sysName.c_str();
|
||||||
|
|
||||||
bool isDol;
|
bool isDol;
|
||||||
bool isSys = IsSystemFile(sysName.sys_str(), isDol);
|
bool isSys = IsSystemFile(sysName.sys_str(), isDol);
|
||||||
@@ -615,7 +590,7 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveMergeNodes(IPartWriteStream
|
|||||||
bool patched;
|
bool patched;
|
||||||
PatchDOL(dolBuf, xferSz, patched);
|
PatchDOL(dolBuf, xferSz, patched);
|
||||||
ws.write(dolBuf.get(), xferSz);
|
ws.write(dolBuf.get(), xferSz);
|
||||||
m_parent.m_progressCB(m_parent.getProgressFactor(), sysName.sys_str() +
|
m_parent.m_progressCB(m_parent.getProgressFactor(), SystemString(sysName.sys_str()) +
|
||||||
(patched ? _S(" [PATCHED]") : _S("")), xferSz);
|
(patched ? _S(" [PATCHED]") : _S("")), xferSz);
|
||||||
++m_parent.m_progressIdx;
|
++m_parent.m_progressIdx;
|
||||||
}
|
}
|
||||||
@@ -641,9 +616,9 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveMergeNodes(IPartWriteStream
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool DiscBuilderBase::PartitionBuilderBase::recursiveMergeFST(const Partition::Node* nodeIn,
|
bool DiscBuilderBase::PartitionBuilderBase::recursiveMergeFST(const Partition::Node* nodeIn,
|
||||||
const SystemChar* dirIn,
|
SystemStringView dirIn,
|
||||||
std::function<void(void)> incParents,
|
std::function<void(void)> incParents,
|
||||||
const SystemString& keyPath)
|
SystemStringView keyPath)
|
||||||
{
|
{
|
||||||
/* Build map of existing nodes to write-through later */
|
/* Build map of existing nodes to write-through later */
|
||||||
std::unordered_map<std::string, const Partition::Node*> fileNodes;
|
std::unordered_map<std::string, const Partition::Node*> fileNodes;
|
||||||
@@ -662,13 +637,13 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveMergeFST(const Partition::N
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Merge this directory's files */
|
/* Merge this directory's files */
|
||||||
if (dirIn)
|
if (!dirIn.empty())
|
||||||
{
|
{
|
||||||
DirectoryEnumerator dEnum(dirIn, DirectoryEnumerator::Mode::DirsThenFilesSorted, false, false, true);
|
DirectoryEnumerator dEnum(dirIn, DirectoryEnumerator::Mode::DirsThenFilesSorted, false, false, true);
|
||||||
for (const DirectoryEnumerator::Entry& e : dEnum)
|
for (const DirectoryEnumerator::Entry& e : dEnum)
|
||||||
{
|
{
|
||||||
SystemUTF8View nameView(e.m_name);
|
SystemUTF8Conv nameView(e.m_name);
|
||||||
SystemString chKeyPath = keyPath + _S('/') + e.m_name;
|
SystemString chKeyPath = SystemString(keyPath) + _S('/') + e.m_name;
|
||||||
|
|
||||||
if (e.m_isDir)
|
if (e.m_isDir)
|
||||||
{
|
{
|
||||||
@@ -677,7 +652,7 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveMergeFST(const Partition::N
|
|||||||
addBuildName(e.m_name);
|
addBuildName(e.m_name);
|
||||||
incParents();
|
incParents();
|
||||||
|
|
||||||
auto search = dirNodes.find(nameView.utf8_str());
|
auto search = dirNodes.find(nameView.utf8_str().data());
|
||||||
if (search != dirNodes.cend())
|
if (search != dirNodes.cend())
|
||||||
{
|
{
|
||||||
if (!recursiveMergeFST(search->second, e.m_path.c_str(),
|
if (!recursiveMergeFST(search->second, e.m_path.c_str(),
|
||||||
@@ -696,7 +671,7 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveMergeFST(const Partition::N
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fileNodes.erase(nameView.utf8_str());
|
fileNodes.erase(nameView.utf8_str().data());
|
||||||
std::pair<uint64_t,uint64_t> fileOffSz = m_fileOffsetsSizes.at(chKeyPath);
|
std::pair<uint64_t,uint64_t> fileOffSz = m_fileOffsetsSizes.at(chKeyPath);
|
||||||
m_buildNodes.emplace_back(false, m_buildNameOff, packOffset(fileOffSz.first), fileOffSz.second);
|
m_buildNodes.emplace_back(false, m_buildNameOff, packOffset(fileOffSz.first), fileOffSz.second);
|
||||||
addBuildName(e.m_name);
|
addBuildName(e.m_name);
|
||||||
@@ -709,8 +684,8 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveMergeFST(const Partition::N
|
|||||||
/* Write-through remaining dir nodes */
|
/* Write-through remaining dir nodes */
|
||||||
for (const auto& p : dirNodes)
|
for (const auto& p : dirNodes)
|
||||||
{
|
{
|
||||||
SystemStringView sysName(p.second->getName());
|
SystemStringConv sysName(p.second->getName());
|
||||||
SystemString chKeyPath = keyPath + _S('/') + sysName.sys_str();
|
SystemString chKeyPath = SystemString(keyPath) + _S('/') + sysName.sys_str().data();
|
||||||
|
|
||||||
size_t dirNodeIdx = m_buildNodes.size();
|
size_t dirNodeIdx = m_buildNodes.size();
|
||||||
m_buildNodes.emplace_back(true, m_buildNameOff, 0, dirNodeIdx+1);
|
m_buildNodes.emplace_back(true, m_buildNameOff, 0, dirNodeIdx+1);
|
||||||
@@ -727,8 +702,8 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveMergeFST(const Partition::N
|
|||||||
for (const auto& p : fileNodes)
|
for (const auto& p : fileNodes)
|
||||||
{
|
{
|
||||||
const Partition::Node& ch = *p.second;
|
const Partition::Node& ch = *p.second;
|
||||||
SystemStringView sysName(ch.getName());
|
SystemStringConv sysName(ch.getName());
|
||||||
SystemString chKeyPath = keyPath + _S('/') + sysName.sys_str();
|
SystemString chKeyPath = SystemString(keyPath) + _S('/') + sysName.sys_str().data();
|
||||||
|
|
||||||
std::pair<uint64_t,uint64_t> fileOffSz = m_fileOffsetsSizes.at(chKeyPath);
|
std::pair<uint64_t,uint64_t> fileOffSz = m_fileOffsetsSizes.at(chKeyPath);
|
||||||
m_buildNodes.emplace_back(false, m_buildNameOff, packOffset(fileOffSz.first), fileOffSz.second);
|
m_buildNodes.emplace_back(false, m_buildNameOff, packOffset(fileOffSz.first), fileOffSz.second);
|
||||||
@@ -742,7 +717,7 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveMergeFST(const Partition::N
|
|||||||
bool DiscBuilderBase::PartitionBuilderBase::RecursiveCalculateTotalSize(
|
bool DiscBuilderBase::PartitionBuilderBase::RecursiveCalculateTotalSize(
|
||||||
uint64_t& totalSz,
|
uint64_t& totalSz,
|
||||||
const DiscBase::IPartition::Node* nodeIn,
|
const DiscBase::IPartition::Node* nodeIn,
|
||||||
const SystemChar* dirIn)
|
SystemStringView dirIn)
|
||||||
{
|
{
|
||||||
/* Build map of existing nodes to write-through later */
|
/* Build map of existing nodes to write-through later */
|
||||||
std::unordered_map<std::string, const Partition::Node*> fileNodes;
|
std::unordered_map<std::string, const Partition::Node*> fileNodes;
|
||||||
@@ -761,16 +736,16 @@ bool DiscBuilderBase::PartitionBuilderBase::RecursiveCalculateTotalSize(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Merge this directory's files */
|
/* Merge this directory's files */
|
||||||
if (dirIn)
|
if (!dirIn.empty())
|
||||||
{
|
{
|
||||||
DirectoryEnumerator dEnum(dirIn, DirectoryEnumerator::Mode::DirsThenFilesSorted, false, false, true);
|
DirectoryEnumerator dEnum(dirIn, DirectoryEnumerator::Mode::DirsThenFilesSorted, false, false, true);
|
||||||
for (const DirectoryEnumerator::Entry& e : dEnum)
|
for (const DirectoryEnumerator::Entry& e : dEnum)
|
||||||
{
|
{
|
||||||
SystemUTF8View nameView(e.m_name);
|
SystemUTF8Conv nameView(e.m_name);
|
||||||
|
|
||||||
if (e.m_isDir)
|
if (e.m_isDir)
|
||||||
{
|
{
|
||||||
auto search = dirNodes.find(nameView.utf8_str());
|
auto search = dirNodes.find(nameView.utf8_str().data());
|
||||||
if (search != dirNodes.cend())
|
if (search != dirNodes.cend())
|
||||||
{
|
{
|
||||||
if (!RecursiveCalculateTotalSize(totalSz, search->second, e.m_path.c_str()))
|
if (!RecursiveCalculateTotalSize(totalSz, search->second, e.m_path.c_str()))
|
||||||
@@ -785,7 +760,7 @@ bool DiscBuilderBase::PartitionBuilderBase::RecursiveCalculateTotalSize(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fileNodes.erase(nameView.utf8_str());
|
fileNodes.erase(nameView.utf8_str().data());
|
||||||
totalSz += ROUND_UP_32(e.m_fileSz);
|
totalSz += ROUND_UP_32(e.m_fileSz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -809,9 +784,9 @@ bool DiscBuilderBase::PartitionBuilderBase::RecursiveCalculateTotalSize(
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool DiscBuilderBase::PartitionBuilderBase::buildFromDirectory(IPartWriteStream& ws,
|
bool DiscBuilderBase::PartitionBuilderBase::buildFromDirectory(IPartWriteStream& ws,
|
||||||
const SystemChar* dirIn)
|
SystemStringView dirIn)
|
||||||
{
|
{
|
||||||
if (!dirIn)
|
if (dirIn.empty())
|
||||||
{
|
{
|
||||||
LogModule.report(logvisor::Error, _S("all arguments must be supplied to buildFromDirectory()"));
|
LogModule.report(logvisor::Error, _S("all arguments must be supplied to buildFromDirectory()"));
|
||||||
return false;
|
return false;
|
||||||
@@ -865,13 +840,13 @@ bool DiscBuilderBase::PartitionBuilderBase::buildFromDirectory(IPartWriteStream&
|
|||||||
return false;
|
return false;
|
||||||
if (!recursiveBuildNodes(ws, false, filesIn.c_str()))
|
if (!recursiveBuildNodes(ws, false, filesIn.c_str()))
|
||||||
return false;
|
return false;
|
||||||
if (!recursiveBuildFST(filesIn.c_str(), [&](){m_buildNodes[0].incrementLength();}))
|
if (!recursiveBuildFST(filesIn.c_str(), [&](){m_buildNodes[0].incrementLength();}, 0))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeBuild(const SystemChar* dirIn,
|
uint64_t DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeBuild(SystemStringView dirIn,
|
||||||
PartitionKind kind, bool isWii)
|
PartitionKind kind, bool isWii)
|
||||||
{
|
{
|
||||||
SystemString dirStr(dirIn);
|
SystemString dirStr(dirIn);
|
||||||
@@ -893,9 +868,9 @@ uint64_t DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeBuild(const Sy
|
|||||||
|
|
||||||
bool DiscBuilderBase::PartitionBuilderBase::mergeFromDirectory(IPartWriteStream& ws,
|
bool DiscBuilderBase::PartitionBuilderBase::mergeFromDirectory(IPartWriteStream& ws,
|
||||||
const nod::Partition* partIn,
|
const nod::Partition* partIn,
|
||||||
const SystemChar* dirIn)
|
SystemStringView dirIn)
|
||||||
{
|
{
|
||||||
if (!dirIn)
|
if (dirIn.empty())
|
||||||
{
|
{
|
||||||
LogModule.report(logvisor::Error, _S("all arguments must be supplied to mergeFromDirectory()"));
|
LogModule.report(logvisor::Error, _S("all arguments must be supplied to mergeFromDirectory()"));
|
||||||
return false;
|
return false;
|
||||||
@@ -950,7 +925,7 @@ bool DiscBuilderBase::PartitionBuilderBase::mergeFromDirectory(IPartWriteStream&
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint64_t DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeMerge(const DiscBase::IPartition* partIn,
|
uint64_t DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeMerge(const DiscBase::IPartition* partIn,
|
||||||
const SystemChar* dirIn)
|
SystemStringView dirIn)
|
||||||
{
|
{
|
||||||
SystemString dirStr(dirIn);
|
SystemString dirStr(dirIn);
|
||||||
SystemString basePath = partIn->isWii() ? dirStr + _S("/") + getKindString(partIn->getKind()) : dirStr;
|
SystemString basePath = partIn->isWii() ? dirStr + _S("/") + getKindString(partIn->getKind()) : dirStr;
|
||||||
|
|||||||
@@ -129,12 +129,12 @@ DiscGCN::DiscGCN(std::unique_ptr<IDiscIO>&& dio, bool& err)
|
|||||||
m_partitions.emplace_back(new PartitionGCN(*this, 0, err));
|
m_partitions.emplace_back(new PartitionGCN(*this, 0, err));
|
||||||
}
|
}
|
||||||
|
|
||||||
DiscBuilderGCN DiscGCN::makeMergeBuilder(const SystemChar* outPath, FProgress progressCB)
|
DiscBuilderGCN DiscGCN::makeMergeBuilder(SystemStringView outPath, FProgress progressCB)
|
||||||
{
|
{
|
||||||
return DiscBuilderGCN(outPath, progressCB);
|
return DiscBuilderGCN(outPath, progressCB);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DiscGCN::extractDiscHeaderFiles(const SystemString& path, const ExtractionContext& ctx) const
|
bool DiscGCN::extractDiscHeaderFiles(SystemStringView path, const ExtractionContext& ctx) const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -244,7 +244,7 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool buildFromDirectory(const SystemChar* dirIn)
|
bool buildFromDirectory(SystemStringView dirIn)
|
||||||
{
|
{
|
||||||
std::unique_ptr<IPartWriteStream> ws = beginWriteStream(0);
|
std::unique_ptr<IPartWriteStream> ws = beginWriteStream(0);
|
||||||
if (!ws)
|
if (!ws)
|
||||||
@@ -336,7 +336,7 @@ public:
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mergeFromDirectory(const PartitionGCN* partIn, const SystemChar* dirIn)
|
bool mergeFromDirectory(const PartitionGCN* partIn, SystemStringView dirIn)
|
||||||
{
|
{
|
||||||
std::unique_ptr<IPartWriteStream> ws = beginWriteStream(0);
|
std::unique_ptr<IPartWriteStream> ws = beginWriteStream(0);
|
||||||
if (!ws)
|
if (!ws)
|
||||||
@@ -384,7 +384,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
EBuildResult DiscBuilderGCN::buildFromDirectory(const SystemChar* dirIn)
|
EBuildResult DiscBuilderGCN::buildFromDirectory(SystemStringView dirIn)
|
||||||
{
|
{
|
||||||
if (!m_fileIO->beginWriteStream())
|
if (!m_fileIO->beginWriteStream())
|
||||||
return EBuildResult::Failed;
|
return EBuildResult::Failed;
|
||||||
@@ -395,16 +395,20 @@ EBuildResult DiscBuilderGCN::buildFromDirectory(const SystemChar* dirIn)
|
|||||||
}
|
}
|
||||||
m_progressCB(getProgressFactor(), _S("Preallocating image"), -1);
|
m_progressCB(getProgressFactor(), _S("Preallocating image"), -1);
|
||||||
++m_progressIdx;
|
++m_progressIdx;
|
||||||
auto ws = m_fileIO->beginWriteStream(0x57058000 - 1);
|
{
|
||||||
if (!ws)
|
auto ws = m_fileIO->beginWriteStream(0);
|
||||||
return EBuildResult::Failed;
|
if (!ws)
|
||||||
ws->write("", 1);
|
return EBuildResult::Failed;
|
||||||
|
char zeroBytes[1024] = {};
|
||||||
|
for (uint64_t i = 0; i < 0x57058000; i += 1024)
|
||||||
|
ws->write(zeroBytes, 1024);
|
||||||
|
}
|
||||||
|
|
||||||
PartitionBuilderGCN& pb = static_cast<PartitionBuilderGCN&>(*m_partitions[0]);
|
PartitionBuilderGCN& pb = static_cast<PartitionBuilderGCN&>(*m_partitions[0]);
|
||||||
return pb.buildFromDirectory(dirIn) ? EBuildResult::Success : EBuildResult::Failed;
|
return pb.buildFromDirectory(dirIn) ? EBuildResult::Success : EBuildResult::Failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t DiscBuilderGCN::CalculateTotalSizeRequired(const SystemChar* dirIn)
|
uint64_t DiscBuilderGCN::CalculateTotalSizeRequired(SystemStringView dirIn)
|
||||||
{
|
{
|
||||||
uint64_t sz = DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeBuild(dirIn, PartitionKind::Data, false);
|
uint64_t sz = DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeBuild(dirIn, PartitionKind::Data, false);
|
||||||
if (sz == -1)
|
if (sz == -1)
|
||||||
@@ -418,18 +422,18 @@ uint64_t DiscBuilderGCN::CalculateTotalSizeRequired(const SystemChar* dirIn)
|
|||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
DiscBuilderGCN::DiscBuilderGCN(const SystemChar* outPath, FProgress progressCB)
|
DiscBuilderGCN::DiscBuilderGCN(SystemStringView outPath, FProgress progressCB)
|
||||||
: DiscBuilderBase(outPath, 0x57058000, progressCB)
|
: DiscBuilderBase(outPath, 0x57058000, progressCB)
|
||||||
{
|
{
|
||||||
PartitionBuilderGCN* partBuilder = new PartitionBuilderGCN(*this);
|
PartitionBuilderGCN* partBuilder = new PartitionBuilderGCN(*this);
|
||||||
m_partitions.emplace_back(partBuilder);
|
m_partitions.emplace_back(partBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
DiscMergerGCN::DiscMergerGCN(const SystemChar* outPath, DiscGCN& sourceDisc, FProgress progressCB)
|
DiscMergerGCN::DiscMergerGCN(SystemStringView outPath, DiscGCN& sourceDisc, FProgress progressCB)
|
||||||
: m_sourceDisc(sourceDisc), m_builder(sourceDisc.makeMergeBuilder(outPath, progressCB))
|
: m_sourceDisc(sourceDisc), m_builder(sourceDisc.makeMergeBuilder(outPath, progressCB))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
EBuildResult DiscMergerGCN::mergeFromDirectory(const SystemChar* dirIn)
|
EBuildResult DiscMergerGCN::mergeFromDirectory(SystemStringView dirIn)
|
||||||
{
|
{
|
||||||
if (!m_builder.getFileIO().beginWriteStream())
|
if (!m_builder.getFileIO().beginWriteStream())
|
||||||
return EBuildResult::Failed;
|
return EBuildResult::Failed;
|
||||||
@@ -440,17 +444,21 @@ EBuildResult DiscMergerGCN::mergeFromDirectory(const SystemChar* dirIn)
|
|||||||
}
|
}
|
||||||
m_builder.m_progressCB(m_builder.getProgressFactor(), _S("Preallocating image"), -1);
|
m_builder.m_progressCB(m_builder.getProgressFactor(), _S("Preallocating image"), -1);
|
||||||
++m_builder.m_progressIdx;
|
++m_builder.m_progressIdx;
|
||||||
auto ws = m_builder.m_fileIO->beginWriteStream(0x57058000 - 1);
|
{
|
||||||
if (!ws)
|
auto ws = m_builder.m_fileIO->beginWriteStream(0);
|
||||||
return EBuildResult::Failed;
|
if (!ws)
|
||||||
ws->write("", 1);
|
return EBuildResult::Failed;
|
||||||
|
char zeroBytes[1024] = {};
|
||||||
|
for (uint64_t i = 0; i < 0x57058000; i += 1024)
|
||||||
|
ws->write(zeroBytes, 1024);
|
||||||
|
}
|
||||||
|
|
||||||
PartitionBuilderGCN& pb = static_cast<PartitionBuilderGCN&>(*m_builder.m_partitions[0]);
|
PartitionBuilderGCN& pb = static_cast<PartitionBuilderGCN&>(*m_builder.m_partitions[0]);
|
||||||
return pb.mergeFromDirectory(static_cast<PartitionGCN*>(m_sourceDisc.getDataPartition()), dirIn) ?
|
return pb.mergeFromDirectory(static_cast<PartitionGCN*>(m_sourceDisc.getDataPartition()), dirIn) ?
|
||||||
EBuildResult::Success : EBuildResult::Failed;
|
EBuildResult::Success : EBuildResult::Failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t DiscMergerGCN::CalculateTotalSizeRequired(DiscGCN& sourceDisc, const SystemChar* dirIn)
|
uint64_t DiscMergerGCN::CalculateTotalSizeRequired(DiscGCN& sourceDisc, SystemStringView dirIn)
|
||||||
{
|
{
|
||||||
uint64_t sz = DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeMerge(
|
uint64_t sz = DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeMerge(
|
||||||
sourceDisc.getDataPartition(), dirIn);
|
sourceDisc.getDataPartition(), dirIn);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class DiscIOISO : public IDiscIO
|
|||||||
{
|
{
|
||||||
std::unique_ptr<IFileIO> m_fio;
|
std::unique_ptr<IFileIO> m_fio;
|
||||||
public:
|
public:
|
||||||
DiscIOISO(const SystemString& fpin)
|
DiscIOISO(SystemStringView fpin)
|
||||||
: m_fio(NewFileIO(fpin)) {}
|
: m_fio(NewFileIO(fpin)) {}
|
||||||
|
|
||||||
class ReadStream : public IReadStream
|
class ReadStream : public IReadStream
|
||||||
@@ -60,7 +60,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<IDiscIO> NewDiscIOISO(const SystemChar* path)
|
std::unique_ptr<IDiscIO> NewDiscIOISO(SystemStringView path)
|
||||||
{
|
{
|
||||||
return std::unique_ptr<IDiscIO>(new DiscIOISO(path));
|
return std::unique_ptr<IDiscIO>(new DiscIOISO(path));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ class DiscIOWBFS : public IDiscIO
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DiscIOWBFS(const SystemString& fpin)
|
DiscIOWBFS(SystemStringView fpin)
|
||||||
: filepath(fpin)
|
: filepath(fpin)
|
||||||
{
|
{
|
||||||
/* Temporary file handle to read LBA table */
|
/* Temporary file handle to read LBA table */
|
||||||
@@ -296,7 +296,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<IDiscIO> NewDiscIOWBFS(const SystemChar* path)
|
std::unique_ptr<IDiscIO> NewDiscIOWBFS(SystemStringView path)
|
||||||
{
|
{
|
||||||
return std::unique_ptr<IDiscIO>(new DiscIOWBFS(path));
|
return std::unique_ptr<IDiscIO>(new DiscIOWBFS(path));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -473,12 +473,13 @@ public:
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool extractCryptoFiles(const SystemString& basePath, const ExtractionContext& ctx) const
|
bool extractCryptoFiles(SystemStringView basePath, const ExtractionContext& ctx) const
|
||||||
{
|
{
|
||||||
Sstat theStat;
|
Sstat theStat;
|
||||||
|
SystemString basePathStr(basePath);
|
||||||
|
|
||||||
/* Extract Ticket */
|
/* Extract Ticket */
|
||||||
SystemString ticketPath = basePath + _S("/ticket.bin");
|
SystemString ticketPath = basePathStr + _S("/ticket.bin");
|
||||||
if (ctx.force || Stat(ticketPath.c_str(), &theStat))
|
if (ctx.force || Stat(ticketPath.c_str(), &theStat))
|
||||||
{
|
{
|
||||||
if (ctx.progressCB)
|
if (ctx.progressCB)
|
||||||
@@ -490,7 +491,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Extract TMD */
|
/* Extract TMD */
|
||||||
SystemString tmdPath = basePath + _S("/tmd.bin");
|
SystemString tmdPath = basePathStr + _S("/tmd.bin");
|
||||||
if (ctx.force || Stat(tmdPath.c_str(), &theStat))
|
if (ctx.force || Stat(tmdPath.c_str(), &theStat))
|
||||||
{
|
{
|
||||||
if (ctx.progressCB)
|
if (ctx.progressCB)
|
||||||
@@ -502,7 +503,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Extract Certs */
|
/* Extract Certs */
|
||||||
SystemString certPath = basePath + _S("/cert.bin");
|
SystemString certPath = basePathStr + _S("/cert.bin");
|
||||||
if (ctx.force || Stat(certPath.c_str(), &theStat))
|
if (ctx.force || Stat(certPath.c_str(), &theStat))
|
||||||
{
|
{
|
||||||
if (ctx.progressCB)
|
if (ctx.progressCB)
|
||||||
@@ -516,7 +517,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Extract H3 */
|
/* Extract H3 */
|
||||||
SystemString h3Path = basePath + _S("/h3.bin");
|
SystemString h3Path = basePathStr + _S("/h3.bin");
|
||||||
if (ctx.force || Stat(h3Path.c_str(), &theStat))
|
if (ctx.force || Stat(h3Path.c_str(), &theStat))
|
||||||
{
|
{
|
||||||
if (ctx.progressCB)
|
if (ctx.progressCB)
|
||||||
@@ -596,23 +597,25 @@ DiscWii::DiscWii(std::unique_ptr<IDiscIO>&& dio, bool& err)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DiscBuilderWii DiscWii::makeMergeBuilder(const SystemChar* outPath, bool dualLayer, FProgress progressCB)
|
DiscBuilderWii DiscWii::makeMergeBuilder(SystemStringView outPath, bool dualLayer, FProgress progressCB)
|
||||||
{
|
{
|
||||||
return DiscBuilderWii(outPath, dualLayer, progressCB);
|
return DiscBuilderWii(outPath, dualLayer, progressCB);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DiscWii::extractDiscHeaderFiles(const SystemString& basePath, const ExtractionContext& ctx) const
|
bool DiscWii::extractDiscHeaderFiles(SystemStringView basePath, const ExtractionContext& ctx) const
|
||||||
{
|
{
|
||||||
if (Mkdir((basePath + _S("/disc")).c_str(), 0755) && errno != EEXIST)
|
SystemString basePathStr(basePath);
|
||||||
|
|
||||||
|
if (Mkdir((basePathStr + _S("/disc")).c_str(), 0755) && errno != EEXIST)
|
||||||
{
|
{
|
||||||
LogModule.report(logvisor::Error, _S("unable to mkdir '%s/disc'"), basePath.c_str());
|
LogModule.report(logvisor::Error, _S("unable to mkdir '%s/disc'"), basePathStr.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sstat theStat;
|
Sstat theStat;
|
||||||
|
|
||||||
/* Extract Header */
|
/* Extract Header */
|
||||||
SystemString headerPath = basePath + _S("/disc/header.bin");
|
SystemString headerPath = basePathStr + _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 +632,7 @@ bool DiscWii::extractDiscHeaderFiles(const SystemString& basePath, const Extract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Extract Region info */
|
/* Extract Region info */
|
||||||
SystemString regionPath = basePath + _S("/disc/region.bin");
|
SystemString regionPath = basePathStr + _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)
|
||||||
@@ -1016,7 +1019,7 @@ public:
|
|||||||
return m_baseOffset + dataOff + groupCount * 0x200000;
|
return m_baseOffset + dataOff + groupCount * 0x200000;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t buildFromDirectory(const SystemChar* dirIn)
|
uint64_t buildFromDirectory(SystemStringView dirIn)
|
||||||
{
|
{
|
||||||
SystemString dirStr(dirIn);
|
SystemString dirStr(dirIn);
|
||||||
SystemString basePath = dirStr + _S("/") + getKindString(m_kind);
|
SystemString basePath = dirStr + _S("/") + getKindString(m_kind);
|
||||||
@@ -1186,7 +1189,7 @@ public:
|
|||||||
}, apploaderStat.st_size);
|
}, apploaderStat.st_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mergeFromDirectory(const PartitionWii* partIn, const SystemChar* dirIn)
|
uint64_t mergeFromDirectory(const PartitionWii* partIn, SystemStringView dirIn)
|
||||||
{
|
{
|
||||||
size_t phSz;
|
size_t phSz;
|
||||||
std::unique_ptr<uint8_t[]> phBuf = partIn->readPartitionHeaderBuf(phSz);
|
std::unique_ptr<uint8_t[]> phBuf = partIn->readPartitionHeaderBuf(phSz);
|
||||||
@@ -1252,10 +1255,10 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
EBuildResult DiscBuilderWii::buildFromDirectory(const SystemChar* dirIn)
|
EBuildResult DiscBuilderWii::buildFromDirectory(SystemStringView dirIn)
|
||||||
{
|
{
|
||||||
SystemString dirStr(dirIn);
|
SystemString dirStr(dirIn);
|
||||||
SystemString basePath = dirStr + _S("/") + getKindString(PartitionKind::Data);
|
SystemString basePath = SystemString(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;
|
||||||
@@ -1269,10 +1272,14 @@ EBuildResult DiscBuilderWii::buildFromDirectory(const SystemChar* dirIn)
|
|||||||
}
|
}
|
||||||
m_progressCB(getProgressFactor(), _S("Preallocating image"), -1);
|
m_progressCB(getProgressFactor(), _S("Preallocating image"), -1);
|
||||||
++m_progressIdx;
|
++m_progressIdx;
|
||||||
std::unique_ptr<IFileIO::IWriteStream> ws = m_fileIO->beginWriteStream(m_discCapacity - 1);
|
{
|
||||||
if (!ws)
|
std::unique_ptr<IFileIO::IWriteStream> ws = m_fileIO->beginWriteStream(0);
|
||||||
return EBuildResult::Failed;
|
if (!ws)
|
||||||
ws->write("", 1);
|
return EBuildResult::Failed;
|
||||||
|
char zeroBytes[1024] = {};
|
||||||
|
for (uint64_t i = 0; i < m_discCapacity; i += 1024)
|
||||||
|
ws->write(zeroBytes, 1024);
|
||||||
|
}
|
||||||
|
|
||||||
/* Assemble image */
|
/* Assemble image */
|
||||||
filledSz = pb.buildFromDirectory(dirIn);
|
filledSz = pb.buildFromDirectory(dirIn);
|
||||||
@@ -1288,7 +1295,7 @@ EBuildResult DiscBuilderWii::buildFromDirectory(const SystemChar* dirIn)
|
|||||||
++m_progressIdx;
|
++m_progressIdx;
|
||||||
|
|
||||||
/* Populate disc header */
|
/* Populate disc header */
|
||||||
ws = m_fileIO->beginWriteStream(0);
|
std::unique_ptr<IFileIO::IWriteStream> ws = m_fileIO->beginWriteStream(0);
|
||||||
if (!ws)
|
if (!ws)
|
||||||
return EBuildResult::Failed;
|
return EBuildResult::Failed;
|
||||||
SystemString headerPath = basePath + _S("/disc/header.bin");
|
SystemString headerPath = basePath + _S("/disc/header.bin");
|
||||||
@@ -1345,7 +1352,7 @@ EBuildResult DiscBuilderWii::buildFromDirectory(const SystemChar* dirIn)
|
|||||||
return EBuildResult::Success;
|
return EBuildResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t DiscBuilderWii::CalculateTotalSizeRequired(const SystemChar* dirIn, bool& dualLayer)
|
uint64_t DiscBuilderWii::CalculateTotalSizeRequired(SystemStringView dirIn, bool& dualLayer)
|
||||||
{
|
{
|
||||||
uint64_t sz = DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeBuild(dirIn, PartitionKind::Data, true);
|
uint64_t sz = DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeBuild(dirIn, PartitionKind::Data, true);
|
||||||
if (sz == -1)
|
if (sz == -1)
|
||||||
@@ -1363,19 +1370,19 @@ uint64_t DiscBuilderWii::CalculateTotalSizeRequired(const SystemChar* dirIn, boo
|
|||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
DiscBuilderWii::DiscBuilderWii(const SystemChar* outPath, bool dualLayer, FProgress progressCB)
|
DiscBuilderWii::DiscBuilderWii(SystemStringView 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, PartitionKind::Data, 0x200000);
|
PartitionBuilderWii* partBuilder = new PartitionBuilderWii(*this, PartitionKind::Data, 0x200000);
|
||||||
m_partitions.emplace_back(partBuilder);
|
m_partitions.emplace_back(partBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
DiscMergerWii::DiscMergerWii(const SystemChar* outPath, DiscWii& sourceDisc,
|
DiscMergerWii::DiscMergerWii(SystemStringView outPath, DiscWii& sourceDisc,
|
||||||
bool dualLayer, FProgress progressCB)
|
bool dualLayer, FProgress progressCB)
|
||||||
: m_sourceDisc(sourceDisc), m_builder(sourceDisc.makeMergeBuilder(outPath, dualLayer, progressCB))
|
: m_sourceDisc(sourceDisc), m_builder(sourceDisc.makeMergeBuilder(outPath, dualLayer, progressCB))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
EBuildResult DiscMergerWii::mergeFromDirectory(const SystemChar* dirIn)
|
EBuildResult DiscMergerWii::mergeFromDirectory(SystemStringView dirIn)
|
||||||
{
|
{
|
||||||
PartitionBuilderWii& pb = static_cast<PartitionBuilderWii&>(*m_builder.m_partitions[0]);
|
PartitionBuilderWii& pb = static_cast<PartitionBuilderWii&>(*m_builder.m_partitions[0]);
|
||||||
uint64_t filledSz = pb.m_baseOffset;
|
uint64_t filledSz = pb.m_baseOffset;
|
||||||
@@ -1389,10 +1396,14 @@ EBuildResult DiscMergerWii::mergeFromDirectory(const SystemChar* dirIn)
|
|||||||
}
|
}
|
||||||
m_builder.m_progressCB(m_builder.getProgressFactor(), _S("Preallocating image"), -1);
|
m_builder.m_progressCB(m_builder.getProgressFactor(), _S("Preallocating image"), -1);
|
||||||
++m_builder.m_progressIdx;
|
++m_builder.m_progressIdx;
|
||||||
std::unique_ptr<IFileIO::IWriteStream> ws = m_builder.m_fileIO->beginWriteStream(m_builder.m_discCapacity - 1);
|
{
|
||||||
if (!ws)
|
std::unique_ptr<IFileIO::IWriteStream> ws = m_builder.m_fileIO->beginWriteStream(0);
|
||||||
return EBuildResult::Failed;
|
if (!ws)
|
||||||
ws->write("", 1);
|
return EBuildResult::Failed;
|
||||||
|
char zeroBytes[1024] = {};
|
||||||
|
for (uint64_t i = 0; i < m_builder.m_discCapacity; i += 1024)
|
||||||
|
ws->write(zeroBytes, 1024);
|
||||||
|
}
|
||||||
|
|
||||||
/* Assemble image */
|
/* Assemble image */
|
||||||
filledSz = pb.mergeFromDirectory(static_cast<PartitionWii*>(m_sourceDisc.getDataPartition()), dirIn);
|
filledSz = pb.mergeFromDirectory(static_cast<PartitionWii*>(m_sourceDisc.getDataPartition()), dirIn);
|
||||||
@@ -1408,7 +1419,7 @@ EBuildResult DiscMergerWii::mergeFromDirectory(const SystemChar* dirIn)
|
|||||||
++m_builder.m_progressIdx;
|
++m_builder.m_progressIdx;
|
||||||
|
|
||||||
/* Populate disc header */
|
/* Populate disc header */
|
||||||
ws = m_builder.m_fileIO->beginWriteStream(0);
|
std::unique_ptr<IFileIO::IWriteStream> ws = m_builder.m_fileIO->beginWriteStream(0);
|
||||||
if (!ws)
|
if (!ws)
|
||||||
return EBuildResult::Failed;
|
return EBuildResult::Failed;
|
||||||
m_sourceDisc.getHeader().write(*ws);
|
m_sourceDisc.getHeader().write(*ws);
|
||||||
@@ -1459,7 +1470,7 @@ EBuildResult DiscMergerWii::mergeFromDirectory(const SystemChar* dirIn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint64_t DiscMergerWii::CalculateTotalSizeRequired(DiscWii& sourceDisc,
|
uint64_t DiscMergerWii::CalculateTotalSizeRequired(DiscWii& sourceDisc,
|
||||||
const SystemChar* dirIn, bool& dualLayer)
|
SystemStringView dirIn, bool& dualLayer)
|
||||||
{
|
{
|
||||||
uint64_t sz = DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeMerge(
|
uint64_t sz = DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeMerge(
|
||||||
sourceDisc.getDataPartition(), dirIn);
|
sourceDisc.getDataPartition(), dirIn);
|
||||||
|
|||||||
@@ -12,9 +12,7 @@ class FileIOFILE : public IFileIO
|
|||||||
SystemString m_path;
|
SystemString m_path;
|
||||||
int64_t m_maxWriteSize;
|
int64_t m_maxWriteSize;
|
||||||
public:
|
public:
|
||||||
FileIOFILE(const SystemString& path, int64_t maxWriteSize)
|
FileIOFILE(SystemStringView path, int64_t maxWriteSize)
|
||||||
: m_path(path), m_maxWriteSize(maxWriteSize) {}
|
|
||||||
FileIOFILE(const SystemChar* path, int64_t maxWriteSize)
|
|
||||||
: m_path(path), m_maxWriteSize(maxWriteSize) {}
|
: m_path(path), m_maxWriteSize(maxWriteSize) {}
|
||||||
|
|
||||||
bool exists()
|
bool exists()
|
||||||
@@ -41,30 +39,30 @@ public:
|
|||||||
{
|
{
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
int64_t m_maxWriteSize;
|
int64_t m_maxWriteSize;
|
||||||
WriteStream(const SystemString& path, int64_t maxWriteSize, bool& err)
|
WriteStream(SystemStringView path, int64_t maxWriteSize, bool& err)
|
||||||
: m_maxWriteSize(maxWriteSize)
|
: m_maxWriteSize(maxWriteSize)
|
||||||
{
|
{
|
||||||
fp = fopen(path.c_str(), "wb");
|
fp = fopen(path.data(), "wb");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
LogModule.report(logvisor::Error, _S("unable to open '%s' for writing"), path.c_str());
|
LogModule.report(logvisor::Error, _S("unable to open '%s' for writing"), path.data());
|
||||||
err = true;
|
err = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WriteStream(const SystemString& path, uint64_t offset, int64_t maxWriteSize, bool& err)
|
WriteStream(SystemStringView path, uint64_t offset, int64_t maxWriteSize, bool& err)
|
||||||
: m_maxWriteSize(maxWriteSize)
|
: m_maxWriteSize(maxWriteSize)
|
||||||
{
|
{
|
||||||
fp = fopen(path.c_str(), "ab");
|
fp = fopen(path.data(), "ab");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
goto FailLoc;
|
goto FailLoc;
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
fp = fopen(path.c_str(), "r+b");
|
fp = fopen(path.data(), "r+b");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
goto FailLoc;
|
goto FailLoc;
|
||||||
FSeek(fp, offset, SEEK_SET);
|
FSeek(fp, offset, SEEK_SET);
|
||||||
return;
|
return;
|
||||||
FailLoc:
|
FailLoc:
|
||||||
LogModule.report(logvisor::Error, _S("unable to open '%s' for writing"), path.c_str());
|
LogModule.report(logvisor::Error, _S("unable to open '%s' for writing"), path.data());
|
||||||
err = true;
|
err = true;
|
||||||
}
|
}
|
||||||
~WriteStream()
|
~WriteStream()
|
||||||
@@ -104,16 +102,16 @@ public:
|
|||||||
struct ReadStream : public IFileIO::IReadStream
|
struct ReadStream : public IFileIO::IReadStream
|
||||||
{
|
{
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
ReadStream(const SystemString& path, bool& err)
|
ReadStream(SystemStringView path, bool& err)
|
||||||
{
|
{
|
||||||
fp = fopen(path.c_str(), "rb");
|
fp = fopen(path.data(), "rb");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
err = true;
|
err = true;
|
||||||
LogModule.report(logvisor::Error, _S("unable to open '%s' for reading"), path.c_str());
|
LogModule.report(logvisor::Error, _S("unable to open '%s' for reading"), path.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ReadStream(const SystemString& path, uint64_t offset, bool& err)
|
ReadStream(SystemStringView path, uint64_t offset, bool& err)
|
||||||
: ReadStream(path, err)
|
: ReadStream(path, err)
|
||||||
{
|
{
|
||||||
if (err)
|
if (err)
|
||||||
@@ -177,12 +175,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<IFileIO> NewFileIO(const SystemString& path, int64_t maxWriteSize)
|
std::unique_ptr<IFileIO> NewFileIO(SystemStringView path, int64_t maxWriteSize)
|
||||||
{
|
|
||||||
return std::unique_ptr<IFileIO>(new FileIOFILE(path, maxWriteSize));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<IFileIO> NewFileIO(const SystemChar* path, int64_t maxWriteSize)
|
|
||||||
{
|
{
|
||||||
return std::unique_ptr<IFileIO>(new FileIOFILE(path, maxWriteSize));
|
return std::unique_ptr<IFileIO>(new FileIOFILE(path, maxWriteSize));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,15 +12,17 @@ class FileIOWin32 : public IFileIO
|
|||||||
SystemString m_path;
|
SystemString m_path;
|
||||||
int64_t m_maxWriteSize;
|
int64_t m_maxWriteSize;
|
||||||
public:
|
public:
|
||||||
FileIOWin32(const SystemString& path, int64_t maxWriteSize)
|
FileIOWin32(SystemStringView path, int64_t maxWriteSize)
|
||||||
: m_path(path), m_maxWriteSize(maxWriteSize) {}
|
|
||||||
FileIOWin32(const SystemChar* path, int64_t maxWriteSize)
|
|
||||||
: m_path(path), m_maxWriteSize(maxWriteSize) {}
|
: m_path(path), m_maxWriteSize(maxWriteSize) {}
|
||||||
|
|
||||||
bool exists()
|
bool exists()
|
||||||
{
|
{
|
||||||
|
#if !WINDOWS_STORE
|
||||||
HANDLE fp = CreateFileW(m_path.c_str(), GENERIC_READ, FILE_SHARE_READ,
|
HANDLE fp = CreateFileW(m_path.c_str(), GENERIC_READ, FILE_SHARE_READ,
|
||||||
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||||
|
#else
|
||||||
|
HANDLE fp = CreateFile2(m_path.c_str(), GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr);
|
||||||
|
#endif
|
||||||
if (fp == INVALID_HANDLE_VALUE)
|
if (fp == INVALID_HANDLE_VALUE)
|
||||||
return false;
|
return false;
|
||||||
CloseHandle(fp);
|
CloseHandle(fp);
|
||||||
@@ -29,8 +31,12 @@ public:
|
|||||||
|
|
||||||
uint64_t size()
|
uint64_t size()
|
||||||
{
|
{
|
||||||
|
#if !WINDOWS_STORE
|
||||||
HANDLE fp = CreateFileW(m_path.c_str(), GENERIC_READ, FILE_SHARE_READ,
|
HANDLE fp = CreateFileW(m_path.c_str(), GENERIC_READ, FILE_SHARE_READ,
|
||||||
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||||
|
#else
|
||||||
|
HANDLE fp = CreateFile2(m_path.c_str(), GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr);
|
||||||
|
#endif
|
||||||
if (fp == INVALID_HANDLE_VALUE)
|
if (fp == INVALID_HANDLE_VALUE)
|
||||||
return 0;
|
return 0;
|
||||||
LARGE_INTEGER sz;
|
LARGE_INTEGER sz;
|
||||||
@@ -47,25 +53,33 @@ public:
|
|||||||
{
|
{
|
||||||
HANDLE fp;
|
HANDLE fp;
|
||||||
int64_t m_maxWriteSize;
|
int64_t m_maxWriteSize;
|
||||||
WriteStream(const SystemString& path, int64_t maxWriteSize, bool& err)
|
WriteStream(SystemStringView path, int64_t maxWriteSize, bool& err)
|
||||||
: m_maxWriteSize(maxWriteSize)
|
: m_maxWriteSize(maxWriteSize)
|
||||||
{
|
{
|
||||||
fp = CreateFileW(path.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE,
|
#if !WINDOWS_STORE
|
||||||
|
fp = CreateFileW(path.data(), GENERIC_WRITE, FILE_SHARE_WRITE,
|
||||||
nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||||
|
#else
|
||||||
|
fp = CreateFile2(path.data(), GENERIC_WRITE, FILE_SHARE_WRITE, CREATE_ALWAYS, nullptr);
|
||||||
|
#endif
|
||||||
if (fp == INVALID_HANDLE_VALUE)
|
if (fp == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
LogModule.report(logvisor::Error, _S("unable to open '%s' for writing"), path.c_str());
|
LogModule.report(logvisor::Error, _S("unable to open '%s' for writing"), path.data());
|
||||||
err = true;
|
err = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WriteStream(const SystemString& path, uint64_t offset, int64_t maxWriteSize, bool& err)
|
WriteStream(SystemStringView path, uint64_t offset, int64_t maxWriteSize, bool& err)
|
||||||
: m_maxWriteSize(maxWriteSize)
|
: m_maxWriteSize(maxWriteSize)
|
||||||
{
|
{
|
||||||
fp = CreateFileW(path.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE,
|
#if !WINDOWS_STORE
|
||||||
|
fp = CreateFileW(path.data(), GENERIC_WRITE, FILE_SHARE_WRITE,
|
||||||
nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||||
|
#else
|
||||||
|
fp = CreateFile2(path.data(), GENERIC_WRITE, FILE_SHARE_WRITE, OPEN_ALWAYS, nullptr);
|
||||||
|
#endif
|
||||||
if (fp == INVALID_HANDLE_VALUE)
|
if (fp == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
LogModule.report(logvisor::Error, _S("unable to open '%s' for writing"), path.c_str());
|
LogModule.report(logvisor::Error, _S("unable to open '%s' for writing"), path.data());
|
||||||
err = true;
|
err = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -116,17 +130,21 @@ public:
|
|||||||
struct ReadStream : public IFileIO::IReadStream
|
struct ReadStream : public IFileIO::IReadStream
|
||||||
{
|
{
|
||||||
HANDLE fp;
|
HANDLE fp;
|
||||||
ReadStream(const SystemString& path, bool& err)
|
ReadStream(SystemStringView path, bool& err)
|
||||||
{
|
{
|
||||||
fp = CreateFileW(path.c_str(), GENERIC_READ, FILE_SHARE_READ,
|
#if !WINDOWS_STORE
|
||||||
|
fp = CreateFileW(path.data(), GENERIC_READ, FILE_SHARE_READ,
|
||||||
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||||
|
#else
|
||||||
|
fp = CreateFile2(path.data(), GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr);
|
||||||
|
#endif
|
||||||
if (fp == INVALID_HANDLE_VALUE)
|
if (fp == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
err = true;
|
err = true;
|
||||||
LogModule.report(logvisor::Error, _S("unable to open '%s' for reading"), path.c_str());
|
LogModule.report(logvisor::Error, _S("unable to open '%s' for reading"), path.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ReadStream(const SystemString& path, uint64_t offset, bool& err)
|
ReadStream(SystemStringView path, uint64_t offset, bool& err)
|
||||||
: ReadStream(path, err)
|
: ReadStream(path, err)
|
||||||
{
|
{
|
||||||
if (err)
|
if (err)
|
||||||
@@ -199,12 +217,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<IFileIO> NewFileIO(const SystemString& path, int64_t maxWriteSize)
|
std::unique_ptr<IFileIO> NewFileIO(SystemStringView path, int64_t maxWriteSize)
|
||||||
{
|
|
||||||
return std::unique_ptr<IFileIO>(new FileIOWin32(path, maxWriteSize));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<IFileIO> NewFileIO(const SystemChar* path, int64_t maxWriteSize)
|
|
||||||
{
|
{
|
||||||
return std::unique_ptr<IFileIO>(new FileIOWin32(path, maxWriteSize));
|
return std::unique_ptr<IFileIO>(new FileIOWin32(path, maxWriteSize));
|
||||||
}
|
}
|
||||||
|
|||||||
14
lib/nod.cpp
14
lib/nod.cpp
@@ -7,16 +7,16 @@ namespace nod
|
|||||||
|
|
||||||
logvisor::Module LogModule("nod");
|
logvisor::Module LogModule("nod");
|
||||||
|
|
||||||
std::unique_ptr<IDiscIO> NewDiscIOISO(const SystemChar* path);
|
std::unique_ptr<IDiscIO> NewDiscIOISO(SystemStringView path);
|
||||||
std::unique_ptr<IDiscIO> NewDiscIOWBFS(const SystemChar* path);
|
std::unique_ptr<IDiscIO> NewDiscIOWBFS(SystemStringView path);
|
||||||
|
|
||||||
std::unique_ptr<DiscBase> OpenDiscFromImage(const SystemChar* path, bool& isWii)
|
std::unique_ptr<DiscBase> OpenDiscFromImage(SystemStringView path, bool& isWii)
|
||||||
{
|
{
|
||||||
/* Temporary file handle to determine image type */
|
/* Temporary file handle to determine image type */
|
||||||
std::unique_ptr<IFileIO> fio = NewFileIO(path);
|
std::unique_ptr<IFileIO> fio = NewFileIO(path);
|
||||||
if (!fio->exists())
|
if (!fio->exists())
|
||||||
{
|
{
|
||||||
LogModule.report(logvisor::Error, _S("Unable to open '%s'"), path);
|
LogModule.report(logvisor::Error, _S("Unable to open '%s'"), path.data());
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
std::unique_ptr<IFileIO::IReadStream> rs = fio->beginReadStream();
|
std::unique_ptr<IFileIO::IReadStream> rs = fio->beginReadStream();
|
||||||
@@ -28,7 +28,7 @@ std::unique_ptr<DiscBase> OpenDiscFromImage(const SystemChar* path, bool& isWii)
|
|||||||
uint32_t magic = 0;
|
uint32_t magic = 0;
|
||||||
if (rs->read(&magic, 4) != 4)
|
if (rs->read(&magic, 4) != 4)
|
||||||
{
|
{
|
||||||
LogModule.report(logvisor::Error, _S("Unable to read magic from '%s'"), path);
|
LogModule.report(logvisor::Error, _S("Unable to read magic from '%s'"), path.data());
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ std::unique_ptr<DiscBase> OpenDiscFromImage(const SystemChar* path, bool& isWii)
|
|||||||
|
|
||||||
if (!discIO)
|
if (!discIO)
|
||||||
{
|
{
|
||||||
LogModule.report(logvisor::Error, _S("'%s' is not a valid image"), path);
|
LogModule.report(logvisor::Error, _S("'%s' is not a valid image"), path.data());
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ std::unique_ptr<DiscBase> OpenDiscFromImage(const SystemChar* path, bool& isWii)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<DiscBase> OpenDiscFromImage(const SystemChar* path)
|
std::unique_ptr<DiscBase> OpenDiscFromImage(SystemStringView path)
|
||||||
{
|
{
|
||||||
bool isWii;
|
bool isWii;
|
||||||
return OpenDiscFromImage(path, isWii);
|
return OpenDiscFromImage(path, isWii);
|
||||||
|
|||||||
2
logvisor
2
logvisor
Submodule logvisor updated: f8ab0e03ba...408ae926d7
Reference in New Issue
Block a user