/// <summary> /// Creates and registers a new outpoint of the specified class and subclass. /// </summary> /// <param name="aClass">The class of pipe allowed to connect to the outpoint.</param> /// <param name="aSubclass">The subclass of pipe allowed to connect to the outpoint.</param> /// <param name="MaxConnections"> /// The maximum number of connections allowed. Use <see cref="PipeConstants.UnlimitedConnections"/> for unlimited connections. /// </param> public BasicOutpoint(PipeClasses aClass, PipeSubclasses aSubclass, int MaxConnections) { Class = aClass; Subclass = aSubclass; SystemCallResults SysCallResult = SystemCalls.RegisterPipeOutpoint(Class, Subclass, MaxConnections); switch (SysCallResult) { case SystemCallResults.Unhandled: //BasicConsole.WriteLine("BasicOutPipe > RegisterPipeOutpoint: Unhandled!"); ExceptionMethods.Throw(new FOS_System.Exceptions.ArgumentException("BasicOutPipe : Register Pipe Outpoint system call unhandled!")); break; case SystemCallResults.Fail: //BasicConsole.WriteLine("BasicOutPipe > RegisterPipeOutpoint: Failed!"); ExceptionMethods.Throw(new FOS_System.Exceptions.ArgumentException("BasicOutPipe : Register Pipe Outpoint system call failed!")); break; case SystemCallResults.OK: //BasicConsole.WriteLine("BasicOutPipe > RegisterPipeOutpoint: Succeeded."); break; default: //BasicConsole.WriteLine("BasicOutPipe > RegisterPipeOutpoint: Unexpected system call result!"); ExceptionMethods.Throw(new FOS_System.Exceptions.ArgumentException("BasicOutPipe : Register Pipe Outpoint system call unexpected result!")); break; } }
/// <summary> /// Initialises a new instance of an outpoint. /// </summary> /// <param name="OwnerProcessId">The Id of the process which owns the outpoint.</param> /// <param name="pipeClass">The class of pipe which can connect to the outpoint.</param> /// <param name="pipeSubclass">The subclass of pipe which can connect to the outpoint.</param> /// <param name="MaximumConnections">The maximum number of connections allowed to the outpoint. Also see <see cref="PipeConstants.UnlimitedConnections"/>.</param> /// <seealso cref="PipeConstants.UnlimitedConnections"/> public PipeOutpoint(uint OwnerProcessId, PipeClasses pipeClass, PipeSubclasses pipeSubclass, int MaximumConnections) { ProcessId = OwnerProcessId; Class = pipeClass; Subclass = pipeSubclass; MaxConnections = MaximumConnections; WaitingThreads = new UInt64List(); }
/// <summary> /// Creates and connects a new pipe to the specified target process. /// </summary> /// <param name="anOutProcessId">The target process to connect to.</param> /// <param name="aClass">The class of pipe to create.</param> /// <param name="aSubclass">The subclass of pipe to create.</param> /// <param name="aBufferSize">The size of buffer to use within the core OS.</param> public BasicInpoint(uint anOutProcessId, PipeClasses aClass, PipeSubclasses aSubclass, int aBufferSize) { OutProcessId = anOutProcessId; Class = aClass; Subclass = aSubclass; BufferSize = aBufferSize; Pipes.CreatePipeRequest *RequestPtr = (Pipes.CreatePipeRequest *)Heap.AllocZeroed((uint)sizeof(Pipes.CreatePipeRequest), "BasicInPipe : Alloc CreatePipeRequest"); if (RequestPtr != null) { try { RequestPtr->BufferSize = aBufferSize; RequestPtr->Class = aClass; RequestPtr->Subclass = aSubclass; SystemCallResults SysCallResult = SystemCalls.CreatePipe(anOutProcessId, RequestPtr); switch (SysCallResult) { case SystemCallResults.Unhandled: //BasicConsole.WriteLine("BasicInPipe > CreatePipe: Unhandled!"); break; case SystemCallResults.Fail: //BasicConsole.WriteLine("BasicInPipe > CreatePipe: Failed!"); break; case SystemCallResults.OK: //BasicConsole.WriteLine("BasicInPipe > CreatePipe: Succeeded."); PipeId = RequestPtr->Result.Id; //BasicConsole.Write("BasicInPipe > CreatePipe: New pipe id = "); //BasicConsole.WriteLine(PipeId); break; default: //BasicConsole.WriteLine("BasicInPipe > CreatePipe: Unexpected system call result!"); break; } } finally { Heap.Free(RequestPtr); } } else { ExceptionMethods.Throw(new FOS_System.Exceptions.ArgumentException("BasicInPipe : Couldn't allocate memory to create pipe!")); //BasicConsole.WriteLine("BasicInPipe > RequestPtr null! No memory allocated."); } }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <summary> /// Creates and connects a new pipe to the specified target process. /// </summary> /// <param name="anOutProcessId">The target process to connect to.</param> /// <param name="aClass">The class of pipe to create.</param> /// <param name="aSubclass">The subclass of pipe to create.</param> /// <param name="aBufferSize">The size of buffer to use within the core OS.</param> public BasicInpoint(uint anOutProcessId, PipeClasses aClass, PipeSubclasses aSubclass, int aBufferSize) { OutProcessId = anOutProcessId; Class = aClass; Subclass = aSubclass; BufferSize = aBufferSize; Pipes.CreatePipeRequest* RequestPtr = (Pipes.CreatePipeRequest*)Heap.AllocZeroed((uint)sizeof(Pipes.CreatePipeRequest), "BasicInPipe : Alloc CreatePipeRequest"); if (RequestPtr != null) { try { RequestPtr->BufferSize = aBufferSize; RequestPtr->Class = aClass; RequestPtr->Subclass = aSubclass; SystemCallResults SysCallResult = SystemCalls.CreatePipe(anOutProcessId, RequestPtr); switch (SysCallResult) { case SystemCallResults.Unhandled: //BasicConsole.WriteLine("BasicInPipe > CreatePipe: Unhandled!"); break; case SystemCallResults.Fail: //BasicConsole.WriteLine("BasicInPipe > CreatePipe: Failed!"); break; case SystemCallResults.OK: //BasicConsole.WriteLine("BasicInPipe > CreatePipe: Succeeded."); PipeId = RequestPtr->Result.Id; //BasicConsole.Write("BasicInPipe > CreatePipe: New pipe id = "); //BasicConsole.WriteLine(PipeId); break; default: //BasicConsole.WriteLine("BasicInPipe > CreatePipe: Unexpected system call result!"); break; } } finally { Heap.Free(RequestPtr); } } else { ExceptionMethods.Throw(new FOS_System.Exceptions.ArgumentException("BasicInPipe : Couldn't allocate memory to create pipe!")); //BasicConsole.WriteLine("BasicInPipe > RequestPtr null! No memory allocated."); } }
/// <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; }
/// <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; }
/// <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; } // Merge memory layouts // so we can access the request structure MemoryLayout OriginalMemoryLayout = SystemCallsHelpers.EnableAccessToMemoryOfProcess(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; } } } SystemCallsHelpers.DisableAccessToMemoryOfProcess(OriginalMemoryLayout); return OK; }
/// <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; }
/// <summary> /// Initialises a new inpoint instance. /// </summary> /// <param name="OwnerProcessId">The process which owns the inpoint.</param> /// <param name="pipeClass">The class of pipe connected to the inpoint.</param> /// <param name="pipeSubclass">The subclass of pipe connected to the inpoint.</param> public PipeInpoint(uint OwnerProcessId, PipeClasses pipeClass, PipeSubclasses pipeSubclass) { ProcessId = OwnerProcessId; Class = pipeClass; Subclass = pipeSubclass; }
/// <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); }
/// <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; }