// Copyright 2018 Dolphin Emulator Project // Licensed under GPLv2+ // Refer to the license.txt file included. #include "DiscIO/WIABlob.h" #include #include "Common/CommonTypes.h" #include "Common/File.h" #include "Common/Logging/Log.h" #include "Common/StringUtil.h" #include "Common/Swap.h" #include "DiscIO/VolumeWii.h" namespace DiscIO { WIAFileReader::WIAFileReader(File::IOFile file, const std::string& path) : m_file(std::move(file)) { m_valid = Initialize(path); } WIAFileReader::~WIAFileReader() = default; bool WIAFileReader::Initialize(const std::string& path) { if (!m_file.Seek(0, SEEK_SET) || !m_file.ReadArray(&m_header_1, 1)) return false; if (m_header_1.magic != WIA_MAGIC) return false; const u32 version = Common::swap32(m_header_1.version); const u32 version_compatible = Common::swap32(m_header_1.version_compatible); if (WIA_VERSION < version_compatible || WIA_VERSION_READ_COMPATIBLE > version) { ERROR_LOG(DISCIO, "Unsupported WIA version %s in %s", VersionToString(version).c_str(), path.c_str()); return false; } if (Common::swap64(m_header_1.wia_file_size) != m_file.GetSize()) { ERROR_LOG(DISCIO, "File size is incorrect for %s", path.c_str()); return false; } if (Common::swap32(m_header_1.header_2_size) < sizeof(WIAHeader2)) return false; if (!m_file.ReadArray(&m_header_2, 1)) return false; const u32 chunk_size = Common::swap32(m_header_2.chunk_size); if (chunk_size % VolumeWii::GROUP_TOTAL_SIZE != 0) return false; return true; } std::unique_ptr WIAFileReader::Create(File::IOFile file, const std::string& path) { std::unique_ptr blob(new WIAFileReader(std::move(file), path)); return blob->m_valid ? std::move(blob) : nullptr; } bool WIAFileReader::Read(u64 offset, u64 size, u8* out_ptr) { if (offset + size <= sizeof(WIAHeader2::disc_header)) { std::memcpy(out_ptr, m_header_2.disc_header.data() + offset, size); return true; } // Not implemented return false; } std::string WIAFileReader::VersionToString(u32 version) { const u8 a = version >> 24; const u8 b = (version >> 16) & 0xff; const u8 c = (version >> 8) & 0xff; const u8 d = version & 0xff; if (d == 0 || d == 0xff) return StringFromFormat("%u.%02x.%02x", a, b, c); else return StringFromFormat("%u.%02x.%02x.beta%u", a, b, c, d); } } // namespace DiscIO