0
0
Fork 0
mirror of https://github.com/ryujinx-mirror/ryujinx.git synced 2024-12-23 18:25:46 +00:00

am: Implement CreateHandleStorage and fixes (#1929)

This commit is contained in:
Ac_K 2021-01-19 03:28:35 +01:00 committed by GitHub
parent 5e1a839eaa
commit 1364f36161
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 11 deletions

View file

@ -26,8 +26,15 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
{ {
long size = context.RequestData.ReadInt64(); long size = context.RequestData.ReadInt64();
if (size <= 0)
{
return ResultCode.ObjectInvalid;
}
MakeObject(context, new IStorage(new byte[size])); MakeObject(context, new IStorage(new byte[size]));
// NOTE: Returns ResultCode.MemoryAllocationFailed if IStorage is null, it doesn't occur in our case.
return ResultCode.Success; return ResultCode.Success;
} }
@ -35,20 +42,44 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
// CreateTransferMemoryStorage(b8, u64, handle<copy>) -> object<nn::am::service::IStorage> // CreateTransferMemoryStorage(b8, u64, handle<copy>) -> object<nn::am::service::IStorage>
public ResultCode CreateTransferMemoryStorage(ServiceCtx context) public ResultCode CreateTransferMemoryStorage(ServiceCtx context)
{ {
bool unknown = context.RequestData.ReadBoolean(); bool isReadOnly = context.RequestData.ReadBoolean();
long size = context.RequestData.ReadInt64(); long size = context.RequestData.ReadInt64();
int handle = context.Request.HandleDesc.ToCopy[0]; int handle = context.Request.HandleDesc.ToCopy[0];
KTransferMemory transferMem = context.Process.HandleTable.GetObject<KTransferMemory>(handle); KTransferMemory transferMem = context.Process.HandleTable.GetObject<KTransferMemory>(handle);
if (transferMem == null) if (size <= 0)
{ {
Logger.Warning?.Print(LogClass.ServiceAm, $"Invalid TransferMemory Handle: {handle:X}"); return ResultCode.ObjectInvalid;
return ResultCode.Success; // TODO: Find correct error code
} }
var data = new byte[transferMem.Size]; byte[] data = new byte[transferMem.Size];
transferMem.Creator.CpuMemory.Read(transferMem.Address, data);
context.Device.System.KernelContext.Syscall.CloseHandle(handle);
MakeObject(context, new IStorage(data, isReadOnly));
return ResultCode.Success;
}
[Command(12)] // 2.0.0+
// CreateHandleStorage(u64, handle<copy>) -> object<nn::am::service::IStorage>
public ResultCode CreateHandleStorage(ServiceCtx context)
{
long size = context.RequestData.ReadInt64();
int handle = context.Request.HandleDesc.ToCopy[0];
KTransferMemory transferMem = context.Process.HandleTable.GetObject<KTransferMemory>(handle);
if (size <= 0)
{
return ResultCode.ObjectInvalid;
}
byte[] data = new byte[transferMem.Size];
transferMem.Creator.CpuMemory.Read(transferMem.Address, data); transferMem.Creator.CpuMemory.Read(transferMem.Address, data);
context.Device.System.KernelContext.Syscall.CloseHandle(handle); context.Device.System.KernelContext.Syscall.CloseHandle(handle);

View file

@ -2,10 +2,12 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE
{ {
class IStorage : IpcService class IStorage : IpcService
{ {
public bool IsReadOnly { get; private set; }
public byte[] Data { get; private set; } public byte[] Data { get; private set; }
public IStorage(byte[] data) public IStorage(byte[] data, bool isReadOnly = false)
{ {
IsReadOnly = isReadOnly;
Data = data; Data = data;
} }

View file

@ -24,6 +24,11 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE
// Write(u64, buffer<bytes, 0x21>) // Write(u64, buffer<bytes, 0x21>)
public ResultCode Write(ServiceCtx context) public ResultCode Write(ServiceCtx context)
{ {
if (_storage.IsReadOnly)
{
return ResultCode.ObjectInvalid;
}
long writePosition = context.RequestData.ReadInt64(); long writePosition = context.RequestData.ReadInt64();
if (writePosition > _storage.Data.Length) if (writePosition > _storage.Data.Length)