public static int SyscallHandler(uint syscallNumber, uint param1, uint param2, uint param3, ref uint Return2, ref uint Return3, ref uint Return4, uint callerProcessId, uint callerThreadId) { SystemCallResults result = HandleSystemCallForKernel(syscallNumber, param1, param2, param3, ref Return2, ref Return3, ref Return4, callerProcessId, callerThreadId); if (result == SystemCallResults.Deferred || result == SystemCallResults.Deferred_PermitActions) { //BasicConsole.WriteLine("Deferring syscall..."); //BasicConsole.WriteLine("Popping unqueued info object..."); DeferredSyscallInfo info = (DeferredSyscallInfo)DeferredSyscallsInfo_Unqueued.Pop(); //BasicConsole.WriteLine("Setting info..."); info.ProcessId = callerProcessId; info.ThreadId = callerThreadId; //BasicConsole.WriteLine("Queuing info object..."); DeferredSyscallsInfo_Queued.Push(info); //BasicConsole.WriteLine("Waking deferred syscalls thread..."); DeferredSyscallsThread._Wake(); } return((int)result); }
public static void DeferredSyscallsThread_Main() { while (!Terminating) { if (DeferredSyscallsInfo_Queued.Count == 0) { Thread.Sleep_Indefinitely(); } while (DeferredSyscallsInfo_Queued.Count > 0) { // Scheduler must be disabled during pop/push from circular buffer or we can // end up in an infinite lock. Consider what happens if a process invokes // a deferred system call during the pop/push here and at the end of this loop. //BasicConsole.WriteLine("DSC: Pausing scheduler..."); //Scheduler.Disable(); //BasicConsole.WriteLine("DSC: Popping queued info object..."); DeferredSyscallInfo info = (DeferredSyscallInfo)DeferredSyscallsInfo_Queued.Pop(); //BasicConsole.WriteLine("DSC: Resuming scheduler..."); //Scheduler.Enable(); //BasicConsole.WriteLine("DSC: Getting process & thread..."); Process CallerProcess = ProcessManager.GetProcessById(info.ProcessId); Thread CallerThread = ProcessManager.GetThreadById(info.ThreadId, CallerProcess); //BasicConsole.WriteLine("DSC: Getting data & calling..."); uint Return2 = CallerThread.Return2; uint Return3 = CallerThread.Return3; uint Return4 = CallerThread.Return4; SystemCallResults result = HandleDeferredSystemCall( CallerProcess, CallerThread, (SystemCallNumbers)CallerThread.SysCallNumber, CallerThread.Param1, CallerThread.Param2, CallerThread.Param3, ref Return2, ref Return3, ref Return4); //BasicConsole.WriteLine("DSC: Ending call..."); if (result != SystemCallResults.Deferred) { EndDeferredSystemCall(CallerThread, result, Return2, Return3, Return4); } //BasicConsole.WriteLine("DSC: Resetting info object..."); info.ProcessId = 0; info.ThreadId = 0; // See comment at top of loop for why this is necessary //BasicConsole.WriteLine("DSC: Pausing scheduler..."); //Scheduler.Disable(); //BasicConsole.WriteLine("DSC: Queuing info object..."); DeferredSyscallsInfo_Unqueued.Push(info); //BasicConsole.WriteLine("DSC: Resuming scheduler..."); //Scheduler.Enable(); } } }
public static void DeferredSyscallsThread_Main() { while (!Terminating) { if (DeferredSyscallsInfo_Queued.Count == 0) { SystemCalls.SleepThread(SystemCalls.IndefiniteSleepThread); } while (DeferredSyscallsInfo_Queued.Count > 0) { // Scheduler must be disabled during pop/push from circular buffer or we can // end up in an infinite lock. Consider what happens if a process invokes // a deferred system call during the pop/push here and at the end of this loop. #if DSC_TRACE BasicConsole.WriteLine("DSC: Pausing scheduler..."); #endif Scheduler.Disable(/*"DSC 1"*/); #if DSC_TRACE BasicConsole.WriteLine("DSC: Popping queued info object..."); #endif DeferredSyscallInfo info = (DeferredSyscallInfo)DeferredSyscallsInfo_Queued.Pop(); #if DSC_TRACE BasicConsole.WriteLine("DSC: Resuming scheduler..."); #endif Scheduler.Enable(); #if DSC_TRACE BasicConsole.WriteLine("DSC: Getting process & thread..."); #endif Process CallerProcess = ProcessManager.GetProcessById(info.ProcessId); Thread CallerThread = ProcessManager.GetThreadById(info.ThreadId, CallerProcess); #if DSC_TRACE BasicConsole.Write("DSC: Process: "); BasicConsole.WriteLine(CallerProcess.Name); BasicConsole.Write("DSC: Thread: "); BasicConsole.WriteLine(CallerThread.Name); #endif ProcessManager.EnableKernelAccessToProcessMemory(CallerProcess); #if DSC_TRACE BasicConsole.WriteLine("DSC: Getting data..."); #endif SystemCallNumbers SysCallNumber = (SystemCallNumbers)CallerThread.SysCallNumber; uint Param1 = CallerThread.Param1; uint Param2 = CallerThread.Param2; uint Param3 = CallerThread.Param3; uint Return2 = CallerThread.Return2; uint Return3 = CallerThread.Return3; uint Return4 = CallerThread.Return4; #if DSC_TRACE BasicConsole.WriteLine("DSC: Getting data done."); #endif ProcessManager.DisableKernelAccessToProcessMemory(CallerProcess); #if DSC_TRACE BasicConsole.WriteLine("DSC: Calling..."); #endif SystemCallResults result = HandleDeferredSystemCall( CallerProcess, CallerThread, SysCallNumber, Param1, Param2, Param3, ref Return2, ref Return3, ref Return4); #if DSC_TRACE BasicConsole.WriteLine("DSC: Ending call..."); #endif if (result != SystemCallResults.Deferred) { EndDeferredSystemCall(CallerProcess, CallerThread, result, Return2, Return3, Return4); } #if DSC_TRACE BasicConsole.WriteLine("DSC: Resetting info object..."); #endif info.ProcessId = 0; info.ThreadId = 0; // See comment at top of loop for why this is necessary #if DSC_TRACE BasicConsole.WriteLine("DSC: Pausing scheduler..."); #endif Scheduler.Disable(/*"DSC 2"*/); #if DSC_TRACE BasicConsole.WriteLine("DSC: Queuing info object..."); #endif DeferredSyscallsInfo_Unqueued.Push(info); #if DSC_TRACE BasicConsole.WriteLine("DSC: Resuming scheduler..."); #endif Scheduler.Enable(); } } }