citra-emu
/
citra
Archived
1
0
Fork 0

Stub some missing AM Ticket functions (#7172)

This commit is contained in:
PabloMK7 2023-11-19 00:55:47 +01:00 committed by GitHub
parent ba702043f0
commit b6acebcb11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 224 additions and 10 deletions

View File

@ -50,6 +50,9 @@ public:
Loader::ResultStatus Load(std::span<const u8> file_data, std::size_t offset = 0);
std::optional<std::array<u8, 16>> GetTitleKey() const;
u64 GetTitleID() const {
return ticket_body.title_id;
}
private:
Body ticket_body;

View File

@ -374,6 +374,45 @@ bool CIAFile::Close() const {
void CIAFile::Flush() const {}
TicketFile::TicketFile() {}
TicketFile::~TicketFile() {
Close();
}
ResultVal<std::size_t> TicketFile::Read(u64 offset, std::size_t length, u8* buffer) const {
UNIMPLEMENTED();
return length;
}
ResultVal<std::size_t> TicketFile::Write(u64 offset, std::size_t length, bool flush,
const u8* buffer) {
written += length;
data.resize(written);
std::memcpy(data.data() + offset, buffer, length);
return length;
}
u64 TicketFile::GetSize() const {
return written;
}
bool TicketFile::SetSize(u64 size) const {
return false;
}
bool TicketFile::Close() const {
FileSys::Ticket ticket;
if (ticket.Load(data, 0) == Loader::ResultStatus::Success) {
LOG_WARNING(Service_AM, "Discarding ticket for {:#016X}.", ticket.GetTitleID());
} else {
LOG_ERROR(Service_AM, "Invalid ticket provided to TicketFile.");
}
return true;
}
void TicketFile::Flush() const {}
InstallStatus InstallCIA(const std::string& path,
std::function<ProgressCallback>&& update_callback) {
LOG_INFO(Service_AM, "Installing {}...", path);
@ -942,6 +981,10 @@ void Module::Interface::GetProgramInfos(Kernel::HLERequestContext& ctx) {
rb.PushMappedBuffer(title_info_out);
}
void Module::Interface::GetProgramInfosIgnorePlatform(Kernel::HLERequestContext& ctx) {
GetProgramInfos(ctx);
}
void Module::Interface::DeleteUserProgram(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx);
auto media_type = rp.PopEnum<FS::MediaType>();
@ -1177,6 +1220,16 @@ void Module::Interface::NeedsCleanup(Kernel::HLERequestContext& ctx) {
rb.Push<bool>(false);
}
void Module::Interface::DoCleanup(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx);
const auto media_type = rp.Pop<u8>();
LOG_DEBUG(Service_AM, "(STUBBED) called, media_type={:#02x}", media_type);
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
}
void Module::Interface::QueryAvailableTitleDatabase(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx);
u8 media_type = rp.Pop<u8>();
@ -1188,6 +1241,45 @@ void Module::Interface::QueryAvailableTitleDatabase(Kernel::HLERequestContext& c
LOG_WARNING(Service_AM, "(STUBBED) media_type={}", media_type);
}
void Module::Interface::GetPersonalizedTicketInfoList(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx);
[[maybe_unused]] u32 ticket_count = rp.Pop<u32>();
[[maybe_unused]] auto& buffer = rp.PopMappedBuffer();
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
rb.Push(RESULT_SUCCESS); // No error
rb.Push(0);
LOG_WARNING(Service_AM, "(STUBBED) called, ticket_count={}", ticket_count);
}
void Module::Interface::GetNumImportTitleContextsFiltered(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx);
u8 media_type = rp.Pop<u8>();
u8 filter = rp.Pop<u8>();
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
rb.Push(RESULT_SUCCESS); // No error
rb.Push(0);
LOG_WARNING(Service_AM, "(STUBBED) called, media_type={}, filter={}", media_type, filter);
}
void Module::Interface::GetImportTitleContextListFiltered(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx);
[[maybe_unused]] const u32 count = rp.Pop<u32>();
const u8 media_type = rp.Pop<u8>();
const u8 filter = rp.Pop<u8>();
auto& buffer = rp.PopMappedBuffer();
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
rb.Push(RESULT_SUCCESS); // No error
rb.Push(0);
rb.PushMappedBuffer(buffer);
LOG_WARNING(Service_AM, "(STUBBED) called, media_type={}, filter={}", media_type, filter);
}
void Module::Interface::CheckContentRights(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx);
u64 tid = rp.Pop<u64>();
@ -1674,6 +1766,30 @@ void Module::Interface::GetMetaDataFromCia(Kernel::HLERequestContext& ctx) {
rb.PushMappedBuffer(output_buffer);
}
void Module::Interface::BeginImportTicket(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx);
// Create our TicketFile handle for the app to write to
auto file = std::make_shared<Service::FS::File>(am->kernel, std::make_unique<TicketFile>(),
FileSys::Path{});
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS); // No error
rb.PushCopyObjects(file->Connect());
LOG_WARNING(Service_AM, "(STUBBED) called");
}
void Module::Interface::EndImportTicket(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx);
[[maybe_unused]] const auto ticket = rp.PopObject<Kernel::ClientSession>();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_AM, "(STUBBED) called");
}
Module::Module(Core::System& system) : kernel(system.Kernel()) {
ScanForAllTitles();
system_updater_mutex = system.Kernel().CreateMutex(false, "AM::SystemUpdaterMutex");

View File

@ -109,6 +109,25 @@ private:
std::unique_ptr<DecryptionState> decryption_state;
};
// A file handled returned for Tickets to be written into and subsequently installed.
class TicketFile final : public FileSys::FileBackend {
public:
explicit TicketFile();
~TicketFile();
ResultVal<std::size_t> Read(u64 offset, std::size_t length, u8* buffer) const override;
ResultVal<std::size_t> Write(u64 offset, std::size_t length, bool flush,
const u8* buffer) override;
u64 GetSize() const override;
bool SetSize(u64 size) const override;
bool Close() const override;
void Flush() const override;
private:
u64 written = 0;
std::vector<u8> data;
};
/**
* Installs a CIA file from a specified file path.
* @param path file path of the CIA file to install
@ -272,6 +291,18 @@ public:
*/
void GetProgramInfos(Kernel::HLERequestContext& ctx);
/**
* AM::GetProgramInfosIgnorePlatform service function
* Inputs:
* 1 : u8 Mediatype
* 2 : Total titles
* 4 : TitleIDList pointer
* 6 : TitleList pointer
* Outputs:
* 1 : Result, 0 on success, otherwise error code
*/
void GetProgramInfosIgnorePlatform(Kernel::HLERequestContext& ctx);
/**
* AM::DeleteUserProgram service function
* Deletes a user program
@ -389,6 +420,15 @@ public:
*/
void NeedsCleanup(Kernel::HLERequestContext& ctx);
/**
* AM::DoCleanup service function
* Inputs:
* 1 : Media Type
* Outputs:
* 1 : Result, 0 on success, otherwise error code
*/
void DoCleanup(Kernel::HLERequestContext& ctx);
/**
* AM::QueryAvailableTitleDatabase service function
* Inputs:
@ -399,6 +439,42 @@ public:
*/
void QueryAvailableTitleDatabase(Kernel::HLERequestContext& ctx);
/**
* AM::GetPersonalizedTicketInfoList service function
* Inputs:
* 1 : Count
* 2-3 : Buffer
* Outputs:
* 1 : Result, 0 on success, otherwise error code
* 2 : Out count
*/
void GetPersonalizedTicketInfoList(Kernel::HLERequestContext& ctx);
/**
* AM::GetNumImportTitleContextsFiltered service function
* Inputs:
* 1 : Count
* 2 : Filter
* Outputs:
* 1 : Result, 0 on success, otherwise error code
* 2 : Num import titles
*/
void GetNumImportTitleContextsFiltered(Kernel::HLERequestContext& ctx);
/**
* AM::GetImportTitleContextListFiltered service function
* Inputs:
* 1 : Count
* 2 : Media type
* 3 : filter
* 4-5 : Buffer
* Outputs:
* 1 : Result, 0 on success, otherwise error code
* 2 : Out count
* 3-4 : Out buffer
*/
void GetImportTitleContextListFiltered(Kernel::HLERequestContext& ctx);
/**
* AM::CheckContentRights service function
* Inputs:
@ -602,6 +678,25 @@ public:
*/
void GetMetaDataFromCia(Kernel::HLERequestContext& ctx);
/**
* AM::BeginImportTicket service function
* Inputs:
* 1 : Media type to install title to
* Outputs:
* 1 : Result, 0 on success, otherwise error code
* 2-3 : TicketHandle handle for application to write to
*/
void BeginImportTicket(Kernel::HLERequestContext& ctx);
/**
* AM::EndImportTicket service function
* Inputs:
* 1-2 : TicketHandle handle application wrote to
* Outputs:
* 1 : Result, 0 on success, otherwise error code
*/
void EndImportTicket(Kernel::HLERequestContext& ctx);
protected:
std::shared_ptr<Module> am;
};

