Compare commits

..

3 Commits

Author SHA1 Message Date
Mary
730d2f4b9b Address gdkchan's comment 2022-08-31 21:33:03 +02:00
Mary
f6a7309b14 account: Implement LoadNetworkServiceLicenseKindAsync
This is needed to run Pokemon Legends Arceus 1.1.1 with guest internet enabled.

The game still get stuck at loading screen.
2022-08-31 21:33:03 +02:00
TSRBerry
472a621589 Bsd: Fix ArgumentOutOfRangeException in SetSocketOption (#3633)
* Bsd: Fix ArgumentOutOfRangeException in SetSocketOption

* Ensure option level is Socket before checking for SoLinger
2022-08-28 14:24:19 +00:00
7 changed files with 107 additions and 24 deletions

View File

@@ -57,5 +57,19 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService
{
return _managerServer.StoreOpenContext(context);
}
[CommandHipc(170)] // 6.0.0+
// LoadNetworkServiceLicenseKindAsync() -> object<nn::account::detail::IAsyncNetworkServiceLicenseKindContext>
public ResultCode LoadNetworkServiceLicenseKindAsync(ServiceCtx context)
{
ResultCode resultCode = _managerServer.LoadNetworkServiceLicenseKindAsync(context, out IAsyncNetworkServiceLicenseKindContext asyncContext);
if (resultCode == ResultCode.Success)
{
MakeObject(context, asyncContext);
}
return resultCode;
}
}
}

View File

@@ -166,5 +166,22 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService
return ResultCode.Success;
}
public ResultCode LoadNetworkServiceLicenseKindAsync(ServiceCtx context, out IAsyncNetworkServiceLicenseKindContext asyncContext)
{
KEvent asyncEvent = new KEvent(context.Device.System.KernelContext);
AsyncExecution asyncExecution = new AsyncExecution(asyncEvent);
Logger.Stub?.PrintStub(LogClass.ServiceAcc);
// NOTE: This is an extension of the data retrieved from the id token cache.
asyncExecution.Initialize(1000, EnsureIdTokenCacheAsyncImpl);
asyncContext = new IAsyncNetworkServiceLicenseKindContext(asyncExecution, NetworkServiceLicenseKind.Subscribed);
// return ResultCode.NullObject if the IAsyncNetworkServiceLicenseKindContext pointer is null. Doesn't occur in our case.
return ResultCode.Success;
}
}
}

View File

