Esempio n. 1
0
        protected static void MakeObject(ServiceCtx context, IpcService obj)
        {
            IpcService service = context.Session.Service;

            if (service._isDomain)
            {
                context.Response.ObjectIds.Add(service.Add(obj));
            }
            else
            {
                KSession session = new KSession(context.Device.System);

                session.ClientSession.Service = obj;

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

                context.Response.HandleDesc = IpcHandleDesc.MakeMove(handle);
            }
        }
Esempio n. 2
0
        public long GetService(ServiceCtx context)
        {
            //Only for kernel version > 3.0.0.
            if (!_isInitialized)
            {
                //return SmNotInitialized;
            }

            string name = string.Empty;

            for (int index = 0; index < 8 &&
                 context.RequestData.BaseStream.Position <
                 context.RequestData.BaseStream.Length; index++)
            {
                byte chr = context.RequestData.ReadByte();

                if (chr >= 0x20 && chr < 0x7f)
                {
                    name += (char)chr;
                }
            }

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

            KSession session = new KSession(ServiceFactory.MakeService(context.Device.System, name), name);

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

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

            return(0);
        }
Esempio n. 3
0
        private KernelResult SendSyncRequest(ulong messagePtr, ulong size, int handle)
        {
            byte[] messageData = _memory.ReadBytes((long)messagePtr, (long)size);

            KSession session = _process.HandleTable.GetObject <KSession>(handle);

            if (session != null)
            {
                _system.CriticalSection.Enter();

                KThread currentThread = _system.Scheduler.GetCurrentThread();

                currentThread.SignaledObj   = null;
                currentThread.ObjSyncResult = KernelResult.Success;

                currentThread.Reschedule(ThreadSchedState.Paused);

                IpcMessage message = new IpcMessage(messageData, (long)messagePtr);

                ThreadPool.QueueUserWorkItem(ProcessIpcRequest, new HleIpcMessage(
                                                 currentThread,
                                                 session,
                                                 message,
                                                 (long)messagePtr));

                _system.ThreadCounter.AddCount();

                _system.CriticalSection.Leave();

                return(currentThread.ObjSyncResult);
            }
            else
            {
                Logger.PrintWarning(LogClass.KernelSvc, $"Invalid session handle 0x{handle:x8}!");

                return(KernelResult.InvalidHandle);
            }
        }
Esempio n. 4
0
        public static long IpcCall(
            Switch Ns,
            Process Process,
            AMemory Memory,
            KSession Session,
            IpcMessage Request,
            long CmdPtr)
        {
            IpcMessage Response = new IpcMessage();

            using (MemoryStream Raw = new MemoryStream(Request.RawData))
            {
                BinaryReader ReqReader = new BinaryReader(Raw);

                if (Request.Type == IpcMessageType.Request)
                {
                    Response.Type = IpcMessageType.Response;

                    using (MemoryStream ResMS = new MemoryStream())
                    {
                        BinaryWriter ResWriter = new BinaryWriter(ResMS);

                        ServiceCtx Context = new ServiceCtx(
                            Ns,
                            Process,
                            Memory,
                            Session,
                            Request,
                            Response,
                            ReqReader,
                            ResWriter);

                        Session.Service.CallMethod(Context);

                        Response.RawData = ResMS.ToArray();
                    }
                }
                else if (Request.Type == IpcMessageType.Control)
                {
                    long Magic = ReqReader.ReadInt64();
                    long CmdId = ReqReader.ReadInt64();

                    switch (CmdId)
                    {
                    case 0:
                    {
                        Request = FillResponse(Response, 0, Session.Service.ConvertToDomain());

                        break;
                    }

                    case 3:
                    {
                        Request = FillResponse(Response, 0, 0x500);

                        break;
                    }

                    //TODO: Whats the difference between IpcDuplicateSession/Ex?
                    case 2:
                    case 4:
                    {
                        int Unknown = ReqReader.ReadInt32();

                        int Handle = Process.HandleTable.OpenHandle(Session);

                        Response.HandleDesc = IpcHandleDesc.MakeMove(Handle);

                        Request = FillResponse(Response, 0);

                        break;
                    }

                    default: throw new NotImplementedException(CmdId.ToString());
                    }
                }
                else if (Request.Type == IpcMessageType.CloseSession)
                {
                    //TODO
                }
                else
                {
                    throw new NotImplementedException(Request.Type.ToString());
                }

                Memory.WriteBytes(CmdPtr, Response.GetBytes(CmdPtr));
            }

            return(0);
        }
