mirror of
https://github.com/azahar-emu/azahar.git
synced 2025-04-28 13:47:59 +03:00
Make AM:GetPersonalizedTicketInfoList only return personal tickets
This commit is contained in:
parent
70be7d987e
commit
84e2f31415
3 changed files with 67 additions and 26 deletions
|
@ -167,4 +167,19 @@ std::optional<std::array<u8, 16>> Ticket::GetTitleKey() const {
|
|||
return title_key;
|
||||
}
|
||||
|
||||
bool Ticket::IsPersonal() {
|
||||
if (ticket_body.console_id == 0u) {
|
||||
// Common ticket
|
||||
return false;
|
||||
}
|
||||
|
||||
auto& otp = HW::UniqueData::GetOTP();
|
||||
if (!otp.Valid()) {
|
||||
LOG_ERROR(HW_AES, "Invalid OTP");
|
||||
return false;
|
||||
}
|
||||
|
||||
return ticket_body.console_id == otp.GetDeviceID();
|
||||
}
|
||||
|
||||
} // namespace FileSys
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018 Citra Emulator Project
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -67,6 +67,8 @@ public:
|
|||
return serialized_size;
|
||||
}
|
||||
|
||||
bool IsPersonal();
|
||||
|
||||
private:
|
||||
Body ticket_body;
|
||||
u32_be signature_type;
|
||||
|
|
|
@ -2777,37 +2777,61 @@ void Module::Interface::QueryAvailableTitleDatabase(Kernel::HLERequestContext& c
|
|||
|
||||
void Module::Interface::GetPersonalizedTicketInfoList(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx);
|
||||
u32 ticket_count = rp.Pop<u32>();
|
||||
auto& out_buffer = rp.PopMappedBuffer();
|
||||
|
||||
LOG_DEBUG(Service_AM, "(STUBBED) called, ticket_count={}", ticket_count);
|
||||
struct AsyncData {
|
||||
u32 ticket_count;
|
||||
|
||||
u32 written = 0;
|
||||
std::scoped_lock lock(am->am_lists_mutex);
|
||||
for (auto it = am->am_ticket_list.begin();
|
||||
it != am->am_ticket_list.end() && written < ticket_count; it++) {
|
||||
u64 title_id = it->first;
|
||||
u32 tid_high = static_cast<u32>(title_id << 32);
|
||||
if ((tid_high & 0x00048010) == 0x00040010 || (tid_high & 0x00048001) == 0x00048001)
|
||||
continue;
|
||||
std::vector<TicketInfo> out;
|
||||
Kernel::MappedBuffer* out_buffer;
|
||||
};
|
||||
std::shared_ptr<AsyncData> async_data = std::make_shared<AsyncData>();
|
||||
async_data->ticket_count = rp.Pop<u32>();
|
||||
async_data->out_buffer = &rp.PopMappedBuffer();
|
||||
|
||||
FileSys::Ticket ticket;
|
||||
if (ticket.Load(title_id, it->second) != Loader::ResultStatus::Success)
|
||||
continue;
|
||||
LOG_DEBUG(Service_AM, "called, ticket_count={}", async_data->ticket_count);
|
||||
|
||||
TicketInfo info = {};
|
||||
info.title_id = ticket.GetTitleID();
|
||||
info.ticket_id = ticket.GetTicketID();
|
||||
info.version = ticket.GetVersion();
|
||||
info.size = static_cast<u32>(ticket.GetSerializedSize());
|
||||
// TODO(PabloMK7): Properly figure out how to detect personalized tickets.
|
||||
|
||||
out_buffer.Write(&info, written * sizeof(TicketInfo), sizeof(TicketInfo));
|
||||
written++;
|
||||
}
|
||||
ctx.RunAsync(
|
||||
[this, async_data](Kernel::HLERequestContext& ctx) {
|
||||
u32 written = 0;
|
||||
std::scoped_lock lock(am->am_lists_mutex);
|
||||
for (auto it = am->am_ticket_list.begin();
|
||||
it != am->am_ticket_list.end() && written < async_data->ticket_count; it++) {
|
||||
u64 title_id = it->first;
|
||||
u32 tid_high = static_cast<u32>(title_id << 32);
|
||||
if ((tid_high & 0x00048010) == 0x00040010 || (tid_high & 0x00048001) == 0x00048001)
|
||||
continue;
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
||||
rb.Push(ResultSuccess); // No error
|
||||
rb.Push(written);
|
||||
FileSys::Ticket ticket;
|
||||
if (ticket.Load(title_id, it->second) != Loader::ResultStatus::Success ||
|
||||
!ticket.IsPersonal())
|
||||
continue;
|
||||
|
||||
TicketInfo info = {};
|
||||
info.title_id = ticket.GetTitleID();
|
||||
info.ticket_id = ticket.GetTicketID();
|
||||
info.version = ticket.GetVersion();
|
||||
info.size = static_cast<u32>(ticket.GetSerializedSize());
|
||||
|
||||
async_data->out.push_back(info);
|
||||
written++;
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
[async_data](Kernel::HLERequestContext& ctx) {
|
||||
u32 written = 0;
|
||||
for (auto& info : async_data->out) {
|
||||
async_data->out_buffer->Write(&info, written * sizeof(TicketInfo),
|
||||
sizeof(TicketInfo));
|
||||
written++;
|
||||
}
|
||||
|
||||
IPC::RequestBuilder rb(ctx, 2, 0);
|
||||
rb.Push(ResultSuccess); // No error
|
||||
rb.Push(written);
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
void Module::Interface::GetNumImportTitleContextsFiltered(Kernel::HLERequestContext& ctx) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue