From 669a21babb89c670746ed0a3ba89543a70f8e05e Mon Sep 17 00:00:00 2001
From: Zach Hilman <zachhilman@gmail.com>
Date: Wed, 10 Apr 2019 14:05:12 -0400
Subject: [PATCH] es: Implement ETicket ListPersonalizedTicket (12)

Returns an application-specific number of entries of personal tickets, starting at offset 0.
---
 src/core/hle/service/es/es.cpp | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/src/core/hle/service/es/es.cpp b/src/core/hle/service/es/es.cpp
index 9a481f41f7..d136566fcf 100644
--- a/src/core/hle/service/es/es.cpp
+++ b/src/core/hle/service/es/es.cpp
@@ -27,7 +27,7 @@ public:
             {9, &ETicket::CountCommonTicket, "CountCommonTicket"},
             {10, &ETicket::CountPersonalizedTicket, "CountPersonalizedTicket"},
             {11, &ETicket::ListCommonTicket, "ListCommonTicket"},
-            {12, nullptr, "ListPersonalizedTicket"},
+            {12, &ETicket::ListPersonalizedTicket, "ListPersonalizedTicket"},
             {13, nullptr, "ListMissingPersonalizedTicket"},
             {14, nullptr, "GetCommonTicketSize"},
             {15, nullptr, "GetPersonalizedTicketSize"},
@@ -167,6 +167,29 @@ private:
         rb.Push<u32>(out_entries);
     }
 
+    void ListPersonalizedTicket(Kernel::HLERequestContext& ctx) {
+        u32 out_entries;
+        if (keys.GetPersonalizedTickets().empty())
+            out_entries = 0;
+        else
+            out_entries = ctx.GetWriteBufferSize() / sizeof(u128);
+
+        LOG_DEBUG(Service_ETicket, "called, entries={:016X}", out_entries);
+
+        keys.PopulateTickets();
+        const auto tickets = keys.GetPersonalizedTickets();
+        std::vector<u128> ids;
+        std::transform(tickets.begin(), tickets.end(), std::back_inserter(ids),
+                       [](const auto& pair) { return pair.first; });
+
+        out_entries = std::min<u32>(ids.size(), out_entries);
+        ctx.WriteBuffer(ids.data(), out_entries * sizeof(u128));
+
+        IPC::ResponseBuilder rb{ctx, 3};
+        rb.Push(RESULT_SUCCESS);
+        rb.Push<u32>(out_entries);
+    }
+
 };
 
 void InstallInterfaces(SM::ServiceManager& service_manager) {