/*********************************************************************** * * Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; version 2.1 * of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, Novell, Inc. * * To contact Novell about this file by physical or electronic mail, * you may find current contact information at www.novell.com. * ***********************************************************************/ using System; using System.IO; using AppModule.InterProcessComm; namespace AppModule.NamedPipes { #region Comments /// <summary> /// An abstract class, which defines the methods for creating named pipes /// connections, reading and writing data. /// </summary> /// <remarks> /// This class is inherited by /// <see cref="AppModule.NamedPipes.ClientPipeConnection">ClientPipeConnection</see> /// and <see cref="AppModule.NamedPipes.ServerPipeConnection">ServerPipeConnection</see> /// classes, used for client and server applications respectively, which communicate /// using NamesPipes. /// </remarks> #endregion public abstract class APipeConnection : IInterProcessConnection { #region Comments /// <summary> /// A <see cref="AppModule.NamedPipes.PipeHandle">PipeHandle</see> object containing /// the native pipe handle. /// </summary> #endregion protected PipeHandle Handle = new PipeHandle(); #region Comments /// <summary> /// The name of the named pipe. /// </summary> /// <remarks> /// This name is used for creating a server pipe and connecting client ones to it. /// </remarks> #endregion protected string Name; #region Comments /// <summary> /// Boolean field used by the IDisposable implementation. /// </summary> #endregion protected bool disposed = false; #region Comments /// <summary> /// The maximum bytes that will be read from the pipe connection. /// </summary> /// <remarks> /// 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. /// </remarks> #endregion protected int maxReadBytes; #region Comments /// <summary> /// Reads a message from the pipe connection and converts it to a string /// using the UTF8 encoding. /// </summary> /// <remarks> /// See the <see cref="AppModule.NamedPipes.NamedPipeWrapper.Read">NamedPipeWrapper.Read</see> /// method for an explanation of the message format. /// </remarks> /// <returns>The UTF8 encoded string representation of the data.</returns> #endregion public string Read() { CheckIfDisposed(); return NamedPipeWrapper.Read(Handle, maxReadBytes); } #region Comments /// <summary> /// Reads a message from the pipe connection. /// </summary> /// <remarks> /// See the <see cref="AppModule.NamedPipes.NamedPipeWrapper.ReadBytes">NamedPipeWrapper.ReadBytes</see> /// method for an explanation of the message format. /// </remarks> /// <returns>The bytes read from the pipe connection.</returns> #endregion public byte[] ReadBytes() { CheckIfDisposed(); return NamedPipeWrapper.ReadBytes(Handle, maxReadBytes); } #region Comments /// <summary> /// Writes a string to the pipe connection/ /// </summary> /// <param name="text">The text to write.</param> #endregion public void Write(string text) { CheckIfDisposed(); NamedPipeWrapper.Write(Handle, text); } #region Comments /// <summary> /// Writes an array of bytes to the pipe connection. /// </summary> /// <param name="bytes">The bytes array.</param> #endregion public void WriteBytes(byte[] bytes) { CheckIfDisposed(); NamedPipeWrapper.WriteBytes(Handle, bytes); } #region Comments /// <summary> /// Closes the pipe connection. /// </summary> #endregion public abstract void Close(); #region Comments /// <summary> /// Connects a pipe connection. /// </summary> #endregion public abstract void Connect(); #region Comments /// <summary> /// Disposes a pipe connection by closing the underlying native handle. /// </summary> #endregion public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } #region Comments /// <summary> /// Disposes a pipe connection by closing the underlying native handle. /// </summary> /// <param name="disposing">A boolean indicating how the method is called.</param> #endregion protected void Dispose(bool disposing) { if(!this.disposed) { NamedPipeWrapper.Close(this.Handle); } disposed = true; } #region Comments /// <summary> /// Checks if the pipe connection is disposed. /// </summary> /// <remarks> /// This check is done before performing any pipe operations. /// </remarks> #endregion public void CheckIfDisposed() { if(this.disposed) { throw new ObjectDisposedException("The Pipe Connection is disposed."); } } #region Comments /// <summary> /// Gets the pipe connection state from the <see cref="AppModule.NamedPipes.PipeHandle">PipeHandle</see> /// object. /// </summary> /// <returns>The pipe connection state.</returns> #endregion public InterProcessConnectionState GetState() { CheckIfDisposed(); return this.Handle.State; } #region Comments /// <summary> /// Retrieved the operating system native handle for the pipe connection. /// </summary> #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); } } }