コード例 #1
0
        private void SvcGetThreadContext3(AThreadState ThreadState)
        {
            long Position = (long)ThreadState.X0;
            int  Handle   = (int)ThreadState.X1;

            KThread Thread = Process.HandleTable.GetData <KThread>(Handle);

            if (Thread == null)
            {
                Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid thread handle 0x{Handle:x8}!");

                ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);

                return;
            }

            if (Process.GetThread(ThreadState.Tpidr) == Thread)
            {
                Ns.Log.PrintWarning(LogClass.KernelSvc, $"Thread handle 0x{Handle:x8} is current thread!");

                ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidThread);

                return;
            }

            Memory.WriteUInt64(Position + 0x0, ThreadState.X0);
            Memory.WriteUInt64(Position + 0x8, ThreadState.X1);
            Memory.WriteUInt64(Position + 0x10, ThreadState.X2);
            Memory.WriteUInt64(Position + 0x18, ThreadState.X3);
            Memory.WriteUInt64(Position + 0x20, ThreadState.X4);
            Memory.WriteUInt64(Position + 0x28, ThreadState.X5);
            Memory.WriteUInt64(Position + 0x30, ThreadState.X6);
            Memory.WriteUInt64(Position + 0x38, ThreadState.X7);
            Memory.WriteUInt64(Position + 0x40, ThreadState.X8);
            Memory.WriteUInt64(Position + 0x48, ThreadState.X9);
            Memory.WriteUInt64(Position + 0x50, ThreadState.X10);
            Memory.WriteUInt64(Position + 0x58, ThreadState.X11);
            Memory.WriteUInt64(Position + 0x60, ThreadState.X12);
            Memory.WriteUInt64(Position + 0x68, ThreadState.X13);
            Memory.WriteUInt64(Position + 0x70, ThreadState.X14);
            Memory.WriteUInt64(Position + 0x78, ThreadState.X15);
            Memory.WriteUInt64(Position + 0x80, ThreadState.X16);
            Memory.WriteUInt64(Position + 0x88, ThreadState.X17);
            Memory.WriteUInt64(Position + 0x90, ThreadState.X18);
            Memory.WriteUInt64(Position + 0x98, ThreadState.X19);
            Memory.WriteUInt64(Position + 0xa0, ThreadState.X20);
            Memory.WriteUInt64(Position + 0xa8, ThreadState.X21);
            Memory.WriteUInt64(Position + 0xb0, ThreadState.X22);
            Memory.WriteUInt64(Position + 0xb8, ThreadState.X23);
            Memory.WriteUInt64(Position + 0xc0, ThreadState.X24);
            Memory.WriteUInt64(Position + 0xc8, ThreadState.X25);
            Memory.WriteUInt64(Position + 0xd0, ThreadState.X26);
            Memory.WriteUInt64(Position + 0xd8, ThreadState.X27);
            Memory.WriteUInt64(Position + 0xe0, ThreadState.X28);
            Memory.WriteUInt64(Position + 0xe8, ThreadState.X29);
            Memory.WriteUInt64(Position + 0xf0, ThreadState.X30);
            Memory.WriteUInt64(Position + 0xf8, ThreadState.X31);

            Memory.WriteInt64(Position + 0x100, Thread.LastPc);

            Memory.WriteUInt64(Position + 0x108, (ulong)ThreadState.Psr);

            Memory.WriteVector128(Position + 0x110, ThreadState.V0);
            Memory.WriteVector128(Position + 0x120, ThreadState.V1);
            Memory.WriteVector128(Position + 0x130, ThreadState.V2);
            Memory.WriteVector128(Position + 0x140, ThreadState.V3);
            Memory.WriteVector128(Position + 0x150, ThreadState.V4);
            Memory.WriteVector128(Position + 0x160, ThreadState.V5);
            Memory.WriteVector128(Position + 0x170, ThreadState.V6);
            Memory.WriteVector128(Position + 0x180, ThreadState.V7);
            Memory.WriteVector128(Position + 0x190, ThreadState.V8);
            Memory.WriteVector128(Position + 0x1a0, ThreadState.V9);
            Memory.WriteVector128(Position + 0x1b0, ThreadState.V10);
            Memory.WriteVector128(Position + 0x1c0, ThreadState.V11);
            Memory.WriteVector128(Position + 0x1d0, ThreadState.V12);
            Memory.WriteVector128(Position + 0x1e0, ThreadState.V13);
            Memory.WriteVector128(Position + 0x1f0, ThreadState.V14);
            Memory.WriteVector128(Position + 0x200, ThreadState.V15);
            Memory.WriteVector128(Position + 0x210, ThreadState.V16);
            Memory.WriteVector128(Position + 0x220, ThreadState.V17);
            Memory.WriteVector128(Position + 0x230, ThreadState.V18);
            Memory.WriteVector128(Position + 0x240, ThreadState.V19);
            Memory.WriteVector128(Position + 0x250, ThreadState.V20);
            Memory.WriteVector128(Position + 0x260, ThreadState.V21);
            Memory.WriteVector128(Position + 0x270, ThreadState.V22);
            Memory.WriteVector128(Position + 0x280, ThreadState.V23);
            Memory.WriteVector128(Position + 0x290, ThreadState.V24);
            Memory.WriteVector128(Position + 0x2a0, ThreadState.V25);
            Memory.WriteVector128(Position + 0x2b0, ThreadState.V26);
            Memory.WriteVector128(Position + 0x2c0, ThreadState.V27);
            Memory.WriteVector128(Position + 0x2d0, ThreadState.V28);
            Memory.WriteVector128(Position + 0x2e0, ThreadState.V29);
            Memory.WriteVector128(Position + 0x2f0, ThreadState.V30);
            Memory.WriteVector128(Position + 0x300, ThreadState.V31);

            Memory.WriteInt32(Position + 0x310, ThreadState.Fpcr);
            Memory.WriteInt32(Position + 0x314, ThreadState.Fpsr);
            Memory.WriteInt64(Position + 0x318, ThreadState.Tpidr);

            ThreadState.X0 = 0;
        }
コード例 #2
0
 private void UnpauseAndTerminateAllThreadsExcept(KThread thread)
 {
     // TODO.
 }
コード例 #3
0
        private void SvcSetThreadCoreMask(AThreadState ThreadState)
        {
            int  Handle    = (int)ThreadState.X0;
            int  IdealCore = (int)ThreadState.X1;
            long CoreMask  = (long)ThreadState.X2;

            Ns.Log.PrintDebug(LogClass.KernelSvc,
                              "Handle = " + Handle.ToString("x8") + ", " +
                              "IdealCore = " + IdealCore.ToString("x8") + ", " +
                              "CoreMask = " + CoreMask.ToString("x16"));

            KThread Thread = GetThread(ThreadState.Tpidr, Handle);

            if (IdealCore == -2)
            {
                //TODO: Get this value from the NPDM file.
                IdealCore = 0;

                CoreMask = 1 << IdealCore;
            }
            else
            {
                if ((uint)IdealCore > 3)
                {
                    if ((IdealCore | 2) != -1)
                    {
                        Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid core id 0x{IdealCore:x8}!");

                        ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidCoreId);

                        return;
                    }
                }
                else if ((CoreMask & (1 << IdealCore)) == 0)
                {
                    Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid core mask 0x{CoreMask:x8}!");

                    ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMaskValue);

                    return;
                }
            }

            if (Thread == null)
            {
                Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid thread handle 0x{Handle:x8}!");

                ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);

                return;
            }

            //-1 is used as "don't care", so the IdealCore value is ignored.
            //-2 is used as "use NPDM default core id" (handled above).
            //-3 is used as "don't update", the old IdealCore value is kept.
            if (IdealCore == -3 && (CoreMask & (1 << Thread.IdealCore)) == 0)
            {
                Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid core mask 0x{CoreMask:x8}!");

                ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMaskValue);

                return;
            }

            Process.Scheduler.ChangeCore(Thread, IdealCore, (int)CoreMask);

            ThreadState.X0 = 0;
        }
コード例 #4
0
ファイル: HttpUnit.cs プロジェクト: cjsjy123/KU_NET
		public void BeginDownLoadFileFlushToMemory(string URL,  Action<byte[], float, bool> callback, bool AutoStart = false)
		{
			m_curRequest.field0 = URL;
			m_curRequest.field1 = HttpType.DOWNLOADFILE_TOMEMORY;
#if USE_COR
			m_curRequest.field2  =m_SuccessEvent;
			requestList.Push(m_curRequest);
            m_task = new Task (UnityConnect (), AutoStart);
#else
			
			this.onProcess = callback;

			m_curRequest.field2 = file;
			
			m_thread = KThread.StartTask(ThreadDownLoad, false);
			
			#endif
			
		}
