diff options
| -rw-r--r-- | src/core/hle/service/am/am.cpp | 69 | ||||
| -rw-r--r-- | src/core/hle/service/am/am.h | 1 |
2 files changed, 64 insertions, 6 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 6373d816d..c59054468 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -1125,7 +1125,7 @@ ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_) | |||
| 1125 | {2, nullptr, "AreAnyLibraryAppletsLeft"}, | 1125 | {2, nullptr, "AreAnyLibraryAppletsLeft"}, |
| 1126 | {10, &ILibraryAppletCreator::CreateStorage, "CreateStorage"}, | 1126 | {10, &ILibraryAppletCreator::CreateStorage, "CreateStorage"}, |
| 1127 | {11, &ILibraryAppletCreator::CreateTransferMemoryStorage, "CreateTransferMemoryStorage"}, | 1127 | {11, &ILibraryAppletCreator::CreateTransferMemoryStorage, "CreateTransferMemoryStorage"}, |
| 1128 | {12, nullptr, "CreateHandleStorage"}, | 1128 | {12, &ILibraryAppletCreator::CreateHandleStorage, "CreateHandleStorage"}, |
| 1129 | }; | 1129 | }; |
| 1130 | RegisterHandlers(functions); | 1130 | RegisterHandlers(functions); |
| 1131 | } | 1131 | } |
| @@ -1134,6 +1134,7 @@ ILibraryAppletCreator::~ILibraryAppletCreator() = default; | |||
| 1134 | 1134 | ||
| 1135 | void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) { | 1135 | void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) { |
| 1136 | IPC::RequestParser rp{ctx}; | 1136 | IPC::RequestParser rp{ctx}; |
| 1137 | |||
| 1137 | const auto applet_id = rp.PopRaw<Applets::AppletId>(); | 1138 | const auto applet_id = rp.PopRaw<Applets::AppletId>(); |
| 1138 | const auto applet_mode = rp.PopRaw<Applets::LibraryAppletMode>(); | 1139 | const auto applet_mode = rp.PopRaw<Applets::LibraryAppletMode>(); |
| 1139 | 1140 | ||
| @@ -1159,9 +1160,18 @@ void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) | |||
| 1159 | 1160 | ||
| 1160 | void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) { | 1161 | void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) { |
| 1161 | IPC::RequestParser rp{ctx}; | 1162 | IPC::RequestParser rp{ctx}; |
| 1162 | const u64 size{rp.Pop<u64>()}; | 1163 | |
| 1164 | const s64 size{rp.Pop<s64>()}; | ||
| 1165 | |||
| 1163 | LOG_DEBUG(Service_AM, "called, size={}", size); | 1166 | LOG_DEBUG(Service_AM, "called, size={}", size); |
| 1164 | 1167 | ||
| 1168 | if (size <= 0) { | ||
| 1169 | LOG_ERROR(Service_AM, "size is less than or equal to 0"); | ||
| 1170 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1171 | rb.Push(RESULT_UNKNOWN); | ||
| 1172 | return; | ||
| 1173 | } | ||
| 1174 | |||
| 1165 | std::vector<u8> buffer(size); | 1175 | std::vector<u8> buffer(size); |
| 1166 | 1176 | ||
| 1167 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 1177 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| @@ -1170,18 +1180,65 @@ void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) { | |||
| 1170 | } | 1180 | } |
| 1171 | 1181 | ||
| 1172 | void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx) { | 1182 | void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx) { |
| 1173 | LOG_DEBUG(Service_AM, "called"); | 1183 | IPC::RequestParser rp{ctx}; |
| 1184 | |||
| 1185 | struct Parameters { | ||
| 1186 | u8 permissions; | ||
| 1187 | s64 size; | ||
| 1188 | }; | ||
| 1189 | |||
| 1190 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1191 | const auto handle{ctx.GetCopyHandle(0)}; | ||
| 1192 | |||
| 1193 | LOG_DEBUG(Service_AM, "called, permissions={}, size={}, handle={:08X}", parameters.permissions, | ||
| 1194 | parameters.size, handle); | ||
| 1195 | |||
| 1196 | if (parameters.size <= 0) { | ||
| 1197 | LOG_ERROR(Service_AM, "size is less than or equal to 0"); | ||
| 1198 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1199 | rb.Push(RESULT_UNKNOWN); | ||
| 1200 | return; | ||
| 1201 | } | ||
| 1202 | |||
| 1203 | auto transfer_mem = | ||
| 1204 | system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(handle); | ||
| 1205 | |||
| 1206 | if (transfer_mem == nullptr) { | ||
| 1207 | LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle); | ||
| 1208 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1209 | rb.Push(RESULT_UNKNOWN); | ||
| 1210 | return; | ||
| 1211 | } | ||
| 1212 | |||
| 1213 | const u8* const mem_begin = transfer_mem->GetPointer(); | ||
| 1214 | const u8* const mem_end = mem_begin + transfer_mem->GetSize(); | ||
| 1215 | std::vector<u8> memory{mem_begin, mem_end}; | ||
| 1174 | 1216 | ||
| 1217 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 1218 | rb.Push(RESULT_SUCCESS); | ||
| 1219 | rb.PushIpcInterface<IStorage>(system, std::move(memory)); | ||
| 1220 | } | ||
| 1221 | |||
| 1222 | void ILibraryAppletCreator::CreateHandleStorage(Kernel::HLERequestContext& ctx) { | ||
| 1175 | IPC::RequestParser rp{ctx}; | 1223 | IPC::RequestParser rp{ctx}; |
| 1176 | 1224 | ||
| 1177 | rp.SetCurrentOffset(3); | 1225 | const s64 size{rp.Pop<s64>()}; |
| 1178 | const auto handle{rp.Pop<Kernel::Handle>()}; | 1226 | const auto handle{ctx.GetCopyHandle(0)}; |
| 1227 | |||
| 1228 | LOG_DEBUG(Service_AM, "called, size={}, handle={:08X}", size, handle); | ||
| 1229 | |||
| 1230 | if (size <= 0) { | ||
| 1231 | LOG_ERROR(Service_AM, "size is less than or equal to 0"); | ||
| 1232 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1233 | rb.Push(RESULT_UNKNOWN); | ||
| 1234 | return; | ||
| 1235 | } | ||
| 1179 | 1236 | ||
| 1180 | auto transfer_mem = | 1237 | auto transfer_mem = |
| 1181 | system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(handle); | 1238 | system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(handle); |
| 1182 | 1239 | ||
| 1183 | if (transfer_mem == nullptr) { | 1240 | if (transfer_mem == nullptr) { |
| 1184 | LOG_ERROR(Service_AM, "shared_mem is a nullpr for handle={:08X}", handle); | 1241 | LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle); |
| 1185 | IPC::ResponseBuilder rb{ctx, 2}; | 1242 | IPC::ResponseBuilder rb{ctx, 2}; |
| 1186 | rb.Push(RESULT_UNKNOWN); | 1243 | rb.Push(RESULT_UNKNOWN); |
| 1187 | return; | 1244 | return; |
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index f6a453ab7..aefbdf0d5 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h | |||
| @@ -254,6 +254,7 @@ private: | |||
| 254 | void CreateLibraryApplet(Kernel::HLERequestContext& ctx); | 254 | void CreateLibraryApplet(Kernel::HLERequestContext& ctx); |
| 255 | void CreateStorage(Kernel::HLERequestContext& ctx); | 255 | void CreateStorage(Kernel::HLERequestContext& ctx); |
| 256 | void CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx); | 256 | void CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx); |
| 257 | void CreateHandleStorage(Kernel::HLERequestContext& ctx); | ||
| 257 | }; | 258 | }; |
| 258 | 259 | ||
| 259 | class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> { | 260 | class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> { |