diff --git a/driver/main.cpp b/driver/main.cpp index 6829f8c..c658245 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -77,22 +77,24 @@ int main(int argc, char* argv[]) else if (!strcasecmp(argv[1], _S("makegcn"))) { #if NOD_UCS2 - if (_wcslen(argv[2]) < 6) - NOD::LogModule.report(LogVisor::FatalError, "game-id is not at least 6 characters"); + if (wcslen(argv[2]) < 6) + NOD::LogModule.report(LogVisor::FatalError, _S("game-id is not at least 6 characters")); #else if (strlen(argv[2]) < 6) - NOD::LogModule.report(LogVisor::FatalError, "game-id is not at least 6 characters"); + NOD::LogModule.report(LogVisor::FatalError, _S("game-id is not at least 6 characters")); #endif /* Pre-validate paths */ NOD::Sstat theStat; if (NOD::Stat(argv[4], &theStat) || !S_ISDIR(theStat.st_mode)) - NOD::LogModule.report(LogVisor::FatalError, "unable to stat %s as directory", argv[4]); + NOD::LogModule.report(LogVisor::FatalError, _S("unable to stat %s as directory"), argv[4]); if (NOD::Stat(argv[5], &theStat) || !S_ISREG(theStat.st_mode)) - NOD::LogModule.report(LogVisor::FatalError, "unable to stat %s as file", argv[5]); + NOD::LogModule.report(LogVisor::FatalError, _S("unable to stat %s as file"), argv[5]); if (NOD::Stat(argv[6], &theStat) || !S_ISREG(theStat.st_mode)) NOD::LogModule.report(LogVisor::FatalError, "unable to stat %s as file", argv[6]); + NOD::SystemUTF8View gameId(argv[2]); + NOD::SystemUTF8View gameTitle(argv[3]); size_t lastIdx = -1; auto progFunc = [&](size_t idx, const NOD::SystemString& name, size_t bytes) { @@ -102,9 +104,9 @@ int main(int argc, char* argv[]) printf("\n"); } if (bytes != -1) - printf("\r%s %" PRISize " B", name.c_str(), bytes); + NOD::Printf(_S("\r%s %" PRISize " B"), name.c_str(), bytes); else - printf("\r%s", name.c_str()); + NOD::Printf(_S("\r%s"), name.c_str()); fflush(stdout); }; @@ -112,12 +114,12 @@ int main(int argc, char* argv[]) { NOD::SystemString outPath(argv[4]); outPath.append(_S(".iso")); - NOD::DiscBuilderGCN b(outPath.c_str(), argv[2], argv[3], 0x0003EB60, progFunc); + NOD::DiscBuilderGCN b(outPath.c_str(), gameId.utf8_str().c_str(), gameTitle.utf8_str().c_str(), 0x0003EB60, progFunc); b.buildFromDirectory(argv[4], argv[5], argv[6]); } else { - NOD::DiscBuilderGCN b(argv[7], argv[2], argv[3], 0x0003EB60, progFunc); + NOD::DiscBuilderGCN b(argv[7], gameId.utf8_str().c_str(), gameTitle.utf8_str().c_str(), 0x0003EB60, progFunc); b.buildFromDirectory(argv[4], argv[5], argv[6]); } @@ -126,24 +128,26 @@ int main(int argc, char* argv[]) else if (!strcasecmp(argv[1], _S("makewiisl")) || !strcasecmp(argv[1], _S("makewiidl"))) { #if NOD_UCS2 - if (_wcslen(argv[2]) < 6) - NOD::LogModule.report(LogVisor::FatalError, "game-id is not at least 6 characters"); + if (wcslen(argv[2]) < 6) + NOD::LogModule.report(LogVisor::FatalError, _S("game-id is not at least 6 characters")); #else if (strlen(argv[2]) < 6) - NOD::LogModule.report(LogVisor::FatalError, "game-id is not at least 6 characters"); + NOD::LogModule.report(LogVisor::FatalError, _S("game-id is not at least 6 characters")); #endif /* Pre-validate paths */ NOD::Sstat theStat; if (NOD::Stat(argv[4], &theStat) || !S_ISDIR(theStat.st_mode)) - NOD::LogModule.report(LogVisor::FatalError, "unable to stat %s as directory", argv[4]); + NOD::LogModule.report(LogVisor::FatalError, _S("unable to stat %s as directory"), argv[4]); if (NOD::Stat(argv[5], &theStat) || !S_ISREG(theStat.st_mode)) - NOD::LogModule.report(LogVisor::FatalError, "unable to stat %s as file", argv[5]); + NOD::LogModule.report(LogVisor::FatalError, _S("unable to stat %s as file"), argv[5]); if (NOD::Stat(argv[6], &theStat) || !S_ISREG(theStat.st_mode)) - NOD::LogModule.report(LogVisor::FatalError, "unable to stat %s as file", argv[6]); + NOD::LogModule.report(LogVisor::FatalError, _S("unable to stat %s as file"), argv[6]); if (NOD::Stat(argv[7], &theStat) || !S_ISREG(theStat.st_mode)) - NOD::LogModule.report(LogVisor::FatalError, "unable to stat %s as file", argv[7]); + NOD::LogModule.report(LogVisor::FatalError, _S("unable to stat %s as file"), argv[7]); + NOD::SystemUTF8View gameId(argv[2]); + NOD::SystemUTF8View gameTitle(argv[3]); size_t lastIdx = -1; auto progFunc = [&](size_t idx, const NOD::SystemString& name, size_t bytes) { @@ -153,9 +157,9 @@ int main(int argc, char* argv[]) printf("\n"); } if (bytes != -1) - printf("\r%s %" PRISize " B", name.c_str(), bytes); + NOD::Printf(_S("\r%s %" PRISize " B"), name.c_str(), bytes); else - printf("\r%s", name.c_str()); + NOD::Printf(_S("\r%s"), name.c_str()); fflush(stdout); }; @@ -165,12 +169,12 @@ int main(int argc, char* argv[]) { NOD::SystemString outPath(argv[4]); outPath.append(_S(".iso")); - NOD::DiscBuilderWii b(outPath.c_str(), argv[2], argv[3], dual, progFunc); + NOD::DiscBuilderWii b(outPath.c_str(), gameId.utf8_str().c_str(), gameTitle.utf8_str().c_str(), dual, progFunc); b.buildFromDirectory(argv[4], argv[5], argv[6], argv[7]); } else { - NOD::DiscBuilderWii b(argv[8], argv[2], argv[3], dual, progFunc); + NOD::DiscBuilderWii b(argv[8], gameId.utf8_str().c_str(), gameTitle.utf8_str().c_str(), dual, progFunc); b.buildFromDirectory(argv[4], argv[5], argv[6], argv[7]); } diff --git a/include/NOD/DiscBase.hpp b/include/NOD/DiscBase.hpp index c36eac3..1dafece 100644 --- a/include/NOD/DiscBase.hpp +++ b/include/NOD/DiscBase.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "Util.hpp" #include "IDiscIO.hpp" #include "IFileIO.hpp" diff --git a/include/NOD/Util.hpp b/include/NOD/Util.hpp index 4c69bb5..ffd5f0a 100644 --- a/include/NOD/Util.hpp +++ b/include/NOD/Util.hpp @@ -23,11 +23,37 @@ #include #include +#include #include #include +#ifdef _MSC_VER +#pragma warning(disable : 4996) + +#include + +#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG) +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#endif + +#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR) +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#endif + +#if !defined(S_ISLNK) +#define S_ISLNK(m) 0 +#endif +#endif + +#undef min +#undef max namespace NOD { +/* define our own min/max to avoid MSVC BS */ +template +inline T min(T a, T b) { return a < b ? a : b; } +template +inline T max(T a, T b) { return a > b ? a : b; } /* Log Module */ extern LogVisor::LogModule LogModule; @@ -52,7 +78,7 @@ static inline void ToLower(SystemString& str) {std::transform(str.begin(), str.end(), str.begin(), towlower);} static inline void ToUpper(SystemString& str) {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 { std::string m_utf8; @@ -111,7 +137,7 @@ public: static inline void Unlink(const SystemChar* file) { -#if _WIN32 +#if NOD_UCS2 _wunlink(file); #else unlink(file); @@ -120,8 +146,8 @@ static inline void Unlink(const SystemChar* file) static inline int StrCmp(const SystemChar* str1, const SystemChar* str2) { -#if HECL_UCS2 - return _wcscmp(str1, str2); +#if NOD_UCS2 + return wcscmp(str1, str2); #else return strcmp(str1, str2); #endif @@ -129,7 +155,7 @@ static inline int StrCmp(const SystemChar* str1, const SystemChar* str2) static inline int StrCaseCmp(const SystemChar* str1, const SystemChar* str2) { -#if HECL_UCS2 +#if NOD_UCS2 return _wcsicmp(str1, str2); #else return strcasecmp(str1, str2); @@ -279,6 +305,21 @@ static inline bool CheckFreeSpace(const SystemChar* path, size_t reqSz) #endif } +#if __GNUC__ +__attribute__((__format__ (__printf__, 1, 2))) +#endif +static inline void Printf(const SystemChar* fmt, ...) +{ + va_list args; + va_start(args, fmt); +#if NOD_UCS2 + vwprintf(fmt, args); +#else + vprintf(fmt, args); +#endif + va_end(args); +} + } #endif // __NOD_UTIL_HPP__ diff --git a/lib/DirectoryEnumerator.cpp b/lib/DirectoryEnumerator.cpp index df087a2..7ad4aaa 100644 --- a/lib/DirectoryEnumerator.cpp +++ b/lib/DirectoryEnumerator.cpp @@ -1,4 +1,4 @@ -#ifdef WIN32 +#ifdef _WIN32 #include #else #include diff --git a/lib/DiscBase.cpp b/lib/DiscBase.cpp index bcdc304..2630537 100644 --- a/lib/DiscBase.cpp +++ b/lib/DiscBase.cpp @@ -5,6 +5,7 @@ #include #include + #ifndef _WIN32 #include #endif @@ -145,9 +146,14 @@ static uint64_t GetInode(const SystemChar* path) { uint64_t inode; #if _WIN32 - OFSTRUCT ofs; - HFILE fp = OpenFile(path, &ofs, OF_READ); - if (fp == HFILE_ERROR) + 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::FatalError, _S("unable to open %s"), path); BY_HANDLE_FILE_INFORMATION info; if (!GetFileInformationByHandle(fp, &info)) @@ -170,22 +176,22 @@ static bool IsSystemFile(const SystemString& name, bool& isDol) if (name.size() < 4) return false; - if (!StrCaseCmp((&*name.cend()) - 4, _S(".dol"))) + if (!StrCaseCmp((&*(name.cend() - 4)), _S(".dol"))) { isDol = true; return true; } - if (!StrCaseCmp((&*name.cend()) - 4, _S(".rel"))) + if (!StrCaseCmp((&*(name.cend() - 4)), _S(".rel"))) return true; - if (!StrCaseCmp((&*name.cend()) - 4, _S(".rso"))) + if (!StrCaseCmp((&*(name.cend() - 4)), _S(".rso"))) return true; - if (!StrCaseCmp((&*name.cend()) - 4, _S(".sel"))) + if (!StrCaseCmp((&*(name.cend() - 4)), _S(".sel"))) return true; - if (!StrCaseCmp((&*name.cend()) - 4, _S(".bnr"))) + if (!StrCaseCmp((&*(name.cend() - 4)), _S(".bnr"))) return true; - if (!StrCaseCmp((&*name.cend()) - 4, _S(".elf"))) + if (!StrCaseCmp((&*(name.cend() - 4)), _S(".elf"))) return true; - if (!StrCaseCmp((&*name.cend()) - 4, _S(".wad"))) + if (!StrCaseCmp((&*(name.cend() - 4)), _S(".wad"))) return true; return false; @@ -243,7 +249,7 @@ void DiscBuilderBase::PartitionBuilderBase::recursiveBuildNodes(IPartWriteStream ++m_parent.m_progressIdx; while (xferSz < e.m_fileSz) { - size_t rdSz = rs->read(buf, std::min(0x8000ul, e.m_fileSz - xferSz)); + size_t rdSz = rs->read(buf, NOD::min(size_t(0x8000ul), e.m_fileSz - xferSz)); if (!rdSz) break; ws.write(buf, rdSz); @@ -295,11 +301,11 @@ bool DiscBuilderBase::PartitionBuilderBase::buildFromDirectory(IPartWriteStream& const SystemChar* apploaderIn) { if (!dirIn || !dolIn || !apploaderIn) - LogModule.report(LogVisor::FatalError, "all arguments must be supplied to buildFromDirectory()"); + LogModule.report(LogVisor::FatalError, _S("all arguments must be supplied to buildFromDirectory()")); /* Clear file */ ++m_parent.m_progressIdx; - m_parent.m_progressCB(m_parent.m_progressIdx, "Preparing output image", -1); + m_parent.m_progressCB(m_parent.m_progressIdx, _S("Preparing output image"), -1); /* Add root node */ m_buildNodes.emplace_back(true, m_buildNameOff, 0, 1); @@ -314,9 +320,30 @@ bool DiscBuilderBase::PartitionBuilderBase::buildFromDirectory(IPartWriteStream& uint64_t fileOff = userAllocate(fileSz, ws); m_dolOffset = fileOff; m_dolSize = fileSz; +<<<<<<< HEAD std::unique_ptr rs = NewFileIO(dolIn)->beginReadStream(); size_t xferSz = PatchDOL(*rs, ws, dolStat.st_size); m_parent.m_progressCB(++m_parent.m_progressIdx, SystemString(dolIn) + _S(" [PATCHED]"), xferSz); +======= + std::unique_ptr ws = m_parent.getFileIO().beginWriteStream(fileOff); + FILE* fp = Fopen(dolIn, _S("rb"), FileLockType::Read); + if (!fp) + LogModule.report(LogVisor::FatalError, _S("unable to open '%s' for reading"), dolIn); + char buf[8192]; + size_t xferSz = 0; + SystemString dolName(dolIn); + ++m_parent.m_progressIdx; + while (xferSz < dolStat.st_size) + { + size_t rdSz = fread(buf, 1, NOD::min(size_t(8192), dolStat.st_size - xferSz), fp); + if (!rdSz) + break; + ws->write(buf, rdSz); + xferSz += rdSz; + m_parent.m_progressCB(m_parent.m_progressIdx, dolName, xferSz); + } + fclose(fp); +>>>>>>> 1c740a3da8495cfaebb7dc648602b9273c097a74 for (size_t i=0 ; i rs = m_parent.getDiscIO().beginReadStream(m_offset); while (rem) { - size_t rdSz = std::min(rem, 8192ul); + size_t rdSz = NOD::min(rem, size_t(8192ul)); rs->read(buf, rdSz); fwrite(buf, 1, rdSz, fp); rem -= rdSz; @@ -876,7 +876,7 @@ bool DiscBuilderWii::buildFromDirectory(const SystemChar* dirIn, const SystemCha } ++m_progressIdx; - m_progressCB(m_progressIdx, "Finishing Disc", -1); + m_progressCB(m_progressIdx, _S("Finishing Disc"), -1); /* Populate disc header */ std::unique_ptr ws = m_fileIO->beginWriteStream(0); diff --git a/lib/sha1.c b/lib/sha1.c index 126ac4c..093a8c8 100644 --- a/lib/sha1.c +++ b/lib/sha1.c @@ -16,7 +16,9 @@ # define SHA_BIG_ENDIAN # endif #else // ! defined __LITTLE_ENDIAN__ +#ifndef _WIN32 # include // machine/endian.h +#endif # if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ # define SHA_BIG_ENDIAN # endif