@@ -7,18 +7,18 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
{
class IAsyncContext : IpcService
{
AsyncExecution _asyncExecution;
protected AsyncExecution AsyncExecution;
public IAsyncContext(AsyncExecution asyncExecution)
{
_asyncExecution = asyncExecution;
AsyncExecution = asyncExecution;
}
[CommandHipc(0)]
// GetSystemEvent() -> handle<copy>
public ResultCode GetSystemEvent(ServiceCtx context)
{
if (context.Process.HandleTable.GenerateHandle(_asyncExecution.SystemEvent.ReadableEvent, out int _systemEventHandle) != KernelResult.Success)
if (context.Process.HandleTable.GenerateHandle(AsyncExecution.SystemEvent.ReadableEvent, out int _systemEventHandle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
@@ -32,14 +32,14 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
// Cancel()
public ResultCode Cancel(ServiceCtx context)
{
if (!_asyncExecution.IsInitialized)
if (!AsyncExecution.IsInitialized)
{
return ResultCode.AsyncExecutionNotInitialized;
}
if (_asyncExecution.IsRunning)
if (AsyncExecution.IsRunning)
{
_asyncExecution.Cancel();
AsyncExecution.Cancel();
}
return ResultCode.Success;
@@ -49,12 +49,12 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
// HasDone() -> b8
public ResultCode HasDone(ServiceCtx context)
{
if (!_asyncExecution.IsInitialized)
if (!AsyncExecution.IsInitialized)
{
return ResultCode.AsyncExecutionNotInitialized;
}
context.ResponseData.Write(_asyncExecution.SystemEvent.ReadableEvent.IsSignaled());
context.ResponseData.Write(AsyncExecution.SystemEvent.ReadableEvent.IsSignaled());
return ResultCode.Success;
}
@@ -63,12 +63,12 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
// GetResult()
public ResultCode GetResult(ServiceCtx context)
{
if (!_asyncExecution.IsInitialized)
if (!AsyncExecution.IsInitialized)
{
return ResultCode.AsyncExecutionNotInitialized;
}
if (!_asyncExecution.SystemEvent.ReadableEvent.IsSignaled())
if (!AsyncExecution.SystemEvent.ReadableEvent.IsSignaled())
{
return ResultCode.Unknown41;
}

View File

@@ -0,0 +1,38 @@
using Ryujinx.HLE.HOS.Services.Account.Acc.AsyncContext;
namespace Ryujinx.HLE.HOS.Services.Account.Acc
{
class IAsyncNetworkServiceLicenseKindContext : IAsyncContext
{
private NetworkServiceLicenseKind? _serviceLicenseKind;
public IAsyncNetworkServiceLicenseKindContext(AsyncExecution asyncExecution, NetworkServiceLicenseKind? serviceLicenseKind) : base(asyncExecution)
{
_serviceLicenseKind = serviceLicenseKind;
}
[CommandHipc(100)]
// GetNetworkServiceLicenseKind() -> nn::account::NetworkServiceLicenseKind
public ResultCode GetNetworkServiceLicenseKind(ServiceCtx context)
{
if (!AsyncExecution.IsInitialized)
{
return ResultCode.AsyncExecutionNotInitialized;
}
if (!AsyncExecution.SystemEvent.ReadableEvent.IsSignaled())
{
return ResultCode.Unknown41;
}
if (!_serviceLicenseKind.HasValue)
{
return ResultCode.MissingNetworkServiceLicenseKind;
}
context.ResponseData.Write((uint)_serviceLicenseKind.Value);
return ResultCode.Success;
}
}
}

View File

@@ -0,0 +1,8 @@
namespace Ryujinx.HLE.HOS.Services.Account.Acc
{
enum NetworkServiceLicenseKind : uint
{
NoSubscription,
Subscribed
}
}

View File

@@ -7,17 +7,18 @@ namespace Ryujinx.HLE.HOS.Services.Account
Success = 0,
NullArgument = (20 << ErrorCodeShift) | ModuleId,
InvalidArgument = (22 << ErrorCodeShift) | ModuleId,
NullInputBuffer = (30 << ErrorCodeShift) | ModuleId,
InvalidBufferSize = (31 << ErrorCodeShift) | ModuleId,
InvalidBuffer = (32 << ErrorCodeShift) | ModuleId,
AsyncExecutionNotInitialized = (40 << ErrorCodeShift) | ModuleId,
Unknown41 = (41 << ErrorCodeShift) | ModuleId,
InternetRequestDenied = (59 << ErrorCodeShift) | ModuleId,
UserNotFound = (100 << ErrorCodeShift) | ModuleId,
NullObject = (302 << ErrorCodeShift) | ModuleId,
Unknown341 = (341 << ErrorCodeShift) | ModuleId,
InvalidIdTokenCacheBufferSize = (451 << ErrorCodeShift) | ModuleId
NullArgument = (20 << ErrorCodeShift) | ModuleId,
InvalidArgument = (22 << ErrorCodeShift) | ModuleId,
NullInputBuffer = (30 << ErrorCodeShift) | ModuleId,
InvalidBufferSize = (31 << ErrorCodeShift) | ModuleId,
InvalidBuffer = (32 << ErrorCodeShift) | ModuleId,
AsyncExecutionNotInitialized = (40 << ErrorCodeShift) | ModuleId,
Unknown41 = (41 << ErrorCodeShift) | ModuleId,
InternetRequestDenied = (59 << ErrorCodeShift) | ModuleId,
UserNotFound = (100 << ErrorCodeShift) | ModuleId,
NullObject = (302 << ErrorCodeShift) | ModuleId,
Unknown341 = (341 << ErrorCodeShift) | ModuleId,
MissingNetworkServiceLicenseKind = (400 << ErrorCodeShift) | ModuleId,
InvalidIdTokenCacheBufferSize = (451 << ErrorCodeShift) | ModuleId
}
}

View File

@@ -323,9 +323,14 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
int value = optionValue.Length >= 4 ? MemoryMarshal.Read<int>(optionValue) : MemoryMarshal.Read<byte>(optionValue);
if (option == BsdSocketOption.SoLinger)
if (level == SocketOptionLevel.Socket && option == BsdSocketOption.SoLinger)
{
int value2 = MemoryMarshal.Read<int>(optionValue[4..]);
int value2 = 0;
if (optionValue.Length >= 8)
{
value2 = MemoryMarshal.Read<int>(optionValue[4..]);
}
Socket.SetSocketOption(level, SocketOptionName.Linger, new LingerOption(value != 0, value2));
}