コード例 #5
0
ファイル: SvcThread.cs プロジェクト: thejonwong/Ryujinx
        private KernelResult GetThreadContext3(ulong address, int handle)
        {
            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
            KThread  currentThread  = _system.Scheduler.GetCurrentThread();

            KThread thread = _process.HandleTable.GetObject <KThread>(handle);

            if (thread == null)
            {
                return(KernelResult.InvalidHandle);
            }

            if (thread.Owner != currentProcess)
            {
                return(KernelResult.InvalidHandle);
            }

            if (currentThread == thread)
            {
                return(KernelResult.InvalidThread);
            }

            IMemoryManager memory = currentProcess.CpuMemory;

            memory.WriteUInt64((long)address + 0x0, thread.Context.GetX(0));
            memory.WriteUInt64((long)address + 0x8, thread.Context.GetX(1));
            memory.WriteUInt64((long)address + 0x10, thread.Context.GetX(2));
            memory.WriteUInt64((long)address + 0x18, thread.Context.GetX(3));
            memory.WriteUInt64((long)address + 0x20, thread.Context.GetX(4));
            memory.WriteUInt64((long)address + 0x28, thread.Context.GetX(5));
            memory.WriteUInt64((long)address + 0x30, thread.Context.GetX(6));
            memory.WriteUInt64((long)address + 0x38, thread.Context.GetX(7));
            memory.WriteUInt64((long)address + 0x40, thread.Context.GetX(8));
            memory.WriteUInt64((long)address + 0x48, thread.Context.GetX(9));
            memory.WriteUInt64((long)address + 0x50, thread.Context.GetX(10));
            memory.WriteUInt64((long)address + 0x58, thread.Context.GetX(11));
            memory.WriteUInt64((long)address + 0x60, thread.Context.GetX(12));
            memory.WriteUInt64((long)address + 0x68, thread.Context.GetX(13));
            memory.WriteUInt64((long)address + 0x70, thread.Context.GetX(14));
            memory.WriteUInt64((long)address + 0x78, thread.Context.GetX(15));
            memory.WriteUInt64((long)address + 0x80, thread.Context.GetX(16));
            memory.WriteUInt64((long)address + 0x88, thread.Context.GetX(17));
            memory.WriteUInt64((long)address + 0x90, thread.Context.GetX(18));
            memory.WriteUInt64((long)address + 0x98, thread.Context.GetX(19));
            memory.WriteUInt64((long)address + 0xa0, thread.Context.GetX(20));
            memory.WriteUInt64((long)address + 0xa8, thread.Context.GetX(21));
            memory.WriteUInt64((long)address + 0xb0, thread.Context.GetX(22));
            memory.WriteUInt64((long)address + 0xb8, thread.Context.GetX(23));
            memory.WriteUInt64((long)address + 0xc0, thread.Context.GetX(24));
            memory.WriteUInt64((long)address + 0xc8, thread.Context.GetX(25));
            memory.WriteUInt64((long)address + 0xd0, thread.Context.GetX(26));
            memory.WriteUInt64((long)address + 0xd8, thread.Context.GetX(27));
            memory.WriteUInt64((long)address + 0xe0, thread.Context.GetX(28));
            memory.WriteUInt64((long)address + 0xe8, thread.Context.GetX(29));
            memory.WriteUInt64((long)address + 0xf0, thread.Context.GetX(30));
            memory.WriteUInt64((long)address + 0xf8, thread.Context.GetX(31));

            memory.WriteInt64((long)address + 0x100, thread.LastPc);

            memory.WriteUInt64((long)address + 0x108, (ulong)GetPsr(thread.Context));

            memory.WriteVector128((long)address + 0x110, thread.Context.GetV(0));
            memory.WriteVector128((long)address + 0x120, thread.Context.GetV(1));
            memory.WriteVector128((long)address + 0x130, thread.Context.GetV(2));
            memory.WriteVector128((long)address + 0x140, thread.Context.GetV(3));
            memory.WriteVector128((long)address + 0x150, thread.Context.GetV(4));
            memory.WriteVector128((long)address + 0x160, thread.Context.GetV(5));
            memory.WriteVector128((long)address + 0x170, thread.Context.GetV(6));
            memory.WriteVector128((long)address + 0x180, thread.Context.GetV(7));
            memory.WriteVector128((long)address + 0x190, thread.Context.GetV(8));
            memory.WriteVector128((long)address + 0x1a0, thread.Context.GetV(9));
            memory.WriteVector128((long)address + 0x1b0, thread.Context.GetV(10));
            memory.WriteVector128((long)address + 0x1c0, thread.Context.GetV(11));
            memory.WriteVector128((long)address + 0x1d0, thread.Context.GetV(12));
            memory.WriteVector128((long)address + 0x1e0, thread.Context.GetV(13));
            memory.WriteVector128((long)address + 0x1f0, thread.Context.GetV(14));
            memory.WriteVector128((long)address + 0x200, thread.Context.GetV(15));
            memory.WriteVector128((long)address + 0x210, thread.Context.GetV(16));
            memory.WriteVector128((long)address + 0x220, thread.Context.GetV(17));
            memory.WriteVector128((long)address + 0x230, thread.Context.GetV(18));
            memory.WriteVector128((long)address + 0x240, thread.Context.GetV(19));
            memory.WriteVector128((long)address + 0x250, thread.Context.GetV(20));
            memory.WriteVector128((long)address + 0x260, thread.Context.GetV(21));
            memory.WriteVector128((long)address + 0x270, thread.Context.GetV(22));
            memory.WriteVector128((long)address + 0x280, thread.Context.GetV(23));
            memory.WriteVector128((long)address + 0x290, thread.Context.GetV(24));
            memory.WriteVector128((long)address + 0x2a0, thread.Context.GetV(25));
            memory.WriteVector128((long)address + 0x2b0, thread.Context.GetV(26));
            memory.WriteVector128((long)address + 0x2c0, thread.Context.GetV(27));
            memory.WriteVector128((long)address + 0x2d0, thread.Context.GetV(28));
            memory.WriteVector128((long)address + 0x2e0, thread.Context.GetV(29));
            memory.WriteVector128((long)address + 0x2f0, thread.Context.GetV(30));
            memory.WriteVector128((long)address + 0x300, thread.Context.GetV(31));

            memory.WriteInt32((long)address + 0x310, (int)thread.Context.Fpcr);
            memory.WriteInt32((long)address + 0x314, (int)thread.Context.Fpsr);
            memory.WriteInt64((long)address + 0x318, thread.Context.Tpidr);

            return(KernelResult.Success);
        }
コード例 #6
0
 public void PushMessage(Switch device, KThread thread, KClientSession session, ulong messagePtr, ulong messageSize)
 {
     _ipcProcessor.Add(new IpcRequest(device, thread, session, messagePtr, messageSize));
 }
コード例 #7
0
        private void CallStopModule( KModule module, int args, int argp )
        {
            if( module.ModuleStop == 0 )
                return;

            // Create a thread
            KThread thread = new KThread( _kernel,
                module,
                _kernel.Partitions[ 2 ],
                "module_stop_thread",
                module.ModuleStop,
                0,
                KThreadAttributes.User,
                0x4000 );
            _kernel.AddHandle( thread );
            thread.Start( ( uint )args, ( uint )argp );

            // Setup handler so that we get the callback when the thread ends and we can kill it
            _kernel.Cpu.SetContextSafetyCallback( thread.ContextID, new ContextSafetyDelegate( this.KmoduleStopThreadEnd ), ( int )thread.UID );

            Log.WriteLine( Verbosity.Verbose, Feature.Bios, "ModuleMgrForUser: starting module_stop thread with UID {0:X} for module {1}", thread.UID, module.Name );

            // Schedule so that our thread runs
            _kernel.Schedule();
        }
コード例 #8
0
ファイル: IpcHandler.cs プロジェクト: VioletteLam/Ryujinx
        public static KernelResult IpcCall(
            Switch device,
            KProcess process,
            IMemoryManager memory,
            KThread thread,
            KClientSession 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,
                            thread,
                            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
                    return(KernelResult.PortRemoteClosed);
                }
                else
                {
                    throw new NotImplementedException(request.Type.ToString());
                }

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

            return(KernelResult.Success);
        }
コード例 #9
0
        private void CondVarSignal(
            AThreadState ThreadState,
            KThread CurrThread,
            long CondVarAddress,
            int Count)
        {
            lock (Process.ThreadSyncLock)
            {
                while (Count == -1 || Count-- > 0)
                {
                    KThread WaitThread = PopCondVarThreadUnsafe(CondVarAddress);

                    if (WaitThread == null)
                    {
                        Ns.Log.PrintDebug(LogClass.KernelSvc, "No more threads to wake up!");

                        break;
                    }

                    WaitThread.CondVarSignaled = true;

                    long MutexAddress = WaitThread.MutexAddress;

                    Memory.SetExclusive(ThreadState, MutexAddress);

                    int MutexValue = Memory.ReadInt32(MutexAddress);

                    while (MutexValue != 0)
                    {
                        if (Memory.TestExclusive(ThreadState, MutexAddress))
                        {
                            //Wait until the lock is released.
                            InsertWaitingMutexThreadUnsafe(MutexValue & ~MutexHasListenersMask, WaitThread);

                            Memory.WriteInt32(MutexAddress, MutexValue | MutexHasListenersMask);

                            Memory.ClearExclusiveForStore(ThreadState);

                            break;
                        }

                        Memory.SetExclusive(ThreadState, MutexAddress);

                        MutexValue = Memory.ReadInt32(MutexAddress);
                    }

                    Ns.Log.PrintDebug(LogClass.KernelSvc, "MutexValue = " + MutexValue.ToString("x8"));

                    if (MutexValue == 0)
                    {
                        //Give the lock to this thread.
                        Memory.WriteInt32ToSharedAddr(MutexAddress, WaitThread.WaitHandle);

                        WaitThread.WaitHandle     = 0;
                        WaitThread.MutexAddress   = 0;
                        WaitThread.CondVarAddress = 0;

                        WaitThread.MutexOwner?.UpdatePriority();

                        WaitThread.MutexOwner = null;

                        Process.Scheduler.WakeUp(WaitThread);
                    }
                }
            }
        }
