예제 #1
1
        /// <summary>
        /// Process the read/write queues of the specified pipe.
        /// </summary>
        /// <param name="pipe">The pipe to process.</param>
        /// <param name="OutProcess">The process which owns the pipe's outpoint.</param>
        /// <param name="InProcess">The process which owns the pipe's inpoint.</param>
        private static void ProcessPipeQueue(Pipe pipe, Process OutProcess, Process InProcess)
        {
#if PIPES_TRACE
            BasicConsole.WriteLine("ProcessPipeQueue: Checking first loop condition");
#endif
            while ((pipe.AreThreadsWaitingToWrite() && pipe.CanWrite()) || (pipe.AreThreadsWaitingToRead() && pipe.CanRead()))
            {
#if PIPES_TRACE
                BasicConsole.WriteLine("ProcessPipeQueue: Loop start");
#endif
                if (pipe.AreThreadsWaitingToWrite() && pipe.CanWrite())
                {
#if PIPES_TRACE
                    BasicConsole.WriteLine("ProcessPipeQueue: Pipe can write");
#endif

                    /*  - Dequeue thread to write
                     *  - Find thread to write
                     *  - Load pointer to request structure from thread's stack
                     *  - Write pipe
                     *  - Setup return values for thread
                     *  - Wake thread
                     *  - Loop back
                     */

#if PIPES_TRACE
                    BasicConsole.WriteLine("ProcessPipeQueue: Dequeuing out thread id");
#endif
                    UInt32 ThreadId;
                    if (!pipe.DequeueToWrite(out ThreadId))
                    {
                        break;
                    }

#if PIPES_TRACE
                    BasicConsole.WriteLine("ProcessPipeQueue: Getting out thread");
#endif
                    Thread WriteThread = ProcessManager.GetThreadById(ThreadId, OutProcess);
                    if (WriteThread == null)
                    {
                        break;
                    }

#if PIPES_TRACE
                    BasicConsole.WriteLine("ProcessPipeQueue: Writing pipe");
#endif
                    WritePipeRequest* Request = (WritePipeRequest*)WriteThread.Param1;
                    bool Successful = pipe.Write(Request->InBuffer, Request->Offset, Request->Length);
                    if (Successful)
                    {
#if PIPES_TRACE
                        BasicConsole.WriteLine("ProcessPipeQueue: Write successful");
#endif
                        WriteThread.Return1 = (uint)SystemCallResults.OK;
                        WriteThread._Wake();
                    }
                    else
                    {
#if PIPES_TRACE
                        BasicConsole.WriteLine("ProcessPipeQueue: Write failed");
#endif
                        WriteThread.Return1 = (uint)SystemCallResults.Fail;
                        WriteThread._Wake();
                    }
                }
                else if (pipe.AreThreadsWaitingToRead() && pipe.CanRead())
                {
#if PIPES_TRACE
                    BasicConsole.WriteLine("ProcessPipeQueue: Pipe can read");
#endif

                    /*  - Dequeue thread to read
                     *  - Find thread to read
                     *  - Load pointer to request structure from thread's stack
                     *  - Read pipe
                     *  - Setup return values for thread
                     *  - Wake thread
                     *  - Loop back
                    */

#if PIPES_TRACE
                    BasicConsole.WriteLine("ProcessPipeQueue: Dequeuing in thread id");
#endif
                    UInt32 ThreadId;
                    if (!pipe.DequeueToRead(out ThreadId))
                    {
                        break;
                    }

#if PIPES_TRACE
                    BasicConsole.WriteLine("ProcessPipeQueue: Getting in thread");
#endif
                    Thread ReadThread = ProcessManager.GetThreadById(ThreadId, InProcess);
                    if (ReadThread == null)
                    {
                        break;
                    }

#if PIPES_TRACE
                    BasicConsole.WriteLine("ProcessPipeQueue: Reading pipe");
#endif
                    ReadPipeRequest* Request = (ReadPipeRequest*)ReadThread.Param1;
                    int BytesRead;
                    bool Successful = pipe.Read(Request->OutBuffer, Request->Offset, Request->Length, out BytesRead);
                    if (Successful)
                    {
#if PIPES_TRACE
                        BasicConsole.WriteLine("ProcessPipeQueue: Read successful");
#endif
                        ReadThread.Return1 = (uint)SystemCallResults.OK;
                        ReadThread.Return2 = (uint)BytesRead;
                        ReadThread._Wake();
                    }
                    else
                    {
#if PIPES_TRACE
                        BasicConsole.WriteLine("ProcessPipeQueue: Read failed");
#endif
                        ReadThread.Return1 = (uint)SystemCallResults.Fail;
                        ReadThread._Wake();
                    }
                }

#if PIPES_TRACE
                BasicConsole.WriteLine("ProcessPipeQueue: Looping...");
#endif
            }
        }
