Merge pull request #3087 from shinyquagsire23/am-more-errors

Services/AM: Add errors and adjust naming for accuracy
This commit is contained in:
Sebastian Valle 2017-11-07 09:09:48 -05:00 committed by GitHub
commit 7d12aaaa20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 69 additions and 23 deletions

View File

@ -215,7 +215,7 @@ void CIAContainer::Print() const {
LOG_DEBUG(Service_FS, "Ticket Size: 0x%08x bytes", GetTicketSize()); LOG_DEBUG(Service_FS, "Ticket Size: 0x%08x bytes", GetTicketSize());
LOG_DEBUG(Service_FS, "TMD Size: 0x%08x bytes", GetTitleMetadataSize()); LOG_DEBUG(Service_FS, "TMD Size: 0x%08x bytes", GetTitleMetadataSize());
LOG_DEBUG(Service_FS, "Meta Size: 0x%08x bytes", GetMetadataSize()); LOG_DEBUG(Service_FS, "Meta Size: 0x%08x bytes", GetMetadataSize());
LOG_DEBUG(Service_FS, "Content Size: 0x%08x bytes\n", GetTotalContentSize()); LOG_DEBUG(Service_FS, "Content Size: 0x%08" PRIx64 " bytes\n", GetTotalContentSize());
LOG_DEBUG(Service_FS, "Certificate Offset: 0x%08" PRIx64 " bytes", GetCertificateOffset()); LOG_DEBUG(Service_FS, "Certificate Offset: 0x%08" PRIx64 " bytes", GetCertificateOffset());
LOG_DEBUG(Service_FS, "Ticket Offset: 0x%08" PRIx64 " bytes", GetTicketOffset()); LOG_DEBUG(Service_FS, "Ticket Offset: 0x%08" PRIx64 " bytes", GetTicketOffset());

View File

@ -401,14 +401,28 @@ void GetNumPrograms(Service::Interface* self) {
rb.Push<u32>(am_title_list[media_type].size()); rb.Push<u32>(am_title_list[media_type].size());
} }
void FindContentInfos(Service::Interface* self) { void FindDLCContentInfos(Service::Interface* self) {
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1002, 4, 4); // 0x10020104 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1002, 4, 4); // 0x10020104
auto media_type = static_cast<Service::FS::MediaType>(rp.Pop<u8>()); auto media_type = static_cast<Service::FS::MediaType>(rp.Pop<u8>());
u64 title_id = rp.Pop<u64>(); u64 title_id = rp.Pop<u64>();
u32 content_count = rp.Pop<u32>(); u32 content_count = rp.Pop<u32>();
VAddr content_requested_in = rp.PopMappedBuffer();
VAddr content_info_out = rp.PopMappedBuffer(); size_t input_buffer_size, output_buffer_size;
IPC::MappedBufferPermissions input_buffer_perms, output_buffer_perms;
VAddr content_requested_in = rp.PopMappedBuffer(&input_buffer_size, &input_buffer_perms);
VAddr content_info_out = rp.PopMappedBuffer(&output_buffer_size, &output_buffer_perms);
// Validate that only DLC TIDs are passed in
u32 tid_high = static_cast<u32>(title_id >> 32);
if (tid_high != TID_HIGH_DLC) {
IPC::RequestBuilder rb = rp.MakeBuilder(1, 4);
rb.Push(ResultCode(ErrCodes::InvalidTIDInList, ErrorModule::AM,
ErrorSummary::InvalidArgument, ErrorLevel::Usage));
rb.PushMappedBuffer(content_requested_in, input_buffer_size, input_buffer_perms);
rb.PushMappedBuffer(content_info_out, output_buffer_size, output_buffer_perms);
return;
}
std::vector<u16_le> content_requested(content_count); std::vector<u16_le> content_requested(content_count);
Memory::ReadBlock(content_requested_in, content_requested.data(), content_count * sizeof(u16)); Memory::ReadBlock(content_requested_in, content_requested.data(), content_count * sizeof(u16));
@ -440,17 +454,34 @@ void FindContentInfos(Service::Interface* self) {
} }
} }
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); IPC::RequestBuilder rb = rp.MakeBuilder(1, 4);
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushMappedBuffer(content_requested_in, input_buffer_size, input_buffer_perms);
rb.PushMappedBuffer(content_info_out, output_buffer_size, output_buffer_perms);
} }
void ListContentInfos(Service::Interface* self) { void ListDLCContentInfos(Service::Interface* self) {
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1003, 5, 2); // 0x10030142 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1003, 5, 2); // 0x10030142
u32 content_count = rp.Pop<u32>(); u32 content_count = rp.Pop<u32>();
auto media_type = static_cast<Service::FS::MediaType>(rp.Pop<u8>()); auto media_type = static_cast<Service::FS::MediaType>(rp.Pop<u8>());
u64 title_id = rp.Pop<u64>(); u64 title_id = rp.Pop<u64>();
u32 start_index = rp.Pop<u32>(); u32 start_index = rp.Pop<u32>();
VAddr content_info_out = rp.PopMappedBuffer();
size_t output_buffer_size;
IPC::MappedBufferPermissions output_buffer_perms;
VAddr content_info_out = rp.PopMappedBuffer(&output_buffer_size, &output_buffer_perms);
// Validate that only DLC TIDs are passed in
u32 tid_high = static_cast<u32>(title_id >> 32);
if (tid_high != TID_HIGH_DLC) {
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
rb.Push(ResultCode(ErrCodes::InvalidTIDInList, ErrorModule::AM,
ErrorSummary::InvalidArgument, ErrorLevel::Usage));
rb.Push<u32>(0);
rb.PushMappedBuffer(content_info_out, output_buffer_size, output_buffer_perms);
return;
}
std::string tmd_path = GetTitleMetadataPath(media_type, title_id); std::string tmd_path = GetTitleMetadataPath(media_type, title_id);
@ -478,9 +509,10 @@ void ListContentInfos(Service::Interface* self) {
} }
} }
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.Push(copied); rb.Push(copied);
rb.PushMappedBuffer(content_info_out, output_buffer_size, output_buffer_perms);
} }
void DeleteContents(Service::Interface* self) { void DeleteContents(Service::Interface* self) {
@ -669,11 +701,21 @@ void ListDataTitleTicketInfos(Service::Interface* self) {
ticket_count, title_id, start_index, ticket_info_out); ticket_count, title_id, start_index, ticket_info_out);
} }
void GetNumContentInfos(Service::Interface* self) { void GetDLCContentInfoCount(Service::Interface* self) {
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1001, 3, 0); // 0x100100C0 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1001, 3, 0); // 0x100100C0
auto media_type = static_cast<Service::FS::MediaType>(rp.Pop<u8>()); auto media_type = static_cast<Service::FS::MediaType>(rp.Pop<u8>());
u64 title_id = rp.Pop<u64>(); u64 title_id = rp.Pop<u64>();
// Validate that only DLC TIDs are passed in
u32 tid_high = static_cast<u32>(title_id >> 32);
if (tid_high != TID_HIGH_DLC) {
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
rb.Push(ResultCode(ErrCodes::InvalidTID, ErrorModule::AM, ErrorSummary::InvalidArgument,
ErrorLevel::Usage));
rb.Push<u32>(0);
return;
}
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
rb.Push(RESULT_SUCCESS); // No error rb.Push(RESULT_SUCCESS); // No error
@ -685,7 +727,7 @@ void GetNumContentInfos(Service::Interface* self) {
} else { } else {
rb.Push<u32>(1); // Number of content infos plus one rb.Push<u32>(1); // Number of content infos plus one
LOG_WARNING(Service_AM, "(STUBBED) called media_type=%u, title_id=0x%016" PRIx64, LOG_WARNING(Service_AM, "(STUBBED) called media_type=%u, title_id=0x%016" PRIx64,
media_type, title_id); static_cast<u32>(media_type), title_id);
} }
} }
@ -793,7 +835,7 @@ void BeginImportProgram(Service::Interface* self) {
Kernel::g_handle_table.Create(std::get<Kernel::SharedPtr<Kernel::ClientSession>>(sessions)) Kernel::g_handle_table.Create(std::get<Kernel::SharedPtr<Kernel::ClientSession>>(sessions))
.Unwrap()); .Unwrap());
LOG_WARNING(Service_AM, "(STUBBED) media_type=%u", media_type); LOG_WARNING(Service_AM, "(STUBBED) media_type=%u", static_cast<u32>(media_type));
} }
void EndImportProgram(Service::Interface* self) { void EndImportProgram(Service::Interface* self) {

View File

@ -22,6 +22,7 @@ namespace AM {
namespace ErrCodes { namespace ErrCodes {
enum { enum {
CIACurrentlyInstalling = 4, CIACurrentlyInstalling = 4,
InvalidTID = 31,
EmptyCIA = 32, EmptyCIA = 32,
InvalidTIDInList = 60, InvalidTIDInList = 60,
InvalidCIAHeader = 104, InvalidCIAHeader = 104,
@ -96,7 +97,8 @@ void ScanForAllTitles();
void GetNumPrograms(Service::Interface* self); void GetNumPrograms(Service::Interface* self);
/** /**
* AM::FindContentInfos service function * AM::FindDLCContentInfos service function
* Explicitly checks that TID high value is 0004008C or an error is returned.
* Inputs: * Inputs:
* 1 : MediaType * 1 : MediaType
* 2-3 : u64, Title ID * 2-3 : u64, Title ID
@ -106,10 +108,11 @@ void GetNumPrograms(Service::Interface* self);
* Outputs: * Outputs:
* 1 : Result, 0 on success, otherwise error code * 1 : Result, 0 on success, otherwise error code
*/ */
void FindContentInfos(Service::Interface* self); void FindDLCContentInfos(Service::Interface* self);
/** /**
* AM::ListContentInfos service function * AM::ListDLCContentInfos service function
* Explicitly checks that TID high value is 0004008C or an error is returned.
* Inputs: * Inputs:
* 1 : Content count * 1 : Content count
* 2 : MediaType * 2 : MediaType
@ -120,7 +123,7 @@ void FindContentInfos(Service::Interface* self);
* 1 : Result, 0 on success, otherwise error code * 1 : Result, 0 on success, otherwise error code
* 2 : Number of content infos returned * 2 : Number of content infos returned
*/ */
void ListContentInfos(Service::Interface* self); void ListDLCContentInfos(Service::Interface* self);
/** /**
* AM::DeleteContents service function * AM::DeleteContents service function
@ -202,7 +205,8 @@ void GetPatchTitleInfos(Service::Interface* self);
void ListDataTitleTicketInfos(Service::Interface* self); void ListDataTitleTicketInfos(Service::Interface* self);
/** /**
* AM::GetNumContentInfos service function * AM::GetDLCContentInfoCount service function
* Explicitly checks that TID high value is 0004008C or an error is returned.
* Inputs: * Inputs:
* 0 : Command header (0x100100C0) * 0 : Command header (0x100100C0)
* 1 : MediaType * 1 : MediaType
@ -211,7 +215,7 @@ void ListDataTitleTicketInfos(Service::Interface* self);
* 1 : Result, 0 on success, otherwise error code * 1 : Result, 0 on success, otherwise error code
* 2 : Number of content infos plus one * 2 : Number of content infos plus one
*/ */
void GetNumContentInfos(Service::Interface* self); void GetDLCContentInfoCount(Service::Interface* self);
/** /**
* AM::DeleteTicket service function * AM::DeleteTicket service function

View File

@ -9,9 +9,9 @@ namespace Service {
namespace AM { namespace AM {
const Interface::FunctionInfo FunctionTable[] = { const Interface::FunctionInfo FunctionTable[] = {
{0x100100C0, GetNumContentInfos, "GetNumContentInfos"}, {0x100100C0, GetDLCContentInfoCount, "GetDLCContentInfoCount"},
{0x10020104, FindContentInfos, "FindContentInfos"}, {0x10020104, FindDLCContentInfos, "FindDLCContentInfos"},
{0x10030142, ListContentInfos, "ListContentInfos"}, {0x10030142, ListDLCContentInfos, "ListDLCContentInfos"},
{0x10040102, DeleteContents, "DeleteContents"}, {0x10040102, DeleteContents, "DeleteContents"},
{0x10050084, GetDLCTitleInfos, "GetDLCTitleInfos"}, {0x10050084, GetDLCTitleInfos, "GetDLCTitleInfos"},
{0x10060080, nullptr, "GetNumDataTitleTickets"}, {0x10060080, nullptr, "GetNumDataTitleTickets"},

View File

@ -54,9 +54,9 @@ const Interface::FunctionInfo FunctionTable[] = {
{0x002B0142, nullptr, "ListExistingContentInfosSystem"}, {0x002B0142, nullptr, "ListExistingContentInfosSystem"},
{0x002C0084, nullptr, "GetProgramInfosIgnorePlatform"}, {0x002C0084, nullptr, "GetProgramInfosIgnorePlatform"},
{0x002D00C0, CheckContentRightsIgnorePlatform, "CheckContentRightsIgnorePlatform"}, {0x002D00C0, CheckContentRightsIgnorePlatform, "CheckContentRightsIgnorePlatform"},
{0x100100C0, GetNumContentInfos, "GetNumContentInfos"}, {0x100100C0, GetDLCContentInfoCount, "GetDLCContentInfoCount"},
{0x10020104, FindContentInfos, "FindContentInfos"}, {0x10020104, FindDLCContentInfos, "FindDLCContentInfos"},
{0x10030142, ListContentInfos, "ListContentInfos"}, {0x10030142, ListDLCContentInfos, "ListDLCContentInfos"},
{0x10040102, DeleteContents, "DeleteContents"}, {0x10040102, DeleteContents, "DeleteContents"},
{0x10050084, GetDLCTitleInfos, "GetDLCTitleInfos"}, {0x10050084, GetDLCTitleInfos, "GetDLCTitleInfos"},
{0x10060080, nullptr, "GetNumDataTitleTickets"}, {0x10060080, nullptr, "GetNumDataTitleTickets"},