using System; using System.IO; using AppModule.InterProcessComm; namespace AppModule.NamedPipes { #region Comments /// /// An abstract class, which defines the methods for creating named pipes /// connections, reading and writing data. /// /// /// This class is inherited by /// ClientPipeConnection /// and ServerPipeConnection /// classes, used for client and server applications respectively, which communicate /// using NamesPipes. /// #endregion public abstract class APipeConnection : IInterProcessConnection { #region Comments /// /// A PipeHandle object containing /// the native pipe handle. /// #endregion protected PipeHandle Handle = new PipeHandle(); #region Comments /// /// The name of the named pipe. /// /// /// This name is used for creating a server pipe and connecting client ones to it. /// #endregion protected string Name; #region Comments /// /// Boolean field used by the IDisposable implementation. /// #endregion protected bool disposed = false; #region Comments /// /// The maximum bytes that will be read from the pipe connection. /// /// /// This field could be used if the maximum length of the client message /// is known and we want to implement some security, which prevents the /// server from reading larger messages. /// #endregion protected int maxReadBytes; #region Comments /// /// Reads a message from the pipe connection and converts it to a string /// using the UTF8 encoding. /// /// /// See the NamedPipeWrapper.Read /// method for an explanation of the message format. /// /// The UTF8 encoded string representation of the data. #endregion public string Read() { CheckIfDisposed(); return NamedPipeWrapper.Read(Handle, maxReadBytes); } #region Comments /// /// Reads a message from the pipe connection. /// /// /// See the NamedPipeWrapper.ReadBytes /// method for an explanation of the message format. /// /// The bytes read from the pipe connection. #endregion public byte[] ReadBytes() { CheckIfDisposed(); return NamedPipeWrapper.ReadBytes(Handle, maxReadBytes); } #region Comments /// /// Writes a string to the pipe connection/ /// /// The text to write. #endregion public void Write(string text) { CheckIfDisposed(); NamedPipeWrapper.Write(Handle, text); } #region Comments /// /// Writes an array of bytes to the pipe connection. /// /// The bytes array. #endregion public void WriteBytes(byte[] bytes) { CheckIfDisposed(); NamedPipeWrapper.WriteBytes(Handle, bytes); } #region Comments /// /// Closes the pipe connection. /// #endregion public abstract void Close(); #region Comments /// /// Connects a pipe connection. /// #endregion public abstract void Connect(); #region Comments /// /// Disposes a pipe connection by closing the underlying native handle. /// #endregion public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } #region Comments /// /// Disposes a pipe connection by closing the underlying native handle. /// /// A boolean indicating how the method is called. #endregion protected void Dispose(bool disposing) { if(!this.disposed) { NamedPipeWrapper.Close(this.Handle); } disposed = true; } #region Comments /// /// Checks if the pipe connection is disposed. /// /// /// This check is done before performing any pipe operations. /// #endregion public void CheckIfDisposed() { if(this.disposed) { throw new ObjectDisposedException("The Pipe Connection is disposed."); } } #region Comments /// /// Gets the pipe connection state from the PipeHandle /// object. /// /// The pipe connection state. #endregion public InterProcessConnectionState GetState() { CheckIfDisposed(); return this.Handle.State; } #region Comments /// /// Retrieved the operating system native handle for the pipe connection. /// #endregion public int NativeHandle { get { CheckIfDisposed(); return (int)this.Handle.Handle; } } public int GetLocalUserID(ref int lowPart, ref int highPart, ref string sSIDString) { return ImpersonateWrapper.GetLocalUserID(this.Handle, ref lowPart, ref highPart, ref sSIDString); } } }