mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-15 05:47:56 -07:00
Merge pull request #6807 from leoetlino/boot
Boot: Migrate to new filesystem interface
This commit is contained in:
commit
e1866d35e5
@ -19,8 +19,6 @@
|
||||
#endif
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/File.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/SettingsHandler.h"
|
||||
#include "Common/Timer.h"
|
||||
|
||||
@ -29,33 +27,24 @@ SettingsHandler::SettingsHandler()
|
||||
Reset();
|
||||
}
|
||||
|
||||
bool SettingsHandler::Open(const std::string& settings_file_path)
|
||||
SettingsHandler::SettingsHandler(Buffer&& buffer)
|
||||
{
|
||||
SetBytes(std::move(buffer));
|
||||
}
|
||||
|
||||
const SettingsHandler::Buffer& SettingsHandler::GetBytes() const
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
void SettingsHandler::SetBytes(SettingsHandler::Buffer&& buffer)
|
||||
{
|
||||
Reset();
|
||||
|
||||
File::IOFile file{settings_file_path, "rb"};
|
||||
if (!file.ReadBytes(m_buffer.data(), m_buffer.size()))
|
||||
return false;
|
||||
|
||||
m_buffer = std::move(buffer);
|
||||
Decrypt();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SettingsHandler::Save(const std::string& destination_file_path) const
|
||||
{
|
||||
if (!File::CreateFullPath(destination_file_path))
|
||||
return false;
|
||||
|
||||
File::IOFile file{destination_file_path, "wb"};
|
||||
return file.WriteBytes(m_buffer.data(), m_buffer.size());
|
||||
}
|
||||
|
||||
const u8* SettingsHandler::GetData() const
|
||||
{
|
||||
return m_buffer.data();
|
||||
}
|
||||
|
||||
const std::string SettingsHandler::GetValue(const std::string& key)
|
||||
std::string SettingsHandler::GetValue(const std::string& key) const
|
||||
{
|
||||
std::string delim = std::string("\r\n");
|
||||
std::string toFind = delim + key + "=";
|
||||
|
@ -21,15 +21,15 @@ public:
|
||||
INITIAL_SEED = 0x73B5DBFA
|
||||
};
|
||||
|
||||
using Buffer = std::array<u8, SETTINGS_SIZE>;
|
||||
SettingsHandler();
|
||||
|
||||
bool Open(const std::string& settings_file_path);
|
||||
bool Save(const std::string& destination_file_path) const;
|
||||
explicit SettingsHandler(Buffer&& buffer);
|
||||
|
||||
void AddSetting(const std::string& key, const std::string& value);
|
||||
|
||||
const u8* GetData() const;
|
||||
const std::string GetValue(const std::string& key);
|
||||
const Buffer& GetBytes() const;
|
||||
void SetBytes(Buffer&& buffer);
|
||||
std::string GetValue(const std::string& key) const;
|
||||
|
||||
void Decrypt();
|
||||
void Reset();
|
||||
|
@ -39,7 +39,10 @@
|
||||
#include "Core/HW/Memmap.h"
|
||||
#include "Core/HW/VideoInterface.h"
|
||||
#include "Core/Host.h"
|
||||
#include "Core/IOS/ES/ES.h"
|
||||
#include "Core/IOS/FS/FileSystem.h"
|
||||
#include "Core/IOS/IOS.h"
|
||||
#include "Core/IOS/Uids.h"
|
||||
#include "Core/PatchEngine.h"
|
||||
#include "Core/PowerPC/PPCAnalyst.h"
|
||||
#include "Core/PowerPC/PPCSymbolDB.h"
|
||||
@ -470,26 +473,28 @@ void StateFlags::UpdateChecksum()
|
||||
|
||||
void UpdateStateFlags(std::function<void(StateFlags*)> update_function)
|
||||
{
|
||||
const std::string file_path =
|
||||
Common::GetTitleDataPath(Titles::SYSTEM_MENU, Common::FROM_SESSION_ROOT) + "/" WII_STATE;
|
||||
CreateSystemMenuTitleDirs();
|
||||
const std::string file_path = Common::GetTitleDataPath(Titles::SYSTEM_MENU) + "/" WII_STATE;
|
||||
const auto fs = IOS::HLE::GetIOS()->GetFS();
|
||||
constexpr IOS::HLE::FS::Mode rw_mode = IOS::HLE::FS::Mode::ReadWrite;
|
||||
const auto file = fs->CreateAndOpenFile(IOS::SYSMENU_UID, IOS::SYSMENU_GID, file_path, rw_mode,
|
||||
rw_mode, rw_mode);
|
||||
if (!file)
|
||||
return;
|
||||
|
||||
File::IOFile file;
|
||||
StateFlags state;
|
||||
if (File::Exists(file_path))
|
||||
{
|
||||
file.Open(file_path, "r+b");
|
||||
file.ReadBytes(&state, sizeof(state));
|
||||
}
|
||||
else
|
||||
{
|
||||
File::CreateFullPath(file_path);
|
||||
file.Open(file_path, "a+b");
|
||||
memset(&state, 0, sizeof(state));
|
||||
}
|
||||
StateFlags state{};
|
||||
if (file->GetStatus()->size == sizeof(StateFlags))
|
||||
file->Read(&state, 1);
|
||||
|
||||
update_function(&state);
|
||||
state.UpdateChecksum();
|
||||
|
||||
file.Seek(0, SEEK_SET);
|
||||
file.WriteBytes(&state, sizeof(state));
|
||||
file->Seek(0, IOS::HLE::FS::SeekMode::Set);
|
||||
file->Write(&state, 1);
|
||||
}
|
||||
|
||||
void CreateSystemMenuTitleDirs()
|
||||
{
|
||||
const auto es = IOS::HLE::GetIOS()->GetES();
|
||||
es->CreateTitleDirectories(Titles::SYSTEM_MENU, IOS::SYSMENU_GID);
|
||||
}
|
||||
|
@ -151,3 +151,9 @@ struct StateFlags
|
||||
// Reads the state file from the NAND, then calls the passed update function to update the struct,
|
||||
// and finally writes the updated state file to the NAND.
|
||||
void UpdateStateFlags(std::function<void(StateFlags*)> update_function);
|
||||
|
||||
/// Create title directories for the system menu (if needed).
|
||||
///
|
||||
/// Normally, this is automatically done by ES when the System Menu is installed,
|
||||
/// but we cannot rely on this because we don't require any system titles to be installed.
|
||||
void CreateSystemMenuTitleDirs();
|
||||
|
@ -9,8 +9,6 @@
|
||||
|
||||
#include "Common/CommonPaths.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/File.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
#include "Common/NandPaths.h"
|
||||
@ -25,7 +23,9 @@
|
||||
#include "Core/HW/Memmap.h"
|
||||
#include "Core/IOS/ES/ES.h"
|
||||
#include "Core/IOS/ES/Formats.h"
|
||||
#include "Core/IOS/FS/FileSystem.h"
|
||||
#include "Core/IOS/IOS.h"
|
||||
#include "Core/IOS/Uids.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
#include "DiscIO/Enums.h"
|
||||
@ -225,15 +225,23 @@ bool CBoot::SetupWiiMemory()
|
||||
|
||||
SettingsHandler gen;
|
||||
std::string serno;
|
||||
const std::string settings_file_path(
|
||||
Common::GetTitleDataPath(Titles::SYSTEM_MENU, Common::FROM_SESSION_ROOT) + "/" WII_SETTING);
|
||||
if (File::Exists(settings_file_path) && gen.Open(settings_file_path))
|
||||
CreateSystemMenuTitleDirs();
|
||||
const std::string settings_file_path(Common::GetTitleDataPath(Titles::SYSTEM_MENU) +
|
||||
"/" WII_SETTING);
|
||||
|
||||
const auto fs = IOS::HLE::GetIOS()->GetFS();
|
||||
{
|
||||
SettingsHandler::Buffer data;
|
||||
const auto file = fs->OpenFile(IOS::SYSMENU_UID, IOS::SYSMENU_GID, settings_file_path,
|
||||
IOS::HLE::FS::Mode::Read);
|
||||
if (file && file->Read(data.data(), data.size()))
|
||||
{
|
||||
gen.SetBytes(std::move(data));
|
||||
serno = gen.GetValue("SERNO");
|
||||
gen.Reset();
|
||||
|
||||
File::Delete(settings_file_path);
|
||||
}
|
||||
}
|
||||
fs->Delete(IOS::SYSMENU_UID, IOS::SYSMENU_GID, settings_file_path);
|
||||
|
||||
if (serno.empty() || serno == "000000000")
|
||||
{
|
||||
@ -258,14 +266,17 @@ bool CBoot::SetupWiiMemory()
|
||||
gen.AddSetting("VIDEO", region_setting.video);
|
||||
gen.AddSetting("GAME", region_setting.game);
|
||||
|
||||
if (!gen.Save(settings_file_path))
|
||||
constexpr IOS::HLE::FS::Mode rw_mode = IOS::HLE::FS::Mode::ReadWrite;
|
||||
const auto settings_file = fs->CreateAndOpenFile(IOS::SYSMENU_UID, IOS::SYSMENU_GID,
|
||||
settings_file_path, rw_mode, rw_mode, rw_mode);
|
||||
if (!settings_file || !settings_file->Write(gen.GetBytes().data(), gen.GetBytes().size()))
|
||||
{
|
||||
PanicAlertT("SetupWiiMemory: Can't create setting.txt file");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write the 256 byte setting.txt to memory.
|
||||
Memory::CopyToEmu(0x3800, gen.GetData(), SettingsHandler::SETTINGS_SIZE);
|
||||
Memory::CopyToEmu(0x3800, gen.GetBytes().data(), gen.GetBytes().size());
|
||||
|
||||
INFO_LOG(BOOT, "Setup Wii Memory...");
|
||||
|
||||
@ -326,11 +337,16 @@ bool CBoot::SetupWiiMemory()
|
||||
|
||||
static void WriteEmptyPlayRecord()
|
||||
{
|
||||
const std::string file_path =
|
||||
Common::GetTitleDataPath(Titles::SYSTEM_MENU, Common::FROM_SESSION_ROOT) + "/play_rec.dat";
|
||||
File::IOFile playrec_file(file_path, "r+b");
|
||||
CreateSystemMenuTitleDirs();
|
||||
const std::string file_path = Common::GetTitleDataPath(Titles::SYSTEM_MENU) + "/play_rec.dat";
|
||||
const auto fs = IOS::HLE::GetIOS()->GetFS();
|
||||
constexpr IOS::HLE::FS::Mode rw_mode = IOS::HLE::FS::Mode::ReadWrite;
|
||||
const auto playrec_file = fs->CreateAndOpenFile(IOS::SYSMENU_UID, IOS::SYSMENU_GID, file_path,
|
||||
rw_mode, rw_mode, rw_mode);
|
||||
if (!playrec_file)
|
||||
return;
|
||||
std::vector<u8> empty_record(0x80);
|
||||
playrec_file.WriteBytes(empty_record.data(), empty_record.size());
|
||||
playrec_file->Write(empty_record.data(), empty_record.size());
|
||||
}
|
||||
|
||||
// __________________________________________________________________________________________________
|
||||
|
@ -139,6 +139,8 @@ public:
|
||||
ReturnCode SetUpStreamKey(u32 uid, const u8* ticket_view, const IOS::ES::TMDReader& tmd,
|
||||
u32* handle);
|
||||
|
||||
bool CreateTitleDirectories(u64 title_id, u16 group_id) const;
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
|
@ -222,40 +222,56 @@ static bool DeleteDirectoriesIfEmpty(FS::FileSystem* fs, const std::string& path
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ES::InitImport(const IOS::ES::TMDReader& tmd)
|
||||
bool ES::CreateTitleDirectories(u64 title_id, u16 group_id) const
|
||||
{
|
||||
const auto fs = m_ios.GetFS();
|
||||
const std::string content_dir = Common::GetTitleContentPath(tmd.GetTitleId());
|
||||
const std::string import_content_dir = Common::GetImportTitlePath(tmd.GetTitleId()) + "/content";
|
||||
|
||||
const std::string content_dir = Common::GetTitleContentPath(title_id);
|
||||
const auto result1 = fs->CreateFullPath(PID_KERNEL, PID_KERNEL, content_dir + '/', 0,
|
||||
FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::Read);
|
||||
const auto result2 = fs->SetMetadata(PID_KERNEL, content_dir, PID_KERNEL, PID_KERNEL, 0,
|
||||
FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::None);
|
||||
const auto result3 = fs->CreateFullPath(PID_KERNEL, PID_KERNEL, import_content_dir + '/', 0,
|
||||
FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::None);
|
||||
if (result1 != FS::ResultCode::Success || result2 != FS::ResultCode::Success ||
|
||||
result3 != FS::ResultCode::Success)
|
||||
if (result1 != FS::ResultCode::Success || result2 != FS::ResultCode::Success)
|
||||
{
|
||||
ERROR_LOG(IOS_ES, "InitImport: Failed to create content dir for %016" PRIx64, tmd.GetTitleId());
|
||||
ERROR_LOG(IOS_ES, "Failed to create or set metadata on content dir for %016" PRIx64, title_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string data_dir = Common::GetTitleDataPath(tmd.GetTitleId());
|
||||
const std::string data_dir = Common::GetTitleDataPath(title_id);
|
||||
const auto data_dir_contents = fs->ReadDirectory(PID_KERNEL, PID_KERNEL, data_dir);
|
||||
if (!data_dir_contents &&
|
||||
(data_dir_contents.Error() != FS::ResultCode::NotFound ||
|
||||
fs->CreateDirectory(PID_KERNEL, PID_KERNEL, data_dir, 0, FS::Mode::ReadWrite, FS::Mode::None,
|
||||
FS::Mode::None) != FS::ResultCode::Success))
|
||||
{
|
||||
ERROR_LOG(IOS_ES, "Failed to create data dir for %016" PRIx64, title_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
IOS::ES::UIDSys uid_sys{fs};
|
||||
const u32 uid = uid_sys.GetOrInsertUIDForTitle(tmd.GetTitleId());
|
||||
if (fs->SetMetadata(0, data_dir, uid, tmd.GetGroupId(), 0, FS::Mode::ReadWrite, FS::Mode::None,
|
||||
const u32 uid = uid_sys.GetOrInsertUIDForTitle(title_id);
|
||||
if (fs->SetMetadata(0, data_dir, uid, group_id, 0, FS::Mode::ReadWrite, FS::Mode::None,
|
||||
FS::Mode::None) != FS::ResultCode::Success)
|
||||
{
|
||||
ERROR_LOG(IOS_ES, "Failed to set metadata on data dir for %016" PRIx64, title_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ES::InitImport(const IOS::ES::TMDReader& tmd)
|
||||
{
|
||||
if (!CreateTitleDirectories(tmd.GetTitleId(), tmd.GetGroupId()))
|
||||
return false;
|
||||
|
||||
const auto fs = m_ios.GetFS();
|
||||
const std::string import_content_dir = Common::GetImportTitlePath(tmd.GetTitleId()) + "/content";
|
||||
const auto result = fs->CreateFullPath(PID_KERNEL, PID_KERNEL, import_content_dir + '/', 0,
|
||||
FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::None);
|
||||
if (result != FS::ResultCode::Success)
|
||||
{
|
||||
ERROR_LOG(IOS_ES, "InitImport: Failed to create content dir for %016" PRIx64, tmd.GetTitleId());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -265,8 +281,9 @@ bool ES::InitImport(const IOS::ES::TMDReader& tmd)
|
||||
if (!file_info || !file_info->is_file)
|
||||
return true;
|
||||
|
||||
const auto result = fs->Rename(PID_KERNEL, PID_KERNEL, content_dir, import_content_dir);
|
||||
if (result != FS::ResultCode::Success)
|
||||
const std::string content_dir = Common::GetTitleContentPath(tmd.GetTitleId());
|
||||
const auto rename_result = fs->Rename(PID_KERNEL, PID_KERNEL, content_dir, import_content_dir);
|
||||
if (rename_result != FS::ResultCode::Success)
|
||||
{
|
||||
ERROR_LOG(IOS_ES, "InitImport: Failed to move content dir for %016" PRIx64, tmd.GetTitleId());
|
||||
return false;
|
||||
|
@ -16,7 +16,9 @@
|
||||
|
||||
#include "Core/CommonTitles.h"
|
||||
#include "Core/HW/Memmap.h"
|
||||
#include "Core/IOS/FS/FileSystem.h"
|
||||
#include "Core/IOS/Network/Socket.h"
|
||||
#include "Core/IOS/Uids.h"
|
||||
|
||||
namespace IOS
|
||||
{
|
||||
@ -82,20 +84,23 @@ IPCCommandResult NetKDRequest::IOCtl(const IOCtlRequest& request)
|
||||
INFO_LOG(IOS_WC24, "NET_KD_REQ: IOCTL_NWC24_REQUEST_GENERATED_USER_ID");
|
||||
if (config.CreationStage() == NWC24::NWC24Config::NWC24_IDCS_INITIAL)
|
||||
{
|
||||
const std::string settings_file_path(
|
||||
Common::GetTitleDataPath(Titles::SYSTEM_MENU, Common::FROM_SESSION_ROOT) +
|
||||
"/" WII_SETTING);
|
||||
SettingsHandler gen;
|
||||
const std::string settings_file_path =
|
||||
Common::GetTitleDataPath(Titles::SYSTEM_MENU) + "/" WII_SETTING;
|
||||
std::string area, model;
|
||||
bool got_settings = false;
|
||||
|
||||
if (File::Exists(settings_file_path) && gen.Open(settings_file_path))
|
||||
const auto fs = m_ios.GetFS();
|
||||
if (const auto file = fs->OpenFile(PID_KD, PID_KD, settings_file_path, FS::Mode::Read))
|
||||
{
|
||||
SettingsHandler::Buffer data;
|
||||
if (file->Read(data.data(), data.size()))
|
||||
{
|
||||
const SettingsHandler gen{std::move(data)};
|
||||
area = gen.GetValue("AREA");
|
||||
model = gen.GetValue("MODEL");
|
||||
got_settings = true;
|
||||
}
|
||||
if (got_settings)
|
||||
}
|
||||
|
||||
if (!area.empty() && !model.empty())
|
||||
{
|
||||
u8 area_code = GetAreaCode(area);
|
||||
u8 id_ctr = config.IdGen();
|
||||
|
Loading…
Reference in New Issue
Block a user