Merge pull request #4298 from Subv/am_titles

Services/AM: Implemented BeginImportProgramTemporarily, EndImportProgramWithoutCommit and CommitImportPrograms.
This commit is contained in:
Weiyi Wang 2018-10-03 17:41:40 -04:00 committed by GitHub
commit ea53b0f795
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 96 additions and 3 deletions

View file

@ -1038,6 +1038,33 @@ void Module::Interface::BeginImportProgram(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) media_type={}", static_cast<u32>(media_type));
}
void Module::Interface::BeginImportProgramTemporarily(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x0403, 0, 0); // 0x04030000
if (am->cia_installing) {
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(ResultCode(ErrCodes::CIACurrentlyInstalling, ErrorModule::AM,
ErrorSummary::InvalidState, ErrorLevel::Permanent));
return;
}
// Note: This function should register the title in the temp_i.db database, but we can get away
// with not doing that because we traverse the file system to detect installed titles.
// Create our CIAFile handle for the app to write to, and while the app writes Citra will store
// contents out to sdmc/nand
const FileSys::Path cia_path = {};
auto file = std::make_shared<Service::FS::File>(std::make_unique<CIAFile>(FS::MediaType::NAND),
cia_path);
am->cia_installing = true;
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS); // No error
rb.PushCopyObjects(file->Connect());
LOG_WARNING(Service_AM, "(STUBBED)");
}
void Module::Interface::EndImportProgram(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x0405, 0, 2); // 0x04050002
auto cia = rp.PopObject<Kernel::ClientSession>();
@ -1049,6 +1076,35 @@ void Module::Interface::EndImportProgram(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
}
void Module::Interface::EndImportProgramWithoutCommit(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x0406, 0, 2); // 0x04060002
auto cia = rp.PopObject<Kernel::ClientSession>();
// Note: This function is basically a no-op for us since we don't use title.db or ticket.db
// files to keep track of installed titles.
am->ScanForAllTitles();
am->cia_installing = false;
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
}
void Module::Interface::CommitImportPrograms(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x0407, 3, 2); // 0x040700C2
auto media_type = static_cast<Service::FS::MediaType>(rp.Pop<u8>());
u32 title_count = rp.Pop<u32>();
u8 database = rp.Pop<u8>();
auto buffer = rp.PopMappedBuffer();
// Note: This function is basically a no-op for us since we don't use title.db or ticket.db
// files to keep track of installed titles.
am->ScanForAllTitles();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushMappedBuffer(buffer);
}
/// Wraps all File operations to allow adding an offset to them.
class AMFileWrapper : public FileSys::FileBackend {
public:

View file

@ -384,6 +384,17 @@ public:
*/
void BeginImportProgram(Kernel::HLERequestContext& ctx);
/**
* AM::BeginImportProgramTemporarily service function
* Begin importing from a CTR Installable Archive into the temporary title database
* Inputs:
* 0 : Command header (0x04030000)
* Outputs:
* 1 : Result, 0 on success, otherwise error code
* 2-3 : CIAFile handle for application to write to
*/
void BeginImportProgramTemporarily(Kernel::HLERequestContext& ctx);
/**
* AM::EndImportProgram service function
* Finish importing from a CTR Installable Archive
@ -395,6 +406,32 @@ public:
*/
void EndImportProgram(Kernel::HLERequestContext& ctx);
/**
* AM::EndImportProgramWithoutCommit service function
* Finish importing from a CTR Installable Archive
* Inputs:
* 0 : Command header (0x04060002)
* 1-2 : CIAFile handle application wrote to
* Outputs:
* 1 : Result, 0 on success, otherwise error code
*/
void EndImportProgramWithoutCommit(Kernel::HLERequestContext& ctx);
/**
* AM::CommitImportPrograms service function
* Commits changes from the temporary title database to the real title database (title.db).
* This is a no-op for us, we don't use title.db
* Inputs:
* 0 : Command header (0x040700C2)
* 1 : Media type
* 2 : Title count
* 3 : Database type
* 4-5 : Title list buffer
* Outputs:
* 1 : Result, 0 on success, otherwise error code
*/
void CommitImportPrograms(Kernel::HLERequestContext& ctx);
/**
* AM::GetProgramInfoFromCia service function
* Get TitleInfo from a CIA file handle

View file

@ -55,11 +55,11 @@ AM_U::AM_U(std::shared_ptr<Module> am) : Module::Interface(std::move(am), "am:u"
{0x002D00C0, nullptr, "CheckContentRightsIgnorePlatform"},
{0x04010080, nullptr, "UpdateFirmwareTo"},
{0x04020040, &AM_U::BeginImportProgram, "BeginImportProgram"},
{0x04030000, nullptr, "BeginImportProgramTemporarily"},
{0x04030000, &AM_U::BeginImportProgramTemporarily, "BeginImportProgramTemporarily"},
{0x04040002, nullptr, "CancelImportProgram"},
{0x04050002, &AM_U::EndImportProgram, "EndImportProgram"},
{0x04060002, nullptr, "EndImportProgramWithoutCommit"},
{0x040700C2, nullptr, "CommitImportPrograms"},
{0x04060002, &AM_U::EndImportProgramWithoutCommit, "EndImportProgramWithoutCommit"},
{0x040700C2, &AM_U::CommitImportPrograms, "CommitImportPrograms"},
{0x04080042, &AM_U::GetProgramInfoFromCia, "GetProgramInfoFromCia"},
{0x04090004, &AM_U::GetSystemMenuDataFromCia, "GetSystemMenuDataFromCia"},
{0x040A0002, &AM_U::GetDependencyListFromCia, "GetDependencyListFromCia"},