/// <summary> /// Writes the specified buffer to the specified pipe. /// </summary> /// <param name="PipeId">The Id of the pipe to write to.</param> /// <param name="Data">The buffer to write to the pipe.</param> /// <param name="Offset">The offset in the buffer to start writing from.</param> /// <param name="Length">The length of data to write from the buffer. (Clamped)</param> /// <param name="Blocking">Whether the write call should be blocking or not.</param> /// <remarks> /// <para> /// Id required since an outpoint can be connected to multiple pipes. /// </para> /// <para> /// Non-blocking calls will still be deferred but will fail if the data cannot be written /// on first pass through the pipe's R/W queue. /// </para> /// </remarks> public void Write(int PipeId, byte[] Data, int Offset, int Length, bool Blocking) { Pipes.WritePipeRequest *WritePipeRequestPtr = (Pipes.WritePipeRequest *)Heap.AllocZeroed((uint)sizeof(Pipes.WritePipeRequest), "BasicOutPipe : Alloc WritePipeRequest"); try { if (WritePipeRequestPtr != null) { WritePipeRequestPtr->Offset = Offset; WritePipeRequestPtr->PipeId = PipeId; WritePipeRequestPtr->Length = FOS_System.Math.Min(Data.Length - Offset, Length); WritePipeRequestPtr->InBuffer = (byte *)Utilities.ObjectUtilities.GetHandle(Data) + FOS_System.Array.FieldsBytesSize; WritePipeRequestPtr->Blocking = Blocking; SystemCallResults SysCallResult = SystemCalls.WritePipe(WritePipeRequestPtr); switch (SysCallResult) { case SystemCallResults.Unhandled: //BasicConsole.WriteLine("BasicOutPipe > WritePipe: Unhandled!"); ExceptionMethods.Throw(new Exceptions.RWUnhandledException("BasicOutPipe : Write Pipe unexpected unhandled!")); break; case SystemCallResults.Fail: //BasicConsole.WriteLine("BasicOutPipe > WritePipe: Failed!"); if (Blocking) { ExceptionMethods.Throw(new Exceptions.RWFailedException("BasicOutPipe : Write Pipe unexpected failed! (Blocking call)")); } else { ExceptionMethods.Throw(new Exceptions.RWFailedException("BasicOutPipe : Write Pipe failed. (Non-blocking call)")); } break; case SystemCallResults.OK: //BasicConsole.WriteLine("BasicOutPipe > WritePipe: Succeeded."); break; default: //BasicConsole.WriteLine("BasicOutPipe > WritePipe: Unexpected system call result!"); ExceptionMethods.Throw(new Exceptions.RWUnhandledException("BasicOutPipe : Write Pipe unexpected result!")); break; } } else { ExceptionMethods.Throw(new FOS_System.Exceptions.ArgumentException("BasicOutPipe : Couldn't allocate memory to write to pipe!")); } } finally { if (WritePipeRequestPtr != null) { Heap.Free(WritePipeRequestPtr); } } }
public static SystemCallResults WritePipe(Pipes.WritePipeRequest *Request) { uint Return1 = 0; uint Return2 = 0; uint Return3 = 0; uint Return4 = 0; Call(SystemCallNumbers.WritePipe, (uint)Request, 0, 0, ref Return1, ref Return2, ref Return3, ref Return4); return((SystemCallResults)Return1); }
public static unsafe SystemCallResults HandleDeferredSystemCall( Process CallerProcess, Thread CallerThread, SystemCallNumbers syscallNumber, uint Param1, uint Param2, uint Param3, ref uint Return2, ref uint Return3, ref uint Return4) { SystemCallResults result = SystemCallResults.Unhandled; switch (syscallNumber) { case SystemCallNumbers.StartThread: //BasicConsole.WriteLine("DSC: Start Thread"); Return2 = CallerProcess.CreateThread((ThreadStartMethod)Utilities.ObjectUtilities.GetObject((void *)Param1), "[From sys call]").Id; //BasicConsole.WriteLine("DSC: Start Thread - done."); result = SystemCallResults.OK; break; case SystemCallNumbers.RegisterPipeOutpoint: { //BasicConsole.WriteLine("DSC: Register Pipe Outpoint"); Pipes.PipeOutpoint outpoint; bool registered = Pipes.PipeManager.RegisterPipeOutpoint(CallerProcess.Id, (Pipes.PipeClasses)Param1, (Pipes.PipeSubclasses)Param2, (int)Param3, out outpoint); if (registered) { result = SystemCallResults.OK; } else { result = SystemCallResults.Fail; } //BasicConsole.WriteLine("DSC: Register Pipe Outpoint - done."); } break; case SystemCallNumbers.GetNumPipeOutpoints: { //BasicConsole.WriteLine("DSC: Get Num Pipe Outpoints"); int numOutpoints; bool obtained = Pipes.PipeManager.GetNumPipeOutpoints((Pipes.PipeClasses)Param1, (Pipes.PipeSubclasses)Param2, out numOutpoints); if (obtained) { result = SystemCallResults.OK; Return2 = (uint)numOutpoints; } else { result = SystemCallResults.Fail; } //BasicConsole.WriteLine("DSC: Get Num Pipe Outpoints - done"); } break; case SystemCallNumbers.GetPipeOutpoints: { //BasicConsole.WriteLine("DSC: Get Pipe Outpoints"); bool obtained = Pipes.PipeManager.GetPipeOutpoints(CallerProcess, (Pipes.PipeClasses)Param1, (Pipes.PipeSubclasses)Param2, (Pipes.PipeOutpointsRequest *)Param3); if (obtained) { result = SystemCallResults.OK; } else { result = SystemCallResults.Fail; } //BasicConsole.WriteLine("DSC: Get Pipe Outpoints - done"); } break; case SystemCallNumbers.CreatePipe: { //BasicConsole.WriteLine("DSC: Create Pipe"); bool created = Pipes.PipeManager.CreatePipe(CallerProcess.Id, Param1, (Pipes.CreatePipeRequest *)Param2); if (created) { result = SystemCallResults.OK; } else { result = SystemCallResults.Fail; } //BasicConsole.WriteLine("DSC: Create Pipe - done"); } break; case SystemCallNumbers.WaitOnPipeCreate: { //BasicConsole.WriteLine("DSC: Wait On Pipe Create"); bool waiting = Pipes.PipeManager.WaitOnPipeCreate(CallerProcess.Id, CallerThread.Id, (Pipes.PipeClasses)Param1, (Pipes.PipeSubclasses)Param2); if (waiting) { result = SystemCallResults.Deferred; } else { result = SystemCallResults.Fail; } //BasicConsole.WriteLine("DSC: Wait On Pipe Create - done"); } break; case SystemCallNumbers.ReadPipe: { //BasicConsole.WriteLine("DSC: Read Pipe"); // Need access to calling process' memory to be able to set values in request structure(s) MemoryLayout OriginalMemoryLayout = SystemCallsHelpers.EnableAccessToMemoryOfProcess(CallerProcess); Pipes.ReadPipeRequest * RequestPtr = (Pipes.ReadPipeRequest *)Param1; Pipes.PipeManager.RWResults RWResult = Pipes.PipeManager.ReadPipe(RequestPtr->PipeId, RequestPtr->Blocking, CallerProcess, CallerThread); if (RWResult == Pipes.PipeManager.RWResults.Error) { result = SystemCallResults.Fail; } else { // Returning Deferred state from here will leave the caller thread // in whatever state ReadPipe decided it should be in. result = SystemCallResults.Deferred; } SystemCallsHelpers.DisableAccessToMemoryOfProcess(OriginalMemoryLayout); //BasicConsole.WriteLine("DSC: Read Pipe - done"); } break; case SystemCallNumbers.WritePipe: { //BasicConsole.WriteLine("DSC: Write Pipe"); // Need access to calling process' memory to be able to set values in request structure(s) MemoryLayout OriginalMemoryLayout = SystemCallsHelpers.EnableAccessToMemoryOfProcess(CallerProcess); Pipes.WritePipeRequest * RequestPtr = (Pipes.WritePipeRequest *)Param1; Pipes.PipeManager.RWResults RWResult = Pipes.PipeManager.WritePipe(RequestPtr->PipeId, RequestPtr->Blocking, CallerProcess, CallerThread); if (RWResult == Pipes.PipeManager.RWResults.Error) { result = SystemCallResults.Fail; } else { // Returning Deferred state from here will leave the caller thread // in whatever state WritePipe decided it should be in. result = SystemCallResults.Deferred; } SystemCallsHelpers.DisableAccessToMemoryOfProcess(OriginalMemoryLayout); //BasicConsole.WriteLine("DSC: Write Pipe - done"); } break; default: BasicConsole.WriteLine("DSC: Unrecognised call number."); BasicConsole.WriteLine((uint)syscallNumber); break; } return(result); }