View File

@ -42,19 +42,19 @@ AM_NET::AM_NET(std::shared_ptr<Module> am) : Module::Interface(std::move(am), "a
{0x001E, nullptr, "ReadTwlBackupInfo"},
{0x001F, nullptr, "DeleteAllExpiredUserPrograms"},
{0x0020, nullptr, "GetTwlArchiveResourceInfo"},
{0x0021, nullptr, "GetPersonalizedTicketInfoList"},
{0x0021, &AM_NET::GetPersonalizedTicketInfoList, "GetPersonalizedTicketInfoList"},
{0x0022, nullptr, "DeleteAllImportContextsFiltered"},
{0x0023, nullptr, "GetNumImportTitleContextsFiltered"},
{0x0024, nullptr, "GetImportTitleContextListFiltered"},
{0x0025, nullptr, "CheckContentRights"},
{0x0023, &AM_NET::GetNumImportTitleContextsFiltered, "GetNumImportTitleContextsFiltered"},
{0x0024, &AM_NET::GetImportTitleContextListFiltered, "GetImportTitleContextListFiltered"},
{0x0025, &AM_NET::CheckContentRights, "CheckContentRights"},
{0x0026, nullptr, "GetTicketLimitInfos"},
{0x0027, nullptr, "GetDemoLaunchInfos"},
{0x0028, nullptr, "ReadTwlBackupInfoEx"},
{0x0029, nullptr, "DeleteUserProgramsAtomically"},
{0x002A, nullptr, "GetNumExistingContentInfosSystem"},
{0x002B, nullptr, "ListExistingContentInfosSystem"},
{0x002C, nullptr, "GetProgramInfosIgnorePlatform"},
{0x002D, nullptr, "CheckContentRightsIgnorePlatform"},
{0x002C, &AM_NET::GetProgramInfosIgnorePlatform, "GetProgramInfosIgnorePlatform"},
{0x002D, &AM_NET::CheckContentRightsIgnorePlatform, "CheckContentRightsIgnorePlatform"},
{0x0401, nullptr, "UpdateFirmwareTo"},
{0x0402, &AM_NET::BeginImportProgram, "BeginImportProgram"},
{0x0403, nullptr, "BeginImportProgramTemporarily"},
@ -72,7 +72,7 @@ AM_NET::AM_NET(std::shared_ptr<Module> am) : Module::Interface(std::move(am), "a
{0x040F, nullptr, "UpdateFirmwareAuto"},
{0x0410, &AM_NET::DeleteProgram, "DeleteProgram"},
{0x0411, nullptr, "GetTwlProgramListForReboot"},
{0x0412, nullptr, "GetSystemUpdaterMutex"},
{0x0412, &AM_NET::GetSystemUpdaterMutex, "GetSystemUpdaterMutex"},
{0x0413, &AM_NET::GetMetaSizeFromCia, "GetMetaSizeFromCia"},
{0x0414, &AM_NET::GetMetaDataFromCia, "GetMetaDataFromCia"},
{0x0415, nullptr, "CheckDemoLaunchRights"},
@ -80,9 +80,9 @@ AM_NET::AM_NET(std::shared_ptr<Module> am) : Module::Interface(std::move(am), "a
{0x0417, nullptr, "PerpetuateAgbSaveData"},
{0x0418, nullptr, "BeginImportProgramForOverWrite"},
{0x0419, nullptr, "BeginImportSystemProgram"},
{0x0801, nullptr, "BeginImportTicket"},
{0x0801, &AM_NET::BeginImportTicket, "BeginImportTicket"},
{0x0802, nullptr, "CancelImportTicket"},
{0x0803, nullptr, "EndImportTicket"},
{0x0803, &AM_NET::EndImportTicket, "EndImportTicket"},
{0x0804, nullptr, "BeginImportTitle"},
{0x0805, nullptr, "StopImportTitle"},
{0x0806, nullptr, "ResumeImportTitle"},

View File

@ -29,7 +29,7 @@ AM_SYS::AM_SYS(std::shared_ptr<Module> am) : Module::Interface(std::move(am), "a
{0x0011, nullptr, "GetImportContentContexts"},
{0x0012, nullptr, "DeleteImportContentContexts"},
{0x0013, &AM_SYS::NeedsCleanup, "NeedsCleanup"},
{0x0014, nullptr, "DoCleanup"},
{0x0014, &AM_SYS::DoCleanup, "DoCleanup"},
{0x0015, nullptr, "DeleteAllImportContexts"},
{0x0016, nullptr, "DeleteAllTemporaryPrograms"},
{0x0017, nullptr, "ImportTwlBackupLegacy"},