Ejemplo n.º 1
0
        /// <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);
                }
            }
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 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:
                //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);
        }