コード例 #10
0
        public KernelResult Receive(ulong customCmdBuffAddr = 0, ulong customCmdBuffSize = 0)
        {
            KThread  serverThread  = KernelStatic.GetCurrentThread();
            KProcess serverProcess = serverThread.Owner;

            KernelContext.CriticalSection.Enter();

            if (_parent.ClientSession.State != ChannelState.Open)
            {
                KernelContext.CriticalSection.Leave();

                return(KernelResult.PortRemoteClosed);
            }

            if (_activeRequest != null || !DequeueRequest(out KSessionRequest request))
            {
                KernelContext.CriticalSection.Leave();

                return(KernelResult.NotFound);
            }

            if (request.ClientThread == null)
            {
                KernelContext.CriticalSection.Leave();

                return(KernelResult.PortRemoteClosed);
            }

            KThread  clientThread  = request.ClientThread;
            KProcess clientProcess = clientThread.Owner;

            KernelContext.CriticalSection.Leave();

            _activeRequest = request;

            request.ServerProcess = serverProcess;

            Message clientMsg = new Message(request);
            Message serverMsg = new Message(serverThread, customCmdBuffAddr, customCmdBuffSize);

            MessageHeader clientHeader = GetClientMessageHeader(clientMsg);
            MessageHeader serverHeader = GetServerMessageHeader(serverMsg);

            KernelResult serverResult = KernelResult.NotFound;
            KernelResult clientResult = KernelResult.Success;

            void CleanUpForError()
            {
                if (request.BufferDescriptorTable.UnmapServerBuffers(serverProcess.MemoryManager) == KernelResult.Success)
                {
                    request.BufferDescriptorTable.RestoreClientBuffers(clientProcess.MemoryManager);
                }

                CloseAllHandles(serverMsg, clientHeader, serverProcess);

                KernelContext.CriticalSection.Enter();

                _activeRequest = null;

                if (_requests.Count != 0)
                {
                    Signal();
                }

                KernelContext.CriticalSection.Leave();

                WakeClientThread(request, clientResult);
            }

            if (clientHeader.ReceiveListType < 2 &&
                clientHeader.ReceiveListOffset > clientMsg.Size)
            {
                CleanUpForError();

                return(KernelResult.InvalidCombination);
            }
            else if (clientHeader.ReceiveListType == 2 &&
                     clientHeader.ReceiveListOffset + 8 > clientMsg.Size)
            {
                CleanUpForError();

                return(KernelResult.InvalidCombination);
            }
            else if (clientHeader.ReceiveListType > 2 &&
                     clientHeader.ReceiveListType * 8 - 0x10 + clientHeader.ReceiveListOffset > clientMsg.Size)
            {
                CleanUpForError();

                return(KernelResult.InvalidCombination);
            }

            if (clientHeader.ReceiveListOffsetInWords < clientHeader.MessageSizeInWords)
            {
                CleanUpForError();

                return(KernelResult.InvalidCombination);
            }

            if (clientHeader.MessageSizeInWords * 4 > clientMsg.Size)
            {
                CleanUpForError();

                return(KernelResult.CmdBufferTooSmall);
            }

            ulong[] receiveList = GetReceiveList(
                serverMsg,
                serverHeader.ReceiveListType,
                serverHeader.ReceiveListOffset);

            serverProcess.CpuMemory.Write(serverMsg.Address + 0, clientHeader.Word0);
            serverProcess.CpuMemory.Write(serverMsg.Address + 4, clientHeader.Word1);

            uint offset;

            // Copy handles.
            if (clientHeader.HasHandles)
            {
                if (clientHeader.MoveHandlesCount != 0)
                {
                    CleanUpForError();

                    return(KernelResult.InvalidCombination);
                }

                serverProcess.CpuMemory.Write(serverMsg.Address + 8, clientHeader.Word2);

                offset = 3;

                if (clientHeader.HasPid)
                {
                    serverProcess.CpuMemory.Write(serverMsg.Address + offset * 4, clientProcess.Pid);

                    offset += 2;
                }

                for (int index = 0; index < clientHeader.CopyHandlesCount; index++)
                {
                    int newHandle = 0;
                    int handle    = KernelContext.Memory.Read <int>(clientMsg.DramAddress + offset * 4);

                    if (clientResult == KernelResult.Success && handle != 0)
                    {
                        clientResult = GetCopyObjectHandle(clientThread, serverProcess, handle, out newHandle);
                    }

                    serverProcess.CpuMemory.Write(serverMsg.Address + offset * 4, newHandle);

                    offset++;
                }

                for (int index = 0; index < clientHeader.MoveHandlesCount; index++)
                {
                    int newHandle = 0;
                    int handle    = KernelContext.Memory.Read <int>(clientMsg.DramAddress + offset * 4);

                    if (handle != 0)
                    {
                        if (clientResult == KernelResult.Success)
                        {
                            clientResult = GetMoveObjectHandle(clientProcess, serverProcess, handle, out newHandle);
                        }
                        else
                        {
                            clientProcess.HandleTable.CloseHandle(handle);
                        }
                    }

                    serverProcess.CpuMemory.Write(serverMsg.Address + offset * 4, newHandle);

                    offset++;
                }

                if (clientResult != KernelResult.Success)
                {
                    CleanUpForError();

                    return(serverResult);
                }
            }
            else
            {
                offset = 2;
            }

            // Copy pointer/receive list buffers.
            uint recvListDstOffset = 0;

            for (int index = 0; index < clientHeader.PointerBuffersCount; index++)
            {
                ulong pointerDesc = KernelContext.Memory.Read <ulong>(clientMsg.DramAddress + offset * 4);

                PointerBufferDesc descriptor = new PointerBufferDesc(pointerDesc);

                if (descriptor.BufferSize != 0)
                {
                    clientResult = GetReceiveListAddress(
                        descriptor,
                        serverMsg,
                        serverHeader.ReceiveListType,
                        clientHeader.MessageSizeInWords,
                        receiveList,
                        ref recvListDstOffset,
                        out ulong recvListBufferAddress);

                    if (clientResult != KernelResult.Success)
                    {
                        CleanUpForError();

                        return(serverResult);
                    }

                    clientResult = clientProcess.MemoryManager.CopyDataToCurrentProcess(
                        recvListBufferAddress,
                        descriptor.BufferSize,
                        descriptor.BufferAddress,
                        MemoryState.IsPoolAllocated,
                        MemoryState.IsPoolAllocated,
                        KMemoryPermission.Read,
                        MemoryAttribute.Uncached,
                        MemoryAttribute.None);

                    if (clientResult != KernelResult.Success)
                    {
                        CleanUpForError();

                        return(serverResult);
                    }

                    descriptor.BufferAddress = recvListBufferAddress;
                }
                else
                {
                    descriptor.BufferAddress = 0;
                }

                serverProcess.CpuMemory.Write(serverMsg.Address + offset * 4, descriptor.Pack());

                offset += 2;
            }

            // Copy send, receive and exchange buffers.
            uint totalBuffersCount =
                clientHeader.SendBuffersCount +
                clientHeader.ReceiveBuffersCount +
                clientHeader.ExchangeBuffersCount;

            for (int index = 0; index < totalBuffersCount; index++)
            {
                ulong clientDescAddress = clientMsg.DramAddress + offset * 4;

                uint descWord0 = KernelContext.Memory.Read <uint>(clientDescAddress + 0);
                uint descWord1 = KernelContext.Memory.Read <uint>(clientDescAddress + 4);
                uint descWord2 = KernelContext.Memory.Read <uint>(clientDescAddress + 8);

                bool isSendDesc     = index < clientHeader.SendBuffersCount;
                bool isExchangeDesc = index >= clientHeader.SendBuffersCount + clientHeader.ReceiveBuffersCount;

                bool notReceiveDesc = isSendDesc || isExchangeDesc;
                bool isReceiveDesc  = !notReceiveDesc;

                KMemoryPermission permission = index >= clientHeader.SendBuffersCount
                    ? KMemoryPermission.ReadAndWrite
                    : KMemoryPermission.Read;

                uint sizeHigh4 = (descWord2 >> 24) & 0xf;

                ulong bufferSize = descWord0 | (ulong)sizeHigh4 << 32;

                ulong dstAddress = 0;

                if (bufferSize != 0)
                {
                    ulong bufferAddress;

                    bufferAddress  = descWord2 >> 28;
                    bufferAddress |= ((descWord2 >> 2) & 7) << 4;

                    bufferAddress = (bufferAddress << 32) | descWord1;

                    MemoryState state = IpcMemoryStates[(descWord2 + 1) & 3];

                    clientResult = serverProcess.MemoryManager.MapBufferFromClientProcess(
                        bufferSize,
                        bufferAddress,
                        clientProcess.MemoryManager,
                        permission,
                        state,
                        notReceiveDesc,
                        out dstAddress);

                    if (clientResult != KernelResult.Success)
                    {
                        CleanUpForError();

                        return(serverResult);
                    }

                    if (isSendDesc)
                    {
                        clientResult = request.BufferDescriptorTable.AddSendBuffer(bufferAddress, dstAddress, bufferSize, state);
                    }
                    else if (isReceiveDesc)
                    {
                        clientResult = request.BufferDescriptorTable.AddReceiveBuffer(bufferAddress, dstAddress, bufferSize, state);
                    }
                    else /* if (isExchangeDesc) */
                    {
                        clientResult = request.BufferDescriptorTable.AddExchangeBuffer(bufferAddress, dstAddress, bufferSize, state);
                    }

                    if (clientResult != KernelResult.Success)
                    {
                        CleanUpForError();

                        return(serverResult);
                    }
                }

                descWord1 = (uint)dstAddress;

                descWord2 &= 3;

                descWord2 |= sizeHigh4 << 24;

                descWord2 |= (uint)(dstAddress >> 34) & 0x3ffffffc;
                descWord2 |= (uint)(dstAddress >> 4) & 0xf0000000;

                ulong serverDescAddress = serverMsg.Address + offset * 4;

                serverProcess.CpuMemory.Write(serverDescAddress + 0, descWord0);
                serverProcess.CpuMemory.Write(serverDescAddress + 4, descWord1);
                serverProcess.CpuMemory.Write(serverDescAddress + 8, descWord2);

                offset += 3;
            }

            // Copy raw data.
            if (clientHeader.RawDataSizeInWords != 0)
            {
                ulong copySrc = clientMsg.Address + offset * 4;
                ulong copyDst = serverMsg.Address + offset * 4;

                ulong copySize = clientHeader.RawDataSizeInWords * 4;

                if (serverMsg.IsCustom || clientMsg.IsCustom)
                {
                    KMemoryPermission permission = clientMsg.IsCustom
                        ? KMemoryPermission.None
                        : KMemoryPermission.Read;

                    clientResult = clientProcess.MemoryManager.CopyDataToCurrentProcess(
                        copyDst,
                        copySize,
                        copySrc,
                        MemoryState.IsPoolAllocated,
                        MemoryState.IsPoolAllocated,
                        permission,
                        MemoryAttribute.Uncached,
                        MemoryAttribute.None);
                }
                else
                {
                    copySrc = clientProcess.MemoryManager.GetDramAddressFromVa(copySrc);
                    copyDst = serverProcess.MemoryManager.GetDramAddressFromVa(copyDst);

                    KernelContext.Memory.Copy(copyDst, copySrc, copySize);
                }

                if (clientResult != KernelResult.Success)
                {
                    CleanUpForError();

                    return(serverResult);
                }
            }

            return(KernelResult.Success);
        }
コード例 #11
0
        public KernelResult Reply(ulong customCmdBuffAddr = 0, ulong customCmdBuffSize = 0)
        {
            KThread  serverThread  = KernelStatic.GetCurrentThread();
            KProcess serverProcess = serverThread.Owner;

            KernelContext.CriticalSection.Enter();

            if (_activeRequest == null)
            {
                KernelContext.CriticalSection.Leave();

                return(KernelResult.InvalidState);
            }

            KSessionRequest request = _activeRequest;

            _activeRequest = null;

            if (_requests.Count != 0)
            {
                Signal();
            }

            KernelContext.CriticalSection.Leave();

            KThread  clientThread  = request.ClientThread;
            KProcess clientProcess = clientThread.Owner;

            Message clientMsg = new Message(request);
            Message serverMsg = new Message(serverThread, customCmdBuffAddr, customCmdBuffSize);

            MessageHeader clientHeader = GetClientMessageHeader(clientMsg);
            MessageHeader serverHeader = GetServerMessageHeader(serverMsg);

            KernelResult clientResult = KernelResult.Success;
            KernelResult serverResult = KernelResult.Success;

            void CleanUpForError()
            {
                CloseAllHandles(clientMsg, serverHeader, clientProcess);

                FinishRequest(request, clientResult);
            }

            if (clientHeader.ReceiveListType < 2 &&
                clientHeader.ReceiveListOffset > clientMsg.Size)
            {
                CleanUpForError();

                return(KernelResult.InvalidCombination);
            }
            else if (clientHeader.ReceiveListType == 2 &&
                     clientHeader.ReceiveListOffset + 8 > clientMsg.Size)
            {
                CleanUpForError();

                return(KernelResult.InvalidCombination);
            }
            else if (clientHeader.ReceiveListType > 2 &&
                     clientHeader.ReceiveListType * 8 - 0x10 + clientHeader.ReceiveListOffset > clientMsg.Size)
            {
                CleanUpForError();

                return(KernelResult.InvalidCombination);
            }

            if (clientHeader.ReceiveListOffsetInWords < clientHeader.MessageSizeInWords)
            {
                CleanUpForError();

                return(KernelResult.InvalidCombination);
            }

            if (serverHeader.MessageSizeInWords * 4 > clientMsg.Size)
            {
                CleanUpForError();

                return(KernelResult.CmdBufferTooSmall);
            }

            if (serverHeader.SendBuffersCount != 0 ||
                serverHeader.ReceiveBuffersCount != 0 ||
                serverHeader.ExchangeBuffersCount != 0)
            {
                CleanUpForError();

                return(KernelResult.InvalidCombination);
            }

            // Read receive list.
            ulong[] receiveList = GetReceiveList(
                clientMsg,
                clientHeader.ReceiveListType,
                clientHeader.ReceiveListOffset);

            // Copy receive and exchange buffers.
            clientResult = request.BufferDescriptorTable.CopyBuffersToClient(clientProcess.MemoryManager);

            if (clientResult != KernelResult.Success)
            {
                CleanUpForError();

                return(serverResult);
            }

            // Copy header.
            KernelContext.Memory.Write(clientMsg.DramAddress + 0, serverHeader.Word0);
            KernelContext.Memory.Write(clientMsg.DramAddress + 4, serverHeader.Word1);

            // Copy handles.
            uint offset;

            if (serverHeader.HasHandles)
            {
                offset = 3;

                KernelContext.Memory.Write(clientMsg.DramAddress + 8, serverHeader.Word2);

                if (serverHeader.HasPid)
                {
                    KernelContext.Memory.Write(clientMsg.DramAddress + offset * 4, serverProcess.Pid);

                    offset += 2;
                }

                for (int index = 0; index < serverHeader.CopyHandlesCount; index++)
                {
                    int newHandle = 0;

                    int handle = serverProcess.CpuMemory.Read <int>(serverMsg.Address + offset * 4);

                    if (handle != 0)
                    {
                        GetCopyObjectHandle(serverThread, clientProcess, handle, out newHandle);
                    }

                    KernelContext.Memory.Write(clientMsg.DramAddress + offset * 4, newHandle);

                    offset++;
                }

                for (int index = 0; index < serverHeader.MoveHandlesCount; index++)
                {
                    int newHandle = 0;

                    int handle = serverProcess.CpuMemory.Read <int>(serverMsg.Address + offset * 4);

                    if (handle != 0)
                    {
                        if (clientResult == KernelResult.Success)
                        {
                            clientResult = GetMoveObjectHandle(serverProcess, clientProcess, handle, out newHandle);
                        }
                        else
                        {
                            serverProcess.HandleTable.CloseHandle(handle);
                        }
                    }

                    KernelContext.Memory.Write(clientMsg.DramAddress + offset * 4, newHandle);

                    offset++;
                }
            }
            else
            {
                offset = 2;
            }

            // Copy pointer/receive list buffers.
            uint recvListDstOffset = 0;

            for (int index = 0; index < serverHeader.PointerBuffersCount; index++)
            {
                ulong pointerDesc = serverProcess.CpuMemory.Read <ulong>(serverMsg.Address + offset * 4);

                PointerBufferDesc descriptor = new PointerBufferDesc(pointerDesc);

                ulong recvListBufferAddress = 0;

                if (descriptor.BufferSize != 0)
                {
                    clientResult = GetReceiveListAddress(
                        descriptor,
                        clientMsg,
                        clientHeader.ReceiveListType,
                        serverHeader.MessageSizeInWords,
                        receiveList,
                        ref recvListDstOffset,
                        out recvListBufferAddress);

                    if (clientResult != KernelResult.Success)
                    {
                        CleanUpForError();

                        return(serverResult);
                    }

                    clientResult = clientProcess.MemoryManager.CopyDataFromCurrentProcess(
                        recvListBufferAddress,
                        descriptor.BufferSize,
                        MemoryState.IsPoolAllocated,
                        MemoryState.IsPoolAllocated,
                        KMemoryPermission.Read,
                        MemoryAttribute.Uncached,
                        MemoryAttribute.None,
                        descriptor.BufferAddress);

                    if (clientResult != KernelResult.Success)
                    {
                        CleanUpForError();

                        return(serverResult);
                    }
                }

                ulong dstDescAddress = clientMsg.DramAddress + offset * 4;

                ulong clientPointerDesc =
                    (recvListBufferAddress << 32) |
                    ((recvListBufferAddress >> 20) & 0xf000) |
                    ((recvListBufferAddress >> 30) & 0xffc0);

                clientPointerDesc |= pointerDesc & 0xffff000f;

                KernelContext.Memory.Write(dstDescAddress + 0, clientPointerDesc);

                offset += 2;
            }

            // Set send, receive and exchange buffer descriptors to zero.
            uint totalBuffersCount =
                serverHeader.SendBuffersCount +
                serverHeader.ReceiveBuffersCount +
                serverHeader.ExchangeBuffersCount;

            for (int index = 0; index < totalBuffersCount; index++)
            {
                ulong dstDescAddress = clientMsg.DramAddress + offset * 4;

                KernelContext.Memory.Write(dstDescAddress + 0, 0);
                KernelContext.Memory.Write(dstDescAddress + 4, 0);
                KernelContext.Memory.Write(dstDescAddress + 8, 0);

                offset += 3;
            }

            // Copy raw data.
            if (serverHeader.RawDataSizeInWords != 0)
            {
                ulong copyDst = clientMsg.Address + offset * 4;
                ulong copySrc = serverMsg.Address + offset * 4;

                ulong copySize = serverHeader.RawDataSizeInWords * 4;

                if (serverMsg.IsCustom || clientMsg.IsCustom)
                {
                    KMemoryPermission permission = clientMsg.IsCustom
                        ? KMemoryPermission.None
                        : KMemoryPermission.Read;

                    clientResult = clientProcess.MemoryManager.CopyDataFromCurrentProcess(
                        copyDst,
                        copySize,
                        MemoryState.IsPoolAllocated,
                        MemoryState.IsPoolAllocated,
                        permission,
                        MemoryAttribute.Uncached,
                        MemoryAttribute.None,
                        copySrc);
                }
                else
                {
                    copyDst = clientProcess.MemoryManager.GetDramAddressFromVa(copyDst);
                    copySrc = serverProcess.MemoryManager.GetDramAddressFromVa(copySrc);

                    KernelContext.Memory.Copy(copyDst, copySrc, copySize);
                }
            }

            // Unmap buffers from server.
            FinishRequest(request, clientResult);

            return(serverResult);
        }