Esempio n. 5
0
        private KernelResult CreateSession(
            bool isLight,
            ulong namePtr,
            out int serverSessionHandle,
            out int clientSessionHandle)
        {
            serverSessionHandle = 0;
            clientSessionHandle = 0;

            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();

            KResourceLimit resourceLimit = currentProcess.ResourceLimit;

            KernelResult result = KernelResult.Success;

            if (resourceLimit != null && !resourceLimit.Reserve(LimitableResource.Session, 1))
            {
                return(KernelResult.ResLimitExceeded);
            }

            if (isLight)
            {
                KLightSession session = new KLightSession(_system);

                result = currentProcess.HandleTable.GenerateHandle(session.ServerSession, out serverSessionHandle);

                if (result == KernelResult.Success)
                {
                    result = currentProcess.HandleTable.GenerateHandle(session.ClientSession, out clientSessionHandle);

                    if (result != KernelResult.Success)
                    {
                        currentProcess.HandleTable.CloseHandle(serverSessionHandle);

                        serverSessionHandle = 0;
                    }
                }

                session.ServerSession.DecrementReferenceCount();
                session.ClientSession.DecrementReferenceCount();
            }
            else
            {
                KSession session = new KSession(_system);

                result = currentProcess.HandleTable.GenerateHandle(session.ServerSession, out serverSessionHandle);

                if (result == KernelResult.Success)
                {
                    result = currentProcess.HandleTable.GenerateHandle(session.ClientSession, out clientSessionHandle);

                    if (result != KernelResult.Success)
                    {
                        currentProcess.HandleTable.CloseHandle(serverSessionHandle);

                        serverSessionHandle = 0;
                    }
                }

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

            return(result);
        }
Esempio n. 6
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);

                    session.ClientSession.Service = serviceAttribute.Parameter != null ? (IpcService)Activator.CreateInstance(type, context, serviceAttribute.Parameter)
                                                                                       : (IpcService)Activator.CreateInstance(type, context);
                }
                else
                {
                    if (ServiceConfiguration.IgnoreMissingServices)
                    {
                        Logger.PrintWarning(LogClass.Service, $"Missing service {name} ignored");

                        session.ClientSession.Service = new DummyService(name);
                    }
                    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);
        }
Esempio n. 7
0
        public static KernelResult IpcCall(
            Switch device,
            KProcess process,
            MemoryManager memory,
            KSession session,
            IpcMessage request,
            long cmdPtr)
        {
            IpcMessage response = new IpcMessage();

            using (MemoryStream raw = new MemoryStream(request.RawData))
            {
                BinaryReader reqReader = new BinaryReader(raw);

                if (request.Type == IpcMessageType.Request ||
                    request.Type == IpcMessageType.RequestWithContext)
                {
                    response.Type = IpcMessageType.Response;

                    using (MemoryStream resMs = new MemoryStream())
                    {
                        BinaryWriter resWriter = new BinaryWriter(resMs);

                        ServiceCtx context = new ServiceCtx(
                            device,
                            process,
                            memory,
                            session,
                            request,
                            response,
                            reqReader,
                            resWriter);

                        session.Service.CallMethod(context);

                        response.RawData = resMs.ToArray();
                    }
                }
                else if (request.Type == IpcMessageType.Control ||
                         request.Type == IpcMessageType.ControlWithContext)
                {
                    long magic = reqReader.ReadInt64();
                    long cmdId = reqReader.ReadInt64();

                    switch (cmdId)
                    {
                    case 0:
                    {
                        request = FillResponse(response, 0, session.Service.ConvertToDomain());

                        break;
                    }

                    case 3:
                    {
                        request = FillResponse(response, 0, 0x500);

                        break;
                    }

                    //TODO: Whats the difference between IpcDuplicateSession/Ex?
                    case 2:
                    case 4:
                    {
                        int unknown = reqReader.ReadInt32();

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

                        response.HandleDesc = IpcHandleDesc.MakeMove(handle);

                        request = FillResponse(response, 0);

                        break;
                    }

                    default: throw new NotImplementedException(cmdId.ToString());
                    }
                }
                else if (request.Type == IpcMessageType.CloseSession)
                {
                    //TODO
                }
                else
                {
                    throw new NotImplementedException(request.Type.ToString());
                }

                memory.WriteBytes(cmdPtr, response.GetBytes(cmdPtr));
            }

            return(KernelResult.Success);
        }