WiiUtils: Add utility functions to handle prep-work for importing 'SD-card export' style Wii saves.
This commit is contained in:
parent
7abe1085e3
commit
46e4c17db3
|
@ -19,6 +19,7 @@
|
|||
#include <fmt/format.h>
|
||||
#include <pugixml.hpp>
|
||||
|
||||
#include "Common/Align.h"
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/FileUtil.h"
|
||||
|
@ -223,6 +224,67 @@ bool IsTitleInstalled(u64 title_id)
|
|||
[](const std::string& file) { return file != "title.tmd"; });
|
||||
}
|
||||
|
||||
bool IsTMDImported(IOS::HLE::FS::FileSystem& fs, u64 title_id)
|
||||
{
|
||||
const auto entries = fs.ReadDirectory(0, 0, Common::GetTitleContentPath(title_id));
|
||||
return entries && std::any_of(entries->begin(), entries->end(),
|
||||
[](const std::string& file) { return file == "title.tmd"; });
|
||||
}
|
||||
|
||||
IOS::ES::TMDReader FindBackupTMD(IOS::HLE::FS::FileSystem& fs, u64 title_id)
|
||||
{
|
||||
auto file = fs.OpenFile(IOS::PID_KERNEL, IOS::PID_KERNEL,
|
||||
"/title/00000001/00000002/data/tmds.sys", IOS::HLE::FS::Mode::Read);
|
||||
if (!file)
|
||||
return {};
|
||||
|
||||
// structure of this file is as follows:
|
||||
// - 32 bytes descriptor of a TMD, which contains a title ID and a length
|
||||
// - the TMD, with padding aligning to 32 bytes
|
||||
// - repeat for as many TMDs as stored
|
||||
while (true)
|
||||
{
|
||||
std::array<u8, 32> descriptor;
|
||||
if (!file->Read(descriptor.data(), descriptor.size()))
|
||||
return {};
|
||||
|
||||
const u64 tid = Common::swap64(descriptor.data());
|
||||
const u32 tmd_length = Common::swap32(descriptor.data() + 8);
|
||||
if (tid == title_id)
|
||||
{
|
||||
// found the right TMD
|
||||
std::vector<u8> tmd_bytes(tmd_length);
|
||||
if (!file->Read(tmd_bytes.data(), tmd_length))
|
||||
return {};
|
||||
return IOS::ES::TMDReader(std::move(tmd_bytes));
|
||||
}
|
||||
|
||||
// not the right TMD, skip this one and go to the next
|
||||
if (!file->Seek(Common::AlignUp(tmd_length, 32), IOS::HLE::FS::SeekMode::Current))
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
bool EnsureTMDIsImported(IOS::HLE::FS::FileSystem& fs, IOS::HLE::Device::ES& es, u64 title_id)
|
||||
{
|
||||
if (IsTMDImported(fs, title_id))
|
||||
return true;
|
||||
|
||||
auto tmd = FindBackupTMD(fs, title_id);
|
||||
if (!tmd.IsValid())
|
||||
return false;
|
||||
|
||||
IOS::HLE::Device::ES::Context context;
|
||||
context.uid = IOS::SYSMENU_UID;
|
||||
context.gid = IOS::SYSMENU_GID;
|
||||
const auto import_result =
|
||||
es.ImportTmd(context, tmd.GetBytes(), Titles::SYSTEM_MENU, IOS::ES::TITLE_TYPE_DEFAULT);
|
||||
if (import_result != IOS::HLE::IPC_SUCCESS)
|
||||
return false;
|
||||
|
||||
return es.ImportTitleDone(context) == IOS::HLE::IPC_SUCCESS;
|
||||
}
|
||||
|
||||
// Common functionality for system updaters.
|
||||
class SystemUpdater
|
||||
{
|
||||
|
|
|
@ -6,10 +6,12 @@
|
|||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/IOS/ES/Formats.h"
|
||||
|
||||
// Small utility functions for common Wii related tasks.
|
||||
|
||||
|
@ -23,6 +25,16 @@ namespace IOS::HLE
|
|||
class Kernel;
|
||||
}
|
||||
|
||||
namespace IOS::HLE::FS
|
||||
{
|
||||
class FileSystem;
|
||||
}
|
||||
|
||||
namespace IOS::HLE::Device
|
||||
{
|
||||
class ES;
|
||||
}
|
||||
|
||||
namespace WiiUtils
|
||||
{
|
||||
enum class InstallType
|
||||
|
@ -40,6 +52,18 @@ bool UninstallTitle(u64 title_id);
|
|||
|
||||
bool IsTitleInstalled(u64 title_id);
|
||||
|
||||
// Checks if there's a title.tmd imported for the given title ID.
|
||||
bool IsTMDImported(IOS::HLE::FS::FileSystem& fs, u64 title_id);
|
||||
|
||||
// Searches for a TMD matching the given title ID in /title/00000001/00000002/data/tmds.sys.
|
||||
// Returns it if it exists, otherwise returns an empty invalid TMD.
|
||||
IOS::ES::TMDReader FindBackupTMD(IOS::HLE::FS::FileSystem& fs, u64 title_id);
|
||||
|
||||
// Checks if there's a title.tmd imported for the given title ID. If there is not, we attempt to
|
||||
// re-import it from the TMDs stored in /title/00000001/00000002/data/tmds.sys.
|
||||
// Returns true if, after this function call, we have an imported title.tmd, or false if not.
|
||||
bool EnsureTMDIsImported(IOS::HLE::FS::FileSystem& fs, IOS::HLE::Device::ES& es, u64 title_id);
|
||||
|
||||
enum class UpdateResult
|
||||
{
|
||||
Succeeded,
|
||||
|
|
Loading…
Reference in New Issue