コード例 #12
0
ファイル: ServerBase.cs プロジェクト: lalalaring/Ryujinx
        private void ServerLoop()
        {
            _selfProcess = KernelStatic.GetCurrentProcess();

            if (SmObjectFactory != null)
            {
                _context.Syscall.ManageNamedPort(out int serverPortHandle, "sm:", 50);

                AddPort(serverPortHandle, SmObjectFactory);
            }

            InitDone.Set();

            KThread thread     = KernelStatic.GetCurrentThread();
            ulong   messagePtr = thread.TlsAddress;

            _context.Syscall.SetHeapSize(out ulong heapAddr, 0x200000);

            _selfProcess.CpuMemory.Write(messagePtr + 0x0, 0);
            _selfProcess.CpuMemory.Write(messagePtr + 0x4, 2 << 10);
            _selfProcess.CpuMemory.Write(messagePtr + 0x8, heapAddr | ((ulong)PointerBufferSize << 48));

            int replyTargetHandle = 0;

            while (true)
            {
                int[] portHandles    = _portHandles.ToArray();
                int[] sessionHandles = _sessionHandles.ToArray();
                int[] handles        = new int[portHandles.Length + sessionHandles.Length];

                portHandles.CopyTo(handles, 0);
                sessionHandles.CopyTo(handles, portHandles.Length);

                // We still need a timeout here to allow the service to pick up and listen new sessions...
                var rc = _context.Syscall.ReplyAndReceive(out int signaledIndex, handles, replyTargetHandle, 1000000L);

                thread.HandlePostSyscall();

                if (!thread.Context.Running)
                {
                    break;
                }

                replyTargetHandle = 0;

                if (rc == KernelResult.Success && signaledIndex >= portHandles.Length)
                {
                    // We got a IPC request, process it, pass to the appropriate service if needed.
                    int signaledHandle = handles[signaledIndex];

                    if (Process(signaledHandle, heapAddr))
                    {
                        replyTargetHandle = signaledHandle;
                    }
                }
                else
                {
                    if (rc == KernelResult.Success)
                    {
                        // We got a new connection, accept the session to allow servicing future requests.
                        if (_context.Syscall.AcceptSession(out int serverSessionHandle, handles[signaledIndex]) == KernelResult.Success)
                        {
                            IpcService obj = _ports[handles[signaledIndex]].Invoke();

                            AddSessionObj(serverSessionHandle, obj);
                        }
                    }

                    _selfProcess.CpuMemory.Write(messagePtr + 0x0, 0);
                    _selfProcess.CpuMemory.Write(messagePtr + 0x4, 2 << 10);
                    _selfProcess.CpuMemory.Write(messagePtr + 0x8, heapAddr | ((ulong)PointerBufferSize << 48));
                }
            }

            Dispose();
        }
コード例 #13
0
ファイル: ServerBase.cs プロジェクト: lalalaring/Ryujinx
        private bool Process(int serverSessionHandle, ulong recvListAddr)
        {
            KProcess process     = KernelStatic.GetCurrentProcess();
            KThread  thread      = KernelStatic.GetCurrentThread();
            ulong    messagePtr  = thread.TlsAddress;
            ulong    messageSize = 0x100;

            byte[] reqData = new byte[messageSize];

            process.CpuMemory.Read(messagePtr, reqData);

            IpcMessage request  = new IpcMessage(reqData, (long)messagePtr);
            IpcMessage response = new IpcMessage();

            ulong tempAddr    = recvListAddr;
            int   sizesOffset = request.RawData.Length - ((request.RecvListBuff.Count * 2 + 3) & ~3);

            bool noReceive = true;

            for (int i = 0; i < request.ReceiveBuff.Count; i++)
            {
                noReceive &= (request.ReceiveBuff[i].Position == 0);
            }

            if (noReceive)
            {
                for (int i = 0; i < request.RecvListBuff.Count; i++)
                {
                    ulong size = (ulong)BinaryPrimitives.ReadInt16LittleEndian(request.RawData.AsSpan(sizesOffset + i * 2, 2));

                    response.PtrBuff.Add(new IpcPtrBuffDesc(tempAddr, (uint)i, size));

                    request.RecvListBuff[i] = new IpcRecvListBuffDesc(tempAddr, size);

                    tempAddr += size;
                }
            }

            bool shouldReply         = true;
            bool isTipcCommunication = false;

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

                if (request.Type == IpcMessageType.HipcRequest ||
                    request.Type == IpcMessageType.HipcRequestWithContext)
                {
                    response.Type = IpcMessageType.HipcResponse;

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

                        ServiceCtx context = new ServiceCtx(
                            _context.Device,
                            process,
                            process.CpuMemory,
                            thread,
                            request,
                            response,
                            reqReader,
                            resWriter);

                        _sessions[serverSessionHandle].CallHipcMethod(context);

                        response.RawData = resMs.ToArray();
                    }
                }
                else if (request.Type == IpcMessageType.HipcControl ||
                         request.Type == IpcMessageType.HipcControlWithContext)
                {
                    uint magic = (uint)reqReader.ReadUInt64();
                    uint cmdId = (uint)reqReader.ReadUInt64();

                    switch (cmdId)
                    {
                    case 0:
                        request = FillResponse(response, 0, _sessions[serverSessionHandle].ConvertToDomain());
                        break;

                    case 3:
                        request = FillResponse(response, 0, PointerBufferSize);
                        break;

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

                        _context.Syscall.CreateSession(out int dupServerSessionHandle, out int dupClientSessionHandle, false, 0);

                        AddSessionObj(dupServerSessionHandle, _sessions[serverSessionHandle]);

                        response.HandleDesc = IpcHandleDesc.MakeMove(dupClientSessionHandle);

                        request = FillResponse(response, 0);

                        break;

                    default: throw new NotImplementedException(cmdId.ToString());
                    }
                }
                else if (request.Type == IpcMessageType.HipcCloseSession || request.Type == IpcMessageType.TipcCloseSession)
                {
                    _context.Syscall.CloseHandle(serverSessionHandle);
                    _sessionHandles.Remove(serverSessionHandle);
                    IpcService service = _sessions[serverSessionHandle];
                    if (service is IDisposable disposableObj)
                    {
                        disposableObj.Dispose();
                    }
                    _sessions.Remove(serverSessionHandle);
                    shouldReply = false;
                }
                // If the type is past 0xF, we are using TIPC
                else if (request.Type > IpcMessageType.TipcCloseSession)
                {
                    isTipcCommunication = true;

                    // Response type is always the same as request on TIPC.
                    response.Type = request.Type;

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

                        ServiceCtx context = new ServiceCtx(
                            _context.Device,
                            process,
                            process.CpuMemory,
                            thread,
                            request,
                            response,
                            reqReader,
                            resWriter);

                        _sessions[serverSessionHandle].CallTipcMethod(context);

                        response.RawData = resMs.ToArray();
                    }

                    process.CpuMemory.Write(messagePtr, response.GetBytesTipc());
                }
                else
                {
                    throw new NotImplementedException(request.Type.ToString());
                }

                if (!isTipcCommunication)
                {
                    process.CpuMemory.Write(messagePtr, response.GetBytes((long)messagePtr, recvListAddr | ((ulong)PointerBufferSize << 48)));
                }

                return(shouldReply);
            }
        }
