forked from Mirror/Ryujinx
am: Implement CreateHandleStorage and fixes (#1929)
This commit is contained in:
parent
5e1a839eaa
commit
1364f36161
3 changed files with 49 additions and 11 deletions
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue