Example #1
0
        /// <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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }