/// <summary> /// Reads up to the specified length of data into the specified buffer at the specified offset in the buffer. /// </summary> /// <param name="Data">The buffer to read into.</param> /// <param name="Offset">The offset in the buffer to write data to.</param> /// <param name="Length">The maximum length of data to read.</param> /// <param name="Blocking">Whether the read should be blocking or non-blocking.</param> /// <returns>The actual number of bytes read.</returns> public int Read(byte[] Data, int Offset, int Length, bool Blocking) { int BytesRead = 0; Pipes.ReadPipeRequest *ReadPipeRequestPtr = (Pipes.ReadPipeRequest *)Heap.AllocZeroed((uint)sizeof(Pipes.ReadPipeRequest), "BasicInPipe : Alloc ReadPipeRequest"); try { if (ReadPipeRequestPtr != null) { ReadPipeRequestPtr->PipeId = PipeId; ReadPipeRequestPtr->Offset = Offset; ReadPipeRequestPtr->Length = FOS_System.Math.Min(Data.Length - Offset, Length); ReadPipeRequestPtr->OutBuffer = (byte *)Utilities.ObjectUtilities.GetHandle(Data) + FOS_System.Array.FieldsBytesSize; ReadPipeRequestPtr->Blocking = Blocking; SystemCallResults SysCallResult = SystemCalls.ReadPipe(ReadPipeRequestPtr, out BytesRead); switch (SysCallResult) { case SystemCallResults.Unhandled: //BasicConsole.WriteLine("BasicInPipe > ReadPipe: Unhandled!"); ExceptionMethods.Throw(new Exceptions.RWUnhandledException("BasicInPipe : Read Pipe unexpected unhandled!")); break; case SystemCallResults.Fail: //BasicConsole.WriteLine("BasicInPipe > ReadPipe: Failed!"); if (Blocking) { ExceptionMethods.Throw(new Exceptions.RWFailedException("BasicInPipe : Write Pipe unexpected failed! (Blocking call)")); } else { ExceptionMethods.Throw(new Exceptions.RWFailedException("BasicInPipe : Write Pipe failed. (Non-blocking call)")); } break; case SystemCallResults.OK: //BasicConsole.WriteLine("BasicInPipe > ReadPipe: Succeeded."); break; default: //BasicConsole.WriteLine("BasicInPipe > ReadPipe: Unexpected system call result!"); ExceptionMethods.Throw(new Exceptions.RWUnhandledException("BasicInPipe : Read Pipe unexpected result!")); break; } } else { ExceptionMethods.Throw(new FOS_System.Exceptions.ArgumentException("BasicInPipe : Couldn't allocate memory to read from pipe!")); } } finally { if (ReadPipeRequestPtr != null) { Heap.Free(ReadPipeRequestPtr); } } return(BytesRead); }
public static SystemCallResults ReadPipe(Pipes.ReadPipeRequest *Request, out int BytesRead) { uint Return1 = 0; uint Return2 = 0; uint Return3 = 0; uint Return4 = 0; Call(SystemCallNumbers.ReadPipe, (uint)Request, 0, 0, ref Return1, ref Return2, ref Return3, ref Return4); BytesRead = (int)Return2; 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: #if DSC_TRACE BasicConsole.WriteLine("DSC: Start Thread"); #endif Return2 = CallerProcess.CreateThread((ThreadStartMethod)Utilities.ObjectUtilities.GetObject((void *)Param1), "[From sys call]").Id; #if DSC_TRACE BasicConsole.WriteLine("DSC: Start Thread - done."); #endif result = SystemCallResults.OK; break; case SystemCallNumbers.RegisterPipeOutpoint: { #if DSC_TRACE BasicConsole.WriteLine("DSC: Register Pipe Outpoint"); #endif 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; } #if DSC_TRACE BasicConsole.WriteLine("DSC: Register Pipe Outpoint - done."); #endif } break; case SystemCallNumbers.GetNumPipeOutpoints: { #if DSC_TRACE BasicConsole.WriteLine("DSC: Get Num Pipe Outpoints"); #endif 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; } #if DSC_TRACE BasicConsole.WriteLine("DSC: Get Num Pipe Outpoints - done"); #endif } break; case SystemCallNumbers.GetPipeOutpoints: { #if DSC_TRACE BasicConsole.WriteLine("DSC: Get Pipe Outpoints"); #endif bool obtained = Pipes.PipeManager.GetPipeOutpoints(CallerProcess, (Pipes.PipeClasses)Param1, (Pipes.PipeSubclasses)Param2, (Pipes.PipeOutpointsRequest *)Param3); if (obtained) { result = SystemCallResults.OK; } else { result = SystemCallResults.Fail; } #if DSC_TRACE BasicConsole.WriteLine("DSC: Get Pipe Outpoints - done"); #endif } break; case SystemCallNumbers.CreatePipe: { #if DSC_TRACE BasicConsole.WriteLine("DSC: Create Pipe"); #endif bool created = Pipes.PipeManager.CreatePipe(CallerProcess.Id, Param1, (Pipes.CreatePipeRequest *)Param2); if (created) { result = SystemCallResults.OK; } else { result = SystemCallResults.Fail; } #if DSC_TRACE BasicConsole.WriteLine("DSC: Create Pipe - done"); #endif } break; case SystemCallNumbers.WaitOnPipeCreate: { #if DSC_TRACE BasicConsole.WriteLine("DSC: Wait On Pipe Create"); #endif bool waiting = Pipes.PipeManager.WaitOnPipeCreate(CallerProcess.Id, CallerThread.Id, (Pipes.PipeClasses)Param1, (Pipes.PipeSubclasses)Param2); if (waiting) { result = SystemCallResults.Deferred; } else { result = SystemCallResults.Fail; } #if DSC_TRACE BasicConsole.WriteLine("DSC: Wait On Pipe Create - done"); #endif } break; case SystemCallNumbers.ReadPipe: { #if DSC_TRACE BasicConsole.WriteLine("DSC: Read Pipe"); #endif // Need access to calling process' memory to be able to read values from request structure ProcessManager.EnableKernelAccessToProcessMemory(CallerProcess); Pipes.ReadPipeRequest *RequestPtr = (Pipes.ReadPipeRequest *)Param1; int PipeId = RequestPtr->PipeId; bool Blocking = RequestPtr->Blocking; ProcessManager.DisableKernelAccessToProcessMemory(CallerProcess); Pipes.PipeManager.RWResults RWResult = Pipes.PipeManager.ReadPipe(PipeId, 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; } #if DSC_TRACE BasicConsole.WriteLine("DSC: Read Pipe - done"); #endif } break; case SystemCallNumbers.WritePipe: { #if DSC_TRACE BasicConsole.WriteLine("DSC: Write Pipe"); #endif // Need access to calling process' memory to be able to read values from request structure ProcessManager.EnableKernelAccessToProcessMemory(CallerProcess); Pipes.ReadPipeRequest *RequestPtr = (Pipes.ReadPipeRequest *)Param1; int PipeId = RequestPtr->PipeId; bool Blocking = RequestPtr->Blocking; ProcessManager.DisableKernelAccessToProcessMemory(CallerProcess); Pipes.PipeManager.RWResults RWResult = Pipes.PipeManager.WritePipe(PipeId, 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; } #if DSC_TRACE BasicConsole.WriteLine("DSC: Write Pipe - done"); #endif } break; default: #if DSC_TRACE BasicConsole.WriteLine("DSC: Unrecognised call number."); BasicConsole.WriteLine((uint)syscallNumber); #endif break; } return(result); }