コード例 #14
0
ファイル: SyscallHandler.cs プロジェクト: ski982/Ryujinx-1
        private void PostSvcHandler()
        {
            KThread currentThread = _context.Scheduler.GetCurrentThread();

            currentThread.HandlePostSyscall();
        }
コード例 #15
0
        private void SvcExitThread(AThreadState ThreadState)
        {
            KThread CurrThread = Process.GetThread(ThreadState.Tpidr);

            CurrThread.Thread.StopExecution();
        }
コード例 #16
0
ファイル: SvcThread.cs プロジェクト: woxihuanjia/Ryujinx
        private KernelResult GetThreadContext3(ulong address, int handle)
        {
            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
            KThread  currentThread  = _system.Scheduler.GetCurrentThread();

            KThread thread = _process.HandleTable.GetObject <KThread>(handle);

            if (thread == null)
            {
                return(KernelResult.InvalidHandle);
            }

            if (thread.Owner != currentProcess)
            {
                return(KernelResult.InvalidHandle);
            }

            if (currentThread == thread)
            {
                return(KernelResult.InvalidThread);
            }

            MemoryManager memory = currentProcess.CpuMemory;

            memory.WriteUInt64((long)address + 0x0, thread.Context.ThreadState.X0);
            memory.WriteUInt64((long)address + 0x8, thread.Context.ThreadState.X1);
            memory.WriteUInt64((long)address + 0x10, thread.Context.ThreadState.X2);
            memory.WriteUInt64((long)address + 0x18, thread.Context.ThreadState.X3);
            memory.WriteUInt64((long)address + 0x20, thread.Context.ThreadState.X4);
            memory.WriteUInt64((long)address + 0x28, thread.Context.ThreadState.X5);
            memory.WriteUInt64((long)address + 0x30, thread.Context.ThreadState.X6);
            memory.WriteUInt64((long)address + 0x38, thread.Context.ThreadState.X7);
            memory.WriteUInt64((long)address + 0x40, thread.Context.ThreadState.X8);
            memory.WriteUInt64((long)address + 0x48, thread.Context.ThreadState.X9);
            memory.WriteUInt64((long)address + 0x50, thread.Context.ThreadState.X10);
            memory.WriteUInt64((long)address + 0x58, thread.Context.ThreadState.X11);
            memory.WriteUInt64((long)address + 0x60, thread.Context.ThreadState.X12);
            memory.WriteUInt64((long)address + 0x68, thread.Context.ThreadState.X13);
            memory.WriteUInt64((long)address + 0x70, thread.Context.ThreadState.X14);
            memory.WriteUInt64((long)address + 0x78, thread.Context.ThreadState.X15);
            memory.WriteUInt64((long)address + 0x80, thread.Context.ThreadState.X16);
            memory.WriteUInt64((long)address + 0x88, thread.Context.ThreadState.X17);
            memory.WriteUInt64((long)address + 0x90, thread.Context.ThreadState.X18);
            memory.WriteUInt64((long)address + 0x98, thread.Context.ThreadState.X19);
            memory.WriteUInt64((long)address + 0xa0, thread.Context.ThreadState.X20);
            memory.WriteUInt64((long)address + 0xa8, thread.Context.ThreadState.X21);
            memory.WriteUInt64((long)address + 0xb0, thread.Context.ThreadState.X22);
            memory.WriteUInt64((long)address + 0xb8, thread.Context.ThreadState.X23);
            memory.WriteUInt64((long)address + 0xc0, thread.Context.ThreadState.X24);
            memory.WriteUInt64((long)address + 0xc8, thread.Context.ThreadState.X25);
            memory.WriteUInt64((long)address + 0xd0, thread.Context.ThreadState.X26);
            memory.WriteUInt64((long)address + 0xd8, thread.Context.ThreadState.X27);
            memory.WriteUInt64((long)address + 0xe0, thread.Context.ThreadState.X28);
            memory.WriteUInt64((long)address + 0xe8, thread.Context.ThreadState.X29);
            memory.WriteUInt64((long)address + 0xf0, thread.Context.ThreadState.X30);
            memory.WriteUInt64((long)address + 0xf8, thread.Context.ThreadState.X31);

            memory.WriteInt64((long)address + 0x100, thread.LastPc);

            memory.WriteUInt64((long)address + 0x108, (ulong)thread.Context.ThreadState.Psr);

            memory.WriteVector128((long)address + 0x110, thread.Context.ThreadState.V0);
            memory.WriteVector128((long)address + 0x120, thread.Context.ThreadState.V1);
            memory.WriteVector128((long)address + 0x130, thread.Context.ThreadState.V2);
            memory.WriteVector128((long)address + 0x140, thread.Context.ThreadState.V3);
            memory.WriteVector128((long)address + 0x150, thread.Context.ThreadState.V4);
            memory.WriteVector128((long)address + 0x160, thread.Context.ThreadState.V5);
            memory.WriteVector128((long)address + 0x170, thread.Context.ThreadState.V6);
            memory.WriteVector128((long)address + 0x180, thread.Context.ThreadState.V7);
            memory.WriteVector128((long)address + 0x190, thread.Context.ThreadState.V8);
            memory.WriteVector128((long)address + 0x1a0, thread.Context.ThreadState.V9);
            memory.WriteVector128((long)address + 0x1b0, thread.Context.ThreadState.V10);
            memory.WriteVector128((long)address + 0x1c0, thread.Context.ThreadState.V11);
            memory.WriteVector128((long)address + 0x1d0, thread.Context.ThreadState.V12);
            memory.WriteVector128((long)address + 0x1e0, thread.Context.ThreadState.V13);
            memory.WriteVector128((long)address + 0x1f0, thread.Context.ThreadState.V14);
            memory.WriteVector128((long)address + 0x200, thread.Context.ThreadState.V15);
            memory.WriteVector128((long)address + 0x210, thread.Context.ThreadState.V16);
            memory.WriteVector128((long)address + 0x220, thread.Context.ThreadState.V17);
            memory.WriteVector128((long)address + 0x230, thread.Context.ThreadState.V18);
            memory.WriteVector128((long)address + 0x240, thread.Context.ThreadState.V19);
            memory.WriteVector128((long)address + 0x250, thread.Context.ThreadState.V20);
            memory.WriteVector128((long)address + 0x260, thread.Context.ThreadState.V21);
            memory.WriteVector128((long)address + 0x270, thread.Context.ThreadState.V22);
            memory.WriteVector128((long)address + 0x280, thread.Context.ThreadState.V23);
            memory.WriteVector128((long)address + 0x290, thread.Context.ThreadState.V24);
            memory.WriteVector128((long)address + 0x2a0, thread.Context.ThreadState.V25);
            memory.WriteVector128((long)address + 0x2b0, thread.Context.ThreadState.V26);
            memory.WriteVector128((long)address + 0x2c0, thread.Context.ThreadState.V27);
            memory.WriteVector128((long)address + 0x2d0, thread.Context.ThreadState.V28);
            memory.WriteVector128((long)address + 0x2e0, thread.Context.ThreadState.V29);
            memory.WriteVector128((long)address + 0x2f0, thread.Context.ThreadState.V30);
            memory.WriteVector128((long)address + 0x300, thread.Context.ThreadState.V31);

            memory.WriteInt32((long)address + 0x310, thread.Context.ThreadState.Fpcr);
            memory.WriteInt32((long)address + 0x314, thread.Context.ThreadState.Fpsr);
            memory.WriteInt64((long)address + 0x318, thread.Context.ThreadState.Tpidr);

            return(KernelResult.Success);
        }
