Ejemplo n.º 1
0
        [CommandTipc(1)] // 12.0.0+
        // GetService(ServiceName name) -> handle<move, session>
        public ResultCode GetService(ServiceCtx context)
        {
            if (!_isInitialized)
            {
                return(ResultCode.NotInitialized);
            }

            string name = ReadName(context);

            if (name == string.Empty)
            {
                return(ResultCode.InvalidName);
            }

            KSession session = new KSession(context.Device.System.KernelContext);

            if (_registeredServices.TryGetValue(name, out KPort port))
            {
                KernelResult result = port.EnqueueIncomingSession(session.ServerSession);

                if (result != KernelResult.Success)
                {
                    throw new InvalidOperationException($"Session enqueue on port returned error \"{result}\".");
                }
            }
            else
            {
                if (_services.TryGetValue(name, out Type type))
                {
                    ServiceAttribute serviceAttribute = (ServiceAttribute)type.GetCustomAttributes(typeof(ServiceAttribute)).First(service => ((ServiceAttribute)service).Name == name);

                    IpcService service = serviceAttribute.Parameter != null
                        ? (IpcService)Activator.CreateInstance(type, context, serviceAttribute.Parameter)
                        : (IpcService)Activator.CreateInstance(type, context);

                    service.TrySetServer(_commonServer);
                    service.Server.AddSessionObj(session.ServerSession, service);
                }
                else
                {
                    if (ServiceConfiguration.IgnoreMissingServices)
                    {
                        Logger.Warning?.Print(LogClass.Service, $"Missing service {name} ignored");
                    }
                    else
                    {
                        throw new NotImplementedException(name);
                    }
                }
            }

            if (context.Process.HandleTable.GenerateHandle(session.ClientSession, out int handle) != KernelResult.Success)
            {
                throw new InvalidOperationException("Out of handles!");
            }

            session.ServerSession.DecrementReferenceCount();
            session.ClientSession.DecrementReferenceCount();

            context.Response.HandleDesc = IpcHandleDesc.MakeMove(handle);

            return(ResultCode.Success);
        }