Removed direct stdio usage

This commit is contained in:
Jack Andersen 2016-01-24 19:55:31 -10:00
parent 9ce2e0a3b2
commit df5e8d068c
9 changed files with 267 additions and 143 deletions

View File

@ -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<IWriteStream> beginWriteStream(uint64_t offset=0) const=0;
};

View File

@ -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;
};

View File

@ -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))

View File

@ -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<IFileIO::IReadStream> 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))

View File

@ -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<IReadStream> 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<IReadStream>();
}
LARGE_INTEGER li;
li.QuadPart = offset;
SetFilePointerEx(fp, li, nullptr, FILE_BEGIN);
return std::unique_ptr<IReadStream>(new ReadStream(fp));
}
#else
std::unique_ptr<IReadStream> 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<IReadStream>();
}
fseeko(fp, offset, SEEK_SET);
FSeek(fp, offset, SEEK_SET);
return std::unique_ptr<IReadStream>(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<IWriteStream> 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<IWriteStream>();
}
LARGE_INTEGER li;
li.QuadPart = offset;
SetFilePointerEx(fp, li, nullptr, FILE_BEGIN);
return std::unique_ptr<IWriteStream>(new WriteStream(fp));
}
#else
std::unique_ptr<IWriteStream> 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<IWriteStream>();
}
fseeko(fp, offset, SEEK_SET);
FSeek(fp, offset, SEEK_SET);
return std::unique_ptr<IWriteStream>(new WriteStream(fp));
}
#endif
};
std::unique_ptr<IDiscIO> NewDiscIOISO(const SystemChar* path)

View File

@ -2,11 +2,7 @@
#include <inttypes.h>
#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<IFileIO> fio = NewFileIO(filepath);
std::unique_ptr<IFileIO::IReadStream> 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;i<p->n_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<IFileIO::IReadStream> fp;
uint64_t m_offset;
std::unique_ptr<uint8_t[]> m_tmpBuffer;
ReadStream(const DiscIOWBFS& parent, FILE* fpin, uint64_t offset)
ReadStream(const DiscIOWBFS& parent, std::unique_ptr<IFileIO::IReadStream>&& 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<IReadStream> 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<IReadStream>();
}
return std::unique_ptr<IReadStream>(new ReadStream(*this, fp, offset));
return std::unique_ptr<IReadStream>(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<IWriteStream> 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<IWriteStream>();
}
fseeko(fp, offset, SEEK_SET);
return std::unique_ptr<IWriteStream>(new WriteStream(fp));
return std::unique_ptr<IWriteStream>();
}
};

View File

@ -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<IFileIO::IWriteStream> ws = NewFileIO(pathOut)->beginWriteStream();
uint64_t h3Off;
{
std::unique_ptr<IDiscIO::IReadStream> 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 ; i<DISC_CAPACITY-filledSz ; ++i)
ws->write("\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;
}

View File

@ -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;

View File

@ -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<IDiscIO> NewDiscIOWBFS(const SystemChar* path);
std::unique_ptr<DiscBase> 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<IFileIO> fio = NewFileIO(path);
if (!fio->exists())
{
LogModule.report(LogVisor::Error, _S("Unable to open '%s'"), path);
return std::unique_ptr<DiscBase>();
}
std::unique_ptr<IFileIO::IReadStream> rs = fio->beginReadStream();
isWii = false;
std::unique_ptr<IDiscIO> 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);
}
}