コード例 #17
0
        private KernelResult GetInfo(uint id, int handle, long subId, out long value)
        {
            value = 0;

            switch (id)
            {
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
            case 7:
            case 12:
            case 13:
            case 14:
            case 15:
            case 16:
            case 17:
            case 18:
            case 20:
            case 21:
            case 22:
            {
                if (subId != 0)
                {
                    return(KernelResult.InvalidCombination);
                }

                KProcess currentProcess = _system.Scheduler.GetCurrentProcess();

                KProcess process = currentProcess.HandleTable.GetKProcess(handle);

                if (process == null)
                {
                    return(KernelResult.InvalidHandle);
                }

                switch (id)
                {
                case 0: value = process.Capabilities.AllowedCpuCoresMask;    break;

                case 1: value = process.Capabilities.AllowedThreadPriosMask; break;

                case 2: value = (long)process.MemoryManager.AliasRegionStart; break;

                case 3: value = (long)(process.MemoryManager.AliasRegionEnd -
                                       process.MemoryManager.AliasRegionStart); break;

                case 4: value = (long)process.MemoryManager.HeapRegionStart; break;

                case 5: value = (long)(process.MemoryManager.HeapRegionEnd -
                                       process.MemoryManager.HeapRegionStart); break;

                case 6: value = (long)process.GetMemoryCapacity(); break;

                case 7: value = (long)process.GetMemoryUsage(); break;

                case 12: value = (long)process.MemoryManager.GetAddrSpaceBaseAddr(); break;

                case 13: value = (long)process.MemoryManager.GetAddrSpaceSize(); break;

                case 14: value = (long)process.MemoryManager.StackRegionStart; break;

                case 15: value = (long)(process.MemoryManager.StackRegionEnd -
                                        process.MemoryManager.StackRegionStart); break;

                case 16: value = (long)process.PersonalMmHeapPagesCount * KMemoryManager.PageSize; break;

                case 17:
                    if (process.PersonalMmHeapPagesCount != 0)
                    {
                        value = process.MemoryManager.GetMmUsedPages() * KMemoryManager.PageSize;
                    }

                    break;

                case 18: value = process.TitleId; break;

                case 20: value = (long)process.UserExceptionContextAddress; break;

                case 21: value = (long)process.GetMemoryCapacityWithoutPersonalMmHeap(); break;

                case 22: value = (long)process.GetMemoryUsageWithoutPersonalMmHeap(); break;
                }

                break;
            }

            case 8:
            {
                if (handle != 0)
                {
                    return(KernelResult.InvalidHandle);
                }

                if (subId != 0)
                {
                    return(KernelResult.InvalidCombination);
                }

                value = _system.Scheduler.GetCurrentProcess().Debug ? 1 : 0;

                break;
            }

            case 9:
            {
                if (handle != 0)
                {
                    return(KernelResult.InvalidHandle);
                }

                if (subId != 0)
                {
                    return(KernelResult.InvalidCombination);
                }

                KProcess currentProcess = _system.Scheduler.GetCurrentProcess();

                if (currentProcess.ResourceLimit != null)
                {
                    KHandleTable   handleTable   = currentProcess.HandleTable;
                    KResourceLimit resourceLimit = currentProcess.ResourceLimit;

                    KernelResult result = handleTable.GenerateHandle(resourceLimit, out int resLimHandle);

                    if (result != KernelResult.Success)
                    {
                        return(result);
                    }

                    value = (uint)resLimHandle;
                }

                break;
            }

            case 10:
            {
                if (handle != 0)
                {
                    return(KernelResult.InvalidHandle);
                }

                int currentCore = _system.Scheduler.GetCurrentThread().CurrentCore;

                if (subId != -1 && subId != currentCore)
                {
                    return(KernelResult.InvalidCombination);
                }

                value = _system.Scheduler.CoreContexts[currentCore].TotalIdleTimeTicks;

                break;
            }

            case 11:
            {
                if (handle != 0)
                {
                    return(KernelResult.InvalidHandle);
                }

                if ((ulong)subId > 3)
                {
                    return(KernelResult.InvalidCombination);
                }

                KProcess currentProcess = _system.Scheduler.GetCurrentProcess();


                value = currentProcess.RandomEntropy[subId];

                break;
            }

            case 0xf0000002u:
            {
                if (subId < -1 || subId > 3)
                {
                    return(KernelResult.InvalidCombination);
                }

                KThread thread = _system.Scheduler.GetCurrentProcess().HandleTable.GetKThread(handle);

                if (thread == null)
                {
                    return(KernelResult.InvalidHandle);
                }

                KThread currentThread = _system.Scheduler.GetCurrentThread();

                int currentCore = currentThread.CurrentCore;

                if (subId != -1 && subId != currentCore)
                {
                    return(KernelResult.Success);
                }

                KCoreContext coreContext = _system.Scheduler.CoreContexts[currentCore];

                long timeDelta = PerformanceCounter.ElapsedMilliseconds - coreContext.LastContextSwitchTime;

                if (subId != -1)
                {
                    value = KTimeManager.ConvertMillisecondsToTicks(timeDelta);
                }
                else
                {
                    long totalTimeRunning = thread.TotalTimeRunning;

                    if (thread == currentThread)
                    {
                        totalTimeRunning += timeDelta;
                    }

                    value = KTimeManager.ConvertMillisecondsToTicks(totalTimeRunning);
                }

                break;
            }

            default: return(KernelResult.InvalidEnumValue);
            }

            return(KernelResult.Success);
        }
コード例 #18
0
 public bool IsExceptionUserThread(KThread thread)
 {
     // TODO
     return(false);
 }
コード例 #19
0
        protected virtual void Dispose(bool disposing)
        {
            if (!_isDisposed && disposing)
            {
                _isDisposed = true;

                KProcess terminationProcess = new KProcess(KernelContext);
                KThread  terminationThread  = new KThread(KernelContext);

                terminationThread.Initialize(0, 0, 0, 3, 0, terminationProcess, ThreadType.Kernel, () =>
                {
                    // Force all threads to exit.
                    lock (KernelContext.Processes)
                    {
                        // Terminate application.
                        foreach (KProcess process in KernelContext.Processes.Values.Where(x => x.Flags.HasFlag(ProcessCreationFlags.IsApplication)))
                        {
                            process.Terminate();
                            process.DecrementReferenceCount();
                        }

                        // The application existed, now surface flinger can exit too.
                        SurfaceFlinger.Dispose();

                        // Terminate HLE services (must be done after the application is already terminated,
                        // otherwise the application will receive errors due to service termination.
                        foreach (KProcess process in KernelContext.Processes.Values.Where(x => !x.Flags.HasFlag(ProcessCreationFlags.IsApplication)))
                        {
                            process.Terminate();
                            process.DecrementReferenceCount();
                        }

                        KernelContext.Processes.Clear();
                    }

                    // Exit ourself now!
                    KernelStatic.GetCurrentThread().Exit();
                });

                terminationThread.Start();

                // Wait until the thread is actually started.
                while (terminationThread.HostThread.ThreadState == ThreadState.Unstarted)
                {
                    Thread.Sleep(10);
                }

                // Wait until the termination thread is done terminating all the other threads.
                terminationThread.HostThread.Join();

                // Destroy nvservices channels as KThread could be waiting on some user events.
                // This is safe as KThread that are likely to call ioctls are going to be terminated by the post handler hook on the SVC facade.
                INvDrvServices.Destroy();

                AudioManager.Dispose();
                AudioOutputManager.Dispose();
                AudioInputManager.Dispose();

                AudioRendererManager.Dispose();

                KernelContext.Dispose();
            }
        }
