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); } }
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); }
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); } }
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); }
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); }
// 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); }
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); }