Services/AM: Implemented BeginImportProgramTemporarily, EndImportProgramWithoutCommit and CommitImportPrograms.
These functions are pretty much identical to BeginImportProgram and EndImportProgram. We don't need to do anything special in EndImportProgramWithoutCommit and CommitImportPrograms because we don't need to implement the two-phase title installation that the 3DS uses to prevent corruption of the title.db.
This commit is contained in:
parent
3790ccc7b2
commit
0f6f7cfd95
|
@ -1038,6 +1038,33 @@ void Module::Interface::BeginImportProgram(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_WARNING(Service_AM, "(STUBBED) media_type={}", static_cast<u32>(media_type));
|
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) {
|
void Module::Interface::EndImportProgram(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp(ctx, 0x0405, 0, 2); // 0x04050002
|
IPC::RequestParser rp(ctx, 0x0405, 0, 2); // 0x04050002
|
||||||
auto cia = rp.PopObject<Kernel::ClientSession>();
|
auto cia = rp.PopObject<Kernel::ClientSession>();
|
||||||
|
@ -1049,6 +1076,35 @@ void Module::Interface::EndImportProgram(Kernel::HLERequestContext& ctx) {
|
||||||
rb.Push(RESULT_SUCCESS);
|
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.
|
/// Wraps all File operations to allow adding an offset to them.
|
||||||
class AMFileWrapper : public FileSys::FileBackend {
|
class AMFileWrapper : public FileSys::FileBackend {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -384,6 +384,17 @@ public:
|
||||||
*/
|
*/
|
||||||
void BeginImportProgram(Kernel::HLERequestContext& ctx);
|
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
|
* AM::EndImportProgram service function
|
||||||
* Finish importing from a CTR Installable Archive
|
* Finish importing from a CTR Installable Archive
|
||||||
|
@ -395,6 +406,32 @@ public:
|
||||||
*/
|
*/
|
||||||
void EndImportProgram(Kernel::HLERequestContext& ctx);
|
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
|
* AM::GetProgramInfoFromCia service function
|
||||||
* Get TitleInfo from a CIA file handle
|
* Get TitleInfo from a CIA file handle
|
||||||
|
|
|
@ -55,11 +55,11 @@ AM_U::AM_U(std::shared_ptr<Module> am) : Module::Interface(std::move(am), "am:u"
|
||||||
{0x002D00C0, nullptr, "CheckContentRightsIgnorePlatform"},
|
{0x002D00C0, nullptr, "CheckContentRightsIgnorePlatform"},
|
||||||
{0x04010080, nullptr, "UpdateFirmwareTo"},
|
{0x04010080, nullptr, "UpdateFirmwareTo"},
|
||||||
{0x04020040, &AM_U::BeginImportProgram, "BeginImportProgram"},
|
{0x04020040, &AM_U::BeginImportProgram, "BeginImportProgram"},
|
||||||
{0x04030000, nullptr, "BeginImportProgramTemporarily"},
|
{0x04030000, &AM_U::BeginImportProgramTemporarily, "BeginImportProgramTemporarily"},
|
||||||
{0x04040002, nullptr, "CancelImportProgram"},
|
{0x04040002, nullptr, "CancelImportProgram"},
|
||||||
{0x04050002, &AM_U::EndImportProgram, "EndImportProgram"},
|
{0x04050002, &AM_U::EndImportProgram, "EndImportProgram"},
|
||||||
{0x04060002, nullptr, "EndImportProgramWithoutCommit"},
|
{0x04060002, &AM_U::EndImportProgramWithoutCommit, "EndImportProgramWithoutCommit"},
|
||||||
{0x040700C2, nullptr, "CommitImportPrograms"},
|
{0x040700C2, &AM_U::CommitImportPrograms, "CommitImportPrograms"},
|
||||||
{0x04080042, &AM_U::GetProgramInfoFromCia, "GetProgramInfoFromCia"},
|
{0x04080042, &AM_U::GetProgramInfoFromCia, "GetProgramInfoFromCia"},
|
||||||
{0x04090004, &AM_U::GetSystemMenuDataFromCia, "GetSystemMenuDataFromCia"},
|
{0x04090004, &AM_U::GetSystemMenuDataFromCia, "GetSystemMenuDataFromCia"},
|
||||||
{0x040A0002, &AM_U::GetDependencyListFromCia, "GetDependencyListFromCia"},
|
{0x040A0002, &AM_U::GetDependencyListFromCia, "GetDependencyListFromCia"},
|
||||||
|
|
Reference in New Issue