コード例 #20
0
        public KernelResult Start(int mainThreadPriority, ulong stackSize)
        {
            lock (_processLock)
            {
                if (State > ProcessState.CreatedAttached)
                {
                    return(KernelResult.InvalidState);
                }

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

                KResourceLimit threadResourceLimit = ResourceLimit;
                KResourceLimit memoryResourceLimit = null;

                if (_mainThreadStackSize != 0)
                {
                    throw new InvalidOperationException("Trying to start a process with a invalid state!");
                }

                ulong stackSizeRounded = BitUtils.AlignUp(stackSize, KPageTableBase.PageSize);

                ulong neededSize = stackSizeRounded + _imageSize;

                // Check if the needed size for the code and the stack will fit on the
                // memory usage capacity of this Process. Also check for possible overflow
                // on the above addition.
                if (neededSize > _memoryUsageCapacity || neededSize < stackSizeRounded)
                {
                    threadResourceLimit?.Release(LimitableResource.Thread, 1);

                    return(KernelResult.OutOfMemory);
                }

                if (stackSizeRounded != 0 && ResourceLimit != null)
                {
                    memoryResourceLimit = ResourceLimit;

                    if (!memoryResourceLimit.Reserve(LimitableResource.Memory, stackSizeRounded))
                    {
                        threadResourceLimit?.Release(LimitableResource.Thread, 1);

                        return(KernelResult.ResLimitExceeded);
                    }
                }

                KernelResult result;

                KThread mainThread = null;

                ulong stackTop = 0;

                void CleanUpForError()
                {
                    HandleTable.Destroy();

                    mainThread?.DecrementReferenceCount();

                    if (_mainThreadStackSize != 0)
                    {
                        ulong stackBottom = stackTop - _mainThreadStackSize;

                        ulong stackPagesCount = _mainThreadStackSize / KPageTableBase.PageSize;

                        MemoryManager.UnmapForKernel(stackBottom, stackPagesCount, MemoryState.Stack);

                        _mainThreadStackSize = 0;
                    }

                    memoryResourceLimit?.Release(LimitableResource.Memory, stackSizeRounded);
                    threadResourceLimit?.Release(LimitableResource.Thread, 1);
                }

                if (stackSizeRounded != 0)
                {
                    ulong stackPagesCount = stackSizeRounded / KPageTableBase.PageSize;

                    ulong regionStart = MemoryManager.StackRegionStart;
                    ulong regionSize  = MemoryManager.StackRegionEnd - regionStart;

                    ulong regionPagesCount = regionSize / KPageTableBase.PageSize;

                    result = MemoryManager.MapPages(
                        stackPagesCount,
                        KPageTableBase.PageSize,
                        0,
                        false,
                        regionStart,
                        regionPagesCount,
                        MemoryState.Stack,
                        KMemoryPermission.ReadAndWrite,
                        out ulong stackBottom);

                    if (result != KernelResult.Success)
                    {
                        CleanUpForError();

                        return(result);
                    }

                    _mainThreadStackSize += stackSizeRounded;

                    stackTop = stackBottom + stackSizeRounded;
                }

                ulong heapCapacity = _memoryUsageCapacity - _mainThreadStackSize - _imageSize;

                result = MemoryManager.SetHeapCapacity(heapCapacity);

                if (result != KernelResult.Success)
                {
                    CleanUpForError();

                    return(result);
                }

                HandleTable = new KHandleTable(KernelContext);

                result = HandleTable.Initialize(Capabilities.HandleTableSize);

                if (result != KernelResult.Success)
                {
                    CleanUpForError();

                    return(result);
                }

                mainThread = new KThread(KernelContext);

                result = mainThread.Initialize(
                    _entrypoint,
                    0,
                    stackTop,
                    mainThreadPriority,
                    DefaultCpuCore,
                    this,
                    ThreadType.User,
                    _customThreadStart);

                if (result != KernelResult.Success)
                {
                    CleanUpForError();

                    return(result);
                }

                result = HandleTable.GenerateHandle(mainThread, out int mainThreadHandle);

                if (result != KernelResult.Success)
                {
                    CleanUpForError();

                    return(result);
                }

                mainThread.SetEntryArguments(0, mainThreadHandle);

                ProcessState oldState = State;
                ProcessState newState = State != ProcessState.Created
                    ? ProcessState.Attached
                    : ProcessState.Started;

                SetState(newState);

                result = mainThread.Start();

                if (result != KernelResult.Success)
                {
                    SetState(oldState);

                    CleanUpForError();
                }

                if (result == KernelResult.Success)
                {
                    mainThread.IncrementReferenceCount();
                }

                mainThread.DecrementReferenceCount();

                return(result);
            }
        }
コード例 #21
0
ファイル: HttpUnit.cs プロジェクト: cjsjy123/KU_NET
        public void BeginGet(string URL, Action<string> callback, bool AutoStart = true)
        {

            m_curRequest.field0 = URL;
            m_curRequest.field1 = HttpType.GET;
            this.m_SuccessEvent = callback;
#if USE_COR
			m_curRequest.field2  =m_SuccessEvent;
			requestList.Push(m_curRequest);
            m_task = new Task (UnityConnect (), AutoStart);
#else
            m_varUtils.field0 = 0;
            m_thread = KThread.StartTask(HttpThread, false);

#endif

        }
コード例 #22
0
        public KernelResult Start(int mainThreadPriority, ulong stackSize)
        {
            lock (_processLock)
            {
                if (_state > ProcessState.CreatedAttached)
                {
                    return(KernelResult.InvalidState);
                }

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

                KResourceLimit threadResourceLimit = ResourceLimit;
                KResourceLimit memoryResourceLimit = null;

                if (_mainThreadStackSize != 0)
                {
                    throw new InvalidOperationException("Trying to start a process with a invalid state!");
                }

                ulong stackSizeRounded = BitUtils.AlignUp(stackSize, KMemoryManager.PageSize);

                ulong neededSize = stackSizeRounded + _imageSize;

                // Check if the needed size for the code and the stack will fit on the
                // memory usage capacity of this Process. Also check for possible overflow
                // on the above addition.
                if (neededSize > _memoryUsageCapacity ||
                    neededSize < stackSizeRounded)
                {
                    threadResourceLimit?.Release(LimitableResource.Thread, 1);

                    return(KernelResult.OutOfMemory);
                }

                if (stackSizeRounded != 0 && ResourceLimit != null)
                {
                    memoryResourceLimit = ResourceLimit;

                    if (!memoryResourceLimit.Reserve(LimitableResource.Memory, stackSizeRounded))
                    {
                        threadResourceLimit?.Release(LimitableResource.Thread, 1);

                        return(KernelResult.ResLimitExceeded);
                    }
                }

                KernelResult result;

                KThread mainThread = null;

                ulong stackTop = 0;

                void CleanUpForError()
                {
                    HandleTable.Destroy();

                    mainThread?.DecrementReferenceCount();

                    if (_mainThreadStackSize != 0)
                    {
                        ulong stackBottom = stackTop - _mainThreadStackSize;

                        ulong stackPagesCount = _mainThreadStackSize / KMemoryManager.PageSize;

                        MemoryManager.UnmapForKernel(stackBottom, stackPagesCount, MemoryState.Stack);

                        _mainThreadStackSize = 0;
                    }

                    memoryResourceLimit?.Release(LimitableResource.Memory, stackSizeRounded);
                    threadResourceLimit?.Release(LimitableResource.Thread, 1);
                }

                if (stackSizeRounded != 0)
                {
                    ulong stackPagesCount = stackSizeRounded / KMemoryManager.PageSize;

                    ulong regionStart = MemoryManager.StackRegionStart;
                    ulong regionSize  = MemoryManager.StackRegionEnd - regionStart;

                    ulong regionPagesCount = regionSize / KMemoryManager.PageSize;

                    result = MemoryManager.AllocateOrMapPa(
                        stackPagesCount,
                        KMemoryManager.PageSize,
                        0,
                        false,
                        regionStart,
                        regionPagesCount,
                        MemoryState.Stack,
                        MemoryPermission.ReadAndWrite,
                        out ulong stackBottom);

                    if (result != KernelResult.Success)
                    {
                        CleanUpForError();

                        return(result);
                    }

                    _mainThreadStackSize += stackSizeRounded;

                    stackTop = stackBottom + stackSizeRounded;
                }

                ulong heapCapacity = _memoryUsageCapacity - _mainThreadStackSize - _imageSize;

                result = MemoryManager.SetHeapCapacity(heapCapacity);

                if (result != KernelResult.Success)
                {
                    CleanUpForError();

                    return(result);
                }

                HandleTable = new KHandleTable(System);

                result = HandleTable.Initialize(Capabilities.HandleTableSize);

                if (result != KernelResult.Success)
                {
                    CleanUpForError();

                    return(result);
                }

                mainThread = new KThread(System);

                result = mainThread.Initialize(
                    _entrypoint,
                    0,
                    stackTop,
                    mainThreadPriority,
                    DefaultCpuCore,
                    this);

                if (result != KernelResult.Success)
                {
                    CleanUpForError();

                    return(result);
                }

                result = HandleTable.GenerateHandle(mainThread, out int mainThreadHandle);

                if (result != KernelResult.Success)
                {
                    CleanUpForError();

                    return(result);
                }

                mainThread.SetEntryArguments(0, mainThreadHandle);

                ProcessState oldState = _state;
                ProcessState newState = _state != ProcessState.Created
                    ? ProcessState.Attached
                    : ProcessState.Started;

                SetState(newState);

                // TODO: We can't call KThread.Start from a non-guest thread.
                // We will need to make some changes to allow the creation of
                // dummy threads that will be used to initialize the current
                // thread on KCoreContext so that GetCurrentThread doesn't fail.

                /* Result = MainThread.Start();
                 *
                 * if (Result != KernelResult.Success)
                 * {
                 *  SetState(OldState);
                 *
                 *  CleanUpForError();
                 * } */

                mainThread.Reschedule(ThreadSchedState.Running);

                if (result == KernelResult.Success)
                {
                    mainThread.IncrementReferenceCount();
                }

                mainThread.DecrementReferenceCount();

                return(result);
            }
        }
コード例 #23
0
ファイル: HttpUnit.cs プロジェクト: cjsjy123/KU_NET
        public void BeginDownLoadFileFlushToFile(string URL, string Filepath, Action<byte[], float, bool> callback, bool AutoStart = false)
        {
            m_curRequest.field0 = URL;
            m_curRequest.field1 = HttpType.DOWNLOADFILE;
#if USE_COR
			m_curRequest.field0 = URL +";"+Filepath;
			m_curRequest.field2 = callback;
			requestList.Push(m_curRequest);
            m_task = new Task (UnityConnect (), AutoStart);
#else

            this.onProcess = callback;

            file.field0 = Filepath;
            m_curRequest.field2 = file;

            m_thread = KThread.StartTask(ThreadDownLoad, false);

#endif

        }
コード例 #24
0
        public virtual ResultCode GetClockContext(KThread thread, out SystemClockContext context)
        {
            context = _context;

            return(ResultCode.Success);
        }