Exemplo n.º 1
0
        /// <summary>
        /// Attempts to add the specified thread to the list of threads waiting on a pipe to be created for the specified outpoint.
        /// </summary>
        /// <param name="OutProcessId">The Id of the process which owns the outpoint and the thread to block.</param>
        /// <param name="OutThreadId">The Id of the thread to block.</param>
        /// <param name="Class">The class of the outpoint.</param>
        /// <param name="Subclass">The subclass of the outpoint.</param>
        /// <returns>True if the request was successful. Otherwise, false.</returns>
        public static bool WaitOnPipeCreate(uint OutProcessId, uint OutThreadId, PipeClasses Class, PipeSubclasses Subclass)
        {
            // Validate inputs
            //   - Check the process exists
            //   - Check the thread exists
            Process OutProcess = ProcessManager.GetProcessById(OutProcessId);

            if (OutProcess == null)
            {
                return(false);
            }
            Thread OutThread = ProcessManager.GetThreadById(OutThreadId, OutProcess);

            if (OutThread == null)
            {
                return(false);
            }

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

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

            // Mark the outpoint as being waited on by the specified process/thread
            outpoint.WaitingThreads.Add(((UInt64)OutProcessId << 32) | OutThreadId);

            return(true);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Attempts to get descriptors of the outpoints of the specified class and subclass.
        /// </summary>
        /// <param name="CallerProcess">The process which owns the memory containing the <paramref cref="request"/>.</param>
        /// <param name="Class">The class of outpoint to search for.</param>
        /// <param name="Subclass">The subclass of outpoint to search for.</param>
        /// <param name="request">A pointer to the request structure (Also used to store the result(s)).</param>
        /// <returns>True if the request was successful. Otherwise, false.</returns>
        public static bool GetPipeOutpoints(Process CallerProcess, PipeClasses Class, PipeSubclasses Subclass, PipeOutpointsRequest *request)
        {
            // Validate inputs & get caller process
            if (CallerProcess == null)
            {
                return(false);
            }

            // Need access to the request structure
            ProcessManager.EnableKernelAccessToProcessMemory(CallerProcess);

            bool OK = true;

            // More validate inputs
            //  - Check request exists (should've been pre-allocated by caller)
            //  - Check request->Outpoints exists (should've been pre-allocated by caller)
            //  - Check request->MaxDescriptors was set correctly
            if (request == null)
            {
                // Should have been pre-allocated by the calling thread (/process)
                OK = false;
            }
            else if (request->Outpoints == null)
            {
                // Should have been pre-allocated by the calling thread (/process)
                OK = false;
            }
            else if (request->MaxDescriptors == 0)
            {
                // Not technically an error but let's not waste time processing 0 descriptors
                OK = true;
            }

            if (OK)
            {
                // Search for all outpoints of correct class and subclass
                int maxDescriptors = request->MaxDescriptors;
                for (int i = 0, j = 0; i < PipeOutpoints.Count && j < maxDescriptors; i++)
                {
                    PipeOutpoint anOutpoint = (PipeOutpoint)PipeOutpoints[i];

                    if (anOutpoint.Class == Class &&
                        anOutpoint.Subclass == Subclass &&
                        (anOutpoint.MaxConnections == PipeConstants.UnlimitedConnections ||
                         anOutpoint.NumConnections < anOutpoint.MaxConnections))
                    {
                        // Set the resultant values
                        request->Outpoints[j++].ProcessId = anOutpoint.ProcessId;
                    }
                }
            }

            ProcessManager.DisableKernelAccessToProcessMemory(CallerProcess);

            return(OK);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Creates a new pipe.
        /// </summary>
        /// <param name="AnId">The pipe's Id.</param>
        /// <param name="outpoint">The outpoint of the pipe.</param>
        /// <param name="inpoint">The inpoint of the pipe.</param>
        /// <param name="BufferSize">The size of buffer to use within the pipe.</param>
        public Pipe(int AnId, PipeOutpoint outpoint, PipeInpoint inpoint, int BufferSize)
        {
            Id       = AnId;
            Outpoint = outpoint;
            Inpoint  = inpoint;

            Buffer        = new byte[BufferSize];
            DataAvailable = 0;

            ThreadsWaitingToRead  = new UInt32Queue(5, true);
            ThreadsWaitingToWrite = new UInt32Queue(5, true);
            SizesWaitingToWrite   = new UInt32Queue(5, true);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Gets the outpoint from the specified process of the desired class and subclass.
        /// </summary>
        /// <param name="OutProcessId">The Id of the process which owns the outpoint.</param>
        /// <param name="Class">The class of the outpoint.</param>
        /// <param name="Subclass">The subclass of the outpoint.</param>
        /// <returns>The outpoint or null if not found.</returns>
        private static PipeOutpoint GetOutpoint(uint OutProcessId, PipeClasses Class, PipeSubclasses Subclass)
        {
            PipeOutpoint outpoint = null;

            for (int i = 0; i < PipeOutpoints.Count; i++)
            {
                PipeOutpoint anOutpoint = (PipeOutpoint)PipeOutpoints[i];

                if (anOutpoint.ProcessId == OutProcessId &&
                    anOutpoint.Class == Class &&
                    anOutpoint.Subclass == Subclass)
                {
                    outpoint = anOutpoint;
                    break;
                }
            }
            return(outpoint);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Wakes all threads waiting on a pipe to be created for the specified outpoint.
        /// </summary>
        /// <param name="outpoint">The outpoint to wake waiting threads of.</param>
        /// <param name="newPipeId">The Id of the newly created pipe.</param>
        private static void WakeWaitingThreads(PipeOutpoint outpoint, int newPipeId)
        {
            while (outpoint.WaitingThreads.Count > 0)
            {
                UInt64 identifier = outpoint.WaitingThreads[0];
                outpoint.WaitingThreads.RemoveAt(0);

                UInt32 processId = (UInt32)(identifier >> 32);
                UInt32 threadId  = (UInt32)(identifier);

                Process process = ProcessManager.GetProcessById(processId);
                Thread  thread  = ProcessManager.GetThreadById(threadId, process);

                thread.Return1 = (uint)SystemCallResults.OK;
                thread.Return2 = (uint)newPipeId;
                thread.Return3 = 0;
                thread.Return4 = 0;
                thread._Wake();
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Attempts to register a pipe outpoint.
        /// </summary>
        /// <param name="OutProcessId">The Id of the process which should own the outpoint.</param>
        /// <param name="Class">The class of pipe the outpoint will create.</param>
        /// <param name="Subclass">The subclass of pipe the outpoint will create.</param>
        /// <param name="MaxConnections">The maximum number of connections allowed to the outpoint. Also see <see cref="PipeConstants.UnlimitedConnections"/>.</param>
        /// <param name="outpoint">Out : The newly created outpoint (or null if the request fails).</param>
        /// <returns>True if the request was successful. Otherwise, false.</returns>
        /// <seealso cref="PipeConstants.UnlimitedConnections"/>
        public static bool RegisterPipeOutpoint(uint OutProcessId, PipeClasses Class, PipeSubclasses Subclass, int MaxConnections, out PipeOutpoint outpoint)
        {
            // Validate inputs
            //  - Check process exists (if it doesn't then hmm...)
            //  - Check MaxConnections > 0 (0 or negative number of connections would be insane)
            if (ProcessManager.GetProcessById(OutProcessId) == null)
            {
                outpoint = null;
                return(false);
            }
            else if (MaxConnections <= 0 && MaxConnections != PipeConstants.UnlimitedConnections)
            {
                outpoint = null;
                return(false);
            }

            // Check no existing outpoints of the same type exist for the specified process
            for (int i = 0; i < PipeOutpoints.Count; i++)
            {
                PipeOutpoint anOutpoint = (PipeOutpoint)PipeOutpoints[i];
                if (anOutpoint.ProcessId == OutProcessId &&
                    anOutpoint.Class == Class &&
                    anOutpoint.Subclass == Subclass)
                {
                    // Set the resultant outpoint to the existing outpoint
                    outpoint = anOutpoint;
                    // Return true because the outpoint exists (even though we didn't create a new one)
                    return(true);
                }
            }

            // None exists? Create a new one
            outpoint = new PipeOutpoint(OutProcessId, Class, Subclass, MaxConnections);
            // Add it to our complete list outpoints
            PipeOutpoints.Add(outpoint);

            // Return true because the outpoint exists (a new one was created)
            return(true);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Attempts to get the number of outpoints of the specified class and subclass.
        /// </summary>
        /// <param name="Class">The class of outpoint to search for.</param>
        /// <param name="Subclass">The subclass of outpoint to search for.</param>
        /// <param name="numOutpoints">Out : The number of outpoints of the specified class and subclass.</param>
        /// <returns>True if the request was successful. Otherwise, false.</returns>
        public static bool GetNumPipeOutpoints(PipeClasses Class, PipeSubclasses Subclass, out int numOutpoints)
        {
            // Initialise count to zero
            numOutpoints = 0;

            // Search for outpoints of correct class and subclass, incrementing count as we go
            for (int i = 0; i < PipeOutpoints.Count; i++)
            {
                PipeOutpoint anOutpoint = (PipeOutpoint)PipeOutpoints[i];

                if (anOutpoint.Class == Class &&
                    anOutpoint.Subclass == Subclass &&
                    (anOutpoint.MaxConnections == PipeConstants.UnlimitedConnections ||
                     anOutpoint.NumConnections < anOutpoint.MaxConnections))
                {
                    numOutpoints++;
                }
            }

            // This method will always succeed unless it throws an exception
            //  - A count result of zero is valid / success
            return(true);
        }
Exemplo n.º 8
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);
            }

            // Need access to the request structure
            bool ShouldDisableKernelAccessToProcessMemory = true;

            ProcessManager.EnableKernelAccessToProcessMemory(InProcessId);

            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;

                    ShouldDisableKernelAccessToProcessMemory = false;
                    ProcessManager.DisableKernelAccessToProcessMemory(InProcessId);

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

            if (ShouldDisableKernelAccessToProcessMemory)
            {
                ProcessManager.DisableKernelAccessToProcessMemory(InProcessId);
            }

            return(OK);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Creates a new pipe.
        /// </summary>
        /// <param name="AnId">The pipe's Id.</param>
        /// <param name="outpoint">The outpoint of the pipe.</param>
        /// <param name="inpoint">The inpoint of the pipe.</param>
        /// <param name="BufferSize">The size of buffer to use within the pipe.</param>
        public Pipe(int AnId, PipeOutpoint outpoint, PipeInpoint inpoint, int BufferSize)
        {
            Id = AnId;
            Outpoint = outpoint;
            Inpoint = inpoint;

            Buffer = new byte[BufferSize];
            DataAvailable = 0;

            ThreadsWaitingToRead = new UInt32Queue(5, true);
            ThreadsWaitingToWrite = new UInt32Queue(5, true);
            SizesWaitingToWrite = new UInt32Queue(5, true);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Attempts to register a pipe outpoint.
        /// </summary>
        /// <param name="OutProcessId">The Id of the process which should own the outpoint.</param>
        /// <param name="Class">The class of pipe the outpoint will create.</param>
        /// <param name="Subclass">The subclass of pipe the outpoint will create.</param>
        /// <param name="MaxConnections">The maximum number of connections allowed to the outpoint. Also see <see cref="PipeConstants.UnlimitedConnections"/>.</param>
        /// <param name="outpoint">Out : The newly created outpoint (or null if the request fails).</param>
        /// <returns>True if the request was successful. Otherwise, false.</returns>
        /// <seealso cref="PipeConstants.UnlimitedConnections"/>
        public static bool RegisterPipeOutpoint(uint OutProcessId, PipeClasses Class, PipeSubclasses Subclass, int MaxConnections, out PipeOutpoint outpoint)
        {
            // Validate inputs
            //  - Check process exists (if it doesn't then hmm...)
            //  - Check MaxConnections > 0 (0 or negative number of connections would be insane)
            if (ProcessManager.GetProcessById(OutProcessId) == null)
            {
                outpoint = null;
                return false;
            }
            else if (MaxConnections <= 0 && MaxConnections != PipeConstants.UnlimitedConnections)
            {
                outpoint = null;
                return false;
            }

            // Check no existing outpoints of the same type exist for the specified process
            for (int i = 0; i < PipeOutpoints.Count; i++)
            {
                PipeOutpoint anOutpoint = (PipeOutpoint)PipeOutpoints[i];
                if (anOutpoint.ProcessId == OutProcessId &&
                    anOutpoint.Class == Class &&
                    anOutpoint.Subclass == Subclass)
                {
                    // Set the resultant outpoint to the existing outpoint
                    outpoint = anOutpoint;
                    // Return true because the outpoint exists (even though we didn't create a new one)
                    return true;
                }
            }

            // None exists? Create a new one
            outpoint = new PipeOutpoint(OutProcessId, Class, Subclass, MaxConnections);
            // Add it to our complete list outpoints
            PipeOutpoints.Add(outpoint);

            // Return true because the outpoint exists (a new one was created)
            return true;
        }
Exemplo n.º 11
0
        /// <summary>
        /// Wakes all threads waiting on a pipe to be created for the specified outpoint.
        /// </summary>
        /// <param name="outpoint">The outpoint to wake waiting threads of.</param>
        /// <param name="newPipeId">The Id of the newly created pipe.</param>
        private static void WakeWaitingThreads(PipeOutpoint outpoint, int newPipeId)
        {
            while (outpoint.WaitingThreads.Count > 0)
            {
                UInt64 identifier = outpoint.WaitingThreads[0];
                outpoint.WaitingThreads.RemoveAt(0);

                UInt32 processId = (UInt32)(identifier >> 32);
                UInt32 threadId = (UInt32)(identifier);

                Process process = ProcessManager.GetProcessById(processId);
                Thread thread = ProcessManager.GetThreadById(threadId, process);

                thread.Return1 = (uint)SystemCallResults.OK;
                thread.Return2 = (uint)newPipeId;
                thread.Return3 = 0;
                thread.Return4 = 0;
                thread._Wake();
            }
        }