// Copyright 2020 Dolphin Emulator Project // Licensed under GPLv2+ // Refer to the license.txt file included. #include "DiscIO/VolumeDisc.h" #include #include #include #include #include #include "Common/CommonTypes.h" #include "DiscIO/DiscExtractor.h" #include "DiscIO/Enums.h" #include "DiscIO/Filesystem.h" namespace DiscIO { std::string VolumeDisc::GetGameID(const Partition& partition) const { char id[6]; if (!Read(0, sizeof(id), reinterpret_cast(id), partition)) return std::string(); return DecodeString(id); } Country VolumeDisc::GetCountry(const Partition& partition) const { // The 0 that we use as a default value is mapped to Country::Unknown and Region::Unknown const u8 country_byte = ReadSwapped(3, partition).value_or(0); const Region region = GetRegion(); const std::optional revision = GetRevision(); if (CountryCodeToRegion(country_byte, GetVolumeType(), region, revision) != region) return TypicalCountryForRegion(region); return CountryCodeToCountry(country_byte, GetVolumeType(), region, revision); } Region VolumeDisc::RegionCodeToRegion(std::optional region_code) const { if (!region_code) return Region::Unknown; const Region region = static_cast(*region_code); return region <= Region::NTSC_K ? region : Region::Unknown; } std::string VolumeDisc::GetMakerID(const Partition& partition) const { char maker_id[2]; if (!Read(0x4, sizeof(maker_id), reinterpret_cast(&maker_id), partition)) return std::string(); return DecodeString(maker_id); } std::optional VolumeDisc::GetRevision(const Partition& partition) const { std::optional revision = ReadSwapped(7, partition); return revision ? *revision : std::optional(); } std::string VolumeDisc::GetInternalName(const Partition& partition) const { char name[0x60]; if (!Read(0x20, sizeof(name), reinterpret_cast(&name), partition)) return std::string(); return DecodeString(name); } std::string VolumeDisc::GetApploaderDate(const Partition& partition) const { char date[16]; if (!Read(0x2440, sizeof(date), reinterpret_cast(&date), partition)) return std::string(); return DecodeString(date); } std::optional VolumeDisc::GetDiscNumber(const Partition& partition) const { return ReadSwapped(6, partition); } bool VolumeDisc::IsNKit() const { constexpr u32 NKIT_MAGIC = 0x4E4B4954; // "NKIT" return ReadSwapped(0x200, PARTITION_NONE) == NKIT_MAGIC; } void VolumeDisc::AddGamePartitionToSyncHash(mbedtls_sha1_context* context) const { const Partition partition = GetGamePartition(); // All headers at the beginning of the partition, plus the apploader ReadAndAddToSyncHash(context, 0, 0x2440 + GetApploaderSize(*this, partition).value_or(0), partition); // Boot DOL (may be missing if this is a Datel disc) const std::optional dol_offset = GetBootDOLOffset(*this, partition); if (dol_offset) { ReadAndAddToSyncHash(context, *dol_offset, GetBootDOLSize(*this, partition, *dol_offset).value_or(0), partition); } // File system const std::optional fst_offset = GetFSTOffset(*this, partition); if (fst_offset) ReadAndAddToSyncHash(context, *fst_offset, GetFSTSize(*this, partition).value_or(0), partition); // opening.bnr (name and banner) const FileSystem* file_system = GetFileSystem(partition); if (file_system) { std::unique_ptr file_info = file_system->FindFileInfo("opening.bnr"); if (file_info && !file_info->IsDirectory()) ReadAndAddToSyncHash(context, file_info->GetOffset(), file_info->GetSize(), partition); } } } // namespace DiscIO