From df5e8d068c07b798ca514892730d043d14f7ee07 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sun, 24 Jan 2016 19:55:31 -1000 Subject: [PATCH] Removed direct stdio usage --- include/NOD/IDiscIO.hpp | 2 +- include/NOD/IFileIO.hpp | 2 + include/NOD/Util.hpp | 13 +++- lib/DiscGCN.cpp | 9 +-- lib/DiscIOISO.cpp | 99 +++++++++++++++++++++----- lib/DiscIOWBFS.cpp | 78 +++++---------------- lib/DiscWii.cpp | 24 ++++--- lib/FileIOFILE.cpp | 151 +++++++++++++++++++++++++++++++++------- lib/NOD.cpp | 32 +++------ 9 files changed, 267 insertions(+), 143 deletions(-) diff --git a/include/NOD/IDiscIO.hpp b/include/NOD/IDiscIO.hpp index 0322ae3..d82ff1f 100644 --- a/include/NOD/IDiscIO.hpp +++ b/include/NOD/IDiscIO.hpp @@ -31,7 +31,7 @@ public: struct IWriteStream { virtual ~IWriteStream() {} - virtual uint64_t write(void* buf, uint64_t length)=0; + virtual uint64_t write(const void* buf, uint64_t length)=0; }; virtual std::unique_ptr beginWriteStream(uint64_t offset=0) const=0; }; diff --git a/include/NOD/IFileIO.hpp b/include/NOD/IFileIO.hpp index b57bfdd..fe4efdc 100644 --- a/include/NOD/IFileIO.hpp +++ b/include/NOD/IFileIO.hpp @@ -13,6 +13,7 @@ class IFileIO { public: virtual ~IFileIO() {} + virtual bool exists()=0; virtual uint64_t size()=0; struct IWriteStream @@ -27,6 +28,7 @@ public: struct IReadStream { virtual ~IReadStream() {} + virtual void seek(int64_t offset, int whence)=0; virtual uint64_t read(void* buf, uint64_t length)=0; virtual uint64_t copyToDisc(struct IPartWriteStream& discio, uint64_t length)=0; }; diff --git a/include/NOD/Util.hpp b/include/NOD/Util.hpp index 2192796..2a42084 100644 --- a/include/NOD/Util.hpp +++ b/include/NOD/Util.hpp @@ -294,9 +294,16 @@ static inline bool CheckFreeSpace(const SystemChar* path, size_t reqSz) { #if _WIN32 ULARGE_INTEGER freeBytes; - if (!GetDiskFreeSpaceExW(path, &freeBytes, nullptr, nullptr)) - LogModule.report(LogVisor::FatalError, "GetDiskFreeSpaceExW %s: %d", path, GetLastError()); - return reqSz < freeBytes; + wchar_t buf[1024]; + wchar_t* end; + DWORD ret = GetFullPathNameW(path, 1024, buf, &end); + if (!ret || ret > 1024) + LogModule.report(LogVisor::FatalError, _S("GetFullPathNameW %s"), path); + if (end) + end[0] = L'\0'; + if (!GetDiskFreeSpaceExW(buf, &freeBytes, nullptr, nullptr)) + LogModule.report(LogVisor::FatalError, _S("GetDiskFreeSpaceExW %s: %d"), path, GetLastError()); + return reqSz < freeBytes.QuadPart; #else struct statvfs svfs; if (statvfs(path, &svfs)) diff --git a/lib/DiscGCN.cpp b/lib/DiscGCN.cpp index 90c3001..0a319c6 100644 --- a/lib/DiscGCN.cpp +++ b/lib/DiscGCN.cpp @@ -181,16 +181,14 @@ public: header.write(*ws); ws = beginWriteStream(0x2440); - FILE* fp = Fopen(apploaderIn, _S("rb"), FileLockType::Read); - if (!fp) - LogModule.report(LogVisor::FatalError, _S("unable to open %s for reading"), apploaderIn); + std::unique_ptr rs = NewFileIO(apploaderIn)->beginReadStream(); char buf[8192]; size_t xferSz = 0; SystemString apploaderName(apploaderIn); ++m_parent.m_progressIdx; while (true) { - size_t rdSz = fread(buf, 1, 8192, fp); + size_t rdSz = rs->read(buf, 8192); if (!rdSz) break; ws->write(buf, rdSz); @@ -200,7 +198,6 @@ public: "apploader flows into user area (one or the other is too big)"); m_parent.m_progressCB(m_parent.m_progressIdx, apploaderName, xferSz); } - fclose(fp); size_t fstOff = ROUND_UP_32(xferSz); size_t fstSz = sizeof(FSTNode) * m_buildNodes.size(); @@ -234,7 +231,7 @@ public: bool DiscBuilderGCN::buildFromDirectory(const SystemChar* dirIn, const SystemChar* dolIn, const SystemChar* apploaderIn) -{ +{ m_fileIO->beginWriteStream(); if (!CheckFreeSpace(m_outPath, 0x57058000)) diff --git a/lib/DiscIOISO.cpp b/lib/DiscIOISO.cpp index 59e7e0f..5cb6f5d 100644 --- a/lib/DiscIOISO.cpp +++ b/lib/DiscIOISO.cpp @@ -2,11 +2,6 @@ #include "NOD/Util.hpp" #include "NOD/IDiscIO.hpp" -#if _WIN32 -#define ftello _ftelli64 -#define fseeko _fseeki64 -#endif - namespace NOD { @@ -20,60 +15,132 @@ public: class ReadStream : public IReadStream { friend class DiscIOISO; +#if _WIN32 + HANDLE fp; + ReadStream(HANDLE fpin) + : fp(fpin) {} + ~ReadStream() {CloseHandle(fp);} +#else FILE* fp; ReadStream(FILE* fpin) : fp(fpin) {} ~ReadStream() {fclose(fp);} +#endif public: +#if _WIN32 + uint64_t read(void* buf, uint64_t length) + { + DWORD ret = 0; + ReadFile(fp, buf, length, &ret, nullptr); + return ret; + } + uint64_t position() const + { + LARGE_INTEGER liOfs={0}; + LARGE_INTEGER liNew={0}; + SetFilePointerEx(fp, liOfs, &liNew, FILE_CURRENT); + return liNew.QuadPart; + } + void seek(int64_t offset, int whence) + { + LARGE_INTEGER li; + li.QuadPart = offset; + SetFilePointerEx(fp, li, nullptr, whence); + } +#else uint64_t read(void* buf, uint64_t length) {return fread(buf, 1, length, fp);} uint64_t position() const {return ftello(fp);} void seek(int64_t offset, int whence) - {fseeko(fp, offset, whence);} + {FSeek(fp, offset, whence);} +#endif }; + +#if _WIN32 std::unique_ptr beginReadStream(uint64_t offset) const { -#if NOD_UCS2 - FILE* fp = _wfopen(filepath.c_str(), L"rb"); + HANDLE fp = CreateFileW(filepath.c_str(), GENERIC_READ, FILE_SHARE_READ, + nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + if (fp == INVALID_HANDLE_VALUE) + { + LogModule.report(LogVisor::Error, _S("Unable to open '%s' for reading"), filepath.c_str()); + return std::unique_ptr(); + } + LARGE_INTEGER li; + li.QuadPart = offset; + SetFilePointerEx(fp, li, nullptr, FILE_BEGIN); + return std::unique_ptr(new ReadStream(fp)); + } #else + std::unique_ptr beginReadStream(uint64_t offset) const + { FILE* fp = fopen(filepath.c_str(), "rb"); -#endif if (!fp) { LogModule.report(LogVisor::Error, _S("Unable to open '%s' for reading"), filepath.c_str()); return std::unique_ptr(); } - fseeko(fp, offset, SEEK_SET); + FSeek(fp, offset, SEEK_SET); return std::unique_ptr(new ReadStream(fp)); } +#endif class WriteStream : public IWriteStream { friend class DiscIOISO; +#if _WIN32 + HANDLE fp; + WriteStream(HANDLE fpin) + : fp(fpin) {} + ~WriteStream() {CloseHandle(fp);} +#else FILE* fp; WriteStream(FILE* fpin) : fp(fpin) {} ~WriteStream() {fclose(fp);} +#endif public: - uint64_t write(void* buf, uint64_t length) - {return fwrite(buf, 1, length, fp);} + uint64_t write(const void* buf, uint64_t length) + { +#if _WIN32 + DWORD ret = 0; + WriteFile(fp, buf, length, &ret, nullptr); + return ret; +#else + return fwrite(buf, 1, length, fp); +#endif + } }; + +#if _WIN32 std::unique_ptr beginWriteStream(uint64_t offset) const { -#if NOD_UCS2 - FILE* fp = _wfopen(filepath.c_str(), L"wb"); + HANDLE fp = CreateFileW(filepath.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, + nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + if (fp == INVALID_HANDLE_VALUE) + { + LogModule.report(LogVisor::Error, _S("Unable to open '%s' for writing"), filepath.c_str()); + return std::unique_ptr(); + } + LARGE_INTEGER li; + li.QuadPart = offset; + SetFilePointerEx(fp, li, nullptr, FILE_BEGIN); + return std::unique_ptr(new WriteStream(fp)); + } #else + std::unique_ptr beginWriteStream(uint64_t offset) const + { FILE* fp = fopen(filepath.c_str(), "wb"); -#endif if (!fp) { LogModule.report(LogVisor::Error, _S("Unable to open '%s' for writing"), filepath.c_str()); return std::unique_ptr(); } - fseeko(fp, offset, SEEK_SET); + FSeek(fp, offset, SEEK_SET); return std::unique_ptr(new WriteStream(fp)); } +#endif }; std::unique_ptr NewDiscIOISO(const SystemChar* path) diff --git a/lib/DiscIOWBFS.cpp b/lib/DiscIOWBFS.cpp index 4a6b2c0..2088386 100644 --- a/lib/DiscIOWBFS.cpp +++ b/lib/DiscIOWBFS.cpp @@ -2,11 +2,7 @@ #include #include "NOD/Util.hpp" #include "NOD/IDiscIO.hpp" - -#if _WIN32 -#define ftello _ftelli64 -#define fseeko _fseeki64 -#endif +#include "NOD/IFileIO.hpp" namespace NOD { @@ -77,16 +73,13 @@ class DiscIOWBFS : public IDiscIO } wbfs; - static int _wbfsReadSector(FILE* fp, uint32_t lba, uint32_t count, void* buf) + static int _wbfsReadSector(IFileIO::IReadStream& rs, uint32_t lba, uint32_t count, void* buf) { uint64_t off = lba; off*=512ULL; - if (fseeko(fp, off, SEEK_SET)) + rs.seek(off, SEEK_SET); + if (rs.read(buf, count*512ULL) != count*512ULL) { - LogModule.report(LogVisor::FatalError, "error seeking in disc partition: %" PRId64 " %d", off, count); - return 1; - } - if (fread(buf, count*512ULL, 1, fp) != 1){ LogModule.report(LogVisor::FatalError, "error reading disc"); return 1; } @@ -98,23 +91,20 @@ public: : filepath(fpin) { /* Temporary file handle to read LBA table */ -#if NOD_UCS2 - FILE* fp = _wfopen(filepath.c_str(), L"rb"); -#else - FILE* fp = fopen(filepath.c_str(), "rb"); -#endif + std::unique_ptr fio = NewFileIO(filepath); + std::unique_ptr rs = fio->beginReadStream(); WBFS* p = &wbfs; WBFSHead tmpHead; - if (fread(&tmpHead, 1, sizeof(tmpHead), fp) != sizeof(tmpHead)) + if (rs->read(&tmpHead, sizeof(tmpHead)) != sizeof(tmpHead)) LogModule.report(LogVisor::FatalError, "unable to read WBFS head"); - fseek(fp, 0, SEEK_SET); unsigned hd_sector_size = 1 << tmpHead.hd_sec_sz_s; unsigned num_hd_sector = SBig(tmpHead.n_hd_sec); wbfsHead.reset(new uint8_t[hd_sector_size]); WBFSHead* head = (WBFSHead*)wbfsHead.get(); - if (fread(head, 1, hd_sector_size, fp) != hd_sector_size) + rs->seek(0, SEEK_SET); + if (rs->read(head, hd_sector_size) != hd_sector_size) LogModule.report(LogVisor::FatalError, "unable to read WBFS head"); //constants, but put here for consistancy @@ -123,7 +113,7 @@ public: p->n_wii_sec = (num_hd_sector/0x8000)*hd_sector_size; p->n_wii_sec_per_disc = 143432*2;//support for double layers discs.. p->part_lba = 0; - _wbfsReadSector(fp, p->part_lba, 1, head); + _wbfsReadSector(*rs, p->part_lba, 1, head); if (hd_sector_size && head->hd_sec_sz_s != size_to_shift(hd_sector_size)) { LogModule.report(LogVisor::FatalError, "hd sector size doesn't match"); } @@ -157,7 +147,7 @@ public: wbfsDiscInfo.reset(new uint8_t[p->disc_info_sz]); if (!wbfsDiscInfo) LogModule.report(LogVisor::FatalError, "allocating memory"); - _wbfsReadSector(fp, p->part_lba+1, disc_info_sz_lba, wbfsDiscInfo.get()); + _wbfsReadSector(*rs, p->part_lba+1, disc_info_sz_lba, wbfsDiscInfo.get()); p->n_disc_open++; //for(i=0;in_wbfs_sec_per_disc;i++) // printf("%d,",wbfs_ntohs(d->header->wlba_table[i])); @@ -168,19 +158,18 @@ public: { friend class DiscIOWBFS; const DiscIOWBFS& m_parent; - FILE* fp; + std::unique_ptr fp; uint64_t m_offset; std::unique_ptr m_tmpBuffer; - ReadStream(const DiscIOWBFS& parent, FILE* fpin, uint64_t offset) + ReadStream(const DiscIOWBFS& parent, std::unique_ptr&& fpin, uint64_t offset) : m_parent(parent), - fp(fpin), + fp(std::move(fpin)), m_offset(offset), m_tmpBuffer(new uint8_t[parent.wbfs.hd_sec_sz]) {} - ~ReadStream() {fclose(fp);} int wbfsReadSector(uint32_t lba, uint32_t count, void* buf) - {return DiscIOWBFS::_wbfsReadSector(fp, lba, count, buf);} + {return DiscIOWBFS::_wbfsReadSector(*fp, lba, count, buf);} int wbfsDiscRead(uint32_t offset, uint8_t *data, uint64_t len) { @@ -279,46 +268,15 @@ public: m_offset += offset; } }; + std::unique_ptr beginReadStream(uint64_t offset) const { -#if NOD_UCS2 - FILE* fp = _wfopen(filepath.c_str(), L"rb"); -#else - FILE* fp = fopen(filepath.c_str(), "rb"); -#endif - if (!fp) - { - LogModule.report(LogVisor::Error, _S("Unable to open '%s' for reading"), filepath.c_str()); - return std::unique_ptr(); - } - return std::unique_ptr(new ReadStream(*this, fp, offset)); + return std::unique_ptr(new ReadStream(*this, NewFileIO(filepath)->beginReadStream(), offset)); } - class WriteStream : public IWriteStream - { - friend class DiscIOWBFS; - FILE* fp; - WriteStream(FILE* fpin) - : fp(fpin) {} - ~WriteStream() {fclose(fp);} - public: - uint64_t write(void* buf, uint64_t length) - {return fwrite(buf, 1, length, fp);} - }; std::unique_ptr beginWriteStream(uint64_t offset) const { -#if NOD_UCS2 - FILE* fp = _wfopen(filepath.c_str(), L"wb"); -#else - FILE* fp = fopen(filepath.c_str(), "wb"); -#endif - if (!fp) - { - LogModule.report(LogVisor::Error, _S("Unable to open '%s' for writing"), filepath.c_str()); - return std::unique_ptr(); - } - fseeko(fp, offset, SEEK_SET); - return std::unique_ptr(new WriteStream(fp)); + return std::unique_ptr(); } }; diff --git a/lib/DiscWii.cpp b/lib/DiscWii.cpp index 8288ac0..b68db90 100644 --- a/lib/DiscWii.cpp +++ b/lib/DiscWii.cpp @@ -342,10 +342,7 @@ public: void writeOutPartitionHeader(const SystemChar* pathOut) const { - FILE* fp = Fopen(pathOut, _S("wb"), FileLockType::Write); - if (!fp) - LogModule.report(LogVisor::FatalError, _S("unable to open %s for writing"), pathOut); - + std::unique_ptr ws = NewFileIO(pathOut)->beginWriteStream(); uint64_t h3Off; { std::unique_ptr rs = m_parent.getDiscIO().beginReadStream(m_offset + 0x2B4); @@ -363,11 +360,9 @@ public: { size_t rdSz = NOD::min(rem, size_t(8192ul)); rs->read(buf, rdSz); - fwrite(buf, 1, rdSz, fp); + ws->write(buf, rdSz); rem -= rdSz; } - - fclose(fp); } }; @@ -910,8 +905,19 @@ bool DiscBuilderWii::buildFromDirectory(const SystemChar* dirIn, const SystemCha /* Fill image to end */ ws = m_fileIO->beginWriteStream(filledSz); - for (size_t i=0 ; iwrite("\xff", 1); + uint8_t fillBuf[512]; + memset(fillBuf, 0xff, 512); + for (size_t i=DISC_CAPACITY-filledSz ; i>0 ;) + { + if (i >= 512) + { + ws->write(fillBuf, 512); + i -= 512; + continue; + } + ws->write(fillBuf, i); + break; + } return true; } diff --git a/lib/FileIOFILE.cpp b/lib/FileIOFILE.cpp index 04d7f3c..efeb8fd 100644 --- a/lib/FileIOFILE.cpp +++ b/lib/FileIOFILE.cpp @@ -24,57 +24,115 @@ public: FileIOFILE(const SystemChar* path) : m_path(path) {} - uint64_t size() + bool exists() { -#if NOD_UCS2 - FILE* fp = _wfopen(m_path.c_str(), L"rb"); +#if _WIN32 + HANDLE fp = CreateFileW(m_path.c_str(), GENERIC_READ, FILE_SHARE_READ, + nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + if (fp == INVALID_HANDLE_VALUE) + return false; + CloseHandle(fp); + return true; #else FILE* fp = fopen(m_path.c_str(), "rb"); + if (!fp) + return false; + fclose(fp); + return true; #endif + } + + uint64_t size() + { +#if _WIN32 + HANDLE fp = CreateFileW(m_path.c_str(), GENERIC_READ, FILE_SHARE_READ, + nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + if (fp == INVALID_HANDLE_VALUE) + return 0; + LARGE_INTEGER sz; + if (!GetFileSizeEx(fp, &sz)) + { + CloseHandle(fp); + return 0; + } + CloseHandle(fp); + return sz.QuadPart; +#else + FILE* fp = fopen(m_path.c_str(), "rb"); if (!fp) return 0; - fseeko(fp, 0, SEEK_END); + FSeek(fp, 0, SEEK_END); uint64_t result = ftello(fp); fclose(fp); return result; +#endif } struct WriteStream : public IFileIO::IWriteStream { uint8_t buf[0x7c00]; +#if _WIN32 + HANDLE fp; +#else FILE* fp; +#endif WriteStream(const SystemString& path) { -#if NOD_UCS2 - fp = _wfopen(path.c_str(), L"wb"); +#if _WIN32 + fp = CreateFileW(path.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, + nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + if (fp == INVALID_HANDLE_VALUE) + goto FailLoc; #else fp = fopen(path.c_str(), "wb"); -#endif if (!fp) - LogModule.report(LogVisor::Error, _S("unable to open '%s' for writing"), path.c_str()); + goto FailLoc; +#endif + return; + FailLoc: + LogModule.report(LogVisor::FatalError, _S("unable to open '%s' for writing"), path.c_str()); } WriteStream(const SystemString& path, uint64_t offset) { -#if NOD_UCS2 - fp = _wfopen(path.c_str(), L"ab"); - fclose(fp); - fp = _wfopen(path.c_str(), L"r+b"); +#if _WIN32 + fp = CreateFileW(path.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, + nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + if (fp == INVALID_HANDLE_VALUE) + goto FailLoc; + LARGE_INTEGER lioffset; + lioffset.QuadPart = offset; + SetFilePointerEx(fp, lioffset, nullptr, FILE_BEGIN); #else fp = fopen(path.c_str(), "ab"); + if (!fp) + goto FailLoc; fclose(fp); fp = fopen(path.c_str(), "r+b"); -#endif if (!fp) - LogModule.report(LogVisor::Error, _S("unable to open '%s' for writing"), path.c_str()); + goto FailLoc; FSeek(fp, offset, SEEK_SET); +#endif + return; + FailLoc: + LogModule.report(LogVisor::FatalError, _S("unable to open '%s' for writing"), path.c_str()); } ~WriteStream() { +#if _WIN32 + CloseHandle(fp); +#else fclose(fp); +#endif } uint64_t write(const void* buf, uint64_t length) { +#if _WIN32 + DWORD ret = 0; + WriteFile(fp, buf, length, &ret, nullptr); + return ret; +#else return fwrite(buf, 1, length, fp); +#endif } uint64_t copyFromDisc(IPartReadStream& discio, uint64_t length) { @@ -85,12 +143,12 @@ public: uint64_t readSz = discio.read(buf, thisSz); if (thisSz != readSz) { - LogModule.report(LogVisor::Error, "unable to read enough from disc"); + LogModule.report(LogVisor::FatalError, "unable to read enough from disc"); return read; } - if (fwrite(buf, 1, readSz, fp) != readSz) + if (write(buf, readSz) != readSz) { - LogModule.report(LogVisor::Error, "unable to write in file"); + LogModule.report(LogVisor::FatalError, "unable to write in file"); return read; } length -= thisSz; @@ -110,40 +168,81 @@ public: struct ReadStream : public IFileIO::IReadStream { +#if _WIN32 + HANDLE fp; +#else FILE* fp; +#endif uint8_t buf[0x7c00]; ReadStream(const SystemString& path) { -#if NOD_UCS2 - fp = _wfopen(path.c_str(), L"rb"); +#if _WIN32 + fp = CreateFileW(path.c_str(), GENERIC_READ, FILE_SHARE_READ, + nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + if (fp == INVALID_HANDLE_VALUE) + goto FailLoc; #else fp = fopen(path.c_str(), "rb"); -#endif if (!fp) - LogModule.report(LogVisor::Error, _S("unable to open '%s' for reading"), path.c_str()); + goto FailLoc; +#endif + return; + FailLoc: + LogModule.report(LogVisor::FatalError, _S("unable to open '%s' for reading"), path.c_str()); } ReadStream(const SystemString& path, uint64_t offset) : ReadStream(path) { +#if _WIN32 + LARGE_INTEGER lioffset; + lioffset.QuadPart = offset; + SetFilePointerEx(fp, lioffset, nullptr, FILE_BEGIN); +#else FSeek(fp, offset, SEEK_SET); +#endif + } + ~ReadStream() + { +#if _WIN32 + CloseHandle(fp); +#else + fclose(fp); +#endif + } + void seek(int64_t offset, int whence) + { +#if _WIN32 + LARGE_INTEGER li; + li.QuadPart = offset; + SetFilePointerEx(fp, li, nullptr, whence); +#else + FSeek(fp, offset, whence); +#endif } - ~ReadStream() {fclose(fp);} uint64_t read(void* buf, uint64_t length) - {return fread(buf, 1, length, fp);} + { +#if _WIN32 + DWORD ret = 0; + ReadFile(fp, buf, length, &ret, nullptr); + return ret; +#else + return fread(buf, 1, length, fp); +#endif + } uint64_t copyToDisc(IPartWriteStream& discio, uint64_t length) { uint64_t written = 0; while (length) { uint64_t thisSz = MIN(0x7c00, length); - if (fread(buf, 1, thisSz, fp) != thisSz) + if (read(buf, thisSz) != thisSz) { - LogModule.report(LogVisor::Error, "unable to read enough from file"); + LogModule.report(LogVisor::FatalError, "unable to read enough from file"); return written; } if (discio.write(buf, thisSz) != thisSz) { - LogModule.report(LogVisor::Error, "unable to write enough to disc"); + LogModule.report(LogVisor::FatalError, "unable to write enough to disc"); return written; } length -= thisSz; diff --git a/lib/NOD.cpp b/lib/NOD.cpp index a52529f..f66bb4c 100644 --- a/lib/NOD.cpp +++ b/lib/NOD.cpp @@ -2,10 +2,6 @@ #include "NOD/NOD.hpp" #include "NOD/DiscBase.hpp" -#if _WIN32 -#define fseeko _fseeki64 -#endif - namespace NOD { @@ -17,49 +13,41 @@ std::unique_ptr NewDiscIOWBFS(const SystemChar* path); std::unique_ptr OpenDiscFromImage(const SystemChar* path, bool& isWii) { /* Temporary file handle to determine image type */ -#if NOD_UCS2 - FILE* fp = _wfopen(path, L"rb"); -#else - FILE* fp = fopen(path, "rb"); -#endif - if (!fp) + std::unique_ptr fio = NewFileIO(path); + if (!fio->exists()) { LogModule.report(LogVisor::Error, _S("Unable to open '%s'"), path); return std::unique_ptr(); } + std::unique_ptr rs = fio->beginReadStream(); isWii = false; std::unique_ptr discIO; - uint32_t magic; - fread(&magic, 1, 4, fp); + uint32_t magic = 0; + if (rs->read(&magic, 4) != 4) + LogModule.report(LogVisor::FatalError, _S("Unable to read magic from '%s'"), path); + if (magic == NOD::SBig((uint32_t)'WBFS')) { - fclose(fp); discIO = NewDiscIOWBFS(path); isWii = true; } else { - fseeko(fp, 0x18, SEEK_SET); - fread(&magic, 1, 4, fp); + rs->seek(0x18, SEEK_SET); + rs->read(&magic, 4); magic = NOD::SBig(magic); if (magic == 0x5D1C9EA3) { - fclose(fp); discIO = NewDiscIOISO(path); isWii = true; } else { - fread(&magic, 1, 4, fp); + rs->read(&magic, 4); magic = NOD::SBig(magic); if (magic == 0xC2339F3D) - { - fclose(fp); discIO = NewDiscIOISO(path); - } - else - fclose(fp); } }