예제 #2
0
 /// <summary>
 /// Determines whether the specified process is allowed to read from the specified pipe.
 /// </summary>
 /// <param name="ThePipe">The pipe to check.</param>
 /// <param name="ProcessId">The Id of the process to check.</param>
 /// <returns>True if the process is allowed. Otherwise, false.</returns>
 private static bool AllowedToReadPipe(Pipe ThePipe, uint ProcessId)
 {
     return ThePipe.Inpoint.ProcessId == ProcessId;
 }
예제 #3
0
 /// <summary>
 /// Determines whether the specified process is allowed to write to the specified pipe.
 /// </summary>
 /// <param name="ThePipe">The pipe to check.</param>
 /// <param name="ProcessId">The Id of the process to check.</param>
 /// <returns>True if the process is allowed. Otherwise, false.</returns>
 private static bool AllowedToWritePipe(Pipe ThePipe, uint ProcessId)
 {
     return ThePipe.Outpoint.ProcessId == ProcessId;
 }
예제 #4
0
        /// <summary>
        /// Attempts to create a new pipe.
        /// </summary>
        /// <param name="InProcessId">The Id of the target process which owns the inpoint.</param>
        /// <param name="OutProcessId">The Id of the target process which owns the outpoint.</param>
        /// <param name="request">A pointer to the request structure (Also used to store the result).</param>
        /// <returns>True if the request was successful. Otherwise, false.</returns>
        public static bool CreatePipe(uint InProcessId, uint OutProcessId, CreatePipeRequest* request)
        {
            // Validate inputs
            //  - Check out process exists
            //  - Check in process exists
            //  - Check request isn't null (should've been pre-allocated)
            Process InProcess = ProcessManager.GetProcessById(InProcessId);
            if (InProcess == null)
            {
                return false;
            }
            else if (ProcessManager.GetProcessById(OutProcessId) == null)
            {
                return false;
            }
            else if (request == null)
            {
                return false;
            }

            // Merge memory layouts 
            //  so we can access the request structure
            MemoryLayout OriginalMemoryLayout = SystemCallsHelpers.EnableAccessToMemoryOfProcess(InProcess);
            bool OK = true;

            // Find the outpoint
            PipeOutpoint outpoint = GetOutpoint(OutProcessId, request->Class, request->Subclass);

            // Check that we actually found the outpoint
            if (outpoint == null)
            {
                OK = false;
            }

            if (OK)
            {
                // Check there are sufficient connections available
                if (outpoint.NumConnections >= outpoint.MaxConnections &&
                    outpoint.MaxConnections != PipeConstants.UnlimitedConnections)
                {
                    OK = false;
                }

                if (OK)
                {
                    // Create new inpoint
                    PipeInpoint inpoint = new PipeInpoint(InProcessId, request->Class, request->Subclass);

                    // Create new pipe
                    Pipe pipe = new Pipe(PipeIdGenerator++, outpoint, inpoint, request->BufferSize);
                    // Add new pipe to list of pipes
                    Pipes.Add(pipe);
                    // Increment number of connections to the outpoint
                    outpoint.NumConnections++;

                    // Set result information
                    request->Result.Id = pipe.Id;

                    // Wake any threads (/processes) which were waiting on a pipe to be created
                    WakeWaitingThreads(outpoint, pipe.Id);
                }
            }

            SystemCallsHelpers.DisableAccessToMemoryOfProcess(OriginalMemoryLayout);

            return OK;
        }