Skip to content

Commit

Permalink
Merge pull request #5210 from leoetlino/es-shared-contents
Browse files Browse the repository at this point in the history
IOS/ES: Implement GetSharedContents (+ count)
  • Loading branch information
degasus committed Apr 21, 2017
2 parents bca9a9d + b09561e commit b5c857d
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Source/Core/Core/IOS/ES/ES.cpp
Expand Up @@ -356,6 +356,11 @@ IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)
case IOCTL_ES_GETSTOREDCONTENTS:
return GetTMDStoredContents(request);

case IOCTL_ES_GETSHAREDCONTENTCNT:
return GetSharedContentsCount(request);
case IOCTL_ES_GETSHAREDCONTENTS:
return GetSharedContents(request);

case IOCTL_ES_GETVIEWCNT:
return GetTicketViewCount(request);
case IOCTL_ES_GETVIEWS:
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/Core/IOS/ES/ES.h
Expand Up @@ -214,6 +214,8 @@ class ES final : public Device
IPCCommandResult GetTMDStoredContents(const IOCtlVRequest& request);
IPCCommandResult GetStoredTMDSize(const IOCtlVRequest& request);
IPCCommandResult GetStoredTMD(const IOCtlVRequest& request);
IPCCommandResult GetSharedContentsCount(const IOCtlVRequest& request) const;
IPCCommandResult GetSharedContents(const IOCtlVRequest& request) const;

// Views for tickets and TMDs
IPCCommandResult GetTicketViewCount(const IOCtlVRequest& request);
Expand Down
10 changes: 10 additions & 0 deletions Source/Core/Core/IOS/ES/Formats.cpp
Expand Up @@ -385,6 +385,16 @@ std::string SharedContentMap::GetFilenameFromSHA1(const std::array<u8, 20>& sha1
return Common::RootUserPath(m_root) + StringFromFormat("/shared1/%s.app", id_string.c_str());
}

std::vector<std::array<u8, 20>> SharedContentMap::GetHashes() const
{
std::vector<std::array<u8, 20>> hashes;
hashes.reserve(m_entries.size());
for (const auto& content_entry : m_entries)
hashes.emplace_back(content_entry.sha1);

return hashes;
}

std::string SharedContentMap::AddSharedContent(const std::array<u8, 20>& sha1)
{
std::string filename = GetFilenameFromSHA1(sha1);
Expand Down
1 change: 1 addition & 0 deletions Source/Core/Core/IOS/ES/Formats.h
Expand Up @@ -204,6 +204,7 @@ class SharedContentMap final

std::string GetFilenameFromSHA1(const std::array<u8, 20>& sha1) const;
std::string AddSharedContent(const std::array<u8, 20>& sha1);
std::vector<std::array<u8, 20>> GetHashes() const;

private:
struct Entry;
Expand Down
17 changes: 17 additions & 0 deletions Source/Core/Core/IOS/ES/NandUtils.cpp
Expand Up @@ -163,6 +163,23 @@ std::vector<Content> GetStoredContentsFromTMD(const TMDReader& tmd)
return stored_contents;
}

u32 GetSharedContentsCount()
{
const std::string shared1_path = Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/shared1";
const auto entries = File::ScanDirectoryTree(shared1_path, false);
return static_cast<u32>(
std::count_if(entries.children.begin(), entries.children.end(), [](const auto& entry) {
return !entry.isDirectory && entry.virtualName.size() == 12 &&
entry.virtualName.compare(8, 4, ".app") == 0;
}));
}

std::vector<std::array<u8, 20>> GetSharedContents()
{
const IOS::ES::SharedContentMap map{Common::FROM_SESSION_ROOT};
return map.GetHashes();
}

bool InitImport(u64 title_id)
{
const std::string content_dir = Common::GetTitleContentPath(title_id, Common::FROM_SESSION_ROOT);
Expand Down
4 changes: 4 additions & 0 deletions Source/Core/Core/IOS/ES/NandUtils.h
Expand Up @@ -4,6 +4,7 @@

#pragma once

#include <array>
#include <vector>

#include "Common/CommonTypes.h"
Expand All @@ -27,6 +28,9 @@ std::vector<u64> GetTitlesWithTickets();

std::vector<Content> GetStoredContentsFromTMD(const TMDReader& tmd);

u32 GetSharedContentsCount();
std::vector<std::array<u8, 20>> GetSharedContents();

// Start a title import.
bool InitImport(u64 title_id);
// Clean up the import content directory and move it back to /title.
Expand Down
29 changes: 29 additions & 0 deletions Source/Core/Core/IOS/ES/TitleInformation.cpp
Expand Up @@ -205,6 +205,35 @@ IPCCommandResult ES::GetBoot2Version(const IOCtlVRequest& request)
Memory::Write_U32(4, request.io_vectors[0].address);
return GetDefaultReply(IPC_SUCCESS);
}

IPCCommandResult ES::GetSharedContentsCount(const IOCtlVRequest& request) const
{
if (!request.HasNumberOfValidVectors(0, 1) || request.io_vectors[0].size != sizeof(u32))
return GetDefaultReply(ES_EINVAL);

const u32 count = IOS::ES::GetSharedContentsCount();
Memory::Write_U32(count, request.io_vectors[0].address);

INFO_LOG(IOS_ES, "GetSharedContentsCount: %u contents", count);
return GetDefaultReply(IPC_SUCCESS);
}

IPCCommandResult ES::GetSharedContents(const IOCtlVRequest& request) const
{
if (!request.HasNumberOfValidVectors(1, 1) || request.in_vectors[0].size != sizeof(u32))
return GetDefaultReply(ES_EINVAL);

const u32 max_count = Memory::Read_U32(request.in_vectors[0].address);
if (request.io_vectors[0].size != 20 * max_count)
return GetDefaultReply(ES_EINVAL);

const std::vector<std::array<u8, 20>> hashes = IOS::ES::GetSharedContents();
const u32 count = std::min(static_cast<u32>(hashes.size()), max_count);
Memory::CopyToEmu(request.io_vectors[0].address, hashes.data(), 20 * count);

INFO_LOG(IOS_ES, "GetSharedContents: %u contents (%u requested)", count, max_count);
return GetDefaultReply(IPC_SUCCESS);
}
} // namespace Device
} // namespace HLE
} // namespace IOS

0 comments on commit b5c857d

Please sign in to comment.