From 4afca6bf5de516961c4109ca363c437c9da2e677 Mon Sep 17 00:00:00 2001
From: Narr the Reg <juangerman-13@hotmail.com>
Date: Sun, 28 Jan 2024 22:29:06 -0600
Subject: [PATCH] service: capsrv: Migrate to new IPC

---
 src/core/hle/service/caps/caps_a.cpp       | 156 ++++++---------------
 src/core/hle/service/caps/caps_a.h         |  34 ++++-
 src/core/hle/service/caps/caps_c.cpp       |  16 +--
 src/core/hle/service/caps/caps_c.h         |   5 +-
 src/core/hle/service/caps/caps_manager.cpp |  61 ++++----
 src/core/hle/service/caps/caps_manager.h   |  16 +--
 src/core/hle/service/caps/caps_ss.cpp      |  82 ++++-------
 src/core/hle/service/caps/caps_ss.h        |  18 ++-
 src/core/hle/service/caps/caps_su.cpp      |  87 ++++--------
 src/core/hle/service/caps/caps_su.h        |  18 ++-
 src/core/hle/service/caps/caps_types.h     |  32 +++--
 src/core/hle/service/caps/caps_u.cpp       | 110 ++++-----------
 src/core/hle/service/caps/caps_u.h         |  16 ++-
 13 files changed, 263 insertions(+), 388 deletions(-)

diff --git a/src/core/hle/service/caps/caps_a.cpp b/src/core/hle/service/caps/caps_a.cpp
index 69acb3a8b6..47ff072c52 100644
--- a/src/core/hle/service/caps/caps_a.cpp
+++ b/src/core/hle/service/caps/caps_a.cpp
@@ -5,7 +5,7 @@
 #include "core/hle/service/caps/caps_a.h"
 #include "core/hle/service/caps/caps_manager.h"
 #include "core/hle/service/caps/caps_result.h"
-#include "core/hle/service/caps/caps_types.h"
+#include "core/hle/service/cmif_serialization.h"
 #include "core/hle/service/ipc_helpers.h"
 
 namespace Service::Capture {
@@ -18,9 +18,9 @@ IAlbumAccessorService::IAlbumAccessorService(Core::System& system_,
         {0, nullptr, "GetAlbumFileCount"},
         {1, nullptr, "GetAlbumFileList"},
         {2, nullptr, "LoadAlbumFile"},
-        {3, &IAlbumAccessorService::DeleteAlbumFile, "DeleteAlbumFile"},
+        {3, C<&IAlbumAccessorService::DeleteAlbumFile>, "DeleteAlbumFile"},
         {4, nullptr, "StorageCopyAlbumFile"},
-        {5, &IAlbumAccessorService::IsAlbumMounted, "IsAlbumMounted"},
+        {5, C<&IAlbumAccessorService::IsAlbumMounted>, "IsAlbumMounted"},
         {6, nullptr, "GetAlbumUsage"},
         {7, nullptr, "GetAlbumFileSize"},
         {8, nullptr, "LoadAlbumFileThumbnail"},
@@ -33,18 +33,18 @@ IAlbumAccessorService::IAlbumAccessorService(Core::System& system_,
         {15, nullptr, "GetAlbumUsage3"},
         {16, nullptr, "GetAlbumMountResult"},
         {17, nullptr, "GetAlbumUsage16"},
-        {18, &IAlbumAccessorService::Unknown18, "Unknown18"},
+        {18, C<&IAlbumAccessorService::Unknown18>, "Unknown18"},
         {19, nullptr, "Unknown19"},
         {100, nullptr, "GetAlbumFileCountEx0"},
-        {101, &IAlbumAccessorService::GetAlbumFileListEx0, "GetAlbumFileListEx0"},
+        {101, C<&IAlbumAccessorService::GetAlbumFileListEx0>, "GetAlbumFileListEx0"},
         {202, nullptr, "SaveEditedScreenShot"},
         {301, nullptr, "GetLastThumbnail"},
         {302, nullptr, "GetLastOverlayMovieThumbnail"},
-        {401,  &IAlbumAccessorService::GetAutoSavingStorage, "GetAutoSavingStorage"},
+        {401,  C<&IAlbumAccessorService::GetAutoSavingStorage>, "GetAutoSavingStorage"},
         {501, nullptr, "GetRequiredStorageSpaceSizeToCopyAll"},
         {1001, nullptr, "LoadAlbumScreenShotThumbnailImageEx0"},
-        {1002, &IAlbumAccessorService::LoadAlbumScreenShotImageEx1, "LoadAlbumScreenShotImageEx1"},
-        {1003, &IAlbumAccessorService::LoadAlbumScreenShotThumbnailImageEx1, "LoadAlbumScreenShotThumbnailImageEx1"},
+        {1002, C<&IAlbumAccessorService::LoadAlbumScreenShotImageEx1>, "LoadAlbumScreenShotImageEx1"},
+        {1003, C<&IAlbumAccessorService::LoadAlbumScreenShotThumbnailImageEx1>, "LoadAlbumScreenShotThumbnailImageEx1"},
         {8001, nullptr, "ForceAlbumUnmounted"},
         {8002, nullptr, "ResetAlbumMountStatus"},
         {8011, nullptr, "RefreshAlbumCache"},
@@ -62,138 +62,70 @@ IAlbumAccessorService::IAlbumAccessorService(Core::System& system_,
 
 IAlbumAccessorService::~IAlbumAccessorService() = default;
 
-void IAlbumAccessorService::DeleteAlbumFile(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const auto file_id{rp.PopRaw<AlbumFileId>()};
-
+Result IAlbumAccessorService::DeleteAlbumFile(AlbumFileId file_id) {
     LOG_INFO(Service_Capture, "called, application_id=0x{:0x}, storage={}, type={}",
              file_id.application_id, file_id.storage, file_id.type);
 
-    Result result = manager->DeleteAlbumFile(file_id);
-    result = TranslateResult(result);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(result);
+    const Result result = manager->DeleteAlbumFile(file_id);
+    R_RETURN(TranslateResult(result));
 }
 
-void IAlbumAccessorService::IsAlbumMounted(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const auto storage{rp.PopEnum<AlbumStorage>()};
-
+Result IAlbumAccessorService::IsAlbumMounted(Out<bool> out_is_mounted, AlbumStorage storage) {
     LOG_INFO(Service_Capture, "called, storage={}", storage);
 
-    Result result = manager->IsAlbumMounted(storage);
-    const bool is_mounted = result.IsSuccess();
-    result = TranslateResult(result);
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(result);
-    rb.Push<u8>(is_mounted);
+    const Result result = manager->IsAlbumMounted(storage);
+    *out_is_mounted = result.IsSuccess();
+    R_RETURN(TranslateResult(result));
 }
 
-void IAlbumAccessorService::Unknown18(HLERequestContext& ctx) {
-    struct UnknownBuffer {
-        INSERT_PADDING_BYTES(0x10);
-    };
-    static_assert(sizeof(UnknownBuffer) == 0x10, "UnknownBuffer is an invalid size");
-
+Result IAlbumAccessorService::Unknown18(
+    Out<u32> out_buffer_size,
+    OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_buffer) {
     LOG_WARNING(Service_Capture, "(STUBBED) called");
-
-    std::vector<UnknownBuffer> buffer{};
-
-    if (!buffer.empty()) {
-        ctx.WriteBuffer(buffer);
-    }
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push(static_cast<u32>(buffer.size()));
+    *out_buffer_size = 0;
+    R_SUCCEED();
 }
 
-void IAlbumAccessorService::GetAlbumFileListEx0(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const auto storage{rp.PopEnum<AlbumStorage>()};
-    const auto flags{rp.Pop<u8>()};
-    const auto album_entry_size{ctx.GetWriteBufferNumElements<AlbumEntry>()};
-
+Result IAlbumAccessorService::GetAlbumFileListEx0(
+    Out<u64> out_entries_size, AlbumStorage storage, u8 flags,
+    OutArray<AlbumEntry, BufferAttr_HipcMapAlias> out_entries) {
     LOG_INFO(Service_Capture, "called, storage={}, flags={}", storage, flags);
 
-    std::vector<AlbumEntry> entries;
-    Result result = manager->GetAlbumFileList(entries, storage, flags);
-    result = TranslateResult(result);
-
-    entries.resize(std::min(album_entry_size, entries.size()));
-
-    if (!entries.empty()) {
-        ctx.WriteBuffer(entries);
-    }
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(result);
-    rb.Push<u64>(entries.size());
+    const Result result = manager->GetAlbumFileList(out_entries, *out_entries_size, storage, flags);
+    R_RETURN(TranslateResult(result));
 }
 
-void IAlbumAccessorService::GetAutoSavingStorage(HLERequestContext& ctx) {
+Result IAlbumAccessorService::GetAutoSavingStorage(Out<bool> out_is_autosaving) {
     LOG_WARNING(Service_Capture, "(STUBBED) called");
 
-    bool is_autosaving{};
-    Result result = manager->GetAutoSavingStorage(is_autosaving);
-    result = TranslateResult(result);
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(result);
-    rb.Push<u8>(is_autosaving);
+    const Result result = manager->GetAutoSavingStorage(*out_is_autosaving);
+    R_RETURN(TranslateResult(result));
 }
 
-void IAlbumAccessorService::LoadAlbumScreenShotImageEx1(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const auto file_id{rp.PopRaw<AlbumFileId>()};
-    const auto decoder_options{rp.PopRaw<ScreenShotDecodeOption>()};
-    const auto image_buffer_size{ctx.GetWriteBufferSize(1)};
-
+Result IAlbumAccessorService::LoadAlbumScreenShotImageEx1(
+    const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options,
+    OutLargeData<LoadAlbumScreenShotImageOutput, BufferAttr_HipcMapAlias> out_image_output,
+    OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_image,
+    OutArray<u8, BufferAttr_HipcMapAlias> out_buffer) {
     LOG_INFO(Service_Capture, "called, application_id=0x{:0x}, storage={}, type={}, flags={}",
              file_id.application_id, file_id.storage, file_id.type, decoder_options.flags);
 
-    std::vector<u8> image;
-    LoadAlbumScreenShotImageOutput image_output;
-    Result result =
-        manager->LoadAlbumScreenShotImage(image_output, image, file_id, decoder_options);
-    result = TranslateResult(result);
-
-    if (image.size() > image_buffer_size) {
-        result = ResultWorkMemoryError;
-    }
-
-    if (result.IsSuccess()) {
-        ctx.WriteBuffer(image_output, 0);
-        ctx.WriteBuffer(image, 1);
-    }
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(result);
+    const Result result =
+        manager->LoadAlbumScreenShotImage(*out_image_output, out_image, file_id, decoder_options);
+    R_RETURN(TranslateResult(result));
 }
 
-void IAlbumAccessorService::LoadAlbumScreenShotThumbnailImageEx1(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const auto file_id{rp.PopRaw<AlbumFileId>()};
-    const auto decoder_options{rp.PopRaw<ScreenShotDecodeOption>()};
-
+Result IAlbumAccessorService::LoadAlbumScreenShotThumbnailImageEx1(
+    const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options,
+    OutLargeData<LoadAlbumScreenShotImageOutput, BufferAttr_HipcMapAlias> out_image_output,
+    OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_image,
+    OutArray<u8, BufferAttr_HipcMapAlias> out_buffer) {
     LOG_INFO(Service_Capture, "called, application_id=0x{:0x}, storage={}, type={}, flags={}",
              file_id.application_id, file_id.storage, file_id.type, decoder_options.flags);
 
-    std::vector<u8> image(ctx.GetWriteBufferSize(1));
-    LoadAlbumScreenShotImageOutput image_output;
-    Result result =
-        manager->LoadAlbumScreenShotThumbnail(image_output, image, file_id, decoder_options);
-    result = TranslateResult(result);
-
-    if (result.IsSuccess()) {
-        ctx.WriteBuffer(image_output, 0);
-        ctx.WriteBuffer(image, 1);
-    }
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(result);
+    const Result result = manager->LoadAlbumScreenShotThumbnail(*out_image_output, out_image,
+                                                                file_id, decoder_options);
+    R_RETURN(TranslateResult(result));
 }
 
 Result IAlbumAccessorService::TranslateResult(Result in_result) {
diff --git a/src/core/hle/service/caps/caps_a.h b/src/core/hle/service/caps/caps_a.h
index c90cff71e5..2cb9b45478 100644
--- a/src/core/hle/service/caps/caps_a.h
+++ b/src/core/hle/service/caps/caps_a.h
@@ -3,6 +3,8 @@
 
 #pragma once
 
+#include "core/hle/service/caps/caps_types.h"
+#include "core/hle/service/cmif_types.h"
 #include "core/hle/service/service.h"
 
 namespace Core {
@@ -19,13 +21,31 @@ public:
     ~IAlbumAccessorService() override;
 
 private:
-    void DeleteAlbumFile(HLERequestContext& ctx);
-    void IsAlbumMounted(HLERequestContext& ctx);
-    void Unknown18(HLERequestContext& ctx);
-    void GetAlbumFileListEx0(HLERequestContext& ctx);
-    void GetAutoSavingStorage(HLERequestContext& ctx);
-    void LoadAlbumScreenShotImageEx1(HLERequestContext& ctx);
-    void LoadAlbumScreenShotThumbnailImageEx1(HLERequestContext& ctx);
+    Result DeleteAlbumFile(AlbumFileId file_id);
+
+    Result IsAlbumMounted(Out<bool> out_is_mounted, AlbumStorage storage);
+
+    Result Unknown18(
+        Out<u32> out_buffer_size,
+        OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure>
+            out_buffer);
+
+    Result GetAlbumFileListEx0(Out<u64> out_entries_size, AlbumStorage storage, u8 flags,
+                               OutArray<AlbumEntry, BufferAttr_HipcMapAlias> out_entries);
+
+    Result GetAutoSavingStorage(Out<bool> out_is_autosaving);
+
+    Result LoadAlbumScreenShotImageEx1(
+        const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options,
+        OutLargeData<LoadAlbumScreenShotImageOutput, BufferAttr_HipcMapAlias> out_image_output,
+        OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_image,
+        OutArray<u8, BufferAttr_HipcMapAlias> out_buffer);
+
+    Result LoadAlbumScreenShotThumbnailImageEx1(
+        const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options,
+        OutLargeData<LoadAlbumScreenShotImageOutput, BufferAttr_HipcMapAlias> out_image_output,
+        OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_image,
+        OutArray<u8, BufferAttr_HipcMapAlias> out_buffer);
 
     Result TranslateResult(Result in_result);
 
diff --git a/src/core/hle/service/caps/caps_c.cpp b/src/core/hle/service/caps/caps_c.cpp
index 1e7fe64744..6993c04c2c 100644
--- a/src/core/hle/service/caps/caps_c.cpp
+++ b/src/core/hle/service/caps/caps_c.cpp
@@ -6,6 +6,7 @@
 #include "core/hle/service/caps/caps_manager.h"
 #include "core/hle/service/caps/caps_result.h"
 #include "core/hle/service/caps/caps_types.h"
+#include "core/hle/service/cmif_serialization.h"
 #include "core/hle/service/ipc_helpers.h"
 
 namespace Service::Capture {
@@ -17,7 +18,7 @@ IAlbumControlService::IAlbumControlService(Core::System& system_,
     static const FunctionInfo functions[] = {
         {1, nullptr, "CaptureRawImage"},
         {2, nullptr, "CaptureRawImageWithTimeout"},
-        {33, &IAlbumControlService::SetShimLibraryVersion, "SetShimLibraryVersion"},
+        {33, C<&IAlbumControlService::SetShimLibraryVersion>, "SetShimLibraryVersion"},
         {1001, nullptr, "RequestTakingScreenShot"},
         {1002, nullptr, "RequestTakingScreenShotWithTimeout"},
         {1011, nullptr, "NotifyTakingScreenShotRefused"},
@@ -42,16 +43,11 @@ IAlbumControlService::IAlbumControlService(Core::System& system_,
 
 IAlbumControlService::~IAlbumControlService() = default;
 
-void IAlbumControlService::SetShimLibraryVersion(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const auto library_version{rp.Pop<u64>()};
-    const auto applet_resource_user_id{rp.Pop<u64>()};
-
+Result IAlbumControlService::SetShimLibraryVersion(ShimLibraryVersion library_version,
+                                                   ClientAppletResourceUserId aruid) {
     LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}",
-                library_version, applet_resource_user_id);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
+                library_version, aruid.pid);
+    R_SUCCEED();
 }
 
 } // namespace Service::Capture
diff --git a/src/core/hle/service/caps/caps_c.h b/src/core/hle/service/caps/caps_c.h
index 92ba242db7..0ecdfa1147 100644
--- a/src/core/hle/service/caps/caps_c.h
+++ b/src/core/hle/service/caps/caps_c.h
@@ -3,6 +3,7 @@
 
 #pragma once
 
+#include "core/hle/service/cmif_types.h"
 #include "core/hle/service/service.h"
 
 namespace Core {
@@ -11,6 +12,7 @@ class System;
 
 namespace Service::Capture {
 class AlbumManager;
+enum class ShimLibraryVersion : u64;
 
 class IAlbumControlService final : public ServiceFramework<IAlbumControlService> {
 public:
@@ -19,7 +21,8 @@ public:
     ~IAlbumControlService() override;
 
 private:
-    void SetShimLibraryVersion(HLERequestContext& ctx);
+    Result SetShimLibraryVersion(ShimLibraryVersion library_version,
+                                 ClientAppletResourceUserId aruid);
 
     std::shared_ptr<AlbumManager> manager = nullptr;
 };
diff --git a/src/core/hle/service/caps/caps_manager.cpp b/src/core/hle/service/caps/caps_manager.cpp
index 3a22b135f1..7f0bc127f9 100644
--- a/src/core/hle/service/caps/caps_manager.cpp
+++ b/src/core/hle/service/caps/caps_manager.cpp
@@ -58,8 +58,8 @@ Result AlbumManager::IsAlbumMounted(AlbumStorage storage) {
     return is_mounted ? ResultSuccess : ResultIsNotMounted;
 }
 
-Result AlbumManager::GetAlbumFileList(std::vector<AlbumEntry>& out_entries, AlbumStorage storage,
-                                      u8 flags) const {
+Result AlbumManager::GetAlbumFileList(std::span<AlbumEntry> out_entries, u64& out_entries_count,
+                                      AlbumStorage storage, u8 flags) const {
     if (storage > AlbumStorage::Sd) {
         return ResultInvalidStorage;
     }
@@ -72,51 +72,55 @@ Result AlbumManager::GetAlbumFileList(std::vector<AlbumEntry>& out_entries, Albu
         if (file_id.storage != storage) {
             continue;
         }
-        if (out_entries.size() >= SdAlbumFileLimit) {
+        if (out_entries_count >= SdAlbumFileLimit) {
+            break;
+        }
+        if (out_entries_count >= out_entries.size()) {
             break;
         }
 
         const auto entry_size = Common::FS::GetSize(path);
-        out_entries.push_back({
+        out_entries[out_entries_count++] = {
             .entry_size = entry_size,
             .file_id = file_id,
-        });
+        };
     }
 
     return ResultSuccess;
 }
 
-Result AlbumManager::GetAlbumFileList(std::vector<ApplicationAlbumFileEntry>& out_entries,
-                                      ContentType content_type, s64 start_posix_time,
-                                      s64 end_posix_time, u64 aruid) const {
+Result AlbumManager::GetAlbumFileList(std::span<ApplicationAlbumFileEntry> out_entries,
+                                      u64& out_entries_count, ContentType content_type,
+                                      s64 start_posix_time, s64 end_posix_time, u64 aruid) const {
     if (!is_mounted) {
         return ResultIsNotMounted;
     }
 
-    std::vector<ApplicationAlbumEntry> album_entries;
+    std::vector<ApplicationAlbumEntry> album_entries(out_entries.size());
     const auto start_date = ConvertToAlbumDateTime(start_posix_time);
     const auto end_date = ConvertToAlbumDateTime(end_posix_time);
-    const auto result = GetAlbumFileList(album_entries, content_type, start_date, end_date, aruid);
+    const auto result = GetAlbumFileList(album_entries, out_entries_count, content_type, start_date,
+                                         end_date, aruid);
 
     if (result.IsError()) {
         return result;
     }
 
-    for (const auto& album_entry : album_entries) {
-        ApplicationAlbumFileEntry entry{
-            .entry = album_entry,
-            .datetime = album_entry.datetime,
+    for (std::size_t i = 0; i < out_entries_count; i++) {
+        out_entries[i] = {
+            .entry = album_entries[i],
+            .datetime = album_entries[i].datetime,
             .unknown = {},
         };
-        out_entries.push_back(entry);
     }
 
     return ResultSuccess;
 }
 
-Result AlbumManager::GetAlbumFileList(std::vector<ApplicationAlbumEntry>& out_entries,
-                                      ContentType content_type, AlbumFileDateTime start_date,
-                                      AlbumFileDateTime end_date, u64 aruid) const {
+Result AlbumManager::GetAlbumFileList(std::span<ApplicationAlbumEntry> out_entries,
+                                      u64& out_entries_count, ContentType content_type,
+                                      AlbumFileDateTime start_date, AlbumFileDateTime end_date,
+                                      u64 aruid) const {
     if (!is_mounted) {
         return ResultIsNotMounted;
     }
@@ -131,12 +135,15 @@ Result AlbumManager::GetAlbumFileList(std::vector<ApplicationAlbumEntry>& out_en
         if (file_id.date < end_date) {
             continue;
         }
-        if (out_entries.size() >= SdAlbumFileLimit) {
+        if (out_entries_count >= SdAlbumFileLimit) {
+            break;
+        }
+        if (out_entries_count >= out_entries.size()) {
             break;
         }
 
         const auto entry_size = Common::FS::GetSize(path);
-        ApplicationAlbumEntry entry{
+        out_entries[out_entries_count++] = {
             .size = entry_size,
             .hash{},
             .datetime = file_id.date,
@@ -144,7 +151,6 @@ Result AlbumManager::GetAlbumFileList(std::vector<ApplicationAlbumEntry>& out_en
             .content = content_type,
             .unknown = 1,
         };
-        out_entries.push_back(entry);
     }
 
     return ResultSuccess;
@@ -156,8 +162,7 @@ Result AlbumManager::GetAutoSavingStorage(bool& out_is_autosaving) const {
 }
 
 Result AlbumManager::LoadAlbumScreenShotImage(LoadAlbumScreenShotImageOutput& out_image_output,
-                                              std::vector<u8>& out_image,
-                                              const AlbumFileId& file_id,
+                                              std::span<u8> out_image, const AlbumFileId& file_id,
                                               const ScreenShotDecodeOption& decoder_options) const {
     if (file_id.storage > AlbumStorage::Sd) {
         return ResultInvalidStorage;
@@ -176,7 +181,9 @@ Result AlbumManager::LoadAlbumScreenShotImage(LoadAlbumScreenShotImageOutput& ou
                 .orientation = AlbumImageOrientation::None,
                 .unknown_1{},
                 .unknown_2{},
+                .pad163{},
             },
+        .pad179{},
     };
 
     std::filesystem::path path;
@@ -186,14 +193,12 @@ Result AlbumManager::LoadAlbumScreenShotImage(LoadAlbumScreenShotImageOutput& ou
         return result;
     }
 
-    out_image.resize(out_image_output.height * out_image_output.width * STBI_rgb_alpha);
-
     return LoadImage(out_image, path, static_cast<int>(out_image_output.width),
                      +static_cast<int>(out_image_output.height), decoder_options.flags);
 }
 
 Result AlbumManager::LoadAlbumScreenShotThumbnail(
-    LoadAlbumScreenShotImageOutput& out_image_output, std::vector<u8>& out_image,
+    LoadAlbumScreenShotImageOutput& out_image_output, std::span<u8> out_image,
     const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options) const {
     if (file_id.storage > AlbumStorage::Sd) {
         return ResultInvalidStorage;
@@ -212,7 +217,9 @@ Result AlbumManager::LoadAlbumScreenShotThumbnail(
                 .orientation = AlbumImageOrientation::None,
                 .unknown_1{},
                 .unknown_2{},
+                .pad163{},
             },
+        .pad179{},
     };
 
     std::filesystem::path path;
@@ -222,8 +229,6 @@ Result AlbumManager::LoadAlbumScreenShotThumbnail(
         return result;
     }
 
-    out_image.resize(out_image_output.height * out_image_output.width * STBI_rgb_alpha);
-
     return LoadImage(out_image, path, static_cast<int>(out_image_output.width),
                      +static_cast<int>(out_image_output.height), decoder_options.flags);
 }
diff --git a/src/core/hle/service/caps/caps_manager.h b/src/core/hle/service/caps/caps_manager.h
index 6fd34f589b..893a9075a0 100644
--- a/src/core/hle/service/caps/caps_manager.h
+++ b/src/core/hle/service/caps/caps_manager.h
@@ -42,20 +42,20 @@ public:
 
     Result DeleteAlbumFile(const AlbumFileId& file_id);
     Result IsAlbumMounted(AlbumStorage storage);
-    Result GetAlbumFileList(std::vector<AlbumEntry>& out_entries, AlbumStorage storage,
-                            u8 flags) const;
-    Result GetAlbumFileList(std::vector<ApplicationAlbumFileEntry>& out_entries,
-                            ContentType content_type, s64 start_posix_time, s64 end_posix_time,
-                            u64 aruid) const;
-    Result GetAlbumFileList(std::vector<ApplicationAlbumEntry>& out_entries,
+    Result GetAlbumFileList(std::span<AlbumEntry> out_entries, u64& out_entries_count,
+                            AlbumStorage storage, u8 flags) const;
+    Result GetAlbumFileList(std::span<ApplicationAlbumFileEntry> out_entries,
+                            u64& out_entries_count, ContentType content_type, s64 start_posix_time,
+                            s64 end_posix_time, u64 aruid) const;
+    Result GetAlbumFileList(std::span<ApplicationAlbumEntry> out_entries, u64& out_entries_count,
                             ContentType content_type, AlbumFileDateTime start_date,
                             AlbumFileDateTime end_date, u64 aruid) const;
     Result GetAutoSavingStorage(bool& out_is_autosaving) const;
     Result LoadAlbumScreenShotImage(LoadAlbumScreenShotImageOutput& out_image_output,
-                                    std::vector<u8>& out_image, const AlbumFileId& file_id,
+                                    std::span<u8> out_image, const AlbumFileId& file_id,
                                     const ScreenShotDecodeOption& decoder_options) const;
     Result LoadAlbumScreenShotThumbnail(LoadAlbumScreenShotImageOutput& out_image_output,
-                                        std::vector<u8>& out_image, const AlbumFileId& file_id,
+                                        std::span<u8> out_image, const AlbumFileId& file_id,
                                         const ScreenShotDecodeOption& decoder_options) const;
 
     Result SaveScreenShot(ApplicationAlbumEntry& out_entry, const ScreenShotAttribute& attribute,
diff --git a/src/core/hle/service/caps/caps_ss.cpp b/src/core/hle/service/caps/caps_ss.cpp
index eab023568f..dfa7f1a840 100644
--- a/src/core/hle/service/caps/caps_ss.cpp
+++ b/src/core/hle/service/caps/caps_ss.cpp
@@ -3,10 +3,9 @@
 
 #include "common/logging/log.h"
 #include "core/hle/service/caps/caps_manager.h"
-#include "core/hle/service/caps/caps_types.h"
-#include "core/hle/service/ipc_helpers.h"
-
 #include "core/hle/service/caps/caps_ss.h"
+#include "core/hle/service/cmif_serialization.h"
+#include "core/hle/service/ipc_helpers.h"
 
 namespace Service::Capture {
 
@@ -17,9 +16,9 @@ IScreenShotService::IScreenShotService(Core::System& system_,
     static const FunctionInfo functions[] = {
         {201, nullptr, "SaveScreenShot"},
         {202, nullptr, "SaveEditedScreenShot"},
-        {203, &IScreenShotService::SaveScreenShotEx0, "SaveScreenShotEx0"},
+        {203, C<&IScreenShotService::SaveScreenShotEx0>, "SaveScreenShotEx0"},
         {204, nullptr, "SaveEditedScreenShotEx0"},
-        {206, &IScreenShotService::SaveEditedScreenShotEx1, "SaveEditedScreenShotEx1"},
+        {206, C<&IScreenShotService::SaveEditedScreenShotEx1>, "SaveEditedScreenShotEx1"},
         {208, nullptr, "SaveScreenShotOfMovieEx1"},
         {1000, nullptr, "Unknown1000"},
     };
@@ -30,69 +29,38 @@ IScreenShotService::IScreenShotService(Core::System& system_,
 
 IScreenShotService::~IScreenShotService() = default;
 
-void IScreenShotService::SaveScreenShotEx0(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    struct Parameters {
-        ScreenShotAttribute attribute{};
-        AlbumReportOption report_option{};
-        INSERT_PADDING_BYTES(0x4);
-        u64 applet_resource_user_id{};
-    };
-    static_assert(sizeof(Parameters) == 0x50, "Parameters has incorrect size.");
-
-    const auto parameters{rp.PopRaw<Parameters>()};
-    const auto image_data_buffer = ctx.ReadBuffer();
-
+Result IScreenShotService::SaveScreenShotEx0(
+    Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute,
+    AlbumReportOption report_option, ClientAppletResourceUserId aruid,
+    InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
+        image_data_buffer) {
     LOG_INFO(Service_Capture,
              "called, report_option={}, image_data_buffer_size={}, applet_resource_user_id={}",
-             parameters.report_option, image_data_buffer.size(),
-             parameters.applet_resource_user_id);
+             report_option, image_data_buffer.size(), aruid.pid);
 
-    ApplicationAlbumEntry entry{};
     manager->FlipVerticallyOnWrite(false);
-    const auto result =
-        manager->SaveScreenShot(entry, parameters.attribute, parameters.report_option,
-                                image_data_buffer, parameters.applet_resource_user_id);
-
-    IPC::ResponseBuilder rb{ctx, 10};
-    rb.Push(result);
-    rb.PushRaw(entry);
+    R_RETURN(manager->SaveScreenShot(*out_entry, attribute, report_option, image_data_buffer,
+                                     aruid.pid));
 }
 
-void IScreenShotService::SaveEditedScreenShotEx1(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    struct Parameters {
-        ScreenShotAttribute attribute;
-        u64 width;
-        u64 height;
-        u64 thumbnail_width;
-        u64 thumbnail_height;
-        AlbumFileId file_id;
-    };
-    static_assert(sizeof(Parameters) == 0x78, "Parameters has incorrect size.");
-
-    const auto parameters{rp.PopRaw<Parameters>()};
-    const auto application_data_buffer = ctx.ReadBuffer(0);
-    const auto image_data_buffer = ctx.ReadBuffer(1);
-    const auto thumbnail_image_data_buffer = ctx.ReadBuffer(2);
-
+Result IScreenShotService::SaveEditedScreenShotEx1(
+    Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute, u64 width,
+    u64 height, u64 thumbnail_width, u64 thumbnail_height, const AlbumFileId& file_id,
+    const InLargeData<std::array<u8, 0x400>, BufferAttr_HipcMapAlias> application_data_buffer,
+    const InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
+        image_data_buffer,
+    const InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
+        thumbnail_image_data_buffer) {
     LOG_INFO(Service_Capture,
              "called, width={}, height={}, thumbnail_width={}, thumbnail_height={}, "
-             "application_id={:016x},  storage={},  type={}, app_data_buffer_size={}, "
+             "application_id={:016x},  storage={},  type={}, "
              "image_data_buffer_size={}, thumbnail_image_buffer_size={}",
-             parameters.width, parameters.height, parameters.thumbnail_width,
-             parameters.thumbnail_height, parameters.file_id.application_id,
-             parameters.file_id.storage, parameters.file_id.type, application_data_buffer.size(),
-             image_data_buffer.size(), thumbnail_image_data_buffer.size());
+             width, height, thumbnail_width, thumbnail_height, file_id.application_id,
+             file_id.storage, file_id.type, image_data_buffer.size(),
+             thumbnail_image_data_buffer.size());
 
-    ApplicationAlbumEntry entry{};
     manager->FlipVerticallyOnWrite(false);
-    const auto result = manager->SaveEditedScreenShot(entry, parameters.attribute,
-                                                      parameters.file_id, image_data_buffer);
-
-    IPC::ResponseBuilder rb{ctx, 10};
-    rb.Push(result);
-    rb.PushRaw(entry);
+    R_RETURN(manager->SaveEditedScreenShot(*out_entry, attribute, file_id, image_data_buffer));
 }
 
 } // namespace Service::Capture
diff --git a/src/core/hle/service/caps/caps_ss.h b/src/core/hle/service/caps/caps_ss.h
index a7e9972ab2..da4b4cc5fc 100644
--- a/src/core/hle/service/caps/caps_ss.h
+++ b/src/core/hle/service/caps/caps_ss.h
@@ -3,6 +3,8 @@
 
 #pragma once
 
+#include "core/hle/service/caps/caps_types.h"
+#include "core/hle/service/cmif_types.h"
 #include "core/hle/service/service.h"
 
 namespace Core {
@@ -17,8 +19,20 @@ public:
     ~IScreenShotService() override;
 
 private:
-    void SaveScreenShotEx0(HLERequestContext& ctx);
-    void SaveEditedScreenShotEx1(HLERequestContext& ctx);
+    Result SaveScreenShotEx0(
+        Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute,
+        AlbumReportOption report_option, ClientAppletResourceUserId aruid,
+        InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
+            image_data_buffer);
+
+    Result SaveEditedScreenShotEx1(
+        Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute, u64 width,
+        u64 height, u64 thumbnail_width, u64 thumbnail_height, const AlbumFileId& file_id,
+        const InLargeData<std::array<u8, 0x400>, BufferAttr_HipcMapAlias> application_data_buffer,
+        const InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
+            image_data_buffer,
+        const InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
+            thumbnail_image_data_buffer);
 
     std::shared_ptr<AlbumManager> manager;
 };
diff --git a/src/core/hle/service/caps/caps_su.cpp b/src/core/hle/service/caps/caps_su.cpp
index 296b07b003..528f364f5f 100644
--- a/src/core/hle/service/caps/caps_su.cpp
+++ b/src/core/hle/service/caps/caps_su.cpp
@@ -6,6 +6,7 @@
 #include "core/hle/service/caps/caps_manager.h"
 #include "core/hle/service/caps/caps_su.h"
 #include "core/hle/service/caps/caps_types.h"
+#include "core/hle/service/cmif_serialization.h"
 #include "core/hle/service/ipc_helpers.h"
 #include "video_core/renderer_base.h"
 
@@ -16,10 +17,10 @@ IScreenShotApplicationService::IScreenShotApplicationService(
     : ServiceFramework{system_, "caps:su"}, manager{album_manager} {
     // clang-format off
     static const FunctionInfo functions[] = {
-        {32, &IScreenShotApplicationService::SetShimLibraryVersion, "SetShimLibraryVersion"},
+        {32, C<&IScreenShotApplicationService::SetShimLibraryVersion>, "SetShimLibraryVersion"},
         {201, nullptr, "SaveScreenShot"},
-        {203, &IScreenShotApplicationService::SaveScreenShotEx0, "SaveScreenShotEx0"},
-        {205, &IScreenShotApplicationService::SaveScreenShotEx1, "SaveScreenShotEx1"},
+        {203, C<&IScreenShotApplicationService::SaveScreenShotEx0>, "SaveScreenShotEx0"},
+        {205, C<&IScreenShotApplicationService::SaveScreenShotEx1>, "SaveScreenShotEx1"},
         {210, nullptr, "SaveScreenShotEx2"},
     };
     // clang-format on
@@ -29,77 +30,40 @@ IScreenShotApplicationService::IScreenShotApplicationService(
 
 IScreenShotApplicationService::~IScreenShotApplicationService() = default;
 
-void IScreenShotApplicationService::SetShimLibraryVersion(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const auto library_version{rp.Pop<u64>()};
-    const auto applet_resource_user_id{rp.Pop<u64>()};
-
+Result IScreenShotApplicationService::SetShimLibraryVersion(ShimLibraryVersion library_version,
+                                                            ClientAppletResourceUserId aruid) {
     LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}",
-                library_version, applet_resource_user_id);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
+                library_version, aruid.pid);
+    R_SUCCEED();
 }
 
-void IScreenShotApplicationService::SaveScreenShotEx0(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    struct Parameters {
-        ScreenShotAttribute attribute{};
-        AlbumReportOption report_option{};
-        INSERT_PADDING_BYTES(0x4);
-        u64 applet_resource_user_id{};
-    };
-    static_assert(sizeof(Parameters) == 0x50, "Parameters has incorrect size.");
-
-    const auto parameters{rp.PopRaw<Parameters>()};
-    const auto image_data_buffer = ctx.ReadBuffer();
-
+Result IScreenShotApplicationService::SaveScreenShotEx0(
+    Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute,
+    AlbumReportOption report_option, ClientAppletResourceUserId aruid,
+    InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
+        image_data_buffer) {
     LOG_INFO(Service_Capture,
              "called, report_option={}, image_data_buffer_size={}, applet_resource_user_id={}",
-             parameters.report_option, image_data_buffer.size(),
-             parameters.applet_resource_user_id);
+             report_option, image_data_buffer.size(), aruid.pid);
 
-    ApplicationAlbumEntry entry{};
     manager->FlipVerticallyOnWrite(false);
-    const auto result =
-        manager->SaveScreenShot(entry, parameters.attribute, parameters.report_option,
-                                image_data_buffer, parameters.applet_resource_user_id);
-
-    IPC::ResponseBuilder rb{ctx, 10};
-    rb.Push(result);
-    rb.PushRaw(entry);
+    R_RETURN(manager->SaveScreenShot(*out_entry, attribute, report_option, image_data_buffer,
+                                     aruid.pid));
 }
 
-void IScreenShotApplicationService::SaveScreenShotEx1(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    struct Parameters {
-        ScreenShotAttribute attribute{};
-        AlbumReportOption report_option{};
-        INSERT_PADDING_BYTES(0x4);
-        u64 applet_resource_user_id{};
-    };
-    static_assert(sizeof(Parameters) == 0x50, "Parameters has incorrect size.");
-
-    const auto parameters{rp.PopRaw<Parameters>()};
-    const auto app_data_buffer = ctx.ReadBuffer(0);
-    const auto image_data_buffer = ctx.ReadBuffer(1);
-
+Result IScreenShotApplicationService::SaveScreenShotEx1(
+    Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute,
+    AlbumReportOption report_option, ClientAppletResourceUserId aruid,
+    const InLargeData<ApplicationData, BufferAttr_HipcMapAlias> app_data_buffer,
+    const InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
+        image_data_buffer) {
     LOG_INFO(Service_Capture,
              "called, report_option={}, image_data_buffer_size={}, applet_resource_user_id={}",
-             parameters.report_option, image_data_buffer.size(),
-             parameters.applet_resource_user_id);
+             report_option, image_data_buffer.size(), aruid.pid);
 
-    ApplicationAlbumEntry entry{};
-    ApplicationData app_data{};
-    std::memcpy(&app_data, app_data_buffer.data(), sizeof(ApplicationData));
     manager->FlipVerticallyOnWrite(false);
-    const auto result =
-        manager->SaveScreenShot(entry, parameters.attribute, parameters.report_option, app_data,
-                                image_data_buffer, parameters.applet_resource_user_id);
-
-    IPC::ResponseBuilder rb{ctx, 10};
-    rb.Push(result);
-    rb.PushRaw(entry);
+    R_RETURN(manager->SaveScreenShot(*out_entry, attribute, report_option, *app_data_buffer,
+                                     image_data_buffer, aruid.pid));
 }
 
 void IScreenShotApplicationService::CaptureAndSaveScreenshot(AlbumReportOption report_option) {
@@ -112,6 +76,7 @@ void IScreenShotApplicationService::CaptureAndSaveScreenshot(AlbumReportOption r
         .orientation = Capture::AlbumImageOrientation::None,
         .unknown_1{},
         .unknown_2{},
+        .pad163{},
     };
 
     renderer.RequestScreenshot(
diff --git a/src/core/hle/service/caps/caps_su.h b/src/core/hle/service/caps/caps_su.h
index 21912e95f6..4b4cbd09e6 100644
--- a/src/core/hle/service/caps/caps_su.h
+++ b/src/core/hle/service/caps/caps_su.h
@@ -3,6 +3,8 @@
 
 #pragma once
 
+#include "core/hle/service/caps/caps_types.h"
+#include "core/hle/service/cmif_types.h"
 #include "core/hle/service/service.h"
 
 namespace Core {
@@ -26,9 +28,19 @@ private:
     static constexpr std::size_t screenshot_height = 720;
     static constexpr std::size_t bytes_per_pixel = 4;
 
-    void SetShimLibraryVersion(HLERequestContext& ctx);
-    void SaveScreenShotEx0(HLERequestContext& ctx);
-    void SaveScreenShotEx1(HLERequestContext& ctx);
+    Result SetShimLibraryVersion(ShimLibraryVersion library_version,
+                                 ClientAppletResourceUserId aruid);
+    Result SaveScreenShotEx0(
+        Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute,
+        AlbumReportOption report_option, ClientAppletResourceUserId aruid,
+        InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
+            image_data_buffer);
+    Result SaveScreenShotEx1(
+        Out<ApplicationAlbumEntry> out_entry, const ScreenShotAttribute& attribute,
+        AlbumReportOption report_option, ClientAppletResourceUserId aruid,
+        const InLargeData<ApplicationData, BufferAttr_HipcMapAlias> app_data_buffer,
+        const InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias>
+            image_data_buffer);
 
     std::array<u8, screenshot_width * screenshot_height * bytes_per_pixel> image_data;
 
diff --git a/src/core/hle/service/caps/caps_types.h b/src/core/hle/service/caps/caps_types.h
index 589ac28d31..3deaaad5b8 100644
--- a/src/core/hle/service/caps/caps_types.h
+++ b/src/core/hle/service/caps/caps_types.h
@@ -41,6 +41,10 @@ enum class ScreenShotDecoderFlag : u64 {
     EnableBlockSmoothing = 1 << 1,
 };
 
+enum class ShimLibraryVersion : u64 {
+    Version1 = 1,
+};
+
 // This is nn::capsrv::AlbumFileDateTime
 struct AlbumFileDateTime {
     s16 year{};
@@ -144,19 +148,23 @@ static_assert(sizeof(ApplicationAlbumFileEntry) == 0x30,
               "ApplicationAlbumFileEntry has incorrect size.");
 
 struct ApplicationData {
-    std::array<u8, 0x400> data{};
-    u32 data_size{};
+    std::array<u8, 0x400> data;
+    u32 data_size;
 };
 static_assert(sizeof(ApplicationData) == 0x404, "ApplicationData is an invalid size");
+static_assert(std::is_trivial_v<ApplicationData>,
+              "ApplicationData type must be trivially copyable.");
 
 struct ScreenShotAttribute {
-    u32 unknown_0{};
-    AlbumImageOrientation orientation{};
-    u32 unknown_1{};
-    u32 unknown_2{};
-    INSERT_PADDING_BYTES(0x30);
+    u32 unknown_0;
+    AlbumImageOrientation orientation;
+    u32 unknown_1;
+    u32 unknown_2;
+    INSERT_PADDING_BYTES_NOINIT(0x30);
 };
 static_assert(sizeof(ScreenShotAttribute) == 0x40, "ScreenShotAttribute is an invalid size");
+static_assert(std::is_trivial_v<ScreenShotAttribute>,
+              "ScreenShotAttribute type must be trivially copyable.");
 
 struct ScreenShotDecodeOption {
     ScreenShotDecoderFlag flags{};
@@ -165,13 +173,15 @@ struct ScreenShotDecodeOption {
 static_assert(sizeof(ScreenShotDecodeOption) == 0x20, "ScreenShotDecodeOption is an invalid size");
 
 struct LoadAlbumScreenShotImageOutput {
-    s64 width{};
-    s64 height{};
-    ScreenShotAttribute attribute{};
-    INSERT_PADDING_BYTES(0x400);
+    s64 width;
+    s64 height;
+    ScreenShotAttribute attribute;
+    INSERT_PADDING_BYTES_NOINIT(0x400);
 };
 static_assert(sizeof(LoadAlbumScreenShotImageOutput) == 0x450,
               "LoadAlbumScreenShotImageOutput is an invalid size");
+static_assert(std::is_trivial_v<LoadAlbumScreenShotImageOutput>,
+              "LoadAlbumScreenShotImageOutput type must be trivially copyable.");
 
 struct LoadAlbumScreenShotImageOutputForApplication {
     s64 width{};
diff --git a/src/core/hle/service/caps/caps_u.cpp b/src/core/hle/service/caps/caps_u.cpp
index b6b33fb2fd..40d4d05fe5 100644
--- a/src/core/hle/service/caps/caps_u.cpp
+++ b/src/core/hle/service/caps/caps_u.cpp
@@ -5,6 +5,7 @@
 #include "core/hle/service/caps/caps_manager.h"
 #include "core/hle/service/caps/caps_types.h"
 #include "core/hle/service/caps/caps_u.h"
+#include "core/hle/service/cmif_serialization.h"
 #include "core/hle/service/ipc_helpers.h"
 
 namespace Service::Capture {
@@ -14,8 +15,8 @@ IAlbumApplicationService::IAlbumApplicationService(Core::System& system_,
     : ServiceFramework{system_, "caps:u"}, manager{album_manager} {
     // clang-format off
     static const FunctionInfo functions[] = {
-        {32, &IAlbumApplicationService::SetShimLibraryVersion, "SetShimLibraryVersion"},
-        {102, &IAlbumApplicationService::GetAlbumFileList0AafeAruidDeprecated, "GetAlbumFileList0AafeAruidDeprecated"},
+        {32, C<&IAlbumApplicationService::SetShimLibraryVersion>, "SetShimLibraryVersion"},
+        {102, C<&IAlbumApplicationService::GetAlbumFileList0AafeAruidDeprecated>, "GetAlbumFileList0AafeAruidDeprecated"},
         {103, nullptr, "DeleteAlbumFileByAruid"},
         {104, nullptr, "GetAlbumFileSizeByAruid"},
         {105, nullptr, "DeleteAlbumFileByAruidForDebug"},
@@ -24,7 +25,7 @@ IAlbumApplicationService::IAlbumApplicationService(Core::System& system_,
         {130, nullptr, "PrecheckToCreateContentsByAruid"},
         {140, nullptr, "GetAlbumFileList1AafeAruidDeprecated"},
         {141, nullptr, "GetAlbumFileList2AafeUidAruidDeprecated"},
-        {142, &IAlbumApplicationService::GetAlbumFileList3AaeAruid, "GetAlbumFileList3AaeAruid"},
+        {142, C<&IAlbumApplicationService::GetAlbumFileList3AaeAruid>, "GetAlbumFileList3AaeAruid"},
         {143, nullptr, "GetAlbumFileList4AaeUidAruid"},
         {144, nullptr, "GetAllAlbumFileList3AaeAruid"},
         {60002, nullptr, "OpenAccessorSessionForApplication"},
@@ -36,101 +37,40 @@ IAlbumApplicationService::IAlbumApplicationService(Core::System& system_,
 
 IAlbumApplicationService::~IAlbumApplicationService() = default;
 
-void IAlbumApplicationService::SetShimLibraryVersion(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const auto library_version{rp.Pop<u64>()};
-    const auto applet_resource_user_id{rp.Pop<u64>()};
-
+Result IAlbumApplicationService::SetShimLibraryVersion(ShimLibraryVersion library_version,
+                                                       ClientAppletResourceUserId aruid) {
     LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}",
-                library_version, applet_resource_user_id);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
+                library_version, aruid.pid);
+    R_SUCCEED();
 }
 
-void IAlbumApplicationService::GetAlbumFileList0AafeAruidDeprecated(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    struct Parameters {
-        ContentType content_type;
-        INSERT_PADDING_BYTES(7);
-        s64 start_posix_time;
-        s64 end_posix_time;
-        u64 applet_resource_user_id;
-    };
-    static_assert(sizeof(Parameters) == 0x20, "Parameters has incorrect size.");
-
-    const auto parameters{rp.PopRaw<Parameters>()};
-
+Result IAlbumApplicationService::GetAlbumFileList0AafeAruidDeprecated(
+    Out<u64> out_entries_count, ContentType content_type, s64 start_posix_time, s64 end_posix_time,
+    ClientAppletResourceUserId aruid,
+    OutArray<ApplicationAlbumFileEntry, BufferAttr_HipcMapAlias> out_entries) {
     LOG_WARNING(Service_Capture,
                 "(STUBBED) called. content_type={}, start_posix_time={}, end_posix_time={}, "
                 "applet_resource_user_id={}",
-                parameters.content_type, parameters.start_posix_time, parameters.end_posix_time,
-                parameters.applet_resource_user_id);
+                content_type, start_posix_time, end_posix_time, aruid.pid);
 
-    Result result = ResultSuccess;
-
-    if (result.IsSuccess()) {
-        result = manager->IsAlbumMounted(AlbumStorage::Sd);
-    }
-
-    std::vector<ApplicationAlbumFileEntry> entries;
-    if (result.IsSuccess()) {
-        result = manager->GetAlbumFileList(entries, parameters.content_type,
-                                           parameters.start_posix_time, parameters.end_posix_time,
-                                           parameters.applet_resource_user_id);
-    }
-
-    if (!entries.empty()) {
-        ctx.WriteBuffer(entries);
-    }
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(result);
-    rb.Push<u64>(entries.size());
+    R_TRY(manager->IsAlbumMounted(AlbumStorage::Sd));
+    R_RETURN(manager->GetAlbumFileList(out_entries, *out_entries_count, content_type,
+                                       start_posix_time, end_posix_time, aruid.pid));
 }
 
-void IAlbumApplicationService::GetAlbumFileList3AaeAruid(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    struct Parameters {
-        ContentType content_type;
-        INSERT_PADDING_BYTES(1);
-        AlbumFileDateTime start_date_time;
-        AlbumFileDateTime end_date_time;
-        INSERT_PADDING_BYTES(6);
-        u64 applet_resource_user_id;
-    };
-    static_assert(sizeof(Parameters) == 0x20, "Parameters has incorrect size.");
-
-    const auto parameters{rp.PopRaw<Parameters>()};
-
+Result IAlbumApplicationService::GetAlbumFileList3AaeAruid(
+    Out<u64> out_entries_count, ContentType content_type, AlbumFileDateTime start_date_time,
+    AlbumFileDateTime end_date_time, ClientAppletResourceUserId aruid,
+    OutArray<ApplicationAlbumEntry, BufferAttr_HipcMapAlias> out_entries) {
     LOG_WARNING(Service_Capture,
                 "(STUBBED) called. content_type={}, start_date={}/{}/{}, "
                 "end_date={}/{}/{}, applet_resource_user_id={}",
-                parameters.content_type, parameters.start_date_time.year,
-                parameters.start_date_time.month, parameters.start_date_time.day,
-                parameters.end_date_time.year, parameters.end_date_time.month,
-                parameters.end_date_time.day, parameters.applet_resource_user_id);
+                content_type, start_date_time.year, start_date_time.month, start_date_time.day,
+                end_date_time.year, end_date_time.month, end_date_time.day, aruid.pid);
 
-    Result result = ResultSuccess;
-
-    if (result.IsSuccess()) {
-        result = manager->IsAlbumMounted(AlbumStorage::Sd);
-    }
-
-    std::vector<ApplicationAlbumEntry> entries;
-    if (result.IsSuccess()) {
-        result =
-            manager->GetAlbumFileList(entries, parameters.content_type, parameters.start_date_time,
-                                      parameters.end_date_time, parameters.applet_resource_user_id);
-    }
-
-    if (!entries.empty()) {
-        ctx.WriteBuffer(entries);
-    }
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(result);
-    rb.Push<u64>(entries.size());
+    R_TRY(manager->IsAlbumMounted(AlbumStorage::Sd));
+    R_RETURN(manager->GetAlbumFileList(out_entries, *out_entries_count, content_type,
+                                       start_date_time, end_date_time, aruid.pid));
 }
 
 } // namespace Service::Capture
diff --git a/src/core/hle/service/caps/caps_u.h b/src/core/hle/service/caps/caps_u.h
index 9458c128ef..023ee1fe79 100644
--- a/src/core/hle/service/caps/caps_u.h
+++ b/src/core/hle/service/caps/caps_u.h
@@ -3,6 +3,7 @@
 
 #pragma once
 
+#include "core/hle/service/cmif_types.h"
 #include "core/hle/service/service.h"
 
 namespace Core {
@@ -19,9 +20,18 @@ public:
     ~IAlbumApplicationService() override;
 
 private:
-    void SetShimLibraryVersion(HLERequestContext& ctx);
-    void GetAlbumFileList0AafeAruidDeprecated(HLERequestContext& ctx);
-    void GetAlbumFileList3AaeAruid(HLERequestContext& ctx);
+    Result SetShimLibraryVersion(ShimLibraryVersion library_version,
+                                 ClientAppletResourceUserId aruid);
+
+    Result GetAlbumFileList0AafeAruidDeprecated(
+        Out<u64> out_entries_count, ContentType content_type, s64 start_posix_time,
+        s64 end_posix_time, ClientAppletResourceUserId aruid,
+        OutArray<ApplicationAlbumFileEntry, BufferAttr_HipcMapAlias> out_entries);
+
+    Result GetAlbumFileList3AaeAruid(
+        Out<u64> out_entries_count, ContentType content_type, AlbumFileDateTime start_date_time,
+        AlbumFileDateTime end_date_time, ClientAppletResourceUserId aruid,
+        OutArray<ApplicationAlbumEntry, BufferAttr_HipcMapAlias> out_entries);
 
     std::shared_ptr<AlbumManager> manager = nullptr;
 };