mirror of
https://github.com/AxioDL/nod.git
synced 2025-07-10 15:16:04 +00:00
Replace logvisor with spdlog
This commit is contained in:
parent
b513a7f4e0
commit
9584303083
@ -59,8 +59,8 @@ endif()
|
|||||||
|
|
||||||
include (CMakePackageConfigHelpers)
|
include (CMakePackageConfigHelpers)
|
||||||
|
|
||||||
if (NOT TARGET logvisor)
|
if(NOT TARGET spdlog)
|
||||||
add_subdirectory(logvisor)
|
find_package(spdlog REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_subdirectory(lib)
|
add_subdirectory(lib)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
add_executable(nodtool main.cpp)
|
add_executable(nodtool main.cpp)
|
||||||
|
|
||||||
target_link_libraries(nodtool nod logvisor)
|
target_link_libraries(nodtool nod spdlog::spdlog)
|
||||||
if (NOT WIN32)
|
if (NOT WIN32)
|
||||||
target_link_libraries(nodtool pthread)
|
target_link_libraries(nodtool pthread)
|
||||||
if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||||
|
@ -8,15 +8,16 @@
|
|||||||
#include <io.h>
|
#include <io.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <logvisor/logvisor.hpp>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
#include <nod/DiscBase.hpp>
|
#include <nod/DiscBase.hpp>
|
||||||
#include <nod/DiscGCN.hpp>
|
#include <nod/DiscGCN.hpp>
|
||||||
#include <nod/DiscWii.hpp>
|
#include <nod/DiscWii.hpp>
|
||||||
#include <nod/nod.hpp>
|
#include <nod/nod.hpp>
|
||||||
|
#include "../lib/Util.hpp"
|
||||||
|
|
||||||
static void printHelp() {
|
static void printHelp() {
|
||||||
fmt::print(stderr, FMT_STRING(
|
fmt::print(stderr,
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
" nodtool extract [options] <image-in> [<dir-out>]\n"
|
" nodtool extract [options] <image-in> [<dir-out>]\n"
|
||||||
" nodtool makegcn [options] <fsroot-in> [<image-out>]\n"
|
" nodtool makegcn [options] <fsroot-in> [<image-out>]\n"
|
||||||
@ -25,7 +26,7 @@ static void printHelp() {
|
|||||||
" nodtool mergewii [options] <fsroot-in> <image-in> [<image-out>]\n"
|
" nodtool mergewii [options] <fsroot-in> <image-in> [<image-out>]\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
" -f Force (extract only)\n"
|
" -f Force (extract only)\n"
|
||||||
" -v Verbose details (extract only).\n"));
|
" -v Verbose details (extract only).\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if _MSC_VER
|
#if _MSC_VER
|
||||||
@ -38,17 +39,13 @@ int main(int argc, char* argv[]) {
|
|||||||
#define PRISize "zu"
|
#define PRISize "zu"
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
#endif
|
#endif
|
||||||
/* Enable logging to console */
|
|
||||||
logvisor::RegisterStandardExceptions();
|
|
||||||
logvisor::RegisterConsoleLogger();
|
|
||||||
|
|
||||||
int argidx = 1;
|
int argidx = 1;
|
||||||
std::string errand;
|
std::string errand;
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
nod::ExtractionContext ctx = {true, [&](std::string_view str, float c) {
|
nod::ExtractionContext ctx = {true, [&](std::string_view str, float c) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
fmt::print(stderr, FMT_STRING("Current node: {}, Extraction {:g}% Complete\n"),
|
fmt::print(stderr, "Current node: {}, Extraction {:g}% Complete\n", str,
|
||||||
str, c * 100.f);
|
c * 100.f);
|
||||||
}};
|
}};
|
||||||
while (argidx < argc) {
|
while (argidx < argc) {
|
||||||
if (!nod::StrCaseCmp(argv[argidx], "-f")) {
|
if (!nod::StrCaseCmp(argv[argidx], "-f")) {
|
||||||
@ -74,11 +71,11 @@ int main(int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto progFunc = [&](float prog, std::string_view name, size_t bytes) {
|
auto progFunc = [&](float prog, std::string_view name, size_t bytes) {
|
||||||
fmt::print(FMT_STRING("\r "));
|
fmt::print("\r ");
|
||||||
if (bytes != SIZE_MAX)
|
if (bytes != SIZE_MAX)
|
||||||
fmt::print(FMT_STRING("\r{:g}% {} {} B"), prog * 100.f, name, bytes);
|
fmt::print("\r{:g}% {} {} B", prog * 100.f, name, bytes);
|
||||||
else
|
else
|
||||||
fmt::print(FMT_STRING("\r{:g}% {}"), prog * 100.f, name);
|
fmt::print("\r{:g}% {}", prog * 100.f, name);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -138,7 +135,7 @@ int main(int argc, char* argv[]) {
|
|||||||
/* Pre-validate path */
|
/* Pre-validate path */
|
||||||
nod::Sstat theStat;
|
nod::Sstat theStat;
|
||||||
if (nod::Stat(fsrootIn.c_str(), &theStat) || !S_ISDIR(theStat.st_mode)) {
|
if (nod::Stat(fsrootIn.c_str(), &theStat) || !S_ISDIR(theStat.st_mode)) {
|
||||||
nod::LogModule.report(logvisor::Error, FMT_STRING("unable to stat {} as directory"), fsrootIn);
|
spdlog::error("unable to stat {} as directory");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +147,7 @@ int main(int argc, char* argv[]) {
|
|||||||
nod::DiscBuilderGCN b(imageOut, progFunc);
|
nod::DiscBuilderGCN b(imageOut, progFunc);
|
||||||
ret = b.buildFromDirectory(fsrootIn);
|
ret = b.buildFromDirectory(fsrootIn);
|
||||||
|
|
||||||
fmt::print(FMT_STRING("\n"));
|
fmt::print("\n");
|
||||||
if (ret != nod::EBuildResult::Success)
|
if (ret != nod::EBuildResult::Success)
|
||||||
return 1;
|
return 1;
|
||||||
} else if (errand == "makewii") {
|
} else if (errand == "makewii") {
|
||||||
@ -176,7 +173,7 @@ int main(int argc, char* argv[]) {
|
|||||||
/* Pre-validate path */
|
/* Pre-validate path */
|
||||||
nod::Sstat theStat;
|
nod::Sstat theStat;
|
||||||
if (nod::Stat(fsrootIn.c_str(), &theStat) || !S_ISDIR(theStat.st_mode)) {
|
if (nod::Stat(fsrootIn.c_str(), &theStat) || !S_ISDIR(theStat.st_mode)) {
|
||||||
nod::LogModule.report(logvisor::Error, FMT_STRING("unable to stat {} as directory"), fsrootIn);
|
spdlog::error("unable to stat {} as directory");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +186,7 @@ int main(int argc, char* argv[]) {
|
|||||||
nod::DiscBuilderWii b(imageOut, dual, progFunc);
|
nod::DiscBuilderWii b(imageOut, dual, progFunc);
|
||||||
ret = b.buildFromDirectory(fsrootIn);
|
ret = b.buildFromDirectory(fsrootIn);
|
||||||
|
|
||||||
fmt::print(FMT_STRING("\n"));
|
fmt::print("\n");
|
||||||
if (ret != nod::EBuildResult::Success)
|
if (ret != nod::EBuildResult::Success)
|
||||||
return 1;
|
return 1;
|
||||||
} else if (errand == "mergegcn") {
|
} else if (errand == "mergegcn") {
|
||||||
@ -220,22 +217,22 @@ int main(int argc, char* argv[]) {
|
|||||||
/* Pre-validate paths */
|
/* Pre-validate paths */
|
||||||
nod::Sstat theStat;
|
nod::Sstat theStat;
|
||||||
if (nod::Stat(fsrootIn.c_str(), &theStat) || !S_ISDIR(theStat.st_mode)) {
|
if (nod::Stat(fsrootIn.c_str(), &theStat) || !S_ISDIR(theStat.st_mode)) {
|
||||||
nod::LogModule.report(logvisor::Error, FMT_STRING("unable to stat {} as directory"), fsrootIn);
|
spdlog::error("unable to stat {} as directory");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (nod::Stat(imageIn.c_str(), &theStat) || !S_ISREG(theStat.st_mode)) {
|
if (nod::Stat(imageIn.c_str(), &theStat) || !S_ISREG(theStat.st_mode)) {
|
||||||
nod::LogModule.report(logvisor::Error, FMT_STRING("unable to stat {} as file"), imageIn);
|
spdlog::error("unable to stat {} as file");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isWii;
|
bool isWii;
|
||||||
std::unique_ptr<nod::DiscBase> disc = nod::OpenDiscFromImage(imageIn, isWii);
|
std::unique_ptr<nod::DiscBase> disc = nod::OpenDiscFromImage(imageIn, isWii);
|
||||||
if (!disc) {
|
if (!disc) {
|
||||||
nod::LogModule.report(logvisor::Error, FMT_STRING("unable to open image {}"), imageIn);
|
spdlog::error("unable to open image {}");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (isWii) {
|
if (isWii) {
|
||||||
nod::LogModule.report(logvisor::Error, FMT_STRING("Wii images should be merged with 'mergewii'"));
|
spdlog::error("Wii images should be merged with 'mergewii'");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +244,7 @@ int main(int argc, char* argv[]) {
|
|||||||
nod::DiscMergerGCN b(imageOut, static_cast<nod::DiscGCN&>(*disc), progFunc);
|
nod::DiscMergerGCN b(imageOut, static_cast<nod::DiscGCN&>(*disc), progFunc);
|
||||||
ret = b.mergeFromDirectory(fsrootIn);
|
ret = b.mergeFromDirectory(fsrootIn);
|
||||||
|
|
||||||
fmt::print(FMT_STRING("\n"));
|
fmt::print("\n");
|
||||||
if (ret != nod::EBuildResult::Success)
|
if (ret != nod::EBuildResult::Success)
|
||||||
return 1;
|
return 1;
|
||||||
} else if (errand == "mergewii") {
|
} else if (errand == "mergewii") {
|
||||||
@ -278,22 +275,22 @@ int main(int argc, char* argv[]) {
|
|||||||
/* Pre-validate paths */
|
/* Pre-validate paths */
|
||||||
nod::Sstat theStat;
|
nod::Sstat theStat;
|
||||||
if (nod::Stat(fsrootIn.c_str(), &theStat) || !S_ISDIR(theStat.st_mode)) {
|
if (nod::Stat(fsrootIn.c_str(), &theStat) || !S_ISDIR(theStat.st_mode)) {
|
||||||
nod::LogModule.report(logvisor::Error, FMT_STRING("unable to stat {} as directory"), fsrootIn);
|
spdlog::error("unable to stat {} as directory");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (nod::Stat(imageIn.c_str(), &theStat) || !S_ISREG(theStat.st_mode)) {
|
if (nod::Stat(imageIn.c_str(), &theStat) || !S_ISREG(theStat.st_mode)) {
|
||||||
nod::LogModule.report(logvisor::Error, FMT_STRING("unable to stat {} as file"), imageIn);
|
spdlog::error("unable to stat {} as file");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isWii;
|
bool isWii;
|
||||||
std::unique_ptr<nod::DiscBase> disc = nod::OpenDiscFromImage(imageIn, isWii);
|
std::unique_ptr<nod::DiscBase> disc = nod::OpenDiscFromImage(imageIn, isWii);
|
||||||
if (!disc) {
|
if (!disc) {
|
||||||
nod::LogModule.report(logvisor::Error, FMT_STRING("unable to open image {}"), argv[3]);
|
spdlog::error("unable to open image {}");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!isWii) {
|
if (!isWii) {
|
||||||
nod::LogModule.report(logvisor::Error, FMT_STRING("GameCube images should be merged with 'mergegcn'"));
|
spdlog::error("GameCube images should be merged with 'mergegcn'");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,7 +303,7 @@ int main(int argc, char* argv[]) {
|
|||||||
nod::DiscMergerWii b(imageOut, static_cast<nod::DiscWii&>(*disc), dual, progFunc);
|
nod::DiscMergerWii b(imageOut, static_cast<nod::DiscWii&>(*disc), dual, progFunc);
|
||||||
ret = b.mergeFromDirectory(fsrootIn);
|
ret = b.mergeFromDirectory(fsrootIn);
|
||||||
|
|
||||||
fmt::print(FMT_STRING("\n"));
|
fmt::print("\n");
|
||||||
if (ret != nod::EBuildResult::Success)
|
if (ret != nod::EBuildResult::Success)
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
@ -314,6 +311,6 @@ int main(int argc, char* argv[]) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
nod::LogModule.report(logvisor::Info, FMT_STRING("Success!"));
|
spdlog::info("Success!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
#include "nod/Util.hpp"
|
#include <string_view>
|
||||||
|
|
||||||
namespace nod {
|
namespace nod {
|
||||||
|
|
||||||
|
@ -4,16 +4,14 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <string_view>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "nod/IDiscIO.hpp"
|
#include "nod/IDiscIO.hpp"
|
||||||
#include "nod/IFileIO.hpp"
|
#include "nod/IFileIO.hpp"
|
||||||
#include "nod/OSUTF.h"
|
#include "nod/OSUTF.h"
|
||||||
#include "nod/Util.hpp"
|
#include "nod/Endian.hpp"
|
||||||
|
|
||||||
namespace nod {
|
namespace nod {
|
||||||
|
|
||||||
|
78
include/nod/Endian.hpp
Normal file
78
include/nod/Endian.hpp
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#undef bswap16
|
||||||
|
#undef bswap32
|
||||||
|
#undef bswap64
|
||||||
|
|
||||||
|
namespace nod {
|
||||||
|
/* Type-sensitive byte swappers */
|
||||||
|
template <typename T>
|
||||||
|
static inline T bswap16(T val) {
|
||||||
|
#if __GNUC__
|
||||||
|
return __builtin_bswap16(val);
|
||||||
|
#elif _WIN32
|
||||||
|
return _byteswap_ushort(val);
|
||||||
|
#else
|
||||||
|
return (val = (val << 8) | ((val >> 8) & 0xFF));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static inline T bswap32(T val) {
|
||||||
|
#if __GNUC__
|
||||||
|
return __builtin_bswap32(val);
|
||||||
|
#elif _WIN32
|
||||||
|
return _byteswap_ulong(val);
|
||||||
|
#else
|
||||||
|
val = (val & 0x0000FFFF) << 16 | (val & 0xFFFF0000) >> 16;
|
||||||
|
val = (val & 0x00FF00FF) << 8 | (val & 0xFF00FF00) >> 8;
|
||||||
|
return val;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static inline T bswap64(T val) {
|
||||||
|
#if __GNUC__
|
||||||
|
return __builtin_bswap64(val);
|
||||||
|
#elif _WIN32
|
||||||
|
return _byteswap_uint64(val);
|
||||||
|
#else
|
||||||
|
return ((val & 0xFF00000000000000ULL) >> 56) | ((val & 0x00FF000000000000ULL) >> 40) |
|
||||||
|
((val & 0x0000FF0000000000ULL) >> 24) | ((val & 0x000000FF00000000ULL) >> 8) |
|
||||||
|
((val & 0x00000000FF000000ULL) << 8) | ((val & 0x0000000000FF0000ULL) << 24) |
|
||||||
|
((val & 0x000000000000FF00ULL) << 40) | ((val & 0x00000000000000FFULL) << 56);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||||
|
static inline int16_t SBig(int16_t val) { return bswap16(val); }
|
||||||
|
static inline uint16_t SBig(uint16_t val) { return bswap16(val); }
|
||||||
|
static inline int32_t SBig(int32_t val) { return bswap32(val); }
|
||||||
|
static inline uint32_t SBig(uint32_t val) { return bswap32(val); }
|
||||||
|
static inline int64_t SBig(int64_t val) { return bswap64(val); }
|
||||||
|
static inline uint64_t SBig(uint64_t val) { return bswap64(val); }
|
||||||
|
|
||||||
|
static inline int16_t SLittle(int16_t val) { return val; }
|
||||||
|
static inline uint16_t SLittle(uint16_t val) { return val; }
|
||||||
|
static inline int32_t SLittle(int32_t val) { return val; }
|
||||||
|
static inline uint32_t SLittle(uint32_t val) { return val; }
|
||||||
|
static inline int64_t SLittle(int64_t val) { return val; }
|
||||||
|
static inline uint64_t SLittle(uint64_t val) { return val; }
|
||||||
|
#else
|
||||||
|
static inline int16_t SLittle(int16_t val) { return bswap16(val); }
|
||||||
|
static inline uint16_t SLittle(uint16_t val) { return bswap16(val); }
|
||||||
|
static inline int32_t SLittle(int32_t val) { return bswap32(val); }
|
||||||
|
static inline uint32_t SLittle(uint32_t val) { return bswap32(val); }
|
||||||
|
static inline int64_t SLittle(int64_t val) { return bswap64(val); }
|
||||||
|
static inline uint64_t SLittle(uint64_t val) { return bswap64(val); }
|
||||||
|
|
||||||
|
static inline int16_t SBig(int16_t val) { return val; }
|
||||||
|
static inline uint16_t SBig(uint16_t val) { return val; }
|
||||||
|
static inline int32_t SBig(int32_t val) { return val; }
|
||||||
|
static inline uint32_t SBig(uint32_t val) { return val; }
|
||||||
|
static inline int64_t SBig(int64_t val) { return val; }
|
||||||
|
static inline uint64_t SBig(uint64_t val) { return val; }
|
||||||
|
#endif
|
||||||
|
} // namespace nod
|
@ -3,11 +3,9 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
#include "nod/IDiscIO.hpp"
|
#include "nod/IDiscIO.hpp"
|
||||||
#include "nod/Util.hpp"
|
|
||||||
|
|
||||||
#include <logvisor/logvisor.hpp>
|
|
||||||
|
|
||||||
namespace nod {
|
namespace nod {
|
||||||
|
|
||||||
@ -18,46 +16,8 @@ public:
|
|||||||
virtual uint64_t size() = 0;
|
virtual uint64_t size() = 0;
|
||||||
|
|
||||||
struct IWriteStream : nod::IWriteStream {
|
struct IWriteStream : nod::IWriteStream {
|
||||||
uint64_t copyFromDisc(IPartReadStream& discio, uint64_t length) {
|
uint64_t copyFromDisc(IPartReadStream& discio, uint64_t length);
|
||||||
uint64_t read = 0;
|
uint64_t copyFromDisc(IPartReadStream& discio, uint64_t length, const std::function<void(float)>& prog);
|
||||||
uint8_t buf[0x7c00];
|
|
||||||
while (length) {
|
|
||||||
uint64_t thisSz = nod::min(uint64_t(0x7c00), length);
|
|
||||||
uint64_t readSz = discio.read(buf, thisSz);
|
|
||||||
if (thisSz != readSz) {
|
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to read enough from disc"));
|
|
||||||
return read;
|
|
||||||
}
|
|
||||||
if (write(buf, readSz) != readSz) {
|
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to write in file"));
|
|
||||||
return read;
|
|
||||||
}
|
|
||||||
length -= thisSz;
|
|
||||||
read += thisSz;
|
|
||||||
}
|
|
||||||
return read;
|
|
||||||
}
|
|
||||||
uint64_t copyFromDisc(IPartReadStream& discio, uint64_t length, const std::function<void(float)>& prog) {
|
|
||||||
uint64_t read = 0;
|
|
||||||
uint8_t buf[0x7c00];
|
|
||||||
uint64_t total = length;
|
|
||||||
while (length) {
|
|
||||||
uint64_t thisSz = nod::min(uint64_t(0x7c00), length);
|
|
||||||
uint64_t readSz = discio.read(buf, thisSz);
|
|
||||||
if (thisSz != readSz) {
|
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to read enough from disc"));
|
|
||||||
return read;
|
|
||||||
}
|
|
||||||
if (write(buf, readSz) != readSz) {
|
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to write in file"));
|
|
||||||
return read;
|
|
||||||
}
|
|
||||||
length -= thisSz;
|
|
||||||
read += thisSz;
|
|
||||||
prog(read / float(total));
|
|
||||||
}
|
|
||||||
return read;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
virtual std::unique_ptr<IWriteStream> beginWriteStream() const = 0;
|
virtual std::unique_ptr<IWriteStream> beginWriteStream() const = 0;
|
||||||
virtual std::unique_ptr<IWriteStream> beginWriteStream(uint64_t offset) const = 0;
|
virtual std::unique_ptr<IWriteStream> beginWriteStream(uint64_t offset) const = 0;
|
||||||
|
@ -2,9 +2,7 @@
|
|||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string_view>
|
||||||
|
|
||||||
#include "nod/Util.hpp"
|
|
||||||
|
|
||||||
namespace nod {
|
namespace nod {
|
||||||
|
|
||||||
|
@ -9,28 +9,30 @@ add_library(nod
|
|||||||
DiscIONFS.cpp
|
DiscIONFS.cpp
|
||||||
DiscIOWBFS.cpp
|
DiscIOWBFS.cpp
|
||||||
DiscWii.cpp
|
DiscWii.cpp
|
||||||
|
IFileIO.cpp
|
||||||
nod.cpp
|
nod.cpp
|
||||||
OSUTF.c
|
OSUTF.c
|
||||||
Util.cpp
|
Util.cpp
|
||||||
|
Util.hpp
|
||||||
|
|
||||||
../include/nod/aes.hpp
|
../include/nod/aes.hpp
|
||||||
../include/nod/DirectoryEnumerator.hpp
|
../include/nod/DirectoryEnumerator.hpp
|
||||||
../include/nod/DiscBase.hpp
|
../include/nod/DiscBase.hpp
|
||||||
../include/nod/DiscGCN.hpp
|
../include/nod/DiscGCN.hpp
|
||||||
../include/nod/DiscWii.hpp
|
../include/nod/DiscWii.hpp
|
||||||
|
../include/nod/Endian.hpp
|
||||||
../include/nod/IDiscIO.hpp
|
../include/nod/IDiscIO.hpp
|
||||||
../include/nod/IFileIO.hpp
|
../include/nod/IFileIO.hpp
|
||||||
../include/nod/nod.hpp
|
../include/nod/nod.hpp
|
||||||
../include/nod/OSUTF.h
|
../include/nod/OSUTF.h
|
||||||
../include/nod/sha1.h
|
../include/nod/sha1.h
|
||||||
../include/nod/Util.hpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(nod PUBLIC
|
target_include_directories(nod PUBLIC
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(nod PUBLIC $<BUILD_INTERFACE:logvisor>)
|
target_link_libraries(nod PUBLIC $<BUILD_INTERFACE:spdlog::spdlog>)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_sources(nod PRIVATE FileIOWin32.cpp)
|
target_sources(nod PRIVATE FileIOWin32.cpp)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "nod/DirectoryEnumerator.hpp"
|
#include "nod/DirectoryEnumerator.hpp"
|
||||||
|
#include "Util.hpp"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#ifndef WIN32_LEAN_AND_MEAN
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
@ -9,13 +9,13 @@
|
|||||||
#include "nod/DirectoryEnumerator.hpp"
|
#include "nod/DirectoryEnumerator.hpp"
|
||||||
#include "nod/IFileIO.hpp"
|
#include "nod/IFileIO.hpp"
|
||||||
#include "nod/nod.hpp"
|
#include "nod/nod.hpp"
|
||||||
#include "nod/Util.hpp"
|
#include "Util.hpp"
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <logvisor/logvisor.hpp>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
static void* memmem(const void* haystack, size_t hlen, const void* needle, size_t nlen) {
|
static void* memmem(const void* haystack, size_t hlen, const void* needle, size_t nlen) {
|
||||||
int needle_first;
|
int needle_first;
|
||||||
@ -40,6 +40,7 @@ static void* memmem(const void* haystack, size_t hlen, const void* needle, size_
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
namespace nod {
|
namespace nod {
|
||||||
|
|
||||||
@ -109,7 +110,7 @@ Node::Node(const IPartition& parent, const FSTNode& node, std::string_view name)
|
|||||||
|
|
||||||
std::unique_ptr<IPartReadStream> Node::beginReadStream(uint64_t offset) const {
|
std::unique_ptr<IPartReadStream> Node::beginReadStream(uint64_t offset) const {
|
||||||
if (m_kind != Kind::File) {
|
if (m_kind != Kind::File) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to stream a non-file {}"), m_name);
|
spdlog::error("unable to stream a non-file {}", m_name);
|
||||||
return std::unique_ptr<IPartReadStream>();
|
return std::unique_ptr<IPartReadStream>();
|
||||||
}
|
}
|
||||||
return m_parent.beginReadStream(m_discOffset + offset);
|
return m_parent.beginReadStream(m_discOffset + offset);
|
||||||
@ -117,7 +118,7 @@ std::unique_ptr<IPartReadStream> Node::beginReadStream(uint64_t offset) const {
|
|||||||
|
|
||||||
std::unique_ptr<uint8_t[]> Node::getBuf() const {
|
std::unique_ptr<uint8_t[]> Node::getBuf() const {
|
||||||
if (m_kind != Kind::File) {
|
if (m_kind != Kind::File) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to buffer a non-file {}"), m_name);
|
spdlog::error("unable to buffer a non-file {}", m_name);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +136,7 @@ bool Node::extractToDirectory(std::string_view basePath, const ExtractionContext
|
|||||||
if (ctx.progressCB && !getName().empty())
|
if (ctx.progressCB && !getName().empty())
|
||||||
ctx.progressCB(nameView.str(), m_parent.m_curNodeIdx / float(m_parent.getNodeCount()));
|
ctx.progressCB(nameView.str(), m_parent.m_curNodeIdx / float(m_parent.getNodeCount()));
|
||||||
if (Mkdir(path.c_str(), 0755) && errno != EEXIST) {
|
if (Mkdir(path.c_str(), 0755) && errno != EEXIST) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to mkdir '{}'"), path);
|
spdlog::error("unable to mkdir '{}'", path);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (Node& subnode : *this)
|
for (Node& subnode : *this)
|
||||||
@ -164,14 +165,14 @@ bool Node::extractToDirectory(std::string_view basePath, const ExtractionContext
|
|||||||
bool IPartition::extractToDirectory(std::string_view path, const ExtractionContext& ctx) {
|
bool IPartition::extractToDirectory(std::string_view path, const ExtractionContext& ctx) {
|
||||||
m_curNodeIdx = 0;
|
m_curNodeIdx = 0;
|
||||||
if (Mkdir(path.data(), 0755) && errno != EEXIST) {
|
if (Mkdir(path.data(), 0755) && errno != EEXIST) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to mkdir '{}'"), path);
|
spdlog::error("unable to mkdir '{}'", path);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string basePath = m_isWii ? std::string(path) + "/" + getKindString(m_kind) : std::string(path);
|
std::string basePath = m_isWii ? std::string(path) + "/" + getKindString(m_kind) : std::string(path);
|
||||||
if (m_isWii) {
|
if (m_isWii) {
|
||||||
if (Mkdir(basePath.c_str(), 0755) && errno != EEXIST) {
|
if (Mkdir(basePath.c_str(), 0755) && errno != EEXIST) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to mkdir '{}'"), basePath);
|
spdlog::error("unable to mkdir '{}'", basePath);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -190,7 +191,7 @@ bool IPartition::extractToDirectory(std::string_view path, const ExtractionConte
|
|||||||
/* Extract Filesystem */
|
/* Extract Filesystem */
|
||||||
std::string fsPath = basePath + "/files";
|
std::string fsPath = basePath + "/files";
|
||||||
if (Mkdir(fsPath.c_str(), 0755) && errno != EEXIST) {
|
if (Mkdir(fsPath.c_str(), 0755) && errno != EEXIST) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to mkdir '{}'"), fsPath);
|
spdlog::error("unable to mkdir '{}'", fsPath);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,7 +201,7 @@ bool IPartition::extractToDirectory(std::string_view path, const ExtractionConte
|
|||||||
bool IPartition::extractSysFiles(std::string_view basePath, const ExtractionContext& ctx) const {
|
bool IPartition::extractSysFiles(std::string_view basePath, const ExtractionContext& ctx) const {
|
||||||
std::string basePathStr(basePath);
|
std::string basePathStr(basePath);
|
||||||
if (Mkdir((basePathStr + "/sys").c_str(), 0755) && errno != EEXIST) {
|
if (Mkdir((basePathStr + "/sys").c_str(), 0755) && errno != EEXIST) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to mkdir '{}/sys'"), basePath);
|
spdlog::error("unable to mkdir '{}/sys'", basePath);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -711,7 +712,7 @@ bool DiscBuilderBase::PartitionBuilderBase::RecursiveCalculateTotalSize(uint64_t
|
|||||||
|
|
||||||
bool DiscBuilderBase::PartitionBuilderBase::buildFromDirectory(IPartWriteStream& ws, std::string_view dirIn) {
|
bool DiscBuilderBase::PartitionBuilderBase::buildFromDirectory(IPartWriteStream& ws, std::string_view dirIn) {
|
||||||
if (dirIn.empty()) {
|
if (dirIn.empty()) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("all arguments must be supplied to buildFromDirectory()"));
|
spdlog::error("all arguments must be supplied to buildFromDirectory()");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -736,7 +737,7 @@ bool DiscBuilderBase::PartitionBuilderBase::buildFromDirectory(IPartWriteStream&
|
|||||||
{
|
{
|
||||||
Sstat dolStat;
|
Sstat dolStat;
|
||||||
if (Stat(dolIn.c_str(), &dolStat)) {
|
if (Stat(dolIn.c_str(), &dolStat)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to stat {}"), dolIn);
|
spdlog::error("unable to stat {}", dolIn);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
size_t fileSz = ROUND_UP_32(dolStat.st_size);
|
size_t fileSz = ROUND_UP_32(dolStat.st_size);
|
||||||
@ -777,7 +778,7 @@ std::optional<uint64_t> DiscBuilderBase::PartitionBuilderBase::CalculateTotalSiz
|
|||||||
|
|
||||||
Sstat dolStat;
|
Sstat dolStat;
|
||||||
if (Stat(dolIn.c_str(), &dolStat)) {
|
if (Stat(dolIn.c_str(), &dolStat)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to stat {}"), dolIn);
|
spdlog::error("unable to stat {}", dolIn);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
uint64_t totalSz = ROUND_UP_32(dolStat.st_size);
|
uint64_t totalSz = ROUND_UP_32(dolStat.st_size);
|
||||||
@ -789,7 +790,7 @@ std::optional<uint64_t> DiscBuilderBase::PartitionBuilderBase::CalculateTotalSiz
|
|||||||
bool DiscBuilderBase::PartitionBuilderBase::mergeFromDirectory(IPartWriteStream& ws, const IPartition* partIn,
|
bool DiscBuilderBase::PartitionBuilderBase::mergeFromDirectory(IPartWriteStream& ws, const IPartition* partIn,
|
||||||
std::string_view dirIn) {
|
std::string_view dirIn) {
|
||||||
if (dirIn.empty()) {
|
if (dirIn.empty()) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("all arguments must be supplied to mergeFromDirectory()"));
|
spdlog::error("all arguments must be supplied to mergeFromDirectory()");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,9 +7,9 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "nod/nod.hpp"
|
#include "nod/nod.hpp"
|
||||||
#include "nod/Util.hpp"
|
#include "Util.hpp"
|
||||||
|
|
||||||
#include <logvisor/logvisor.hpp>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
#define BUFFER_SZ 0x8000
|
#define BUFFER_SZ 0x8000
|
||||||
|
|
||||||
@ -168,7 +168,7 @@ public:
|
|||||||
m_curUser -= reqSz;
|
m_curUser -= reqSz;
|
||||||
m_curUser &= 0xfffffffffffffff0;
|
m_curUser &= 0xfffffffffffffff0;
|
||||||
if (m_curUser < 0x30000) {
|
if (m_curUser < 0x30000) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("user area low mark reached"));
|
spdlog::error("user area low mark reached");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
static_cast<PartWriteStream&>(ws).seek(m_curUser);
|
static_cast<PartWriteStream&>(ws).seek(m_curUser);
|
||||||
@ -211,7 +211,7 @@ public:
|
|||||||
fstSz = ROUND_UP_32(fstSz);
|
fstSz = ROUND_UP_32(fstSz);
|
||||||
|
|
||||||
if (fstOff + fstSz >= m_curUser) {
|
if (fstOff + fstSz >= m_curUser) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("FST flows into user area (one or the other is too big)"));
|
spdlog::error("FST flows into user area (one or the other is too big)");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,7 +240,7 @@ public:
|
|||||||
std::string apploaderIn = dirStr + "/sys/apploader.img";
|
std::string apploaderIn = dirStr + "/sys/apploader.img";
|
||||||
Sstat apploaderStat;
|
Sstat apploaderStat;
|
||||||
if (Stat(apploaderIn.c_str(), &apploaderStat)) {
|
if (Stat(apploaderIn.c_str(), &apploaderStat)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to stat {}"), apploaderIn);
|
spdlog::error("unable to stat {}", apploaderIn);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,7 +248,7 @@ public:
|
|||||||
std::string bootIn = dirStr + "/sys/boot.bin";
|
std::string bootIn = dirStr + "/sys/boot.bin";
|
||||||
Sstat bootStat;
|
Sstat bootStat;
|
||||||
if (Stat(bootIn.c_str(), &bootStat)) {
|
if (Stat(bootIn.c_str(), &bootStat)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to stat {}"), bootIn);
|
spdlog::error("unable to stat {}", bootIn);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,7 +256,7 @@ public:
|
|||||||
std::string bi2In = dirStr + "/sys/bi2.bin";
|
std::string bi2In = dirStr + "/sys/bi2.bin";
|
||||||
Sstat bi2Stat;
|
Sstat bi2Stat;
|
||||||
if (Stat(bi2In.c_str(), &bi2Stat)) {
|
if (Stat(bi2In.c_str(), &bi2Stat)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to stat {}"), bi2In);
|
spdlog::error("unable to stat {}", bi2In);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,7 +298,7 @@ public:
|
|||||||
ws.write(buf, rdSz);
|
ws.write(buf, rdSz);
|
||||||
xferSz += rdSz;
|
xferSz += rdSz;
|
||||||
if (0x2440 + xferSz >= m_curUser) {
|
if (0x2440 + xferSz >= m_curUser) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("apploader flows into user area (one or the other is too big)"));
|
spdlog::error("apploader flows into user area (one or the other is too big)");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_parent.m_progressCB(m_parent.getProgressFactor(), apploaderIn, xferSz);
|
m_parent.m_progressCB(m_parent.getProgressFactor(), apploaderIn, xferSz);
|
||||||
@ -340,7 +340,7 @@ public:
|
|||||||
ws.write(apploaderBuf.get(), apploaderSz);
|
ws.write(apploaderBuf.get(), apploaderSz);
|
||||||
xferSz += apploaderSz;
|
xferSz += apploaderSz;
|
||||||
if (0x2440 + xferSz >= m_curUser) {
|
if (0x2440 + xferSz >= m_curUser) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("apploader flows into user area (one or the other is too big)"));
|
spdlog::error("apploader flows into user area (one or the other is too big)");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_parent.m_progressCB(m_parent.getProgressFactor(), apploaderName, xferSz);
|
m_parent.m_progressCB(m_parent.getProgressFactor(), apploaderName, xferSz);
|
||||||
@ -354,7 +354,7 @@ EBuildResult DiscBuilderGCN::buildFromDirectory(std::string_view dirIn) {
|
|||||||
if (!m_fileIO->beginWriteStream())
|
if (!m_fileIO->beginWriteStream())
|
||||||
return EBuildResult::Failed;
|
return EBuildResult::Failed;
|
||||||
if (!CheckFreeSpace(m_outPath.c_str(), 0x57058000)) {
|
if (!CheckFreeSpace(m_outPath.c_str(), 0x57058000)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("not enough free disk space for {}"), m_outPath);
|
spdlog::error("not enough free disk space for {}", m_outPath);
|
||||||
return EBuildResult::DiskFull;
|
return EBuildResult::DiskFull;
|
||||||
}
|
}
|
||||||
m_progressCB(getProgressFactor(), "Preallocating image", -1);
|
m_progressCB(getProgressFactor(), "Preallocating image", -1);
|
||||||
@ -373,12 +373,13 @@ EBuildResult DiscBuilderGCN::buildFromDirectory(std::string_view dirIn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<uint64_t> DiscBuilderGCN::CalculateTotalSizeRequired(std::string_view dirIn) {
|
std::optional<uint64_t> DiscBuilderGCN::CalculateTotalSizeRequired(std::string_view dirIn) {
|
||||||
std::optional<uint64_t> sz = DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeBuild(dirIn, PartitionKind::Data, false);
|
std::optional<uint64_t> sz =
|
||||||
|
DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeBuild(dirIn, PartitionKind::Data, false);
|
||||||
if (!sz)
|
if (!sz)
|
||||||
return sz;
|
return sz;
|
||||||
*sz += 0x30000;
|
*sz += 0x30000;
|
||||||
if (sz > 0x57058000) {
|
if (sz > 0x57058000) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("disc capacity exceeded [{} / {}]"), *sz, 0x57058000);
|
spdlog::error("disc capacity exceeded [{} / {}]", *sz, 0x57058000);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
return sz;
|
return sz;
|
||||||
@ -396,7 +397,7 @@ EBuildResult DiscMergerGCN::mergeFromDirectory(std::string_view dirIn) {
|
|||||||
if (!m_builder.getFileIO().beginWriteStream())
|
if (!m_builder.getFileIO().beginWriteStream())
|
||||||
return EBuildResult::Failed;
|
return EBuildResult::Failed;
|
||||||
if (!CheckFreeSpace(m_builder.m_outPath.c_str(), 0x57058000)) {
|
if (!CheckFreeSpace(m_builder.m_outPath.c_str(), 0x57058000)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("not enough free disk space for {}"), m_builder.m_outPath);
|
spdlog::error("not enough free disk space for {}", m_builder.m_outPath);
|
||||||
return EBuildResult::DiskFull;
|
return EBuildResult::DiskFull;
|
||||||
}
|
}
|
||||||
m_builder.m_progressCB(m_builder.getProgressFactor(), "Preallocating image", -1);
|
m_builder.m_progressCB(m_builder.getProgressFactor(), "Preallocating image", -1);
|
||||||
@ -417,12 +418,13 @@ EBuildResult DiscMergerGCN::mergeFromDirectory(std::string_view dirIn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<uint64_t> DiscMergerGCN::CalculateTotalSizeRequired(DiscGCN& sourceDisc, std::string_view dirIn) {
|
std::optional<uint64_t> DiscMergerGCN::CalculateTotalSizeRequired(DiscGCN& sourceDisc, std::string_view dirIn) {
|
||||||
std::optional<uint64_t> sz = DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeMerge(sourceDisc.getDataPartition(), dirIn);
|
std::optional<uint64_t> sz =
|
||||||
|
DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeMerge(sourceDisc.getDataPartition(), dirIn);
|
||||||
if (!sz)
|
if (!sz)
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
*sz += 0x30000;
|
*sz += 0x30000;
|
||||||
if (sz > 0x57058000) {
|
if (sz > 0x57058000) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("disc capacity exceeded [{} / {}]"), *sz, 0x57058000);
|
spdlog::error("disc capacity exceeded [{} / {}]", *sz, 0x57058000);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
return sz;
|
return sz;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "nod/IDiscIO.hpp"
|
#include "nod/IDiscIO.hpp"
|
||||||
#include "nod/IFileIO.hpp"
|
#include "nod/IFileIO.hpp"
|
||||||
#include "nod/Util.hpp"
|
|
||||||
|
#include "Util.hpp"
|
||||||
|
|
||||||
namespace nod {
|
namespace nod {
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
#include "nod/IDiscIO.hpp"
|
#include "nod/IDiscIO.hpp"
|
||||||
#include "nod/IFileIO.hpp"
|
#include "nod/IFileIO.hpp"
|
||||||
#include "nod/Util.hpp"
|
|
||||||
#include "nod/aes.hpp"
|
#include "nod/aes.hpp"
|
||||||
|
#include "nod/Endian.hpp"
|
||||||
|
#include "Util.hpp"
|
||||||
|
|
||||||
#include <logvisor/logvisor.hpp>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
namespace nod {
|
namespace nod {
|
||||||
|
|
||||||
@ -69,9 +70,7 @@ public:
|
|||||||
const auto slashPos = SignedSize(fpin.find_last_of("/\\"));
|
const auto slashPos = SignedSize(fpin.find_last_of("/\\"));
|
||||||
if (fpin.size() <= 4 || dotPos == -1 || dotPos <= slashPos || fpin.compare(slashPos + 1, 4, "hif_") ||
|
if (fpin.size() <= 4 || dotPos == -1 || dotPos <= slashPos || fpin.compare(slashPos + 1, 4, "hif_") ||
|
||||||
fpin.compare(dotPos, fpin.size() - dotPos, ".nfs")) {
|
fpin.compare(dotPos, fpin.size() - dotPos, ".nfs")) {
|
||||||
LogModule.report(logvisor::Error,
|
spdlog::error("'{}' must begin with 'hif_' and end with '.nfs' to be accepted as an NFS image", fpin);
|
||||||
FMT_STRING("'{}' must begin with 'hif_' and end with '.nfs' to be accepted as an NFS image"),
|
|
||||||
fpin);
|
|
||||||
err = true;
|
err = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -82,32 +81,32 @@ public:
|
|||||||
if (!keyFile)
|
if (!keyFile)
|
||||||
keyFile = NewFileIO(dir + "htk.bin")->beginReadStream();
|
keyFile = NewFileIO(dir + "htk.bin")->beginReadStream();
|
||||||
if (!keyFile) {
|
if (!keyFile) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("Unable to open '{}../code/htk.bin' or '{}htk.bin'"), dir, dir);
|
spdlog::error("Unable to open '{}../code/htk.bin' or '{}htk.bin'", dir, dir);
|
||||||
err = true;
|
err = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (keyFile->read(key, 16) != 16) {
|
if (keyFile->read(key, 16) != 16) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("Unable to read from '{}../code/htk.bin' or '{}htk.bin'"), dir, dir);
|
spdlog::error("Unable to read from '{}../code/htk.bin' or '{}htk.bin'", dir, dir);
|
||||||
err = true;
|
err = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load header from first file */
|
/* Load header from first file */
|
||||||
const std::string firstPath = fmt::format(FMT_STRING("{}hif_{:06}.nfs"), dir, 0);
|
const std::string firstPath = fmt::format("{}hif_{:06}.nfs", dir, 0);
|
||||||
files.push_back(NewFileIO(firstPath));
|
files.push_back(NewFileIO(firstPath));
|
||||||
auto rs = files.back()->beginReadStream();
|
auto rs = files.back()->beginReadStream();
|
||||||
if (!rs) {
|
if (!rs) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("'{}' does not exist"), firstPath);
|
spdlog::error("'{}' does not exist", firstPath);
|
||||||
err = true;
|
err = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (rs->read(&nfsHead, 0x200) != 0x200) {
|
if (rs->read(&nfsHead, 0x200) != 0x200) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("Unable to read header from '{}'"), firstPath);
|
spdlog::error("Unable to read header from '{}'", firstPath);
|
||||||
err = true;
|
err = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (std::memcmp(&nfsHead.magic, "EGGS", 4)) {
|
if (std::memcmp(&nfsHead.magic, "EGGS", 4)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("Invalid magic in '{}'"), firstPath);
|
spdlog::error("Invalid magic in '{}'", firstPath);
|
||||||
err = true;
|
err = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -122,10 +121,10 @@ public:
|
|||||||
const uint32_t numFiles = calculateNumFiles();
|
const uint32_t numFiles = calculateNumFiles();
|
||||||
files.reserve(numFiles);
|
files.reserve(numFiles);
|
||||||
for (uint32_t i = 1; i < numFiles; ++i) {
|
for (uint32_t i = 1; i < numFiles; ++i) {
|
||||||
std::string path = fmt::format(FMT_STRING("{}hif_{:06}.nfs"), dir, i);
|
std::string path = fmt::format("{}hif_{:06}.nfs", dir, i);
|
||||||
files.push_back(NewFileIO(path));
|
files.push_back(NewFileIO(path));
|
||||||
if (!files.back()->exists()) {
|
if (!files.back()->exists()) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("'{}' does not exist"), path);
|
spdlog::error("'{}' does not exist", path);
|
||||||
err = true;
|
err = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -163,7 +162,7 @@ public:
|
|||||||
|
|
||||||
void setCurFile(uint32_t curFile) {
|
void setCurFile(uint32_t curFile) {
|
||||||
if (curFile >= m_parent.files.size()) {
|
if (curFile >= m_parent.files.size()) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("Out of bounds NFS file access"));
|
spdlog::error("Out of bounds NFS file access");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_curFile = curFile;
|
m_curFile = curFile;
|
||||||
|
@ -5,9 +5,10 @@
|
|||||||
|
|
||||||
#include "nod/IDiscIO.hpp"
|
#include "nod/IDiscIO.hpp"
|
||||||
#include "nod/IFileIO.hpp"
|
#include "nod/IFileIO.hpp"
|
||||||
#include "nod/Util.hpp"
|
#include "nod/Endian.hpp"
|
||||||
|
#include "Util.hpp"
|
||||||
|
|
||||||
#include <logvisor/logvisor.hpp>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
namespace nod {
|
namespace nod {
|
||||||
|
|
||||||
@ -76,7 +77,7 @@ class DiscIOWBFS : public IDiscIO {
|
|||||||
off *= 512ULL;
|
off *= 512ULL;
|
||||||
rs.seek(off, SEEK_SET);
|
rs.seek(off, SEEK_SET);
|
||||||
if (rs.read(buf, count * 512ULL) != count * 512ULL) {
|
if (rs.read(buf, count * 512ULL) != count * 512ULL) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("error reading disc"));
|
spdlog::error("error reading disc");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -92,7 +93,7 @@ public:
|
|||||||
WBFS* p = &wbfs;
|
WBFS* p = &wbfs;
|
||||||
WBFSHead tmpHead;
|
WBFSHead tmpHead;
|
||||||
if (rs->read(&tmpHead, sizeof(tmpHead)) != sizeof(tmpHead)) {
|
if (rs->read(&tmpHead, sizeof(tmpHead)) != sizeof(tmpHead)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to read WBFS head"));
|
spdlog::error("unable to read WBFS head");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unsigned hd_sector_size = 1 << tmpHead.hd_sec_sz_s;
|
unsigned hd_sector_size = 1 << tmpHead.hd_sec_sz_s;
|
||||||
@ -102,7 +103,7 @@ public:
|
|||||||
WBFSHead* head = (WBFSHead*)wbfsHead.get();
|
WBFSHead* head = (WBFSHead*)wbfsHead.get();
|
||||||
rs->seek(0, SEEK_SET);
|
rs->seek(0, SEEK_SET);
|
||||||
if (rs->read(head, hd_sector_size) != hd_sector_size) {
|
if (rs->read(head, hd_sector_size) != hd_sector_size) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to read WBFS head"));
|
spdlog::error("unable to read WBFS head");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,11 +116,11 @@ public:
|
|||||||
if (_wbfsReadSector(*rs, p->part_lba, 1, head))
|
if (_wbfsReadSector(*rs, p->part_lba, 1, head))
|
||||||
return;
|
return;
|
||||||
if (hd_sector_size && head->hd_sec_sz_s != size_to_shift(hd_sector_size)) {
|
if (hd_sector_size && head->hd_sec_sz_s != size_to_shift(hd_sector_size)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("hd sector size doesn't match"));
|
spdlog::error("hd sector size doesn't match");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (num_hd_sector && head->n_hd_sec != SBig(num_hd_sector)) {
|
if (num_hd_sector && head->n_hd_sec != SBig(num_hd_sector)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("hd num sector doesn't match"));
|
spdlog::error("hd num sector doesn't match");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p->hd_sec_sz = 1 << head->hd_sec_sz_s;
|
p->hd_sec_sz = 1 << head->hd_sec_sz_s;
|
||||||
@ -147,7 +148,7 @@ public:
|
|||||||
if (head->disc_table[0]) {
|
if (head->disc_table[0]) {
|
||||||
wbfsDiscInfo.reset(new uint8_t[p->disc_info_sz]);
|
wbfsDiscInfo.reset(new uint8_t[p->disc_info_sz]);
|
||||||
if (!wbfsDiscInfo) {
|
if (!wbfsDiscInfo) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("allocating memory"));
|
spdlog::error("allocating memory");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_wbfsReadSector(*rs, p->part_lba + 1, disc_info_sz_lba, wbfsDiscInfo.get()))
|
if (_wbfsReadSector(*rs, p->part_lba + 1, disc_info_sz_lba, wbfsDiscInfo.get()))
|
||||||
|
@ -9,7 +9,9 @@
|
|||||||
#include "nod/aes.hpp"
|
#include "nod/aes.hpp"
|
||||||
#include "nod/nod.hpp"
|
#include "nod/nod.hpp"
|
||||||
#include "nod/sha1.h"
|
#include "nod/sha1.h"
|
||||||
#include "nod/Util.hpp"
|
#include "Util.hpp"
|
||||||
|
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
namespace nod {
|
namespace nod {
|
||||||
|
|
||||||
@ -421,7 +423,7 @@ public:
|
|||||||
|
|
||||||
uint32_t h3;
|
uint32_t h3;
|
||||||
if (rs->read(&h3, 4) != 4) {
|
if (rs->read(&h3, 4) != 4) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to read H3 offset apploader"));
|
spdlog::error("unable to read H3 offset apploader");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
h3 = SBig(h3);
|
h3 = SBig(h3);
|
||||||
@ -539,7 +541,7 @@ DiscWii::DiscWii(std::unique_ptr<IDiscIO>&& dio, bool& err) : DiscBase(std::move
|
|||||||
kind = part.partType;
|
kind = part.partType;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("invalid partition type {}"), part.partType);
|
spdlog::error("invalid partition type {}", static_cast<uint32_t>(part.partType));
|
||||||
err = true;
|
err = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -557,7 +559,7 @@ bool DiscWii::extractDiscHeaderFiles(std::string_view basePath, const Extraction
|
|||||||
std::string basePathStr(basePath);
|
std::string basePathStr(basePath);
|
||||||
|
|
||||||
if (Mkdir((basePathStr + "/disc").c_str(), 0755) && errno != EEXIST) {
|
if (Mkdir((basePathStr + "/disc").c_str(), 0755) && errno != EEXIST) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to mkdir '{}/disc'"), basePathStr);
|
spdlog::error("unable to mkdir '{}/disc'", basePathStr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -675,7 +677,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_fio->write(m_buf, 0x200000) != 0x200000) {
|
if (m_fio->write(m_buf, 0x200000) != 0x200000) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to write full disc group"));
|
spdlog::error("unable to write full disc group");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -684,7 +686,7 @@ public:
|
|||||||
PartWriteStream(PartitionBuilderWii& parent, uint64_t baseOffset, uint64_t offset, bool& err)
|
PartWriteStream(PartitionBuilderWii& parent, uint64_t baseOffset, uint64_t offset, bool& err)
|
||||||
: m_parent(parent), m_baseOffset(baseOffset), m_offset(offset) {
|
: m_parent(parent), m_baseOffset(baseOffset), m_offset(offset) {
|
||||||
if (offset % 0x1F0000) {
|
if (offset % 0x1F0000) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("partition write stream MUST begin on 0x1F0000-aligned boundary"));
|
spdlog::error("partition write stream MUST begin on 0x1F0000-aligned boundary");
|
||||||
err = true;
|
err = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -754,13 +756,13 @@ public:
|
|||||||
uint64_t userAllocate(uint64_t reqSz, IPartWriteStream& ws) override {
|
uint64_t userAllocate(uint64_t reqSz, IPartWriteStream& ws) override {
|
||||||
reqSz = ROUND_UP_32(reqSz);
|
reqSz = ROUND_UP_32(reqSz);
|
||||||
if (m_curUser + reqSz >= 0x1FB450000) {
|
if (m_curUser + reqSz >= 0x1FB450000) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("partition exceeds maximum single-partition capacity"));
|
spdlog::error("partition exceeds maximum single-partition capacity");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
uint64_t ret = m_curUser;
|
uint64_t ret = m_curUser;
|
||||||
PartWriteStream& cws = static_cast<PartWriteStream&>(ws);
|
PartWriteStream& cws = static_cast<PartWriteStream&>(ws);
|
||||||
if (cws.m_offset > ret) {
|
if (cws.m_offset > ret) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("partition overwrite error"));
|
spdlog::error("partition overwrite error");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
while (cws.m_offset < ret)
|
while (cws.m_offset < ret)
|
||||||
@ -838,7 +840,7 @@ public:
|
|||||||
fstSz = ROUND_UP_32(fstSz);
|
fstSz = ROUND_UP_32(fstSz);
|
||||||
|
|
||||||
if (fstOff + fstSz >= 0x1F0000) {
|
if (fstOff + fstSz >= 0x1F0000) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("FST flows into user area (one or the other is too big)"));
|
spdlog::error("FST flows into user area (one or the other is too big)");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -854,7 +856,7 @@ public:
|
|||||||
|
|
||||||
size_t fstOffRel = fstOff - 0x2440;
|
size_t fstOffRel = fstOff - 0x2440;
|
||||||
if (xferSz > fstOffRel) {
|
if (xferSz > fstOffRel) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("apploader unexpectedly flows into FST"));
|
spdlog::error("apploader unexpectedly flows into FST");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < fstOffRel - xferSz; ++i)
|
for (size_t i = 0; i < fstOffRel - xferSz; ++i)
|
||||||
@ -938,7 +940,7 @@ public:
|
|||||||
std::string ticketIn = basePath + "/ticket.bin";
|
std::string ticketIn = basePath + "/ticket.bin";
|
||||||
Sstat theStat;
|
Sstat theStat;
|
||||||
if (Stat(ticketIn.c_str(), &theStat)) {
|
if (Stat(ticketIn.c_str(), &theStat)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to stat {}"), ticketIn);
|
spdlog::error("unable to stat {}", ticketIn);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -946,7 +948,7 @@ public:
|
|||||||
std::string tmdIn = basePath + "/tmd.bin";
|
std::string tmdIn = basePath + "/tmd.bin";
|
||||||
Sstat tmdStat;
|
Sstat tmdStat;
|
||||||
if (Stat(tmdIn.c_str(), &tmdStat)) {
|
if (Stat(tmdIn.c_str(), &tmdStat)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to stat {}"), tmdIn);
|
spdlog::error("unable to stat {}", tmdIn);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -954,7 +956,7 @@ public:
|
|||||||
std::string certIn = basePath + "/cert.bin";
|
std::string certIn = basePath + "/cert.bin";
|
||||||
Sstat certStat;
|
Sstat certStat;
|
||||||
if (Stat(certIn.c_str(), &certStat)) {
|
if (Stat(certIn.c_str(), &certStat)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to stat {}"), certIn);
|
spdlog::error("unable to stat {}", certIn);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -962,7 +964,7 @@ public:
|
|||||||
std::string apploaderIn = basePath + "/sys/apploader.img";
|
std::string apploaderIn = basePath + "/sys/apploader.img";
|
||||||
Sstat apploaderStat;
|
Sstat apploaderStat;
|
||||||
if (Stat(apploaderIn.c_str(), &apploaderStat)) {
|
if (Stat(apploaderIn.c_str(), &apploaderStat)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to stat {}"), apploaderIn);
|
spdlog::error("unable to stat {}", apploaderIn);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -970,7 +972,7 @@ public:
|
|||||||
std::string bootIn = basePath + "/sys/boot.bin";
|
std::string bootIn = basePath + "/sys/boot.bin";
|
||||||
Sstat bootStat;
|
Sstat bootStat;
|
||||||
if (Stat(bootIn.c_str(), &bootStat)) {
|
if (Stat(bootIn.c_str(), &bootStat)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to stat {}"), bootIn);
|
spdlog::error("unable to stat {}", bootIn);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -978,7 +980,7 @@ public:
|
|||||||
std::string bi2In = basePath + "/sys/bi2.bin";
|
std::string bi2In = basePath + "/sys/bi2.bin";
|
||||||
Sstat bi2Stat;
|
Sstat bi2Stat;
|
||||||
if (Stat(bi2In.c_str(), &bi2Stat)) {
|
if (Stat(bi2In.c_str(), &bi2Stat)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to stat {}"), bi2In);
|
spdlog::error("unable to stat {}", bi2In);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1071,7 +1073,7 @@ public:
|
|||||||
cws.write(buf, rdSz);
|
cws.write(buf, rdSz);
|
||||||
xferSz += rdSz;
|
xferSz += rdSz;
|
||||||
if (0x2440 + xferSz >= 0x1F0000) {
|
if (0x2440 + xferSz >= 0x1F0000) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("apploader flows into user area (one or the other is too big)"));
|
spdlog::error("apploader flows into user area (one or the other is too big)");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_parent.m_progressCB(m_parent.getProgressFactor(), apploaderIn, xferSz);
|
m_parent.m_progressCB(m_parent.getProgressFactor(), apploaderIn, xferSz);
|
||||||
@ -1129,7 +1131,7 @@ public:
|
|||||||
cws.write(apploaderBuf.get(), apploaderSz);
|
cws.write(apploaderBuf.get(), apploaderSz);
|
||||||
xferSz += apploaderSz;
|
xferSz += apploaderSz;
|
||||||
if (0x2440 + xferSz >= 0x1F0000) {
|
if (0x2440 + xferSz >= 0x1F0000) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("apploader flows into user area (one or the other is too big)"));
|
spdlog::error("apploader flows into user area (one or the other is too big)");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_parent.m_progressCB(m_parent.getProgressFactor(), apploaderName, xferSz);
|
m_parent.m_progressCB(m_parent.getProgressFactor(), apploaderName, xferSz);
|
||||||
@ -1153,7 +1155,7 @@ EBuildResult DiscBuilderWii::buildFromDirectory(std::string_view dirIn) {
|
|||||||
return EBuildResult::Failed;
|
return EBuildResult::Failed;
|
||||||
|
|
||||||
if (!CheckFreeSpace(m_outPath.c_str(), m_discCapacity)) {
|
if (!CheckFreeSpace(m_outPath.c_str(), m_discCapacity)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("not enough free disk space for {}"), m_outPath);
|
spdlog::error("not enough free disk space for {}", m_outPath);
|
||||||
return EBuildResult::DiskFull;
|
return EBuildResult::DiskFull;
|
||||||
}
|
}
|
||||||
m_progressCB(getProgressFactor(), "Preallocating image", -1);
|
m_progressCB(getProgressFactor(), "Preallocating image", -1);
|
||||||
@ -1172,7 +1174,7 @@ EBuildResult DiscBuilderWii::buildFromDirectory(std::string_view dirIn) {
|
|||||||
if (filledSz == UINT64_MAX)
|
if (filledSz == UINT64_MAX)
|
||||||
return EBuildResult::Failed;
|
return EBuildResult::Failed;
|
||||||
else if (filledSz >= uint64_t(m_discCapacity)) {
|
else if (filledSz >= uint64_t(m_discCapacity)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("data partition exceeds disc capacity"));
|
spdlog::error("data partition exceeds disc capacity");
|
||||||
return EBuildResult::Failed;
|
return EBuildResult::Failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1246,7 +1248,7 @@ std::optional<uint64_t> DiscBuilderWii::CalculateTotalSizeRequired(std::string_v
|
|||||||
*sz += 0x200000;
|
*sz += 0x200000;
|
||||||
dualLayer = (sz > 0x118240000);
|
dualLayer = (sz > 0x118240000);
|
||||||
if (sz > 0x1FB4E0000) {
|
if (sz > 0x1FB4E0000) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("disc capacity exceeded [{} / {}]"), *sz, 0x1FB4E0000);
|
spdlog::error("disc capacity exceeded [{} / {}]", *sz, 0x1FB4E0000);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
return sz;
|
return sz;
|
||||||
@ -1267,7 +1269,7 @@ EBuildResult DiscMergerWii::mergeFromDirectory(std::string_view dirIn) {
|
|||||||
return EBuildResult::Failed;
|
return EBuildResult::Failed;
|
||||||
|
|
||||||
if (!CheckFreeSpace(m_builder.m_outPath.c_str(), m_builder.m_discCapacity)) {
|
if (!CheckFreeSpace(m_builder.m_outPath.c_str(), m_builder.m_discCapacity)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("not enough free disk space for {}"), m_builder.m_outPath);
|
spdlog::error("not enough free disk space for {}", m_builder.m_outPath);
|
||||||
return EBuildResult::DiskFull;
|
return EBuildResult::DiskFull;
|
||||||
}
|
}
|
||||||
m_builder.m_progressCB(m_builder.getProgressFactor(), "Preallocating image", -1);
|
m_builder.m_progressCB(m_builder.getProgressFactor(), "Preallocating image", -1);
|
||||||
@ -1286,7 +1288,7 @@ EBuildResult DiscMergerWii::mergeFromDirectory(std::string_view dirIn) {
|
|||||||
if (filledSz == UINT64_MAX)
|
if (filledSz == UINT64_MAX)
|
||||||
return EBuildResult::Failed;
|
return EBuildResult::Failed;
|
||||||
else if (filledSz >= uint64_t(m_builder.m_discCapacity)) {
|
else if (filledSz >= uint64_t(m_builder.m_discCapacity)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("data partition exceeds disc capacity"));
|
spdlog::error("data partition exceeds disc capacity");
|
||||||
return EBuildResult::Failed;
|
return EBuildResult::Failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1353,7 +1355,7 @@ std::optional<uint64_t> DiscMergerWii::CalculateTotalSizeRequired(DiscWii& sourc
|
|||||||
*sz += 0x200000;
|
*sz += 0x200000;
|
||||||
dualLayer = (sz > 0x118240000);
|
dualLayer = (sz > 0x118240000);
|
||||||
if (sz > 0x1FB4E0000) {
|
if (sz > 0x1FB4E0000) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("disc capacity exceeded [{} / {}]"), *sz, 0x1FB4E0000);
|
spdlog::error("disc capacity exceeded [{} / {}]", *sz, 0x1FB4E0000);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
return sz;
|
return sz;
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "nod/IFileIO.hpp"
|
#include "nod/IFileIO.hpp"
|
||||||
#include "nod/Util.hpp"
|
#include "Util.hpp"
|
||||||
|
|
||||||
#include <logvisor/logvisor.hpp>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
namespace nod {
|
namespace nod {
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ public:
|
|||||||
WriteStream(std::string_view path, int64_t maxWriteSize, bool& err) : m_maxWriteSize(maxWriteSize) {
|
WriteStream(std::string_view path, int64_t maxWriteSize, bool& err) : m_maxWriteSize(maxWriteSize) {
|
||||||
fp = Fopen(path.data(), "wb");
|
fp = Fopen(path.data(), "wb");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to open '{}' for writing"), path);
|
spdlog::error("unable to open '{}' for writing", path);
|
||||||
err = true;
|
err = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -57,15 +57,14 @@ public:
|
|||||||
FSeek(fp, offset, SEEK_SET);
|
FSeek(fp, offset, SEEK_SET);
|
||||||
return;
|
return;
|
||||||
FailLoc:
|
FailLoc:
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to open '{}' for writing"), path);
|
spdlog::error("unable to open '{}' for writing", path);
|
||||||
err = true;
|
err = true;
|
||||||
}
|
}
|
||||||
~WriteStream() override { fclose(fp); }
|
~WriteStream() override { fclose(fp); }
|
||||||
uint64_t write(const void* buf, uint64_t length) override {
|
uint64_t write(const void* buf, uint64_t length) override {
|
||||||
if (m_maxWriteSize >= 0) {
|
if (m_maxWriteSize >= 0) {
|
||||||
if (FTell(fp) + length > m_maxWriteSize) {
|
if (FTell(fp) + length > m_maxWriteSize) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("write operation exceeds file's {}-byte limit"),
|
spdlog::error("write operation exceeds file's {}-byte limit", m_maxWriteSize);
|
||||||
m_maxWriteSize);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,7 +98,7 @@ public:
|
|||||||
fp = Fopen(path.data(), "rb");
|
fp = Fopen(path.data(), "rb");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
err = true;
|
err = true;
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to open '{}' for reading"), path);
|
spdlog::error("unable to open '{}' for reading", path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ReadStream(std::string_view path, uint64_t offset, bool& err) : ReadStream(path, err) {
|
ReadStream(std::string_view path, uint64_t offset, bool& err) : ReadStream(path, err) {
|
||||||
@ -117,11 +116,11 @@ public:
|
|||||||
while (length) {
|
while (length) {
|
||||||
uint64_t thisSz = nod::min(uint64_t(0x7c00), length);
|
uint64_t thisSz = nod::min(uint64_t(0x7c00), length);
|
||||||
if (read(buf, thisSz) != thisSz) {
|
if (read(buf, thisSz) != thisSz) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to read enough from file"));
|
spdlog::error("unable to read enough from file");
|
||||||
return written;
|
return written;
|
||||||
}
|
}
|
||||||
if (discio.write(buf, thisSz) != thisSz) {
|
if (discio.write(buf, thisSz) != thisSz) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to write enough to disc"));
|
spdlog::error("unable to write enough to disc");
|
||||||
return written;
|
return written;
|
||||||
}
|
}
|
||||||
length -= thisSz;
|
length -= thisSz;
|
||||||
|
@ -10,9 +10,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "nod/IFileIO.hpp"
|
#include "nod/IFileIO.hpp"
|
||||||
#include "nod/Util.hpp"
|
#include "Util.hpp"
|
||||||
|
|
||||||
#include <logvisor/logvisor.hpp>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
#include <nowide/convert.hpp>
|
#include <nowide/convert.hpp>
|
||||||
#include <nowide/stackstring.hpp>
|
#include <nowide/stackstring.hpp>
|
||||||
@ -25,8 +25,7 @@ class FileIOWin32 : public IFileIO {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
FileIOWin32(std::string_view path, int64_t maxWriteSize)
|
FileIOWin32(std::string_view path, int64_t maxWriteSize)
|
||||||
: m_wpath(nowide::widen(path))
|
: m_wpath(nowide::widen(path)), m_maxWriteSize(maxWriteSize) {}
|
||||||
, m_maxWriteSize(maxWriteSize) {}
|
|
||||||
|
|
||||||
bool exists() override {
|
bool exists() override {
|
||||||
#if !WINDOWS_STORE
|
#if !WINDOWS_STORE
|
||||||
@ -71,7 +70,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
if (fp == INVALID_HANDLE_VALUE) {
|
if (fp == INVALID_HANDLE_VALUE) {
|
||||||
const nowide::stackstring path(wpath.data(), wpath.data() + wpath.size());
|
const nowide::stackstring path(wpath.data(), wpath.data() + wpath.size());
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to open '{}' for writing"), path.get());
|
spdlog::error("unable to open '{}' for writing", path.get());
|
||||||
err = true;
|
err = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,7 +84,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
if (fp == INVALID_HANDLE_VALUE) {
|
if (fp == INVALID_HANDLE_VALUE) {
|
||||||
const nowide::stackstring path(wpath.data(), wpath.data() + wpath.size());
|
const nowide::stackstring path(wpath.data(), wpath.data() + wpath.size());
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to open '{}' for writing"), path.get());
|
spdlog::error("unable to open '{}' for writing", path.get());
|
||||||
err = true;
|
err = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -100,8 +99,7 @@ public:
|
|||||||
LARGE_INTEGER res;
|
LARGE_INTEGER res;
|
||||||
SetFilePointerEx(fp, li, &res, FILE_CURRENT);
|
SetFilePointerEx(fp, li, &res, FILE_CURRENT);
|
||||||
if (res.QuadPart + int64_t(length) > m_maxWriteSize) {
|
if (res.QuadPart + int64_t(length) > m_maxWriteSize) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("write operation exceeds file's {}-byte limit"),
|
spdlog::error("write operation exceeds file's {}-byte limit", m_maxWriteSize);
|
||||||
m_maxWriteSize);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -144,7 +142,7 @@ public:
|
|||||||
if (fp == INVALID_HANDLE_VALUE) {
|
if (fp == INVALID_HANDLE_VALUE) {
|
||||||
err = true;
|
err = true;
|
||||||
const nowide::stackstring path(wpath.data(), wpath.data() + wpath.size());
|
const nowide::stackstring path(wpath.data(), wpath.data() + wpath.size());
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to open '{}' for reading"), path.get());
|
spdlog::error("unable to open '{}' for reading", path.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ReadStream(std::wstring_view wpath, uint64_t offset, bool& err) : ReadStream(wpath, err) {
|
ReadStream(std::wstring_view wpath, uint64_t offset, bool& err) : ReadStream(wpath, err) {
|
||||||
@ -177,11 +175,11 @@ public:
|
|||||||
while (length) {
|
while (length) {
|
||||||
uint64_t thisSz = nod::min(uint64_t(0x7c00), length);
|
uint64_t thisSz = nod::min(uint64_t(0x7c00), length);
|
||||||
if (read(buf, thisSz) != thisSz) {
|
if (read(buf, thisSz) != thisSz) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to read enough from file"));
|
spdlog::error("unable to read enough from file");
|
||||||
return written;
|
return written;
|
||||||
}
|
}
|
||||||
if (discio.write(buf, thisSz) != thisSz) {
|
if (discio.write(buf, thisSz) != thisSz) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("unable to write enough to disc"));
|
spdlog::error("unable to write enough to disc");
|
||||||
return written;
|
return written;
|
||||||
}
|
}
|
||||||
length -= thisSz;
|
length -= thisSz;
|
||||||
|
48
lib/IFileIO.cpp
Normal file
48
lib/IFileIO.cpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#include "nod/IFileIO.hpp"
|
||||||
|
#include "Util.hpp"
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
|
namespace nod {
|
||||||
|
uint64_t IFileIO::IWriteStream::copyFromDisc(IPartReadStream& discio, uint64_t length) {
|
||||||
|
uint64_t read = 0;
|
||||||
|
uint8_t buf[0x7c00];
|
||||||
|
while (length) {
|
||||||
|
uint64_t thisSz = nod::min(uint64_t(0x7c00), length);
|
||||||
|
uint64_t readSz = discio.read(buf, thisSz);
|
||||||
|
if (thisSz != readSz) {
|
||||||
|
spdlog::error("unable to read enough from disc");
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
if (write(buf, readSz) != readSz) {
|
||||||
|
spdlog::error("unable to write in file");
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
length -= thisSz;
|
||||||
|
read += thisSz;
|
||||||
|
}
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t IFileIO::IWriteStream::copyFromDisc(IPartReadStream& discio, uint64_t length,
|
||||||
|
const std::function<void(float)>& prog) {
|
||||||
|
uint64_t read = 0;
|
||||||
|
uint8_t buf[0x7c00];
|
||||||
|
uint64_t total = length;
|
||||||
|
while (length) {
|
||||||
|
uint64_t thisSz = nod::min(uint64_t(0x7c00), length);
|
||||||
|
uint64_t readSz = discio.read(buf, thisSz);
|
||||||
|
if (thisSz != readSz) {
|
||||||
|
spdlog::error("unable to read enough from disc");
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
if (write(buf, readSz) != readSz) {
|
||||||
|
spdlog::error("unable to write in file");
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
length -= thisSz;
|
||||||
|
read += thisSz;
|
||||||
|
prog(read / float(total));
|
||||||
|
}
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
} // namespace nod
|
12
lib/Util.cpp
12
lib/Util.cpp
@ -1,4 +1,6 @@
|
|||||||
#include <nod/Util.hpp>
|
#include "Util.hpp"
|
||||||
|
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
#ifndef WIN32_LEAN_AND_MEAN
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
@ -31,7 +33,7 @@ FILE* Fopen(const char* path, const char* mode, FileLockType lock) {
|
|||||||
&ov);
|
&ov);
|
||||||
#else
|
#else
|
||||||
if (flock(fileno(fp), ((lock == FileLockType::Write) ? LOCK_EX : LOCK_SH) | LOCK_NB))
|
if (flock(fileno(fp), ((lock == FileLockType::Write) ? LOCK_EX : LOCK_SH) | LOCK_NB))
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("flock {}: {}"), path, strerror(errno));
|
spdlog::error("flock {}: {}", path, strerror(errno));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,21 +48,21 @@ bool CheckFreeSpace(const char* path, size_t reqSz) {
|
|||||||
wchar_t* end = nullptr;
|
wchar_t* end = nullptr;
|
||||||
DWORD ret = GetFullPathNameW(wpath.get(), 1024, buf.data(), &end);
|
DWORD ret = GetFullPathNameW(wpath.get(), 1024, buf.data(), &end);
|
||||||
if (ret == 0 || ret > 1024) {
|
if (ret == 0 || ret > 1024) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("GetFullPathNameW {}"), path);
|
spdlog::error("GetFullPathNameW {}", path);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (end != nullptr) {
|
if (end != nullptr) {
|
||||||
end[0] = L'\0';
|
end[0] = L'\0';
|
||||||
}
|
}
|
||||||
if (!GetDiskFreeSpaceExW(buf.data(), &freeBytes, nullptr, nullptr)) {
|
if (!GetDiskFreeSpaceExW(buf.data(), &freeBytes, nullptr, nullptr)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("GetDiskFreeSpaceExW {}: {}"), path, GetLastError());
|
spdlog::error("GetDiskFreeSpaceExW {}: {}", path, GetLastError());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return reqSz < freeBytes.QuadPart;
|
return reqSz < freeBytes.QuadPart;
|
||||||
#else
|
#else
|
||||||
struct statvfs svfs;
|
struct statvfs svfs;
|
||||||
if (statvfs(path, &svfs)) {
|
if (statvfs(path, &svfs)) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("statvfs {}: {}"), path, strerror(errno));
|
spdlog::error("statvfs {}: {}", path, strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return reqSz < svfs.f_frsize * svfs.f_bavail;
|
return reqSz < svfs.f_frsize * svfs.f_bavail;
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <logvisor/logvisor.hpp>
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(disable : 4996)
|
#pragma warning(disable : 4996)
|
||||||
|
|
||||||
@ -67,9 +66,6 @@ constexpr auto div(T a, T b) {
|
|||||||
return DivTp{a / b, a % b};
|
return DivTp{a / b, a % b};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Log Module */
|
|
||||||
extern logvisor::Module LogModule;
|
|
||||||
|
|
||||||
/* filesystem char type */
|
/* filesystem char type */
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
static inline int Mkdir(const char* path, int) {
|
static inline int Mkdir(const char* path, int) {
|
||||||
@ -97,78 +93,6 @@ static inline int StrCaseCmp(const char* str1, const char* str2) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef bswap16
|
|
||||||
#undef bswap32
|
|
||||||
#undef bswap64
|
|
||||||
/* Type-sensitive byte swappers */
|
|
||||||
template <typename T>
|
|
||||||
static inline T bswap16(T val) {
|
|
||||||
#if __GNUC__
|
|
||||||
return __builtin_bswap16(val);
|
|
||||||
#elif _WIN32
|
|
||||||
return _byteswap_ushort(val);
|
|
||||||
#else
|
|
||||||
return (val = (val << 8) | ((val >> 8) & 0xFF));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static inline T bswap32(T val) {
|
|
||||||
#if __GNUC__
|
|
||||||
return __builtin_bswap32(val);
|
|
||||||
#elif _WIN32
|
|
||||||
return _byteswap_ulong(val);
|
|
||||||
#else
|
|
||||||
val = (val & 0x0000FFFF) << 16 | (val & 0xFFFF0000) >> 16;
|
|
||||||
val = (val & 0x00FF00FF) << 8 | (val & 0xFF00FF00) >> 8;
|
|
||||||
return val;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static inline T bswap64(T val) {
|
|
||||||
#if __GNUC__
|
|
||||||
return __builtin_bswap64(val);
|
|
||||||
#elif _WIN32
|
|
||||||
return _byteswap_uint64(val);
|
|
||||||
#else
|
|
||||||
return ((val & 0xFF00000000000000ULL) >> 56) | ((val & 0x00FF000000000000ULL) >> 40) |
|
|
||||||
((val & 0x0000FF0000000000ULL) >> 24) | ((val & 0x000000FF00000000ULL) >> 8) |
|
|
||||||
((val & 0x00000000FF000000ULL) << 8) | ((val & 0x0000000000FF0000ULL) << 24) |
|
|
||||||
((val & 0x000000000000FF00ULL) << 40) | ((val & 0x00000000000000FFULL) << 56);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
|
||||||
static inline int16_t SBig(int16_t val) { return bswap16(val); }
|
|
||||||
static inline uint16_t SBig(uint16_t val) { return bswap16(val); }
|
|
||||||
static inline int32_t SBig(int32_t val) { return bswap32(val); }
|
|
||||||
static inline uint32_t SBig(uint32_t val) { return bswap32(val); }
|
|
||||||
static inline int64_t SBig(int64_t val) { return bswap64(val); }
|
|
||||||
static inline uint64_t SBig(uint64_t val) { return bswap64(val); }
|
|
||||||
|
|
||||||
static inline int16_t SLittle(int16_t val) { return val; }
|
|
||||||
static inline uint16_t SLittle(uint16_t val) { return val; }
|
|
||||||
static inline int32_t SLittle(int32_t val) { return val; }
|
|
||||||
static inline uint32_t SLittle(uint32_t val) { return val; }
|
|
||||||
static inline int64_t SLittle(int64_t val) { return val; }
|
|
||||||
static inline uint64_t SLittle(uint64_t val) { return val; }
|
|
||||||
#else
|
|
||||||
static inline int16_t SLittle(int16_t val) { return bswap16(val); }
|
|
||||||
static inline uint16_t SLittle(uint16_t val) { return bswap16(val); }
|
|
||||||
static inline int32_t SLittle(int32_t val) { return bswap32(val); }
|
|
||||||
static inline uint32_t SLittle(uint32_t val) { return bswap32(val); }
|
|
||||||
static inline int64_t SLittle(int64_t val) { return bswap64(val); }
|
|
||||||
static inline uint64_t SLittle(uint64_t val) { return bswap64(val); }
|
|
||||||
|
|
||||||
static inline int16_t SBig(int16_t val) { return val; }
|
|
||||||
static inline uint16_t SBig(uint16_t val) { return val; }
|
|
||||||
static inline int32_t SBig(int32_t val) { return val; }
|
|
||||||
static inline uint32_t SBig(uint32_t val) { return val; }
|
|
||||||
static inline int64_t SBig(int64_t val) { return val; }
|
|
||||||
static inline uint64_t SBig(uint64_t val) { return val; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ROUND_UP_32
|
#ifndef ROUND_UP_32
|
||||||
#define ROUND_UP_32(val) (((val) + 31) & ~31)
|
#define ROUND_UP_32(val) (((val) + 31) & ~31)
|
||||||
#define ROUND_UP_16(val) (((val) + 15) & ~15)
|
#define ROUND_UP_16(val) (((val) + 15) & ~15)
|
11
lib/nod.cpp
11
lib/nod.cpp
@ -6,10 +6,9 @@
|
|||||||
#include "nod/DiscGCN.hpp"
|
#include "nod/DiscGCN.hpp"
|
||||||
#include "nod/DiscWii.hpp"
|
#include "nod/DiscWii.hpp"
|
||||||
|
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
namespace nod {
|
namespace nod {
|
||||||
|
|
||||||
logvisor::Module LogModule("nod");
|
|
||||||
|
|
||||||
std::unique_ptr<IDiscIO> NewDiscIOISO(std::string_view path);
|
std::unique_ptr<IDiscIO> NewDiscIOISO(std::string_view path);
|
||||||
std::unique_ptr<IDiscIO> NewDiscIOWBFS(std::string_view path);
|
std::unique_ptr<IDiscIO> NewDiscIOWBFS(std::string_view path);
|
||||||
std::unique_ptr<IDiscIO> NewDiscIONFS(std::string_view path);
|
std::unique_ptr<IDiscIO> NewDiscIONFS(std::string_view path);
|
||||||
@ -18,7 +17,7 @@ std::unique_ptr<DiscBase> OpenDiscFromImage(std::string_view 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, FMT_STRING("Unable to open '{}'"), path);
|
spdlog::error("Unable to open '{}'", path);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
std::unique_ptr<IFileIO::IReadStream> rs = fio->beginReadStream();
|
std::unique_ptr<IFileIO::IReadStream> rs = fio->beginReadStream();
|
||||||
@ -29,7 +28,7 @@ std::unique_ptr<DiscBase> OpenDiscFromImage(std::string_view path, bool& isWii)
|
|||||||
std::unique_ptr<IDiscIO> discIO;
|
std::unique_ptr<IDiscIO> discIO;
|
||||||
uint32_t magic = 0;
|
uint32_t magic = 0;
|
||||||
if (rs->read(&magic, 4) != 4) {
|
if (rs->read(&magic, 4) != 4) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("Unable to read magic from '{}'"), path);
|
spdlog::error("Unable to read magic from '{}'", path);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +59,7 @@ std::unique_ptr<DiscBase> OpenDiscFromImage(std::string_view path, bool& isWii)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!discIO) {
|
if (!discIO) {
|
||||||
LogModule.report(logvisor::Error, FMT_STRING("'{}' is not a valid image"), path);
|
spdlog::error("'{}' is not a valid image", path);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
logvisor
1
logvisor
@ -1 +0,0 @@
|
|||||||
Subproject commit 208a8c1f84f9968695d712b8e5625c0dc85edbae
|
|
Loading…
x
Reference in New Issue
Block a user