aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Horizon/Arp/Ipc/Reader.cs
blob: de99c2ade8c3b9a231f4bd282e770d2738b78cb2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
using Ryujinx.Horizon.Common;
using Ryujinx.Horizon.Sdk.Arp;
using Ryujinx.Horizon.Sdk.Arp.Detail;
using Ryujinx.Horizon.Sdk.Ns;
using Ryujinx.Horizon.Sdk.Sf;
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using System;

namespace Ryujinx.Horizon.Arp.Ipc
{
    partial class Reader : IReader, IServiceObject
    {
        private readonly ApplicationInstanceManager _applicationInstanceManager;

        public Reader(ApplicationInstanceManager applicationInstanceManager)
        {
            _applicationInstanceManager = applicationInstanceManager;
        }

        [CmifCommand(0)]
        public Result GetApplicationLaunchProperty(out ApplicationLaunchProperty applicationLaunchProperty, ulong applicationInstanceId)
        {
            if (_applicationInstanceManager.Entries[applicationInstanceId] == null || !_applicationInstanceManager.Entries[applicationInstanceId].LaunchProperty.HasValue)
            {
                applicationLaunchProperty = default;

                return ArpResult.InvalidInstanceId;
            }

            applicationLaunchProperty = _applicationInstanceManager.Entries[applicationInstanceId].LaunchProperty.Value;

            return Result.Success;
        }

        [CmifCommand(1)]
        public Result GetApplicationControlProperty([Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias, 0x4000)] out ApplicationControlProperty applicationControlProperty, ulong applicationInstanceId)
        {
            if (_applicationInstanceManager.Entries[applicationInstanceId] == null || !_applicationInstanceManager.Entries[applicationInstanceId].ControlProperty.HasValue)
            {
                applicationControlProperty = default;

                return ArpResult.InvalidInstanceId;
            }

            applicationControlProperty = _applicationInstanceManager.Entries[applicationInstanceId].ControlProperty.Value;

            return Result.Success;
        }

        [CmifCommand(2)]
        public Result GetApplicationProcessProperty(out ApplicationProcessProperty applicationProcessProperty, ulong applicationInstanceId)
        {
            if (_applicationInstanceManager.Entries[applicationInstanceId] == null || !_applicationInstanceManager.Entries[applicationInstanceId].ProcessProperty.HasValue)
            {
                applicationProcessProperty = default;

                return ArpResult.InvalidInstanceId;
            }

            applicationProcessProperty = _applicationInstanceManager.Entries[applicationInstanceId].ProcessProperty.Value;

            return Result.Success;
        }

        [CmifCommand(3)]
        public Result GetApplicationInstanceId(out ulong applicationInstanceId, ulong pid)
        {
            applicationInstanceId = 0;

            if (pid == 0)
            {
                return ArpResult.InvalidPid;
            }

            for (int i = 0; i < _applicationInstanceManager.Entries.Length; i++)
            {
                if (_applicationInstanceManager.Entries[i] != null && _applicationInstanceManager.Entries[i].Pid == pid)
                {
                    applicationInstanceId = (ulong)i;

                    return Result.Success;
                }
            }

            return ArpResult.InvalidPid;
        }

        [CmifCommand(4)]
        public Result GetApplicationInstanceUnregistrationNotifier(out IUnregistrationNotifier unregistrationNotifier)
        {
            unregistrationNotifier = new UnregistrationNotifier(_applicationInstanceManager);

            return Result.Success;
        }

        [CmifCommand(5)]
        public Result ListApplicationInstanceId(out int count, [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span<ulong> applicationInstanceIdList)
        {
            count = 0;

            if (_applicationInstanceManager.Entries[0] != null)
            {
                applicationInstanceIdList[count++] = 0;
            }

            if (_applicationInstanceManager.Entries[1] != null)
            {
                applicationInstanceIdList[count++] = 1;
            }

            return Result.Success;
        }

        [CmifCommand(6)]
        public Result GetMicroApplicationInstanceId(out ulong microApplicationInstanceId, [ClientProcessId] ulong pid)
        {
            return GetApplicationInstanceId(out microApplicationInstanceId, pid);
        }

        [CmifCommand(7)]
        public Result GetApplicationCertificate([Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias | HipcBufferFlags.FixedSize, 0x528)] out ApplicationCertificate applicationCertificate, ulong applicationInstanceId)
        {
            if (_applicationInstanceManager.Entries[applicationInstanceId] == null)
            {
                applicationCertificate = default;

                return ArpResult.InvalidInstanceId;
            }

            applicationCertificate = _applicationInstanceManager.Entries[applicationInstanceId].Certificate.Value;

            return Result.Success;
        }
    }
}