summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Boot/Boot.cpp82
-rw-r--r--Source/Core/Core/Boot/Boot.h7
-rw-r--r--Source/Core/Core/Boot/DolReader.cpp6
-rw-r--r--Source/Core/Core/Boot/DolReader.h6
-rw-r--r--Source/Core/Core/Boot/ElfReader.cpp7
-rw-r--r--Source/Core/Core/Boot/ElfReader.h6
-rw-r--r--Source/Core/DiscIO/Blob.cpp17
-rw-r--r--Source/Core/DiscIO/CMakeLists.txt2
-rw-r--r--Source/Core/DiscIO/DirectoryBlob.cpp (renamed from Source/Core/DiscIO/VolumeDirectory.cpp)275
-rw-r--r--Source/Core/DiscIO/DirectoryBlob.h (renamed from Source/Core/DiscIO/VolumeDirectory.h)64
-rw-r--r--Source/Core/DiscIO/DiscIO.vcxproj4
-rw-r--r--Source/Core/DiscIO/DiscIO.vcxproj.filters8
-rw-r--r--Source/Core/DiscIO/Volume.cpp11
-rw-r--r--Source/Core/DiscIO/Volume.h3
14 files changed, 203 insertions, 295 deletions
diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp
index bf1f87b3ec..fd442a2a5b 100644
--- a/Source/Core/Core/Boot/Boot.cpp
+++ b/Source/Core/Core/Boot/Boot.cpp
@@ -132,44 +132,6 @@ bool CBoot::DVDRead(const DiscIO::Volume& volume, u64 dvd_offset, u32 output_add
return true;
}
-void CBoot::Load_FST(bool is_wii, const DiscIO::Volume* volume)
-{
- if (!volume)
- return;
-
- const DiscIO::Partition partition = volume->GetGamePartition();
-
- // copy first 32 bytes of disc to start of Mem 1
- DVDRead(*volume, /*offset*/ 0, /*address*/ 0, /*length*/ 0x20, DiscIO::PARTITION_NONE);
-
- // copy of game id
- Memory::Write_U32(Memory::Read_U32(0x0000), 0x3180);
-
- u32 shift = 0;
- if (is_wii)
- shift = 2;
-
- const std::optional<u32> fst_offset = volume->ReadSwapped<u32>(0x0424, partition);
- const std::optional<u32> fst_size = volume->ReadSwapped<u32>(0x0428, partition);
- const std::optional<u32> max_fst_size = volume->ReadSwapped<u32>(0x042c, partition);
- if (!fst_offset || !fst_size || !max_fst_size)
- return;
-
- u32 arena_high = Common::AlignDown(0x817FFFFF - (*max_fst_size << shift), 0x20);
- Memory::Write_U32(arena_high, 0x00000034);
-
- // load FST
- DVDRead(*volume, *fst_offset << shift, arena_high, *fst_size << shift, partition);
- Memory::Write_U32(arena_high, 0x00000038);
- Memory::Write_U32(*max_fst_size << shift, 0x0000003c);
-
- if (is_wii)
- {
- // the apploader changes IOS MEM1_ARENA_END too
- Memory::Write_U32(arena_high, 0x00003110);
- }
-}
-
void CBoot::UpdateDebugger_MapLoaded()
{
Host_NotifyMapLoaded();
@@ -308,15 +270,11 @@ bool CBoot::Load_BS2(const std::string& boot_rom_filename)
return true;
}
-static const DiscIO::Volume* SetDefaultDisc()
+static void SetDefaultDisc()
{
const SConfig& config = SConfig::GetInstance();
- // load default image or create virtual drive from directory
- if (!config.m_strDVDRoot.empty())
- return SetDisc(DiscIO::CreateVolumeFromDirectory(config.m_strDVDRoot, config.bWii));
if (!config.m_strDefaultISO.empty())
- return SetDisc(DiscIO::CreateVolumeFromFilename(config.m_strDefaultISO));
- return nullptr;
+ SetDisc(DiscIO::CreateVolumeFromFilename(config.m_strDefaultISO));
}
// Third boot step after BootManager and Core. See Call schedule in BootManager.cpp
@@ -358,34 +316,14 @@ bool CBoot::BootUp(std::unique_ptr<BootParameters> boot)
if (!executable.reader->IsValid())
return false;
- const DiscIO::Volume* volume = nullptr;
- // VolumeDirectory only works with DOLs.
- if (StringEndsWith(executable.path, ".dol"))
- {
- if (!config.m_strDVDRoot.empty())
- {
- NOTICE_LOG(BOOT, "Setting DVDRoot %s", config.m_strDVDRoot.c_str());
- volume = SetDisc(DiscIO::CreateVolumeFromDirectory(
- config.m_strDVDRoot, config.bWii, config.m_strApploader, executable.path));
- }
- else if (!config.m_strDefaultISO.empty())
- {
- NOTICE_LOG(BOOT, "Loading default ISO %s", config.m_strDefaultISO.c_str());
- volume = SetDisc(DiscIO::CreateVolumeFromFilename(config.m_strDefaultISO));
- }
- }
- else
- {
- volume = SetDefaultDisc();
- }
-
if (!executable.reader->LoadIntoMemory())
{
PanicAlertT("Failed to load the executable to memory.");
return false;
}
- // Poor man's bootup
+ SetDefaultDisc();
+
if (config.bWii)
{
HID4.SBE = 1;
@@ -393,14 +331,13 @@ bool CBoot::BootUp(std::unique_ptr<BootParameters> boot)
SetupBAT(config.bWii);
// Because there is no TMD to get the requested system (IOS) version from,
// we default to IOS58, which is the version used by the Homebrew Channel.
- SetupWiiMemory(volume, 0x000000010000003a);
+ SetupWiiMemory(nullptr, 0x000000010000003a);
}
else
{
- EmulatedBS2_GC(volume, true);
+ EmulatedBS2_GC(nullptr, true);
}
- Load_FST(config.bWii, volume);
PC = executable.reader->GetEntryPoint();
if (executable.reader->LoadSymbols() || LoadMapFromFilename())
@@ -464,8 +401,13 @@ bool CBoot::BootUp(std::unique_ptr<BootParameters> boot)
}
BootExecutableReader::BootExecutableReader(const std::string& file_name)
+ : BootExecutableReader(File::IOFile{file_name, "rb"})
+{
+}
+
+BootExecutableReader::BootExecutableReader(File::IOFile file)
{
- File::IOFile file{file_name, "rb"};
+ file.Seek(0, SEEK_SET);
m_bytes.resize(file.GetSize());
file.ReadBytes(m_bytes.data(), m_bytes.size());
}
diff --git a/Source/Core/Core/Boot/Boot.h b/Source/Core/Core/Boot/Boot.h
index 1f52daa1c5..69f784c827 100644
--- a/Source/Core/Core/Boot/Boot.h
+++ b/Source/Core/Core/Boot/Boot.h
@@ -15,6 +15,11 @@
#include "DiscIO/Enums.h"
#include "DiscIO/Volume.h"
+namespace File
+{
+class IOFile;
+}
+
struct RegionSetting
{
const std::string area;
@@ -101,7 +106,6 @@ private:
static bool EmulatedBS2_Wii(const DiscIO::Volume* volume);
static bool EmulatedBS2(bool is_wii, const DiscIO::Volume* volume);
static bool Load_BS2(const std::string& boot_rom_filename);
- static void Load_FST(bool is_wii, const DiscIO::Volume* volume);
static bool SetupWiiMemory(const DiscIO::Volume* volume, u64 ios_title_id);
};
@@ -110,6 +114,7 @@ class BootExecutableReader
{
public:
explicit BootExecutableReader(const std::string& file_name);
+ explicit BootExecutableReader(File::IOFile file);
explicit BootExecutableReader(const std::vector<u8>& buffer);
virtual ~BootExecutableReader();
diff --git a/Source/Core/Core/Boot/DolReader.cpp b/Source/Core/Core/Boot/DolReader.cpp
index 391aace573..ef1ece315b 100644
--- a/Source/Core/Core/Boot/DolReader.cpp
+++ b/Source/Core/Core/Boot/DolReader.cpp
@@ -6,6 +6,7 @@
#include <cstring>
#include <string>
+#include <utility>
#include <vector>
#include "Common/File.h"
@@ -18,6 +19,11 @@ DolReader::DolReader(const std::vector<u8>& buffer) : BootExecutableReader(buffe
m_is_valid = Initialize(buffer);
}
+DolReader::DolReader(File::IOFile file) : BootExecutableReader(std::move(file))
+{
+ m_is_valid = Initialize(m_bytes);
+}
+
DolReader::DolReader(const std::string& filename) : BootExecutableReader(filename)
{
m_is_valid = Initialize(m_bytes);
diff --git a/Source/Core/Core/Boot/DolReader.h b/Source/Core/Core/Boot/DolReader.h
index e2daa04733..38f6616ccb 100644
--- a/Source/Core/Core/Boot/DolReader.h
+++ b/Source/Core/Core/Boot/DolReader.h
@@ -10,10 +10,16 @@
#include "Common/CommonTypes.h"
#include "Core/Boot/Boot.h"
+namespace File
+{
+class IOFile;
+}
+
class DolReader final : public BootExecutableReader
{
public:
explicit DolReader(const std::string& filename);
+ explicit DolReader(File::IOFile file);
explicit DolReader(const std::vector<u8>& buffer);
~DolReader();
diff --git a/Source/Core/Core/Boot/ElfReader.cpp b/Source/Core/Core/Boot/ElfReader.cpp
index 78a77954ed..99faaa6fda 100644
--- a/Source/Core/Core/Boot/ElfReader.cpp
+++ b/Source/Core/Core/Boot/ElfReader.cpp
@@ -5,8 +5,10 @@
#include "Core/Boot/ElfReader.h"
#include <string>
+#include <utility>
#include "Common/CommonTypes.h"
+#include "Common/FileUtil.h"
#include "Common/Logging/Log.h"
#include "Common/MsgHandler.h"
#include "Common/Swap.h"
@@ -71,6 +73,11 @@ ElfReader::ElfReader(const std::vector<u8>& buffer) : BootExecutableReader(buffe
Initialize(m_bytes.data());
}
+ElfReader::ElfReader(File::IOFile file) : BootExecutableReader(std::move(file))
+{
+ Initialize(m_bytes.data());
+}
+
ElfReader::ElfReader(const std::string& filename) : BootExecutableReader(filename)
{
Initialize(m_bytes.data());
diff --git a/Source/Core/Core/Boot/ElfReader.h b/Source/Core/Core/Boot/ElfReader.h
index 951f5a7b57..d9ffa78345 100644
--- a/Source/Core/Core/Boot/ElfReader.h
+++ b/Source/Core/Core/Boot/ElfReader.h
@@ -8,6 +8,11 @@
#include "Core/Boot/Boot.h"
#include "Core/Boot/ElfTypes.h"
+namespace File
+{
+class IOFile;
+}
+
enum KnownElfTypes
{
KNOWNELF_PSP = 0,
@@ -22,6 +27,7 @@ class ElfReader final : public BootExecutableReader
{
public:
explicit ElfReader(const std::string& filename);
+ explicit ElfReader(File::IOFile file);
explicit ElfReader(const std::vector<u8>& buffer);
~ElfReader();
u32 Read32(int off) const { return base32[off >> 2]; }
diff --git a/Source/Core/DiscIO/Blob.cpp b/Source/Core/DiscIO/Blob.cpp
index da8640c7bc..a27f6861e1 100644
--- a/Source/Core/DiscIO/Blob.cpp
+++ b/Source/Core/DiscIO/Blob.cpp
@@ -16,6 +16,7 @@
#include "DiscIO/Blob.h"
#include "DiscIO/CISOBlob.h"
#include "DiscIO/CompressedBlob.h"
+#include "DiscIO/DirectoryBlob.h"
#include "DiscIO/DriveBlob.h"
#include "DiscIO/FileBlob.h"
#include "DiscIO/TGCBlob.h"
@@ -183,12 +184,13 @@ std::unique_ptr<BlobReader> CreateBlobReader(const std::string& filename)
if (!file.ReadArray(&magic, 1))
return nullptr;
- // Conveniently, every supported file format (except for plain disc images) starts
- // with a 4-byte magic number that identifies the format, so we just need a simple
- // switch statement to create the right blob type. If the magic number doesn't
- // match any known magic number, we assume it's a plain disc image. If that
- // assumption is wrong, the volume code that runs later will notice the error
- // because the blob won't provide valid data when reading the GC/Wii disc header.
+ // Conveniently, every supported file format (except for plain disc images and
+ // extracted discs) starts with a 4-byte magic number that identifies the format,
+ // so we just need a simple switch statement to create the right blob type. If the
+ // magic number doesn't match any known magic number and the directory structure
+ // doesn't match the directory blob format, we assume it's a plain disc image. If
+ // that assumption is wrong, the volume code that runs later will notice the error
+ // because the blob won't provide the right data when reading the GC/Wii disc header.
switch (magic)
{
@@ -201,6 +203,9 @@ std::unique_ptr<BlobReader> CreateBlobReader(const std::string& filename)
case WBFS_MAGIC:
return WbfsFileReader::Create(std::move(file), filename);
default:
+ if (DirectoryBlobReader::IsValidDirectoryBlob(filename))
+ return DirectoryBlobReader::Create(std::move(file), filename);
+
return PlainFileReader::Create(std::move(file));
}
}
diff --git a/Source/Core/DiscIO/CMakeLists.txt b/Source/Core/DiscIO/CMakeLists.txt
index b59435efa0..ef1598ecd7 100644
--- a/Source/Core/DiscIO/CMakeLists.txt
+++ b/Source/Core/DiscIO/CMakeLists.txt
@@ -3,6 +3,7 @@ set(SRCS
CISOBlob.cpp
WbfsBlob.cpp
CompressedBlob.cpp
+ DirectoryBlob.cpp
DiscExtractor.cpp
DiscScrubber.cpp
DriveBlob.cpp
@@ -14,7 +15,6 @@ set(SRCS
NANDImporter.cpp
TGCBlob.cpp
Volume.cpp
- VolumeDirectory.cpp
VolumeGC.cpp
VolumeWad.cpp
VolumeWii.cpp
diff --git a/Source/Core/DiscIO/VolumeDirectory.cpp b/Source/Core/DiscIO/DirectoryBlob.cpp
index 854aec3da6..9425869f26 100644
--- a/Source/Core/DiscIO/VolumeDirectory.cpp
+++ b/Source/Core/DiscIO/DirectoryBlob.cpp
@@ -2,14 +2,18 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
+#include "DiscIO/DirectoryBlob.h"
+
#include <algorithm>
+#include <array>
+#include <cinttypes>
#include <cstddef>
#include <cstring>
#include <locale>
#include <map>
#include <memory>
-#include <optional>
#include <string>
+#include <utility>
#include <vector>
#include "Common/Align.h"
@@ -20,10 +24,9 @@
#include "Common/FileUtil.h"
#include "Common/Logging/Log.h"
#include "Common/StringUtil.h"
+#include "Common/Swap.h"
+#include "Core/Boot/DolReader.h"
#include "DiscIO/Blob.h"
-#include "DiscIO/Enums.h"
-#include "DiscIO/Volume.h"
-#include "DiscIO/VolumeDirectory.h"
namespace DiscIO
{
@@ -31,58 +34,77 @@ static u32 ComputeNameSize(const File::FSTEntry& parent_entry);
static std::string ASCIIToUppercase(std::string str);
static void ConvertUTF8NamesToSHIFTJIS(File::FSTEntry& parent_entry);
-const size_t VolumeDirectory::MAX_NAME_LENGTH;
-const size_t VolumeDirectory::MAX_ID_LENGTH;
+constexpr u64 GAME_PARTITION_ADDRESS = 0x50000;
+constexpr u64 PARTITION_TABLE_ADDRESS = 0x40000;
+const std::array<u32, 10> PARTITION_TABLE = {
+ {Common::swap32(1), Common::swap32((PARTITION_TABLE_ADDRESS + 0x20) >> 2), 0, 0, 0, 0, 0, 0,
+ Common::swap32(GAME_PARTITION_ADDRESS >> 2), 0}};
-VolumeDirectory::VolumeDirectory(const std::string& directory, bool is_wii,
- const std::string& apploader, const std::string& dol)
- : m_data_start_address(UINT64_MAX), m_disk_header(DISKHEADERINFO_ADDRESS),
- m_disk_header_info(std::make_unique<SDiskHeaderInfo>()), m_fst_address(0), m_dol_address(0)
-{
- m_root_directory = ExtractDirectoryName(directory);
+const size_t DirectoryBlobReader::MAX_NAME_LENGTH;
+const size_t DirectoryBlobReader::MAX_ID_LENGTH;
- // create the default disk header
- SetGameID("AGBJ01");
- SetName("Default name");
+static bool PathCharactersEqual(char a, char b)
+{
+ return a == b
+#ifdef _WIN32
+ || (a == '/' && b == '\\') || (a == '\\' && b == '/')
+#endif
+ ;
+}
- if (is_wii)
- SetDiskTypeWii();
- else
- SetDiskTypeGC();
+static bool PathEndsWith(const std::string& path, const std::string& suffix)
+{
+ if (suffix.size() > path.size())
+ return false;
- // Don't load the DOL if we don't have an apploader
- if (SetApploader(apploader))
- SetDOL(dol);
+ std::string::const_iterator path_iterator = path.cend() - suffix.size();
+ std::string::const_iterator suffix_iterator = suffix.cbegin();
+ while (path_iterator != path.cend())
+ {
+ if (!PathCharactersEqual(*path_iterator, *suffix_iterator))
+ return false;
+ path_iterator++;
+ suffix_iterator++;
+ }
- BuildFST();
+ return true;
}
-VolumeDirectory::~VolumeDirectory()
+bool DirectoryBlobReader::IsValidDirectoryBlob(const std::string& dol_path)
{
+ return PathEndsWith(dol_path, "/sys/main.dol");
}
-bool VolumeDirectory::IsValidDirectory(const std::string& directory)
+std::unique_ptr<DirectoryBlobReader> DirectoryBlobReader::Create(File::IOFile dol,
+ const std::string& dol_path)
{
- return File::IsDirectory(ExtractDirectoryName(directory));
+ if (!dol || !IsValidDirectoryBlob(dol_path))
+ return nullptr;
+
+ const size_t chars_to_remove = std::string("sys/main.dol").size();
+ const std::string root_directory = dol_path.substr(0, dol_path.size() - chars_to_remove);
+ return std::unique_ptr<DirectoryBlobReader>(
+ new DirectoryBlobReader(std::move(dol), root_directory));
}
-bool VolumeDirectory::Read(u64 offset, u64 length, u8* buffer, const Partition& partition) const
+DirectoryBlobReader::DirectoryBlobReader(File::IOFile dol_file, const std::string& root_directory)
+ : m_root_directory(root_directory), m_data_start_address(UINT64_MAX),
+ m_disk_header(DISKHEADERINFO_ADDRESS),
+ m_disk_header_info(std::make_unique<SDiskHeaderInfo>()), m_fst_address(0), m_dol_address(0)
{
- bool decrypt = partition != PARTITION_NONE;
+ // create the default disk header
+ SetGameID("AGBJ01");
+ SetName("Default name");
- if (!decrypt && (offset + length >= 0x400) && m_is_wii)
- {
- // Fully supporting this would require re-encrypting every file that's read.
- // Only supporting the areas that IOS allows software to read could be more feasible.
- // Currently, only the header (up to 0x400) is supported, though we're cheating a bit
- // with it by reading the header inside the current partition instead. Supporting the
- // header is enough for booting games, but not for running things like the Disc Channel.
- return false;
- }
+ // Setting the DOL relies on m_dol_address, which is set by SetApploader
+ if (SetApploader(m_root_directory + "sys/apploader.img"))
+ SetDOLAndDiskType(std::move(dol_file));
- if (decrypt && !m_is_wii)
- return false;
+ BuildFST();
+}
+bool DirectoryBlobReader::ReadPartition(u64 offset, u64 length, u8* buffer)
+{
// header
if (offset < DISKHEADERINFO_ADDRESS)
{
@@ -161,134 +183,80 @@ bool VolumeDirectory::Read(u64 offset, u64 length, u8* buffer, const Partition&
return true;
}
-std::vector<Partition> VolumeDirectory::GetPartitions() const
-{
- return m_is_wii ? std::vector<Partition>{GetGamePartition()} : std::vector<Partition>();
-}
-
-Partition VolumeDirectory::GetGamePartition() const
+bool DirectoryBlobReader::ReadNonPartition(u64 offset, u64 length, u8* buffer)
{
- return m_is_wii ? Partition(0x50000) : PARTITION_NONE;
-}
-
-std::string VolumeDirectory::GetGameID(const Partition& partition) const
-{
- return std::string(m_disk_header.begin(), m_disk_header.begin() + MAX_ID_LENGTH);
-}
+ // header
+ if (offset < DISKHEADERINFO_ADDRESS)
+ {
+ WriteToBuffer(DISKHEADER_ADDRESS, DISKHEADERINFO_ADDRESS, m_disk_header.data(), &offset,
+ &length, &buffer);
+ }
+ if (offset >= 0x40000)
+ {
+ WriteToBuffer(PARTITION_TABLE_ADDRESS, PARTITION_TABLE.size() * sizeof(u32),
+ reinterpret_cast<const u8*>(PARTITION_TABLE.data()), &offset, &length, &buffer);
+ }
-void VolumeDirectory::SetGameID(const std::string& id)
-{
- memcpy(m_disk_header.data(), id.c_str(), std::min(id.length(), MAX_ID_LENGTH));
-}
+ // TODO: TMDs, tickets, more headers, the partition contents...
-Region VolumeDirectory::GetRegion() const
-{
- if (m_is_wii)
- return RegionSwitchWii(m_disk_header[3]);
+ if (length > 0)
+ {
+ ERROR_LOG(DISCIO, "Unsupported raw read in DirectoryBlob at 0x%" PRIx64, offset);
+ return false;
+ }
- return RegionSwitchGC(m_disk_header[3]);
+ return true;
}
-Country VolumeDirectory::GetCountry(const Partition& partition) const
+bool DirectoryBlobReader::Read(u64 offset, u64 length, u8* buffer)
{
- return CountrySwitch(m_disk_header[3]);
+ return m_is_wii ? ReadNonPartition(offset, length, buffer) :
+ ReadPartition(offset, length, buffer);
}
-std::string VolumeDirectory::GetMakerID(const Partition& partition) const
+bool DirectoryBlobReader::SupportsReadWiiDecrypted() const
{
- // Not implemented
- return "00";
+ return m_is_wii;
}
-std::string VolumeDirectory::GetInternalName(const Partition& partition) const
+bool DirectoryBlobReader::ReadWiiDecrypted(u64 offset, u64 size, u8* buffer, u64 partition_offset)
{
- char name[0x60];
- if (Read(0x20, 0x60, (u8*)name, partition))
- return DecodeString(name);
- else
- return "";
-}
+ if (!m_is_wii || partition_offset != GAME_PARTITION_ADDRESS)
+ return false;
-std::map<Language, std::string> VolumeDirectory::GetLongNames() const
-{
- std::string name = GetInternalName();
- if (name.empty())
- return {};
- return {{Language::LANGUAGE_UNKNOWN, name}};
+ return ReadPartition(offset, size, buffer);
}
-std::vector<u32> VolumeDirectory::GetBanner(int* width, int* height) const
+void DirectoryBlobReader::SetGameID(const std::string& id)
{
- // Not implemented
- *width = 0;
- *height = 0;
- return std::vector<u32>();
+ memcpy(m_disk_header.data(), id.c_str(), std::min(id.length(), MAX_ID_LENGTH));
}
-void VolumeDirectory::SetName(const std::string& name)
+void DirectoryBlobReader::SetName(const std::string& name)
{
size_t length = std::min(name.length(), MAX_NAME_LENGTH);
memcpy(&m_disk_header[0x20], name.c_str(), length);
m_disk_header[length + 0x20] = 0;
}
-std::string VolumeDirectory::GetApploaderDate(const Partition& partition) const
-{
- // Not implemented
- return "VOID";
-}
-
-Platform VolumeDirectory::GetVolumeType() const
-{
- return m_is_wii ? Platform::WII_DISC : Platform::GAMECUBE_DISC;
-}
-
-BlobType VolumeDirectory::GetBlobType() const
+BlobType DirectoryBlobReader::GetBlobType() const
{
- // VolumeDirectory isn't actually a blob, but it sort of acts
- // like one, so it makes sense that it has its own blob type.
- // It should be made into a proper blob in the future.
return BlobType::DIRECTORY;
}
-u64 VolumeDirectory::GetSize() const
+u64 DirectoryBlobReader::GetRawSize() const
{
// Not implemented
return 0;
}
-u64 VolumeDirectory::GetRawSize() const
+u64 DirectoryBlobReader::GetDataSize() const
{
// Not implemented
return 0;
}
-std::string VolumeDirectory::ExtractDirectoryName(const std::string& directory)
-{
- std::string result = directory;
-
- size_t last_separator = result.find_last_of(DIR_SEP_CHR);
-
- if (last_separator != result.size() - 1)
- {
- // TODO: This assumes that file names will always have a dot in them
- // and directory names never will; both assumptions are often
- // right but in general wrong.
- size_t extension_start = result.find_last_of('.');
- if (extension_start != std::string::npos && extension_start > last_separator)
- {
- result.resize(last_separator);
- }
- }
- else
- {
- result.resize(last_separator);
- }
-
- return result;
-}
-
-void VolumeDirectory::SetDiskTypeWii()
+void DirectoryBlobReader::SetDiskTypeWii()
{
Write32(0x5d1c9ea3, 0x18, &m_disk_header);
memset(&m_disk_header[0x1c], 0, 4);
@@ -297,7 +265,7 @@ void VolumeDirectory::SetDiskTypeWii()
m_address_shift = 2;
}
-void VolumeDirectory::SetDiskTypeGC()
+void DirectoryBlobReader::SetDiskTypeGC()
{
memset(&m_disk_header[0x18], 0, 4);
Write32(0xc2339f3d, 0x1c, &m_disk_header);
@@ -306,7 +274,7 @@ void VolumeDirectory::SetDiskTypeGC()
m_address_shift = 0;
}
-bool VolumeDirectory::SetApploader(const std::string& apploader)
+bool DirectoryBlobReader::SetApploader(const std::string& apploader)
{
if (!apploader.empty())
{
@@ -339,27 +307,28 @@ bool VolumeDirectory::SetApploader(const std::string& apploader)
}
}
-void VolumeDirectory::SetDOL(const std::string& dol)
+void DirectoryBlobReader::SetDOLAndDiskType(File::IOFile dol_file)
{
- if (!dol.empty())
- {
- std::string data;
- File::ReadFileToString(dol, data);
- m_dol.resize(data.size());
- std::copy(data.begin(), data.end(), m_dol.begin());
+ m_dol.resize(dol_file.GetSize());
+ dol_file.Seek(0, SEEK_SET);
+ dol_file.ReadBytes(m_dol.data(), m_dol.size());
- Write32((u32)(m_dol_address >> m_address_shift), 0x0420, &m_disk_header);
+ if (DolReader(std::move(dol_file)).IsWii())
+ SetDiskTypeWii();
+ else
+ SetDiskTypeGC();
- // 32byte aligned (plus 0x20 padding)
- m_fst_address = Common::AlignUp(m_dol_address + m_dol.size() + 0x20, 0x20ull);
- }
+ Write32((u32)(m_dol_address >> m_address_shift), 0x0420, &m_disk_header);
+
+ // 32byte aligned (plus 0x20 padding)
+ m_fst_address = Common::AlignUp(m_dol_address + m_dol.size() + 0x20, 0x20ull);
}
-void VolumeDirectory::BuildFST()
+void DirectoryBlobReader::BuildFST()
{
m_fst_data.clear();
- File::FSTEntry rootEntry = File::ScanDirectoryTree(m_root_directory, true);
+ File::FSTEntry rootEntry = File::ScanDirectoryTree(m_root_directory + "files/", true);
ConvertUTF8NamesToSHIFTJIS(rootEntry);
@@ -395,8 +364,9 @@ void VolumeDirectory::BuildFST()
Write32((u32)(m_fst_data.size() >> m_address_shift), 0x042c, &m_disk_header);
}
-void VolumeDirectory::WriteToBuffer(u64 source_start_address, u64 source_length, const u8* source,
- u64* address, u64* length, u8** buffer) const
+void DirectoryBlobReader::WriteToBuffer(u64 source_start_address, u64 source_length,
+ const u8* source, u64* address, u64* length,
+ u8** buffer) const
{
if (*length == 0)
return;
@@ -417,7 +387,8 @@ void VolumeDirectory::WriteToBuffer(u64 source_start_address, u64 source_length,
}
}
-void VolumeDirectory::PadToAddress(u64 start_address, u64* address, u64* length, u8** buffer) const
+void DirectoryBlobReader::PadToAddress(u64 start_address, u64* address, u64* length,
+ u8** buffer) const
{
if (start_address > *address && *length > 0)
{
@@ -429,7 +400,7 @@ void VolumeDirectory::PadToAddress(u64 start_address, u64* address, u64* length,
}
}
-void VolumeDirectory::Write32(u32 data, u32 offset, std::vector<u8>* const buffer)
+void DirectoryBlobReader::Write32(u32 data, u32 offset, std::vector<u8>* const buffer)
{
(*buffer)[offset++] = (data >> 24);
(*buffer)[offset++] = (data >> 16) & 0xff;
@@ -437,8 +408,8 @@ void VolumeDirectory::Write32(u32 data, u32 offset, std::vector<u8>* const buffe
(*buffer)[offset] = (data)&0xff;
}
-void VolumeDirectory::WriteEntryData(u32* entry_offset, u8 type, u32 name_offset, u64 data_offset,
- u64 length, u32 address_shift)
+void DirectoryBlobReader::WriteEntryData(u32* entry_offset, u8 type, u32 name_offset,
+ u64 data_offset, u64 length, u32 address_shift)
{
m_fst_data[(*entry_offset)++] = type;
@@ -453,15 +424,15 @@ void VolumeDirectory::WriteEntryData(u32* entry_offset, u8 type, u32 name_offset
*entry_offset += 4;
}
-void VolumeDirectory::WriteEntryName(u32* name_offset, const std::string& name)
+void DirectoryBlobReader::WriteEntryName(u32* name_offset, const std::string& name)
{
strncpy((char*)&m_fst_data[*name_offset + m_fst_name_offset], name.c_str(), name.length() + 1);
*name_offset += (u32)(name.length() + 1);
}
-void VolumeDirectory::WriteDirectory(const File::FSTEntry& parent_entry, u32* fst_offset,
- u32* name_offset, u64* data_offset, u32 parent_entry_index)
+void DirectoryBlobReader::WriteDirectory(const File::FSTEntry& parent_entry, u32* fst_offset,
+ u32* name_offset, u64* data_offset, u32 parent_entry_index)
{
std::vector<File::FSTEntry> sorted_entries = parent_entry.children;
diff --git a/Source/Core/DiscIO/VolumeDirectory.h b/Source/Core/DiscIO/DirectoryBlob.h
index 360570b063..f79929615d 100644
--- a/Source/Core/DiscIO/VolumeDirectory.h
+++ b/Source/Core/DiscIO/DirectoryBlob.h
@@ -11,74 +11,48 @@
#include <vector>
#include "Common/CommonTypes.h"
-#include "DiscIO/Volume.h"
+#include "Common/FileUtil.h"
+#include "DiscIO/Blob.h"
namespace File
{
struct FSTEntry;
+class IOFile;
}
-//
-// --- this volume type is used for reading files directly from the hard drive ---
-//
-
namespace DiscIO
{
-enum class BlobType;
-enum class Country;
-enum class Language;
-enum class Region;
-enum class Platform;
-
-class VolumeDirectory : public Volume
+class DirectoryBlobReader : public BlobReader
{
public:
- VolumeDirectory(const std::string& directory, bool is_wii, const std::string& apploader = "",
- const std::string& dol = "");
+ static bool IsValidDirectoryBlob(const std::string& dol_path);
+ static std::unique_ptr<DirectoryBlobReader> Create(File::IOFile dol, const std::string& dol_path);
- ~VolumeDirectory();
+ bool Read(u64 offset, u64 length, u8* buffer) override;
+ bool SupportsReadWiiDecrypted() const override;
+ bool ReadWiiDecrypted(u64 offset, u64 size, u8* buffer, u64 partition_offset) override;
- static bool IsValidDirectory(const std::string& directory);
-
- bool Read(u64 offset, u64 length, u8* buffer, const Partition& partition) const override;
- std::vector<Partition> GetPartitions() const override;
- Partition GetGamePartition() const override;
+ BlobType GetBlobType() const override;
+ u64 GetRawSize() const override;
+ u64 GetDataSize() const override;
- std::string GetGameID(const Partition& partition = PARTITION_NONE) const override;
void SetGameID(const std::string& id);
-
- std::string GetMakerID(const Partition& partition = PARTITION_NONE) const override;
-
- std::optional<u16> GetRevision(const Partition& partition = PARTITION_NONE) const override
- {
- return {};
- }
- std::string GetInternalName(const Partition& partition = PARTITION_NONE) const override;
- std::map<Language, std::string> GetLongNames() const override;
- std::vector<u32> GetBanner(int* width, int* height) const override;
void SetName(const std::string&);
- std::string GetApploaderDate(const Partition& partition = PARTITION_NONE) const override;
- Platform GetVolumeType() const override;
-
- Region GetRegion() const override;
- Country GetCountry(const Partition& partition = PARTITION_NONE) const override;
-
- BlobType GetBlobType() const override;
- u64 GetSize() const override;
- u64 GetRawSize() const override;
-
void BuildFST();
private:
- static std::string ExtractDirectoryName(const std::string& directory);
+ DirectoryBlobReader(File::IOFile dol_file, const std::string& root_directory);
+
+ bool ReadPartition(u64 offset, u64 length, u8* buffer);
+ bool ReadNonPartition(u64 offset, u64 length, u8* buffer);
void SetDiskTypeWii();
void SetDiskTypeGC();
bool SetApploader(const std::string& apploader);
- void SetDOL(const std::string& dol);
+ void SetDOLAndDiskType(File::IOFile dol_file);
// writing to read buffer
void WriteToBuffer(u64 source_start_address, u64 source_length, const u8* source, u64* address,
@@ -99,10 +73,10 @@ private:
std::map<u64, std::string> m_virtual_disk;
- bool m_is_wii;
+ bool m_is_wii = false;
// GameCube has no shift, Wii has 2 bit shift
- u32 m_address_shift;
+ u32 m_address_shift = 0;
// first address on disk containing file data
u64 m_data_start_address;
diff --git a/Source/Core/DiscIO/DiscIO.vcxproj b/Source/Core/DiscIO/DiscIO.vcxproj
index 3a978ad262..b7ef5b9875 100644
--- a/Source/Core/DiscIO/DiscIO.vcxproj
+++ b/Source/Core/DiscIO/DiscIO.vcxproj
@@ -39,6 +39,7 @@
<ClCompile Include="Blob.cpp" />
<ClCompile Include="CISOBlob.cpp" />
<ClCompile Include="CompressedBlob.cpp" />
+ <ClCompile Include="DirectoryBlob.cpp" />
<ClCompile Include="DiscExtractor.cpp" />
<ClCompile Include="DiscScrubber.cpp" />
<ClCompile Include="DriveBlob.cpp" />
@@ -50,7 +51,6 @@
<ClCompile Include="NANDImporter.cpp" />
<ClCompile Include="TGCBlob.cpp" />
<ClCompile Include="Volume.cpp" />
- <ClCompile Include="VolumeDirectory.cpp" />
<ClCompile Include="VolumeGC.cpp" />
<ClCompile Include="VolumeWad.cpp" />
<ClCompile Include="VolumeWii.cpp" />
@@ -61,6 +61,7 @@
<ClInclude Include="Blob.h" />
<ClInclude Include="CISOBlob.h" />
<ClInclude Include="CompressedBlob.h" />
+ <ClInclude Include="DirectoryBlob.h" />
<ClInclude Include="DiscExtractor.h" />
<ClInclude Include="DiscScrubber.h" />
<ClInclude Include="DriveBlob.h" />
@@ -72,7 +73,6 @@
<ClInclude Include="NANDImporter.h" />
<ClInclude Include="TGCBlob.h" />
<ClInclude Include="Volume.h" />
- <ClInclude Include="VolumeDirectory.h" />
<ClInclude Include="VolumeGC.h" />
<ClInclude Include="VolumeWad.h" />
<ClInclude Include="VolumeWii.h" />
diff --git a/Source/Core/DiscIO/DiscIO.vcxproj.filters b/Source/Core/DiscIO/DiscIO.vcxproj.filters
index 3c1f85ca10..3cebc18705 100644
--- a/Source/Core/DiscIO/DiscIO.vcxproj.filters
+++ b/Source/Core/DiscIO/DiscIO.vcxproj.filters
@@ -57,8 +57,8 @@
<ClCompile Include="WbfsBlob.cpp">
<Filter>Volume\Blob</Filter>
</ClCompile>
- <ClCompile Include="VolumeDirectory.cpp">
- <Filter>Volume</Filter>
+ <ClCompile Include="DirectoryBlob.cpp">
+ <Filter>Volume\Blob</Filter>
</ClCompile>
<ClCompile Include="VolumeGC.cpp">
<Filter>Volume</Filter>
@@ -122,8 +122,8 @@
<ClInclude Include="Volume.h">
<Filter>Volume</Filter>
</ClInclude>
- <ClInclude Include="VolumeDirectory.h">
- <Filter>Volume</Filter>
+ <ClInclude Include="DirectoryBlob.h">
+ <Filter>Volume\Blob</Filter>
</ClInclude>
<ClInclude Include="VolumeGC.h">
<Filter>Volume</Filter>
diff --git a/Source/Core/DiscIO/Volume.cpp b/Source/Core/DiscIO/Volume.cpp
index 876136e6b9..014eda7d31 100644
--- a/Source/Core/DiscIO/Volume.cpp
+++ b/Source/Core/DiscIO/Volume.cpp
@@ -22,7 +22,6 @@
#include "DiscIO/Blob.h"
#include "DiscIO/Enums.h"
-#include "DiscIO/VolumeDirectory.h"
#include "DiscIO/VolumeGC.h"
#include "DiscIO/VolumeWad.h"
#include "DiscIO/VolumeWii.h"
@@ -112,14 +111,4 @@ std::unique_ptr<Volume> CreateVolumeFromFilename(const std::string& filename)
return nullptr;
}
-std::unique_ptr<Volume> CreateVolumeFromDirectory(const std::string& directory, bool is_wii,
- const std::string& apploader,
- const std::string& dol)
-{
- if (VolumeDirectory::IsValidDirectory(directory))
- return std::make_unique<VolumeDirectory>(directory, is_wii, apploader, dol);
-
- return nullptr;
-}
-
} // namespace
diff --git a/Source/Core/DiscIO/Volume.h b/Source/Core/DiscIO/Volume.h
index 209a0d09a9..979a63a23f 100644
--- a/Source/Core/DiscIO/Volume.h
+++ b/Source/Core/DiscIO/Volume.h
@@ -120,8 +120,5 @@ protected:
};
std::unique_ptr<Volume> CreateVolumeFromFilename(const std::string& filename);
-std::unique_ptr<Volume> CreateVolumeFromDirectory(const std::string& directory, bool is_wii,
- const std::string& apploader = "",
- const std::string& dol = "");
} // namespace