Merge pull request #5309 from leoetlino/ios-uid-gid
IOS: Implement UID/GID changes for the PPC
This commit is contained in:
commit
286e9b74ee
|
@ -158,6 +158,21 @@ IPCCommandResult ES::GetTitleID(const IOCtlVRequest& request)
|
|||
return GetDefaultReply(IPC_SUCCESS);
|
||||
}
|
||||
|
||||
static bool UpdateUIDAndGID(const IOS::ES::TMDReader& tmd)
|
||||
{
|
||||
IOS::ES::UIDSys uid_sys{Common::FromWhichRoot::FROM_SESSION_ROOT};
|
||||
const u64 title_id = tmd.GetTitleId();
|
||||
const u32 uid = uid_sys.GetOrInsertUIDForTitle(title_id);
|
||||
if (!uid)
|
||||
{
|
||||
ERROR_LOG(IOS_ES, "Failed to get UID for title %016" PRIx64, title_id);
|
||||
return false;
|
||||
}
|
||||
SetUIDForPPC(uid);
|
||||
SetGIDForPPC(tmd.GetGroupId());
|
||||
return true;
|
||||
}
|
||||
|
||||
IPCCommandResult ES::SetUID(const IOCtlVRequest& request)
|
||||
{
|
||||
if (!request.HasNumberOfValidVectors(1, 0))
|
||||
|
@ -226,6 +241,16 @@ bool ES::LaunchPPCTitle(u64 title_id, bool skip_reload)
|
|||
s_title_context.Update(content_loader);
|
||||
INFO_LOG(IOS_ES, "LaunchPPCTitle: Title context changed: %016" PRIx64,
|
||||
s_title_context.tmd.GetTitleId());
|
||||
|
||||
// Note: the UID/GID is also updated for IOS titles, but since we have no guarantee IOS titles
|
||||
// are installed, we can only do this for PPC titles.
|
||||
if (!UpdateUIDAndGID(s_title_context.tmd))
|
||||
{
|
||||
s_title_context.Clear();
|
||||
INFO_LOG(IOS_ES, "LaunchPPCTitle: Title context changed: (none)");
|
||||
return false;
|
||||
}
|
||||
|
||||
return BootstrapPPC(content_loader);
|
||||
}
|
||||
|
||||
|
@ -533,6 +558,9 @@ s32 ES::DIVerify(const IOS::ES::TMDReader& tmd, const IOS::ES::TicketReader& tic
|
|||
if (tmd.GetTitleId() != ticket.GetTitleId())
|
||||
return ES_EINVAL;
|
||||
|
||||
s_title_context.Update(tmd, ticket);
|
||||
INFO_LOG(IOS_ES, "ES_DIVerify: Title context changed: %016" PRIx64, tmd.GetTitleId());
|
||||
|
||||
std::string tmd_path = Common::GetTMDFileName(tmd.GetTitleId(), Common::FROM_SESSION_ROOT);
|
||||
|
||||
File::CreateFullPath(tmd_path);
|
||||
|
@ -545,14 +573,15 @@ s32 ES::DIVerify(const IOS::ES::TMDReader& tmd, const IOS::ES::TicketReader& tic
|
|||
if (!tmd_file.WriteBytes(tmd_bytes.data(), tmd_bytes.size()))
|
||||
ERROR_LOG(IOS_ES, "DIVerify failed to write disc TMD to NAND.");
|
||||
}
|
||||
IOS::ES::UIDSys uid_sys{Common::FromWhichRoot::FROM_SESSION_ROOT};
|
||||
uid_sys.AddTitle(tmd.GetTitleId());
|
||||
// DI_VERIFY writes to title.tmd, which is read and cached inside the NAND Content Manager.
|
||||
// clear the cache to avoid content access mismatches.
|
||||
DiscIO::CNANDContentManager::Access().ClearCache();
|
||||
|
||||
s_title_context.Update(tmd, ticket);
|
||||
INFO_LOG(IOS_ES, "ES_DIVerify: Title context changed: %016" PRIx64, tmd.GetTitleId());
|
||||
if (!UpdateUIDAndGID(s_title_context.tmd))
|
||||
{
|
||||
return ES_SHORT_READ;
|
||||
}
|
||||
|
||||
return IPC_SUCCESS;
|
||||
}
|
||||
} // namespace Device
|
||||
|
|
|
@ -446,11 +446,11 @@ UIDSys::UIDSys(Common::FromWhichRoot root)
|
|||
|
||||
if (m_entries.empty())
|
||||
{
|
||||
AddTitle(TITLEID_SYSMENU);
|
||||
GetOrInsertUIDForTitle(TITLEID_SYSMENU);
|
||||
}
|
||||
}
|
||||
|
||||
u32 UIDSys::GetUIDFromTitle(u64 title_id)
|
||||
u32 UIDSys::GetUIDFromTitle(u64 title_id) const
|
||||
{
|
||||
const auto it = std::find_if(m_entries.begin(), m_entries.end(),
|
||||
[title_id](const auto& entry) { return entry.second == title_id; });
|
||||
|
@ -464,26 +464,33 @@ u32 UIDSys::GetNextUID() const
|
|||
return m_entries.rbegin()->first + 1;
|
||||
}
|
||||
|
||||
void UIDSys::AddTitle(u64 title_id)
|
||||
u32 UIDSys::GetOrInsertUIDForTitle(const u64 title_id)
|
||||
{
|
||||
if (GetUIDFromTitle(title_id))
|
||||
const u32 current_uid = GetUIDFromTitle(title_id);
|
||||
if (current_uid)
|
||||
{
|
||||
INFO_LOG(IOS_ES, "Title %016" PRIx64 " already exists in uid.sys", title_id);
|
||||
return;
|
||||
return current_uid;
|
||||
}
|
||||
|
||||
u32 uid = GetNextUID();
|
||||
const u32 uid = GetNextUID();
|
||||
m_entries.insert({uid, title_id});
|
||||
|
||||
// Byte swap before writing.
|
||||
title_id = Common::swap64(title_id);
|
||||
uid = Common::swap32(uid);
|
||||
const u64 swapped_title_id = Common::swap64(title_id);
|
||||
const u32 swapped_uid = Common::swap32(uid);
|
||||
|
||||
File::CreateFullPath(m_file_path);
|
||||
File::IOFile file(m_file_path, "ab");
|
||||
|
||||
if (!file.WriteBytes(&title_id, sizeof(title_id)) || !file.WriteBytes(&uid, sizeof(uid)))
|
||||
if (!file.WriteBytes(&swapped_title_id, sizeof(title_id)) ||
|
||||
!file.WriteBytes(&swapped_uid, sizeof(uid)))
|
||||
{
|
||||
ERROR_LOG(IOS_ES, "Failed to write to /sys/uid.sys");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return uid;
|
||||
}
|
||||
} // namespace ES
|
||||
} // namespace IOS
|
||||
|
|
|
@ -219,8 +219,8 @@ class UIDSys final
|
|||
public:
|
||||
explicit UIDSys(Common::FromWhichRoot root);
|
||||
|
||||
u32 GetUIDFromTitle(u64 title_id);
|
||||
void AddTitle(u64 title_id);
|
||||
u32 GetUIDFromTitle(u64 title_id) const;
|
||||
u32 GetOrInsertUIDForTitle(u64 title_id);
|
||||
u32 GetNextUID() const;
|
||||
|
||||
private:
|
||||
|
|
|
@ -194,7 +194,7 @@ bool InitImport(u64 title_id)
|
|||
}
|
||||
|
||||
UIDSys uid_sys{Common::FROM_CONFIGURED_ROOT};
|
||||
uid_sys.AddTitle(title_id);
|
||||
uid_sys.GetOrInsertUIDForTitle(title_id);
|
||||
|
||||
// IOS moves the title content directory to /import if the TMD exists during an import.
|
||||
if (File::Exists(Common::GetTMDFileName(title_id, Common::FROM_SESSION_ROOT)))
|
||||
|
|
|
@ -91,6 +91,9 @@ static u64 s_last_reply_time;
|
|||
|
||||
static u64 s_active_title_id;
|
||||
|
||||
static u32 s_ppc_uid;
|
||||
static u16 s_ppc_gid;
|
||||
|
||||
static constexpr u64 ENQUEUE_REQUEST_FLAG = 0x100000000ULL;
|
||||
static constexpr u64 ENQUEUE_ACKNOWLEDGEMENT_FLAG = 0x200000000ULL;
|
||||
|
||||
|
@ -702,6 +705,28 @@ bool Reload(const u64 ios_title_id)
|
|||
return true;
|
||||
}
|
||||
|
||||
// Since we don't have actual processes, we keep track of only the PPC's UID/GID.
|
||||
// These functions roughly correspond to syscalls 0x2b, 0x2c, 0x2d, 0x2e (though only for the PPC).
|
||||
void SetUIDForPPC(u32 uid)
|
||||
{
|
||||
s_ppc_uid = uid;
|
||||
}
|
||||
|
||||
u32 GetUIDForPPC()
|
||||
{
|
||||
return s_ppc_uid;
|
||||
}
|
||||
|
||||
void SetGIDForPPC(u16 gid)
|
||||
{
|
||||
s_ppc_gid = gid;
|
||||
}
|
||||
|
||||
u16 GetGIDForPPC()
|
||||
{
|
||||
return s_ppc_gid;
|
||||
}
|
||||
|
||||
// This corresponds to syscall 0x41, which loads a binary from the NAND and bootstraps the PPC.
|
||||
// Unlike 0x42, IOS will set up some constants in memory before booting the PPC.
|
||||
bool BootstrapPPC(const DiscIO::CNANDContentLoader& content_loader)
|
||||
|
@ -783,6 +808,8 @@ void DoState(PointerWrap& p)
|
|||
p.Do(s_reply_queue);
|
||||
p.Do(s_last_reply_time);
|
||||
p.Do(s_active_title_id);
|
||||
p.Do(s_ppc_uid);
|
||||
p.Do(s_ppc_gid);
|
||||
|
||||
if (s_active_title_id == MIOS_TITLE_ID)
|
||||
return;
|
||||
|
|
|
@ -59,6 +59,11 @@ void Shutdown();
|
|||
bool Reload(u64 ios_title_id);
|
||||
u32 GetVersion();
|
||||
|
||||
void SetUIDForPPC(u32 uid);
|
||||
u32 GetUIDForPPC();
|
||||
void SetGIDForPPC(u16 gid);
|
||||
u16 GetGIDForPPC();
|
||||
|
||||
bool BootstrapPPC(const DiscIO::CNANDContentLoader& content_loader);
|
||||
|
||||
// Do State
|
||||
|
|
|
@ -71,7 +71,7 @@ static Common::Event g_compressAndDumpStateSyncEvent;
|
|||
static std::thread g_save_thread;
|
||||
|
||||
// Don't forget to increase this after doing changes on the savestate system
|
||||
static const u32 STATE_VERSION = 79; // Last changed in PR 4981
|
||||
static const u32 STATE_VERSION = 80; // Last changed in PR 5309
|
||||
|
||||
// Maps savestate versions to Dolphin versions.
|
||||
// Versions after 42 don't need to be added to this list,
|
||||
|
|
|
@ -336,7 +336,7 @@ u64 CNANDContentManager::Install_WiiWAD(const std::string& filename)
|
|||
}
|
||||
|
||||
IOS::ES::UIDSys uid_sys{Common::FromWhichRoot::FROM_CONFIGURED_ROOT};
|
||||
uid_sys.AddTitle(title_id);
|
||||
uid_sys.GetOrInsertUIDForTitle(title_id);
|
||||
|
||||
ClearCache();
|
||||
|
||||
|
|
Loading…
Reference in New Issue