| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- using Ryujinx.Common;
- using Ryujinx.Common.Logging;
- using Ryujinx.Cpu;
- using Ryujinx.HLE.HOS.Services.Account.Acc.AccountService;
- using System.Collections.Generic;
- namespace Ryujinx.HLE.HOS.Services.Account.Acc
- {
- class ApplicationServiceServer
- {
- readonly AccountServiceFlag _serviceFlag;
- public ApplicationServiceServer(AccountServiceFlag serviceFlag)
- {
- _serviceFlag = serviceFlag;
- }
- public ResultCode GetUserCountImpl(ServiceCtx context)
- {
- context.ResponseData.Write(context.Device.System.AccountManager.GetUserCount());
- return ResultCode.Success;
- }
- public ResultCode GetUserExistenceImpl(ServiceCtx context)
- {
- ResultCode resultCode = CheckUserId(context, out UserId userId);
- if (resultCode != ResultCode.Success)
- {
- return resultCode;
- }
- context.ResponseData.Write(context.Device.System.AccountManager.TryGetUser(userId, out _));
- return ResultCode.Success;
- }
- public ResultCode ListAllUsers(ServiceCtx context)
- {
- return WriteUserList(context, context.Device.System.AccountManager.GetAllUsers());
- }
- public ResultCode ListOpenUsers(ServiceCtx context)
- {
- return WriteUserList(context, context.Device.System.AccountManager.GetOpenedUsers());
- }
- private ResultCode WriteUserList(ServiceCtx context, IEnumerable<UserProfile> profiles)
- {
- if (context.Request.RecvListBuff.Count == 0)
- {
- return ResultCode.InvalidBuffer;
- }
- ulong outputPosition = context.Request.RecvListBuff[0].Position;
- ulong outputSize = context.Request.RecvListBuff[0].Size;
- MemoryHelper.FillWithZeros(context.Memory, outputPosition, (int)outputSize);
- ulong offset = 0;
- foreach (UserProfile userProfile in profiles)
- {
- if (offset + 0x10 > outputSize)
- {
- break;
- }
- context.Memory.Write(outputPosition + offset, userProfile.UserId.High);
- context.Memory.Write(outputPosition + offset + 8, userProfile.UserId.Low);
- offset += 0x10;
- }
- return ResultCode.Success;
- }
- public ResultCode GetLastOpenedUser(ServiceCtx context)
- {
- context.Device.System.AccountManager.LastOpenedUser.UserId.Write(context.ResponseData);
- return ResultCode.Success;
- }
- public ResultCode GetProfile(ServiceCtx context, out IProfile profile)
- {
- profile = default;
- ResultCode resultCode = CheckUserId(context, out UserId userId);
- if (resultCode != ResultCode.Success)
- {
- return resultCode;
- }
- if (!context.Device.System.AccountManager.TryGetUser(userId, out UserProfile userProfile))
- {
- Logger.Warning?.Print(LogClass.ServiceAcc, $"User 0x{userId} not found!");
- return ResultCode.UserNotFound;
- }
- profile = new IProfile(userProfile);
- // Doesn't occur in our case.
- // return ResultCode.NullObject;
- return ResultCode.Success;
- }
- public ResultCode IsUserRegistrationRequestPermitted(ServiceCtx context)
- {
- context.ResponseData.Write(_serviceFlag != AccountServiceFlag.Application);
- return ResultCode.Success;
- }
- public ResultCode TrySelectUserWithoutInteraction(ServiceCtx context)
- {
- if (context.Device.System.AccountManager.GetUserCount() < 1)
- {
- // Invalid UserId.
- UserId.Null.Write(context.ResponseData);
- return ResultCode.UserNotFound;
- }
- bool isNetworkServiceAccountRequired = context.RequestData.ReadBoolean();
- if (isNetworkServiceAccountRequired)
- {
- // NOTE: This checks something related to baas (online), and then return an invalid UserId if the check in baas returns an error code.
- // In our case, we can just log it for now.
- Logger.Stub?.PrintStub(LogClass.ServiceAcc, new { isNetworkServiceAccountRequired });
- }
- // NOTE: As we returned an invalid UserId if there is more than one user earlier, now we can return only the first one.
- context.Device.System.AccountManager.GetFirst().UserId.Write(context.ResponseData);
- return ResultCode.Success;
- }
- public ResultCode StoreSaveDataThumbnail(ServiceCtx context)
- {
- ResultCode resultCode = CheckUserId(context, out UserId _);
- if (resultCode != ResultCode.Success)
- {
- return resultCode;
- }
- if (context.Request.SendBuff.Count == 0)
- {
- return ResultCode.InvalidBuffer;
- }
- ulong inputPosition = context.Request.SendBuff[0].Position;
- ulong inputSize = context.Request.SendBuff[0].Size;
- if (inputSize != 0x24000)
- {
- return ResultCode.InvalidBufferSize;
- }
- byte[] thumbnailBuffer = new byte[inputSize];
- context.Memory.Read(inputPosition, thumbnailBuffer);
- // NOTE: Account service call nn::fs::WriteSaveDataThumbnailFile().
- // TODO: Store thumbnailBuffer somewhere, in save data 0x8000000000000010 ?
- Logger.Stub?.PrintStub(LogClass.ServiceAcc);
- return ResultCode.Success;
- }
- public ResultCode ClearSaveDataThumbnail(ServiceCtx context)
- {
- ResultCode resultCode = CheckUserId(context, out UserId _);
- if (resultCode != ResultCode.Success)
- {
- return resultCode;
- }
- /*
- // NOTE: Doesn't occur in our case.
- if (userId == null)
- {
- return ResultCode.InvalidArgument;
- }
- */
- // NOTE: Account service call nn::fs::WriteSaveDataThumbnailFileHeader();
- // TODO: Clear the Thumbnail somewhere, in save data 0x8000000000000010 ?
- Logger.Stub?.PrintStub(LogClass.ServiceAcc);
- return ResultCode.Success;
- }
- public ResultCode ListOpenContextStoredUsers(ServiceCtx context)
- {
- return WriteUserList(context, context.Device.System.AccountManager.GetStoredOpenedUsers());
- }
- public ResultCode ListQualifiedUsers(ServiceCtx context)
- {
- // TODO: Determine how users are "qualified". We assume all users are "qualified" for now.
- return WriteUserList(context, context.Device.System.AccountManager.GetAllUsers());
- }
- public ResultCode CheckUserId(ServiceCtx context, out UserId userId)
- {
- userId = context.RequestData.ReadStruct<UserId>();
- if (userId.IsNull)
- {
- return ResultCode.NullArgument;
- }
- return ResultCode.Success;
- }
- }
- }
|