Moving micasa 1.5 trunk to Novell forge.
This commit is contained in:
		
							
								
								
									
										184
									
								
								c_micasad/communication/win/NamedPipes/APipeConnection.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								c_micasad/communication/win/NamedPipes/APipeConnection.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,184 @@ | ||||
| ////////////////////////////////////////////////// | ||||
| // Created by Ivan Latunov - IvanWeb.com        // | ||||
| //----------------------------------------------// | ||||
| // This program is free software. You can       // | ||||
| // redistribute it and/or modify it as you wish // | ||||
| ////////////////////////////////////////////////// | ||||
|  | ||||
|  | ||||
| using System; | ||||
| using System.IO; | ||||
| using sscs.communication.win.InterProcessComm; | ||||
|  | ||||
| namespace sscs.communication.win.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 NamedPipeWrapper.GetLocalUserID(this.Handle, ref lowPart, ref highPart, ref sSIDString);				 | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										110
									
								
								c_micasad/communication/win/NamedPipes/ClientPipeConnection.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								c_micasad/communication/win/NamedPipes/ClientPipeConnection.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | ||||
| ////////////////////////////////////////////////// | ||||
| // Created by Ivan Latunov - IvanWeb.com        // | ||||
| //----------------------------------------------// | ||||
| // This program is free software. You can       // | ||||
| // redistribute it and/or modify it as you wish // | ||||
| ////////////////////////////////////////////////// | ||||
|  | ||||
|  | ||||
| using System; | ||||
| using System.IO; | ||||
|  | ||||
| using sscs.communication.win.InterProcessComm; | ||||
|  | ||||
| namespace sscs.communication.win.NamedPipes { | ||||
| 	#region Comments | ||||
| 	/// <summary> | ||||
| 	/// Used by client applications to communicate with server ones by using named pipes. | ||||
| 	/// </summary> | ||||
| 	#endregion | ||||
| 	public sealed class ClientPipeConnection : APipeConnection { | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// The network name of the server where the server pipe is created. | ||||
| 		/// </summary> | ||||
| 		/// <remarks> | ||||
| 		/// If "." is used as a server name then the pipe is connected to the local machine. | ||||
| 		/// </remarks> | ||||
| 		#endregion | ||||
| 		private string Server = "."; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Closes a client named pipe connection. | ||||
| 		/// </summary> | ||||
| 		/// <remarks> | ||||
| 		/// A client pipe connection is closed by closing the underlying pipe handle. | ||||
| 		/// </remarks> | ||||
| 		#endregion | ||||
| 		public override void Close() { | ||||
| 			CheckIfDisposed(); | ||||
| 			NamedPipeWrapper.Close(this.Handle); | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Connects a client pipe to an existing server one. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public override void Connect() { | ||||
| 			CheckIfDisposed(); | ||||
| 			this.Handle = NamedPipeWrapper.ConnectToPipe(this.Name, this.Server); | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Attempts to establish a connection to the a server named pipe.  | ||||
| 		/// </summary> | ||||
| 		/// <remarks> | ||||
| 		/// If the attempt is successful the method creates the  | ||||
| 		/// <see cref="AppModule.NamedPipes.PipeHandle">PipeHandle</see> object | ||||
| 		/// and assigns it to the <see cref="AppModule.NamedPipes.APipeConnection.Handle">Handle</see> | ||||
| 		/// field.<br/><br/> | ||||
| 		/// This method is used when it is not known whether a server pipe already exists. | ||||
| 		/// </remarks> | ||||
| 		/// <returns>True if a connection is established.</returns> | ||||
| 		#endregion | ||||
| 		public bool TryConnect() { | ||||
| 			CheckIfDisposed(); | ||||
| 			bool ReturnVal = NamedPipeWrapper.TryConnectToPipe(this.Name, this.Server, out this.Handle); | ||||
|  | ||||
| 			return ReturnVal; | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Creates an instance of the ClientPipeConnection assuming that the server pipe | ||||
| 		/// is created on the same machine. | ||||
| 		/// </summary> | ||||
| 		/// <remarks> | ||||
| 		/// The maximum bytes to read from the client is set to be Int32.MaxValue. | ||||
| 		/// </remarks> | ||||
| 		/// <param name="name">The name of the server pipe.</param> | ||||
| 		#endregion | ||||
| 		public ClientPipeConnection(string name) { | ||||
| 			this.Name = name; | ||||
| 			this.Server = "."; | ||||
| 			this.maxReadBytes = Int32.MaxValue; | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Creates an instance of the ClientPipeConnection specifying the network name | ||||
| 		/// of the server. | ||||
| 		/// </summary> | ||||
| 		/// <remarks> | ||||
| 		/// The maximum bytes to read from the client is set to be Int32.MaxValue. | ||||
| 		/// </remarks> | ||||
| 		/// <param name="name">The name of the server pipe.</param> | ||||
| 		/// <param name="server">The network name of the machine, where the server pipe is created.</param> | ||||
| 		#endregion | ||||
| 		public ClientPipeConnection(string name, string server) { | ||||
| 			this.Name = name; | ||||
| 			this.Server = server; | ||||
| 			this.maxReadBytes = Int32.MaxValue; | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Object destructor. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		~ClientPipeConnection() { | ||||
| 			Dispose(false); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,52 @@ | ||||
| ////////////////////////////////////////////////// | ||||
| // Created by Ivan Latunov - IvanWeb.com        // | ||||
| //----------------------------------------------// | ||||
| // This program is free software. You can       // | ||||
| // redistribute it and/or modify it as you wish // | ||||
| ////////////////////////////////////////////////// | ||||
|  | ||||
|  | ||||
| using System; | ||||
| using System.Runtime.Serialization; | ||||
|  | ||||
| using sscs.communication.win.InterProcessComm; | ||||
|  | ||||
| namespace sscs.communication.win.NamedPipes { | ||||
| 	#region Comments | ||||
| 	/// <summary> | ||||
| 	/// This exception is thrown by named pipes communication methods. | ||||
| 	/// </summary> | ||||
| 	#endregion | ||||
| 	public class NamedPipeIOException : InterProcessIOException { | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Creates a NamedPipeIOException instance. | ||||
| 		/// </summary> | ||||
| 		/// <param name="text">The error message text.</param> | ||||
| 		#endregion | ||||
| 		public NamedPipeIOException(String text) : base(text) { | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Creates a NamedPipeIOException instance. | ||||
| 		/// </summary> | ||||
| 		/// <param name="text">The error message text.</param> | ||||
| 		/// <param name="errorCode">The native error code.</param> | ||||
| 		#endregion | ||||
| 		public NamedPipeIOException(String text, uint errorCode) : base(text) { | ||||
| 			this.ErrorCode = errorCode; | ||||
| 			if (errorCode == NamedPipeNative.ERROR_CANNOT_CONNECT_TO_PIPE) { | ||||
| 				this.IsServerAvailable = false; | ||||
| 			} | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Creates a NamedPipeIOException instance. | ||||
| 		/// </summary> | ||||
| 		/// <param name="info">The serialization information.</param> | ||||
| 		/// <param name="context">The streaming context.</param> | ||||
| 		#endregion | ||||
| 		protected NamedPipeIOException(SerializationInfo info, StreamingContext context) : base(info, context) { | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										641
									
								
								c_micasad/communication/win/NamedPipes/NamedPipeNative.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										641
									
								
								c_micasad/communication/win/NamedPipes/NamedPipeNative.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,641 @@ | ||||
| using System; | ||||
| using System.Text; | ||||
| using System.Security; | ||||
| using System.Runtime.InteropServices; | ||||
|  | ||||
| namespace sscs.communication.win.NamedPipes { | ||||
| 	#region Comments | ||||
| 	/// <summary> | ||||
| 	/// This utility class exposes kernel32.dll methods for named pipes communication. | ||||
| 	/// </summary> | ||||
| 	/// <remarks> | ||||
| 	/// Use the following links for complete information about the exposed methods: | ||||
| 	/// <list type="bullet"> | ||||
| 	/// <item> | ||||
| 	/// <description><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ipc/base/pipe_functions.asp" target="_blank">Named Pipe Functions</a></description> | ||||
| 	/// </item> | ||||
| 	/// <item> | ||||
| 	/// <description><a href="http://msdn.microsoft.com/library/en-us/fileio/base/file_management_functions.asp" target="_blank">File Management Functions</a></description> | ||||
| 	/// </item> | ||||
| 	/// <item> | ||||
| 	/// <description><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/handle_and_object_functions.asp" target="_blank">Handle and Object Functions</a></description> | ||||
| 	/// </item> | ||||
| 	/// <item> | ||||
| 	/// <description><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/system_error_codes.asp" target="_blank">System Error Codes</a></description> | ||||
| 	/// </item> | ||||
| 	/// </list> | ||||
| 	/// </remarks> | ||||
| 	#endregion | ||||
| 	[SuppressUnmanagedCodeSecurity] | ||||
| 	public sealed class NamedPipeNative { | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Outbound pipe access. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint PIPE_ACCESS_OUTBOUND = 0x00000002; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Duplex pipe access. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint PIPE_ACCESS_DUPLEX = 0x00000003; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Inbound pipe access. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint PIPE_ACCESS_INBOUND = 0x00000001; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Pipe blocking mode. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint PIPE_WAIT = 0x00000000; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Pipe non-blocking mode. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint PIPE_NOWAIT = 0x00000001; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Pipe read mode of type Byte. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint PIPE_READMODE_BYTE = 0x00000000; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Pipe read mode of type Message. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint PIPE_READMODE_MESSAGE = 0x00000002; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Byte pipe type. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint PIPE_TYPE_BYTE = 0x00000000; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Message pipe type. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint PIPE_TYPE_MESSAGE = 0x00000004; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Pipe client end. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint PIPE_CLIENT_END = 0x00000000; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Pipe server end. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint PIPE_SERVER_END = 0x00000001; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Unlimited server pipe instances. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint PIPE_UNLIMITED_INSTANCES = 255; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Waits indefinitely when connecting to a pipe. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint NMPWAIT_WAIT_FOREVER = 0xffffffff; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Does not wait for the named pipe. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint NMPWAIT_NOWAIT = 0x00000001; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Uses the default time-out specified in a call to the CreateNamedPipe method. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint NMPWAIT_USE_DEFAULT_WAIT = 0x00000000; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		///  | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint GENERIC_READ = (0x80000000); | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Generic write access to the pipe. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint GENERIC_WRITE = (0x40000000); | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Generic execute access to the pipe. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint GENERIC_EXECUTE = (0x20000000); | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Read, write, and execute access. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint GENERIC_ALL = (0x10000000); | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Create new file. Fails if the file exists. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint CREATE_NEW        = 1; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Create new file. Overrides an existing file. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint CREATE_ALWAYS     = 2; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Open existing file. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint OPEN_EXISTING     = 3; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Open existing file. If the file does not exist, creates it. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint OPEN_ALWAYS       = 4; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Opens the file and truncates it so that its size is zero bytes. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const uint TRUNCATE_EXISTING = 5; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Invalid operating system handle. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const int INVALID_HANDLE_VALUE = -1; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// The operation completed successfully. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const ulong ERROR_SUCCESS = 0; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// The system cannot find the file specified. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const ulong ERROR_CANNOT_CONNECT_TO_PIPE = 2; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// All pipe instances are busy. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const ulong ERROR_PIPE_BUSY = 231; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// The pipe is being closed. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const ulong ERROR_NO_DATA = 232; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// No process is on the other end of the pipe. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const ulong ERROR_PIPE_NOT_CONNECTED = 233; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// More data is available. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const ulong ERROR_MORE_DATA = 234; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// There is a process on other end of the pipe. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const ulong ERROR_PIPE_CONNECTED = 535; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Waiting for a process to open the other end of the pipe. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const ulong ERROR_PIPE_LISTENING = 536; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		///  | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public const int TOKEN_QUERY = 0X00000008; | ||||
| 		 | ||||
| 		public enum TOKEN_INFORMATION_CLASS | ||||
| 		{ | ||||
| 			TokenUser = 1, | ||||
| 			TokenGroups, | ||||
| 			TokenPrivileges, | ||||
| 			TokenOwner, | ||||
| 			TokenPrimaryGroup, | ||||
| 			TokenDefaultDacl, | ||||
| 			TokenSource, | ||||
| 			TokenType, | ||||
| 			TokenImpersonationLevel, | ||||
| 			TokenStatistics, | ||||
| 			TokenRestrictedSids, | ||||
| 			TokenSessionId | ||||
| 		} | ||||
|  | ||||
| 		[StructLayout(LayoutKind.Sequential)] | ||||
| 			public struct TOKEN_USER | ||||
| 		{ | ||||
| 			public _SID_AND_ATTRIBUTES User; | ||||
| 		} | ||||
|  | ||||
| 		[StructLayout(LayoutKind.Sequential)] | ||||
| 			public struct _SID_AND_ATTRIBUTES | ||||
| 		{ | ||||
| 			public IntPtr Sid; | ||||
| 			public int Attributes; | ||||
| 		} | ||||
|  | ||||
| 		[StructLayout(LayoutKind.Sequential)] | ||||
| 		public struct _LUID  | ||||
| 		{  | ||||
| 			public int LowPart ;  | ||||
| 			public int HighPart;  | ||||
| 		} //LUID, *PLUID;  | ||||
|  | ||||
|  | ||||
| 		[StructLayout(LayoutKind.Sequential)] | ||||
| 		public struct TOKEN_STATISTICS  | ||||
| 		{  | ||||
| 			public _LUID TokenId;  | ||||
| 			public _LUID AuthenticationId;  | ||||
| 			public int ExpirationTime;  | ||||
| 			public int TokenType;			// enum ini in 1 TOKEN_TYPE  | ||||
| 			public int ImpersonationLevel;	//SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;  | ||||
| 			public int DynamicCharged;		////DWORD  | ||||
| 			public int DynamicAvailable;	//DWORD  | ||||
| 			public int GroupCount;			//DWORD  | ||||
| 			public int PrivilegeCount;		//DWORD  | ||||
| 			public _LUID ModifiedId;  | ||||
| 		}// TOKEN_STATISTICS, *PTOKEN_STATISTICS;  | ||||
|  | ||||
|  | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Creates an instance of a named pipe and returns a handle for  | ||||
| 		/// subsequent pipe operations. | ||||
| 		/// </summary> | ||||
| 		/// <param name="lpName">Pointer to the null-terminated string that  | ||||
| 		/// uniquely identifies the pipe.</param> | ||||
| 		/// <param name="dwOpenMode">Pipe access mode, the overlapped mode,  | ||||
| 		/// the write-through mode, and the security access mode of the pipe handle.</param> | ||||
| 		/// <param name="dwPipeMode">Type, read, and wait modes of the pipe handle.</param> | ||||
| 		/// <param name="nMaxInstances">Maximum number of instances that can be  | ||||
| 		/// created for this pipe.</param> | ||||
| 		/// <param name="nOutBufferSize">Number of bytes to reserve for the output buffer.</param> | ||||
| 		/// <param name="nInBufferSize">Number of bytes to reserve for the input buffer.</param> | ||||
| 		/// <param name="nDefaultTimeOut">Default time-out value, in milliseconds.</param> | ||||
| 		/// <param name="pipeSecurityDescriptor">Pointer to a  | ||||
| 		/// <see cref="AppModule.NamedPipes.SecurityAttributes">SecurityAttributes</see>  | ||||
| 		/// object that specifies a security descriptor for the new named pipe.</param> | ||||
| 		/// <returns>If the function succeeds, the return value is a handle  | ||||
| 		/// to the server end of a named pipe instance.</returns> | ||||
| 		#endregion | ||||
| 		[DllImport("kernel32.dll")] | ||||
| 		public static extern IntPtr CreateNamedPipe( | ||||
| 			String lpName,									// pipe name | ||||
| 			uint dwOpenMode,								// pipe open mode | ||||
| 			uint dwPipeMode,								// pipe-specific modes | ||||
| 			uint nMaxInstances,							// maximum number of instances | ||||
| 			uint nOutBufferSize,						// output buffer size | ||||
| 			uint nInBufferSize,							// input buffer size | ||||
| 			uint nDefaultTimeOut,						// time-out interval | ||||
| 			IntPtr pipeSecurityDescriptor		// SD | ||||
| 			); | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Enables a named pipe server process to wait for a client  | ||||
| 		/// process to connect to an instance of a named pipe. | ||||
| 		/// </summary> | ||||
| 		/// <param name="hHandle">Handle to the server end of a named pipe instance.</param> | ||||
| 		/// <param name="lpOverlapped">Pointer to an  | ||||
| 		/// <see cref="AppModule.NamedPipes.Overlapped">Overlapped</see> object.</param> | ||||
| 		/// <returns>If the function succeeds, the return value is nonzero.</returns> | ||||
| 		#endregion | ||||
| 		[DllImport("kernel32.dll")] | ||||
| 		public static extern bool ConnectNamedPipe( | ||||
| 			IntPtr hHandle,									// handle to named pipe | ||||
| 			Overlapped lpOverlapped					// overlapped structure | ||||
| 			); | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Connects to a message-type pipe (and waits if an instance of the  | ||||
| 		/// pipe is not available), writes to and reads from the pipe, and then closes the pipe. | ||||
| 		/// </summary> | ||||
| 		/// <param name="lpNamedPipeName">Pointer to a null-terminated string  | ||||
| 		/// specifying the pipe name.</param> | ||||
| 		/// <param name="lpInBuffer">Pointer to the buffer containing the data written  | ||||
| 		/// to the pipe.</param> | ||||
| 		/// <param name="nInBufferSize">Size of the write buffer, in bytes.</param> | ||||
| 		/// <param name="lpOutBuffer">Pointer to the buffer that receives the data  | ||||
| 		/// read from the pipe.</param> | ||||
| 		/// <param name="nOutBufferSize">Size of the read buffer, in bytes.</param> | ||||
| 		/// <param name="lpBytesRead">Pointer to a variable that receives the number  | ||||
| 		/// of bytes read from the pipe.</param> | ||||
| 		/// <param name="nTimeOut">Number of milliseconds to wait for the  | ||||
| 		/// named pipe to be available.</param> | ||||
| 		/// <returns>If the function succeeds, the return value is nonzero.</returns> | ||||
| 		#endregion | ||||
| 		[DllImport("kernel32.dll")] | ||||
| 		public static extern bool CallNamedPipe( | ||||
| 			string lpNamedPipeName, | ||||
| 			byte[] lpInBuffer, | ||||
| 			uint nInBufferSize, | ||||
| 			byte[] lpOutBuffer, | ||||
| 			uint nOutBufferSize, | ||||
| 			byte[] lpBytesRead, | ||||
| 			int nTimeOut | ||||
| 			); | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Creates or opens a file, directory, physical disk, volume, console buffer,  | ||||
| 		/// tape drive, communications resource, mailslot, or named pipe. | ||||
| 		/// </summary> | ||||
| 		/// <param name="lpFileName">Pointer to a null-terminated string that  | ||||
| 		/// specifies the name of the object to create or open.</param> | ||||
| 		/// <param name="dwDesiredAccess">Access to the object (reading, writing, or both).</param> | ||||
| 		/// <param name="dwShareMode">Sharing mode of the object (reading, writing, both, or neither).</param> | ||||
| 		/// <param name="attr">Pointer to a  | ||||
| 		/// <see cref="AppModule.NamedPipes.SecurityAttributes">SecurityAttributes</see>  | ||||
| 		/// object that determines whether the returned handle can be inherited  | ||||
| 		/// by child processes.</param> | ||||
| 		/// <param name="dwCreationDisposition">Action to take on files that exist,  | ||||
| 		/// and which action to take when files do not exist.</param> | ||||
| 		/// <param name="dwFlagsAndAttributes">File attributes and flags.</param> | ||||
| 		/// <param name="hTemplateFile">Handle to a template file, with the GENERIC_READ access right.</param> | ||||
| 		/// <returns>If the function succeeds, the return value is an open handle to the specified file.</returns> | ||||
| 		#endregion | ||||
| 		[DllImport("kernel32.dll")] | ||||
| 		public static extern IntPtr CreateFile( | ||||
| 			String lpFileName,						  // file name | ||||
| 			uint dwDesiredAccess,					  // access mode | ||||
| 			uint dwShareMode,								// share mode | ||||
| 			SecurityAttributes attr,				// SD | ||||
| 			uint dwCreationDisposition,			// how to create | ||||
| 			uint dwFlagsAndAttributes,			// file attributes | ||||
| 			uint hTemplateFile);					  // handle to template file | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Reads data from a file, starting at the position indicated by the file pointer. | ||||
| 		/// </summary> | ||||
| 		/// <param name="hHandle">Handle to the file to be read.</param> | ||||
| 		/// <param name="lpBuffer">Pointer to the buffer that receives the data read from the file.</param> | ||||
| 		/// <param name="nNumberOfBytesToRead">Number of bytes to be read from the file.</param> | ||||
| 		/// <param name="lpNumberOfBytesRead">Pointer to the variable that receives the number of bytes read.</param> | ||||
| 		/// <param name="lpOverlapped">Pointer to an  | ||||
| 		/// <see cref="AppModule.NamedPipes.Overlapped">Overlapped</see> object.</param> | ||||
| 		/// <returns>The ReadFile function returns when one of the following  | ||||
| 		/// conditions is met: a write operation completes on the write end of  | ||||
| 		/// the pipe, the number of bytes requested has been read, or an error occurs.</returns> | ||||
| 		#endregion | ||||
| 		[DllImport("kernel32.dll")] | ||||
| 		public static extern bool ReadFile( | ||||
| 			IntPtr hHandle,											// handle to file | ||||
| 			byte[] lpBuffer,								// data buffer | ||||
| 			uint nNumberOfBytesToRead,			// number of bytes to read | ||||
| 			byte[] lpNumberOfBytesRead,			// number of bytes read | ||||
| 			uint lpOverlapped								// overlapped buffer | ||||
| 			); | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Writes data to a file at the position specified by the file pointer. | ||||
| 		/// </summary> | ||||
| 		/// <param name="hHandle">Handle to the file.</param> | ||||
| 		/// <param name="lpBuffer">Pointer to the buffer containing the data to be written to the file.</param> | ||||
| 		/// <param name="nNumberOfBytesToWrite"></param> | ||||
| 		/// <param name="lpNumberOfBytesWritten">Pointer to the variable that receives the number of bytes written.</param> | ||||
| 		/// <param name="lpOverlapped">Pointer to an  | ||||
| 		/// <see cref="AppModule.NamedPipes.Overlapped">Overlapped</see> object.</param> | ||||
| 		/// <returns>If the function succeeds, the return value is nonzero.</returns> | ||||
| 		#endregion | ||||
| 		[DllImport("kernel32.dll")] | ||||
| 		public static extern bool WriteFile( | ||||
| 			IntPtr hHandle,											// handle to file | ||||
| 			byte[] lpBuffer,							  // data buffer | ||||
| 			uint nNumberOfBytesToWrite,			// number of bytes to write | ||||
| 			byte[] lpNumberOfBytesWritten,	// number of bytes written | ||||
| 			uint lpOverlapped								// overlapped buffer | ||||
| 			); | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Retrieves information about a specified named pipe. | ||||
| 		/// </summary> | ||||
| 		/// <param name="hHandle">Handle to the named pipe for which information is wanted.</param> | ||||
| 		/// <param name="lpState">Pointer to a variable that indicates the current  | ||||
| 		/// state of the handle.</param> | ||||
| 		/// <param name="lpCurInstances">Pointer to a variable that receives the  | ||||
| 		/// number of current pipe instances.</param> | ||||
| 		/// <param name="lpMaxCollectionCount">Pointer to a variable that receives  | ||||
| 		/// the maximum number of bytes to be collected on the client's computer  | ||||
| 		/// before transmission to the server.</param> | ||||
| 		/// <param name="lpCollectDataTimeout">Pointer to a variable that receives  | ||||
| 		/// the maximum time, in milliseconds, that can pass before a remote named  | ||||
| 		/// pipe transfers information over the network.</param> | ||||
| 		/// <param name="lpUserName">Pointer to a buffer that receives the  | ||||
| 		/// null-terminated string containing the user name string associated  | ||||
| 		/// with the client application. </param> | ||||
| 		/// <param name="nMaxUserNameSize">Size of the buffer specified by the  | ||||
| 		/// lpUserName parameter.</param> | ||||
| 		/// <returns>If the function succeeds, the return value is nonzero.</returns> | ||||
| 		#endregion | ||||
| 		[DllImport("kernel32.dll")] | ||||
| 		public static extern bool GetNamedPipeHandleState( | ||||
| 			IntPtr hHandle, | ||||
| 			IntPtr lpState, | ||||
| 			ref uint lpCurInstances, | ||||
| 			IntPtr lpMaxCollectionCount, | ||||
| 			IntPtr lpCollectDataTimeout, | ||||
| 			IntPtr lpUserName, | ||||
| 			IntPtr nMaxUserNameSize | ||||
| 			); | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Cancels all pending input and output (I/O) operations that were  | ||||
| 		/// issued by the calling thread for the specified file handle. | ||||
| 		/// </summary> | ||||
| 		/// <param name="hHandle">Handle to a file.</param> | ||||
| 		/// <returns>If the function succeeds, the return value is nonzero.</returns> | ||||
| 		#endregion | ||||
| 		[DllImport("kernel32.dll")] | ||||
| 		public static extern bool CancelIo( | ||||
| 			IntPtr hHandle | ||||
| 			); | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Waits until either a time-out interval elapses or an instance  | ||||
| 		/// of the specified named pipe is available for connection. | ||||
| 		/// </summary> | ||||
| 		/// <param name="name">Pointer to a null-terminated string that specifies  | ||||
| 		/// the name of the named pipe.</param> | ||||
| 		/// <param name="timeout">Number of milliseconds that the function will  | ||||
| 		/// wait for an instance of the named pipe to be available.</param> | ||||
| 		/// <returns>If an instance of the pipe is available before the  | ||||
| 		/// time-out interval elapses, the return value is nonzero.</returns> | ||||
| 		#endregion | ||||
| 		[DllImport("kernel32.dll")] | ||||
| 		public static extern bool WaitNamedPipe( | ||||
| 			String name, | ||||
| 			int timeout); | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Retrieves the calling thread's last-error code value. | ||||
| 		/// </summary> | ||||
| 		/// <returns>The return value is the calling thread's last-error code value.</returns> | ||||
| 		#endregion | ||||
| 		[DllImport("kernel32.dll")] | ||||
| 		public static extern uint GetLastError(); | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Flushes the buffers of the specified file and causes all buffered data to be written to the file. | ||||
| 		/// </summary> | ||||
| 		/// <param name="hHandle">Handle to an open file.</param> | ||||
| 		/// <returns>If the function succeeds, the return value is nonzero.</returns> | ||||
| 		#endregion | ||||
| 		[DllImport("kernel32.dll")] | ||||
| 		public static extern bool FlushFileBuffers( | ||||
| 			IntPtr hHandle); | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Disconnects the server end of a named pipe instance from a client process. | ||||
| 		/// </summary> | ||||
| 		/// <param name="hHandle">Handle to an instance of a named pipe.</param> | ||||
| 		/// <returns>If the function succeeds, the return value is nonzero.</returns> | ||||
| 		#endregion | ||||
| 		[DllImport("kernel32.dll")] | ||||
| 		public static extern bool DisconnectNamedPipe( | ||||
| 			IntPtr hHandle); | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Sets the read mode and the blocking mode of the specified named pipe. | ||||
| 		/// </summary> | ||||
| 		/// <remarks> | ||||
| 		/// If the specified handle is to the client end of a named pipe and if  | ||||
| 		/// the named pipe server process is on a remote computer, the function  | ||||
| 		/// can also be used to control local buffering. | ||||
| 		/// </remarks> | ||||
| 		/// <param name="hHandle">Handle to the named pipe instance.</param> | ||||
| 		/// <param name="mode">Pointer to a variable that supplies the new mode.</param> | ||||
| 		/// <param name="cc">Pointer to a variable that specifies the maximum  | ||||
| 		/// number of bytes collected on the client computer before  | ||||
| 		/// transmission to the server.</param> | ||||
| 		/// <param name="cd">Pointer to a variable that specifies the  | ||||
| 		/// maximum time, in milliseconds, that can pass before a remote  | ||||
| 		/// named pipe transfers information over the network.</param> | ||||
| 		/// <returns>If the function succeeds, the return value is nonzero.</returns> | ||||
| 		#endregion | ||||
| 		[DllImport("kernel32.dll")] | ||||
| 		public static extern bool SetNamedPipeHandleState( | ||||
| 			IntPtr hHandle, | ||||
| 			ref uint mode, | ||||
| 			IntPtr cc, | ||||
| 			IntPtr cd); | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Closes an open object handle. | ||||
| 		/// </summary> | ||||
| 		/// <param name="hHandle">Handle to an open object.</param> | ||||
| 		/// <returns>If the function succeeds, the return value is nonzero.</returns> | ||||
| 		#endregion | ||||
| 		[DllImport("kernel32.dll")] | ||||
| 		public static extern bool CloseHandle( | ||||
| 			IntPtr hHandle); | ||||
|  | ||||
| 		[DllImport("kernel32.dll")] | ||||
| 		public static extern IntPtr GetCurrentThread(); | ||||
|  | ||||
| 		// native for named pipes | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Closes an open object handle. | ||||
| 		/// </summary> | ||||
| 		/// <param name="hHandle">Handle to an open object.</param> | ||||
| 		/// <returns>If the function succeeds, the return value is nonzero.</returns> | ||||
| 		#endregion | ||||
| 		[DllImport("advapi32" )] | ||||
| 		public static extern int ImpersonateNamedPipeClient( | ||||
| 			IntPtr hHandle); | ||||
|  | ||||
| 		[DllImport("advapi32" )] | ||||
| 		public static extern bool RevertToSelf(); | ||||
|  | ||||
| 		[DllImport("advapi32",  SetLastError=true)] | ||||
| 		public static extern bool OpenThreadToken( | ||||
| 			IntPtr hThread, | ||||
| 			uint desiredInfo, | ||||
| 			bool openAsSelf, | ||||
| 			out IntPtr TokenHandle); // handle to open access token  | ||||
|  | ||||
| 		[DllImport("advapi32")] | ||||
| 		public static extern bool OpenProcessToken( | ||||
| 			IntPtr ProcessHandle, // handle to process | ||||
| 			int DesiredAccess, // desired access to process | ||||
| 			ref IntPtr TokenHandle // handle to open access token | ||||
| 			); | ||||
|  | ||||
| 		[DllImport("advapi32", CharSet=CharSet.Auto)] | ||||
| 		public static extern bool GetTokenInformation( | ||||
| 			IntPtr hToken, | ||||
| 			TOKEN_INFORMATION_CLASS tokenInfoClass, | ||||
| 			IntPtr TokenInformation, | ||||
| 			int tokeInfoLength, | ||||
| 			ref int reqLength); | ||||
|  | ||||
|  | ||||
| 		[DllImport("advapi32", CharSet=CharSet.Auto)] | ||||
| 		public static extern bool LookupAccountSid | ||||
| 			( | ||||
| 			[In,MarshalAs(UnmanagedType.LPTStr)] string lpSystemName, // name of local or remote computer | ||||
| 			IntPtr pSid, // security identifier | ||||
| 			StringBuilder Account, // account name buffer | ||||
| 			ref int cbName, // size of account name buffer | ||||
| 			StringBuilder DomainName, // domain name | ||||
| 			ref int cbDomainName, // size of domain name buffer | ||||
| 			ref int peUse // SID type | ||||
| 			// ref _SID_NAME_USE peUse // SID type | ||||
| 			); | ||||
|  | ||||
| 		[DllImport("advapi32", CharSet=CharSet.Auto)] | ||||
| 		public static extern bool ConvertSidToStringSid( | ||||
| 			IntPtr pSID, | ||||
| 			[In,Out,MarshalAs(UnmanagedType.LPTStr)] ref string pStringSid); | ||||
|  | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Private constructor. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		private NamedPipeNative() {} | ||||
| 	} | ||||
| 	#region Comments | ||||
| 	/// <summary> | ||||
| 	/// This class is used as a dummy parameter only. | ||||
| 	/// </summary> | ||||
| 	#endregion | ||||
| 	[StructLayout(LayoutKind.Sequential)] | ||||
| 	public class SecurityAttributes { | ||||
| 	} | ||||
| 	#region Comments | ||||
| 	/// <summary> | ||||
| 	/// This class is used as a dummy parameter only. | ||||
| 	/// </summary> | ||||
| 	#endregion | ||||
| 	[StructLayout(LayoutKind.Sequential)] | ||||
| 	public class Overlapped { | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										628
									
								
								c_micasad/communication/win/NamedPipes/NamedPipeWrapper.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										628
									
								
								c_micasad/communication/win/NamedPipes/NamedPipeWrapper.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,628 @@ | ||||
| ////////////////////////////////////////////////// | ||||
| // Created by Ivan Latunov - IvanWeb.com        // | ||||
| //----------------------------------------------// | ||||
| // This program is free software. You can       // | ||||
| // redistribute it and/or modify it as you wish // | ||||
| ////////////////////////////////////////////////// | ||||
|  | ||||
|  | ||||
| using System; | ||||
|  | ||||
| using sscs.communication.win.InterProcessComm; | ||||
| using System.Runtime.InteropServices; | ||||
| using System.Text; | ||||
|  | ||||
| using HANDLE = System.IntPtr; | ||||
|  | ||||
| namespace sscs.communication.win.NamedPipes  | ||||
| { | ||||
| 	#region Comments | ||||
| 	/// <summary> | ||||
| 	/// A utility class that exposes named pipes operations. | ||||
| 	/// </summary> | ||||
| 	/// <remarks> | ||||
| 	/// This class uses the exposed exposed kernel32.dll methods by the  | ||||
| 	/// <see cref="AppModule.NamedPipes.NamedPipeNative">NamedPipeNative</see> class | ||||
| 	/// to provided controlled named pipe functionality. | ||||
| 	/// </remarks> | ||||
| 	#endregion | ||||
| 	public sealed class NamedPipeWrapper  | ||||
| 	{ | ||||
|  | ||||
| 		public const int TOKEN_QUERY = 0X00000008; | ||||
|  | ||||
| 		const int ERROR_NO_MORE_ITEMS = 259; | ||||
|  | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// The number of retries when creating a pipe or connecting to a pipe. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		private const int ATTEMPTS = 2; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Wait time for the  | ||||
| 		/// <see cref="AppModule.NamedPipes.NamedPipeNative.WaitNamedPipe">NamedPipeNative.WaitNamedPipe</see>  | ||||
| 		/// operation. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		private const int WAIT_TIME = 5000; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Reads a string from a named pipe using the UTF8 encoding. | ||||
| 		/// </summary> | ||||
| 		/// <param name="handle">The pipe handle.</param> | ||||
| 		/// <param name="maxBytes">The maximum bytes to read.</param> | ||||
| 		/// <returns>A UTF8 string.</returns> | ||||
| 		/// <remarks>This function uses  | ||||
| 		/// <see cref="AppModule.NamedPipes.NamedPipeWrapper.ReadBytes">AppModule.NamedPipes.ReadBytes</see>  | ||||
| 		/// to read the bytes from the pipe and then converts them to string.<br/><br/> | ||||
| 		/// The first four bytes of the pipe data are expected to contain  | ||||
| 		/// the data length of the message. This method first reads those four  | ||||
| 		/// bytes and converts them to integer. It then continues to read from the pipe using  | ||||
| 		/// the extracted data length. | ||||
| 		/// </remarks> | ||||
| 		#endregion | ||||
| 		public static string Read(PipeHandle handle, int maxBytes)  | ||||
| 		{		 | ||||
| 			string returnVal = ""; | ||||
| 			byte[] bytes = ReadBytes(handle, maxBytes); | ||||
| 			if (bytes != null)  | ||||
| 			{ | ||||
| 				returnVal = System.Text.Encoding.UTF8.GetString(bytes); | ||||
| 			} | ||||
|  | ||||
| 			return returnVal; | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Reads the bytes from a named pipe. | ||||
| 		/// </summary> | ||||
| 		/// <param name="handle">The pipe handle.</param> | ||||
| 		/// <param name="maxBytes">The maximum bytes to read.</param> | ||||
| 		/// <returns>An array of bytes.</returns> | ||||
| 		/// <remarks>This method expects that the first four bytes in the pipe define  | ||||
| 		/// the length of the data to read. If the data length is greater than  | ||||
| 		/// <b>maxBytes</b> the method returns null.<br/><br/> | ||||
| 		/// The first four bytes of the pipe data are expected to contain  | ||||
| 		/// the data length of the message. This method first reads those four  | ||||
| 		/// bytes and converts them to integer. It then continues to read from the pipe using  | ||||
| 		/// the extracted data length. | ||||
| 		/// </remarks> | ||||
| 		#endregion | ||||
| 		public static byte[] ReadBytes(PipeHandle handle, int maxBytes)  | ||||
| 		{			 | ||||
| 			byte[] numReadWritten = new byte[4]; | ||||
| 			byte[] intBytes = new byte[4]; | ||||
| 			byte[] msgBytes = null; | ||||
| 			int len; | ||||
| 			 | ||||
| 			// Set the Handle state to Reading | ||||
| 			handle.State = InterProcessConnectionState.Reading; | ||||
| 			// Read the first four bytes and convert them to integer | ||||
| 			bool bReadSuccessful = true; | ||||
| 			 | ||||
| 			try  | ||||
| 			{ | ||||
| 				bReadSuccessful = NamedPipeNative.ReadFile(handle.Handle, intBytes, 4, numReadWritten, 0); | ||||
| 			} | ||||
| 			catch (Exception) | ||||
| 			{ | ||||
| 				// Console.WriteLine("Error on ReadFile "+e.ToString()); | ||||
| 			} | ||||
| 			 | ||||
| 			if (bReadSuccessful)  | ||||
| 			{ | ||||
| 				len = BitConverter.ToInt32(intBytes, 0); | ||||
| 				msgBytes = new byte[len]; | ||||
| 				// Read the rest of the data | ||||
| 				if (!NamedPipeNative.ReadFile(handle.Handle, msgBytes, (uint)len, numReadWritten, 0))  | ||||
| 				{				 | ||||
| 					handle.State = InterProcessConnectionState.Error; | ||||
| 					throw new NamedPipeIOException("Error reading from pipe. Internal error: " + NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError()); | ||||
| 				} | ||||
| 			} | ||||
| 			else  | ||||
| 			{ | ||||
| 				handle.State = InterProcessConnectionState.Error; | ||||
| 				throw new NamedPipeIOException("Error reading from pipe. Internal error: " + NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError()); | ||||
| 			} | ||||
| 			handle.State = InterProcessConnectionState.ReadData; | ||||
| 			if (len > maxBytes)  | ||||
| 			{ | ||||
| 				return null; | ||||
| 			} | ||||
| 			return msgBytes; | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Writes a string to a named pipe. | ||||
| 		/// </summary> | ||||
| 		/// <param name="handle">The pipe handle.</param> | ||||
| 		/// <param name="text">The text to write to the pipe.</param> | ||||
| 		/// <remarks>This method converts the text into an array of bytes, using the  | ||||
| 		/// UTF8 encoding and the uses  | ||||
| 		/// <see cref="AppModule.NamedPipes.NamedPipeWrapper.WriteBytes">AppModule.NamedPipes.WriteBytes</see> | ||||
| 		/// to write to the pipe.<br/><br/> | ||||
| 		/// When writing to a pipe the method first writes four bytes that define the data length. | ||||
| 		/// It then writes the whole message.</remarks> | ||||
| 		#endregion | ||||
| 		public static void Write(PipeHandle handle, string text)  | ||||
| 		{ | ||||
| 			WriteBytes(handle, System.Text.Encoding.UTF8.GetBytes(text)); | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Writes an array of bytes to a named pipe. | ||||
| 		/// </summary> | ||||
| 		/// <param name="handle">The pipe handle.</param> | ||||
| 		/// <param name="bytes">The bytes to write.</param> | ||||
| 		/// <remarks>If we try bytes array we attempt to write is empty then this method write a space character to the pipe. This is necessary because the other end of the pipe uses a blocking Read operation so we must write someting.<br/><br/> | ||||
| 		/// The bytes length is restricted by the <b>maxBytes</b> parameter, which is done primarily for security reasons.<br/><br/> | ||||
| 		/// When writing to a pipe the method first writes four bytes that define the data length. | ||||
| 		/// It then writes the whole message.</remarks> | ||||
| 		#endregion | ||||
| 		public static void WriteBytes(PipeHandle handle, byte[] bytes)  | ||||
| 		{			 | ||||
| 			byte[] numReadWritten = new byte[4]; | ||||
| 			uint len; | ||||
|  | ||||
| 			if (bytes == null)  | ||||
| 			{ | ||||
| 				bytes = new byte[0]; | ||||
| 			} | ||||
| 			if (bytes.Length == 0)  | ||||
| 			{ | ||||
| 				bytes = new byte[1]; | ||||
| 				bytes = System.Text.Encoding.UTF8.GetBytes(" "); | ||||
| 			} | ||||
| 			// Get the message length | ||||
| 			len = (uint)bytes.Length; | ||||
| 			handle.State = InterProcessConnectionState.Writing; | ||||
| 			// Write four bytes that define the message length | ||||
| 			if (NamedPipeNative.WriteFile(handle.Handle, BitConverter.GetBytes(len), 4, numReadWritten, 0)) { | ||||
| 				// Write the whole message | ||||
| 				if (!NamedPipeNative.WriteFile(handle.Handle, bytes, len, numReadWritten, 0)) { | ||||
| 					handle.State = InterProcessConnectionState.Error; | ||||
| 					throw new NamedPipeIOException("Error writing to pipe. Internal error: " + NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError()); | ||||
| 				} | ||||
| 			} | ||||
| 			else { | ||||
| 				handle.State = InterProcessConnectionState.Error; | ||||
| 				throw new NamedPipeIOException("Error writing to pipe. Internal error: " + NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError()); | ||||
| 			} | ||||
| 			handle.State = InterProcessConnectionState.Flushing; | ||||
| 			Flush(handle); | ||||
| 			handle.State = InterProcessConnectionState.FlushedData; | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Tries to connect to a named pipe on the same machine. | ||||
| 		/// </summary> | ||||
| 		/// <param name="pipeName">The name of the pipe.</param> | ||||
| 		/// <param name="handle">The resulting pipe handle.</param> | ||||
| 		/// <returns>Return true if the attempt succeeds.</returns> | ||||
| 		/// <remarks>This method is used mainly when stopping the pipe server. It unblocks the existing pipes, which wait for client connection.</remarks> | ||||
| 		#endregion | ||||
| 		public static bool TryConnectToPipe(string pipeName, out PipeHandle handle)  | ||||
| 		{ | ||||
| 			return TryConnectToPipe(pipeName, ".", out handle); | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Tries to connect to a named pipe. | ||||
| 		/// </summary> | ||||
| 		/// <param name="pipeName">The name of the pipe.</param> | ||||
| 		/// <param name="serverName">The name of the server.</param> | ||||
| 		/// <param name="handle">The resulting pipe handle.</param> | ||||
| 		/// <returns>Return true if the attempt succeeds.</returns> | ||||
| 		/// <remarks>This method is used mainly when stopping the pipe server. It unblocks the existing pipes, which wait for client connection.</remarks> | ||||
| 		#endregion | ||||
| 		public static bool TryConnectToPipe(string pipeName, string serverName, out PipeHandle handle)  | ||||
| 		{ | ||||
| 			handle = new PipeHandle(); | ||||
| 			// Build the pipe name string | ||||
| 			string name = @"\\" + serverName + @"\pipe\" + pipeName; | ||||
| 			handle.State = InterProcessConnectionState.ConnectingToServer; | ||||
| 			// Try to connect to a server pipe | ||||
| 			handle.Handle = NamedPipeNative.CreateFile(name, NamedPipeNative.GENERIC_READ | NamedPipeNative.GENERIC_WRITE, 0, null, NamedPipeNative.OPEN_EXISTING, 0, 0); | ||||
| 			if (handle.Handle.ToInt32() != NamedPipeNative.INVALID_HANDLE_VALUE)  | ||||
| 			{ | ||||
| 				handle.State = InterProcessConnectionState.ConnectedToServer; | ||||
| 				return true; | ||||
| 			}  | ||||
| 			else  | ||||
| 			{ | ||||
| 				handle.State = InterProcessConnectionState.Error; | ||||
| 				return false; | ||||
| 			} | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Connects to a server named pipe on the same machine. | ||||
| 		/// </summary> | ||||
| 		/// <param name="pipeName">The pipe name.</param> | ||||
| 		/// <returns>The pipe handle, which also contains the pipe state.</returns> | ||||
| 		/// <remarks>This method is used by clients to establish a pipe connection with a server pipe.</remarks> | ||||
| 		#endregion | ||||
| 		public static PipeHandle ConnectToPipe(string pipeName)  | ||||
| 		{ | ||||
| 			return ConnectToPipe(pipeName, "."); | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Connects to a server named pipe. | ||||
| 		/// </summary> | ||||
| 		/// <param name="pipeName">The pipe name.</param> | ||||
| 		/// <param name="serverName">The server name.</param> | ||||
| 		/// <returns>The pipe handle, which also contains the pipe state.</returns> | ||||
| 		/// <remarks>This method is used by clients to establish a pipe connection with a server pipe.</remarks> | ||||
| 		#endregion | ||||
| 		public static PipeHandle ConnectToPipe(string pipeName, string serverName)  | ||||
| 		{ | ||||
| 			PipeHandle handle = new PipeHandle(); | ||||
| 			// Build the name of the pipe. | ||||
| 			string name = @"\\" + serverName + @"\PIPE\" + pipeName; | ||||
|  | ||||
| 			for (int i = 1; i<=ATTEMPTS; i++)  | ||||
| 			{ | ||||
| 				handle.State = InterProcessConnectionState.ConnectingToServer; | ||||
| 				// Try to connect to the server | ||||
| 				handle.Handle = NamedPipeNative.CreateFile(name, NamedPipeNative.GENERIC_READ | NamedPipeNative.GENERIC_WRITE, 0, null, NamedPipeNative.OPEN_EXISTING, 0, 0); | ||||
| 				if (handle.Handle.ToInt32() != NamedPipeNative.INVALID_HANDLE_VALUE)  | ||||
| 				{ | ||||
| 					// The client managed to connect to the server pipe | ||||
| 					handle.State = InterProcessConnectionState.ConnectedToServer; | ||||
| 					// Set the read mode of the pipe channel | ||||
| 					uint mode = NamedPipeNative.PIPE_READMODE_MESSAGE; | ||||
| 					if (NamedPipeNative.SetNamedPipeHandleState(handle.Handle, ref mode, IntPtr.Zero, IntPtr.Zero))  | ||||
| 					{ | ||||
| 						break; | ||||
| 					}	 | ||||
| 					if (i >= ATTEMPTS)  | ||||
| 					{ | ||||
| 						handle.State = InterProcessConnectionState.Error; | ||||
| 						throw new NamedPipeIOException("Error setting read mode on pipe " + name + " . Internal error: " + NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError()); | ||||
| 					} | ||||
| 				} | ||||
| 				if (i >= ATTEMPTS)  | ||||
| 				{ | ||||
| 					if (NamedPipeNative.GetLastError() != NamedPipeNative.ERROR_PIPE_BUSY)  | ||||
| 					{ | ||||
| 						handle.State = InterProcessConnectionState.Error; | ||||
| 						// After a certain number of unsuccessful attempt raise an exception | ||||
| 						throw new NamedPipeIOException("Error connecting to pipe " + name + " . Internal error: " + NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError()); | ||||
| 					}  | ||||
| 					else  | ||||
| 					{ | ||||
| 						handle.State = InterProcessConnectionState.Error; | ||||
| 						throw new NamedPipeIOException("Pipe " + name + " is too busy. Internal error: " + NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError()); | ||||
| 					} | ||||
| 				}  | ||||
| 				else  | ||||
| 				{ | ||||
| 					// The pipe is busy so lets wait for some time and try again | ||||
| 					if (NamedPipeNative.GetLastError() == NamedPipeNative.ERROR_PIPE_BUSY)  | ||||
| 						NamedPipeNative.WaitNamedPipe(name, WAIT_TIME); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			return handle; | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Creates a server named pipe. | ||||
| 		/// </summary> | ||||
| 		/// <param name="name">The name of the pipe.</param> | ||||
| 		/// <param name="outBuffer">The size of the outbound buffer.</param> | ||||
| 		/// <param name="inBuffer">The size of the inbound buffer.</param> | ||||
| 		/// <returns>The pipe handle.</returns> | ||||
| 		#endregion | ||||
| 		public static PipeHandle Create(string name, uint outBuffer, uint inBuffer)  | ||||
| 		{			 | ||||
| 			if ((name.IndexOf("pipe") < 0)  && (name.IndexOf("PIPE") < 0))			 | ||||
| 				name = @"\\.\pipe\" + name; | ||||
|  | ||||
| 			PipeHandle handle = new PipeHandle(); | ||||
| 			for (int i = 1; i<=ATTEMPTS; i++)  | ||||
| 			{ | ||||
| 				handle.State = InterProcessConnectionState.Creating; | ||||
| 				handle.Handle = NamedPipeNative.CreateNamedPipe( | ||||
| 					name, | ||||
| 					NamedPipeNative.PIPE_ACCESS_DUPLEX,					 | ||||
| 					NamedPipeNative.PIPE_TYPE_MESSAGE | NamedPipeNative.PIPE_READMODE_MESSAGE | NamedPipeNative.PIPE_WAIT, | ||||
| 					NamedPipeNative.PIPE_UNLIMITED_INSTANCES, | ||||
| 					outBuffer, | ||||
| 					inBuffer, | ||||
| 					NamedPipeNative.NMPWAIT_WAIT_FOREVER, | ||||
| 					IntPtr.Zero); | ||||
| 				if (handle.Handle.ToInt32() != NamedPipeNative.INVALID_HANDLE_VALUE)  | ||||
| 				{ | ||||
| 					handle.State = InterProcessConnectionState.Created; | ||||
| 					break; | ||||
| 				} | ||||
| 				if (i >= ATTEMPTS)  | ||||
| 				{ | ||||
| 					handle.State = InterProcessConnectionState.Error; | ||||
| 					throw new NamedPipeIOException("Error creating named pipe " + name + " . Internal error: " + NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError()); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			return handle; | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Starts waiting for client connections. | ||||
| 		/// </summary> | ||||
| 		/// <remarks> | ||||
| 		/// Blocks the current execution until a client pipe attempts to establish a connection. | ||||
| 		/// </remarks> | ||||
| 		/// <param name="handle">The pipe handle.</param> | ||||
| 		#endregion | ||||
| 		public static void Connect(PipeHandle handle)  | ||||
| 		{ | ||||
| 			handle.State = InterProcessConnectionState.WaitingForClient; | ||||
| 			bool connected = NamedPipeNative.ConnectNamedPipe(handle.Handle, null); | ||||
| 			handle.State = InterProcessConnectionState.ConnectedToClient; | ||||
| 			if (!connected && NamedPipeNative.GetLastError() != NamedPipeNative.ERROR_PIPE_CONNECTED)  | ||||
| 			{ | ||||
| 				handle.State = InterProcessConnectionState.Error; | ||||
| 				throw new NamedPipeIOException("Error connecting pipe. Internal error: " + NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError()); | ||||
| 			} | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Returns the number of instances of a named pipe. | ||||
| 		/// </summary> | ||||
| 		/// <param name="handle">The pipe handle.</param> | ||||
| 		/// <returns>The number of instances.</returns> | ||||
| 		#endregion | ||||
| 		public static uint NumberPipeInstances(PipeHandle handle)  | ||||
| 		{ | ||||
| 			uint curInstances = 0; | ||||
|  | ||||
| 			if (NamedPipeNative.GetNamedPipeHandleState(handle.Handle, IntPtr.Zero, ref curInstances, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero))  | ||||
| 			{ | ||||
| 				return curInstances; | ||||
| 			}  | ||||
| 			else  | ||||
| 			{ | ||||
| 				throw new NamedPipeIOException("Error getting the pipe state. Internal error: " + NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError()); | ||||
| 			} | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Closes a named pipe and releases the native handle. | ||||
| 		/// </summary> | ||||
| 		/// <param name="handle">The pipe handle.</param> | ||||
| 		#endregion | ||||
| 		public static void Close(PipeHandle handle)  | ||||
| 		{ | ||||
| 			handle.State = InterProcessConnectionState.Closing; | ||||
| 			NamedPipeNative.CloseHandle(handle.Handle); | ||||
| 			handle.Handle = IntPtr.Zero; | ||||
| 			handle.State = InterProcessConnectionState.Closed; | ||||
| 		}	 | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Flushes all the data in a named pipe. | ||||
| 		/// </summary> | ||||
| 		/// <param name="handle">The pipe handle.</param> | ||||
| 		#endregion | ||||
| 		public static void Flush(PipeHandle handle)  | ||||
| 		{ | ||||
| 			handle.State = InterProcessConnectionState.Flushing; | ||||
| 			NamedPipeNative.FlushFileBuffers(handle.Handle); | ||||
| 			handle.State = InterProcessConnectionState.FlushedData; | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Disconnects a server named pipe from the client. | ||||
| 		/// </summary> | ||||
| 		/// <remarks> | ||||
| 		/// Server pipes can be reused by first disconnecting them from the client and then | ||||
| 		/// calling the <see cref="AppModule.NamedPipes.NamedPipeWrapper.Connect">Connect</see> | ||||
| 		/// method to start listening. This improves the performance as it is not necessary | ||||
| 		/// to create new pipe handles. | ||||
| 		/// </remarks> | ||||
| 		/// <param name="handle">The pipe handle.</param> | ||||
| 		#endregion | ||||
| 		public static void Disconnect(PipeHandle handle)  | ||||
| 		{ | ||||
| 			handle.State = InterProcessConnectionState.Disconnecting; | ||||
| 			NamedPipeNative.DisconnectNamedPipe(handle.Handle); | ||||
| 			handle.State = InterProcessConnectionState.Disconnected; | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Private constructor. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		private NamedPipeWrapper() {} | ||||
|  | ||||
|  | ||||
| 		// Client USERID stuff | ||||
| 		// 1. call ImpersonateNamedPipeClient(hPipe) | ||||
| 		// 2. call OpenThreadToken(GetCurrentThread(), | ||||
| 		//							TOKEN_QUERY | TOKEN_QUERY_SOURCE, | ||||
| 		//							FALSE, | ||||
| 		//							phUserToken); | ||||
|  | ||||
| 		public static int ImpersonateNamePipeClient(IntPtr hPipeHandle) | ||||
| 		{ | ||||
| 			int rcode = NamedPipeNative.ImpersonateNamedPipeClient(hPipeHandle);					 | ||||
| 			return rcode; | ||||
| 		} | ||||
|  | ||||
|  | ||||
| 		static int PerformDump(HANDLE token) | ||||
| 		{ | ||||
| 			StringBuilder sb = new StringBuilder(); | ||||
| 			NamedPipeNative.TOKEN_USER tokUser; | ||||
| 			const int bufLength = 256; | ||||
| 			IntPtr tu = Marshal.AllocHGlobal( bufLength ); | ||||
| 			int cb = bufLength; | ||||
| 			if (NamedPipeNative.GetTokenInformation( token, NamedPipeNative.TOKEN_INFORMATION_CLASS.TokenUser, tu, cb, ref cb )) | ||||
| 				Console.WriteLine("GetTokenInformation successful"); | ||||
| 			else | ||||
| 			{ | ||||
| 				Console.WriteLine("GetTokenInformation NOT successful"); | ||||
| 				uint error = NamedPipeNative.GetLastError(); | ||||
| 				Console.WriteLine("error" + error.ToString()); | ||||
| 			} | ||||
|  | ||||
| 			tokUser = (NamedPipeNative.TOKEN_USER) Marshal.PtrToStructure(tu, typeof(NamedPipeNative.TOKEN_USER) ); | ||||
| 			//sb.Append(DumpAccountSid(tokUser.User.Sid)); | ||||
| 			IntPtr pUserID = tokUser.User.Sid; | ||||
| 			//Console.WriteLine("UserID: " + pUserID); | ||||
|  | ||||
| 			DumpAccountSid(pUserID); | ||||
| 			Marshal.FreeHGlobal( tu ); | ||||
|  | ||||
|  | ||||
| 			tu = Marshal.AllocHGlobal(bufLength); | ||||
| 			cb = bufLength; | ||||
|  | ||||
| 			// get token states | ||||
| 			NamedPipeNative.TOKEN_STATISTICS stats;			 | ||||
|  | ||||
| 			if (NamedPipeNative.GetTokenInformation(token, NamedPipeNative.TOKEN_INFORMATION_CLASS.TokenStatistics, tu, cb, ref cb)) | ||||
| 			{			 | ||||
| 				stats = (NamedPipeNative.TOKEN_STATISTICS) Marshal.PtrToStructure(tu, typeof(NamedPipeNative.TOKEN_STATISTICS));	 | ||||
| 				Console.WriteLine("UserLow: "+stats.AuthenticationId.LowPart.ToString()); | ||||
| 				Console.WriteLine("UserHigh: "+stats.AuthenticationId.HighPart.ToString()); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				Console.WriteLine("failed");				 | ||||
| 			} | ||||
| 			 | ||||
| 			return (int)pUserID; | ||||
| 		} | ||||
|  | ||||
|  | ||||
| 		static string DumpAccountSid(IntPtr SID) | ||||
| 		{ | ||||
| 			int cchAccount = 0; | ||||
| 			int cchDomain = 0; | ||||
| 			int snu = 0 ; | ||||
| 			StringBuilder sb = new StringBuilder(); | ||||
|  | ||||
| 			// Caller allocated buffer | ||||
| 			StringBuilder Account= null; | ||||
| 			StringBuilder Domain = null; | ||||
| 			bool ret = NamedPipeNative.LookupAccountSid(null, SID, Account, ref cchAccount, Domain, ref cchDomain, ref snu); | ||||
| 			if ( ret == true ) | ||||
| 				if ( Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS ) | ||||
| 					return "Error"; | ||||
| 			try | ||||
| 			{ | ||||
| 				Account = new StringBuilder( cchAccount ); | ||||
| 				Domain = new StringBuilder( cchDomain ); | ||||
| 				ret = NamedPipeNative.LookupAccountSid(null, SID, Account, ref cchAccount, Domain, ref cchDomain, ref snu); | ||||
| 				if (ret) | ||||
| 				{ | ||||
| 					sb.Append(Domain); | ||||
| 					sb.Append(@"\\"); | ||||
| 					sb.Append(Account); | ||||
| 				} | ||||
| 				else | ||||
| 					Console.WriteLine("logon account (no name) "); | ||||
| 			} | ||||
| 			catch (Exception ex) | ||||
| 			{ | ||||
| 				Console.WriteLine(ex.Message); | ||||
| 			} | ||||
| 			finally | ||||
| 			{ | ||||
| 			} | ||||
| 			string SidString = null; | ||||
| 			NamedPipeNative.ConvertSidToStringSid(SID, ref SidString); | ||||
| 			sb.Append("\nSID: "); | ||||
| 			sb.Append(SidString);			 | ||||
|  | ||||
| 			 | ||||
| 			Console.WriteLine("Acct info: "+ sb.ToString()); | ||||
| 			return sb.ToString(); | ||||
| 		} | ||||
|  | ||||
| 		public static int GetLocalUserID(PipeHandle handle, ref int lowPart, ref int highPart, ref string SidString) | ||||
| 		{			 | ||||
| 			int rcode = -1; | ||||
| 			// get client userID | ||||
| 			int code = NamedPipeNative.ImpersonateNamedPipeClient(handle.Handle); | ||||
| 			if (code == 0) | ||||
| 			{ | ||||
| 				uint lastError = NamedPipeNative.GetLastError(); | ||||
| 				Console.WriteLine("ImpersonateNamedPipeClient Error: "+rcode.ToString()); | ||||
| 				return -1; | ||||
| 			} | ||||
|  | ||||
| 			try  | ||||
| 			{ | ||||
| 				IntPtr hThread = NamedPipeNative.GetCurrentThread(); | ||||
| 				uint iDesiredInfo = 24; //TOKEN_QUERY | TOKEN_QUERY_SOURCE; | ||||
| 				IntPtr userToken = Marshal.AllocHGlobal(4); | ||||
|  | ||||
| 				if (NamedPipeNative.OpenThreadToken(hThread, iDesiredInfo, true, out userToken)) | ||||
| 				{ | ||||
|  | ||||
| 					StringBuilder sb = new StringBuilder(); | ||||
| 					NamedPipeNative.TOKEN_USER tokUser; | ||||
| 					const int bufLength = 256; | ||||
| 					IntPtr tu = Marshal.AllocHGlobal( bufLength ); | ||||
| 					int cb = bufLength; | ||||
| 					if (NamedPipeNative.GetTokenInformation( userToken, NamedPipeNative.TOKEN_INFORMATION_CLASS.TokenUser, tu, cb, ref cb )) | ||||
| 					{					 | ||||
| 						tokUser = (NamedPipeNative.TOKEN_USER) Marshal.PtrToStructure(tu, typeof(NamedPipeNative.TOKEN_USER) );				 | ||||
| 						IntPtr pUserID = tokUser.User.Sid;								 | ||||
| 						Marshal.FreeHGlobal( tu ); | ||||
|  | ||||
| 						// get SID | ||||
| 						//string SidString = null; | ||||
| 						NamedPipeNative.ConvertSidToStringSid(pUserID, ref SidString); | ||||
|  | ||||
| 						// get token states | ||||
| 						tu = Marshal.AllocHGlobal(bufLength); | ||||
| 						cb = bufLength; | ||||
| 						NamedPipeNative.TOKEN_STATISTICS stats;			 | ||||
| 						if (NamedPipeNative.GetTokenInformation(userToken, NamedPipeNative.TOKEN_INFORMATION_CLASS.TokenStatistics, tu, cb, ref cb)) | ||||
| 						{					 | ||||
| 							stats = (NamedPipeNative.TOKEN_STATISTICS) Marshal.PtrToStructure(tu, typeof(NamedPipeNative.TOKEN_STATISTICS)); | ||||
| 							// copy low and high part										 | ||||
| 							lowPart = stats.AuthenticationId.LowPart; | ||||
| 							highPart = stats.AuthenticationId.HighPart;	 | ||||
| 							rcode = -1;		 | ||||
| 						} | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						Console.WriteLine("GetTokenInformation NOT successful"); | ||||
| 						uint error = NamedPipeNative.GetLastError(); | ||||
| 						Console.WriteLine("error" + error.ToString());				 | ||||
| 					} | ||||
|  | ||||
| 					// close handle | ||||
| 					NamedPipeNative.CloseHandle(hThread); | ||||
| 					NamedPipeNative.RevertToSelf(); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					int lastError = Marshal.GetLastWin32Error(); | ||||
| 					uint errorcode = NamedPipeNative.GetLastError(); | ||||
| 					Console.WriteLine("OpenThreadToken Error: "+ errorcode.ToString() + " code2: "+rcode.ToString()); | ||||
| 				} | ||||
| 			} | ||||
| 			catch (Exception ex) | ||||
| 			{ | ||||
| 				int error = Marshal.GetLastWin32Error(); | ||||
| 				Console.WriteLine(ex.ToString()); | ||||
| 				return rcode; | ||||
| 			} | ||||
| 			// end | ||||
|  | ||||
| 			return rcode; | ||||
|  | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										63
									
								
								c_micasad/communication/win/NamedPipes/PipeHandle.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								c_micasad/communication/win/NamedPipes/PipeHandle.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| ////////////////////////////////////////////////// | ||||
| // Created by Ivan Latunov - IvanWeb.com        // | ||||
| //----------------------------------------------// | ||||
| // This program is free software. You can       // | ||||
| // redistribute it and/or modify it as you wish // | ||||
| ////////////////////////////////////////////////// | ||||
|  | ||||
|  | ||||
| using System; | ||||
|  | ||||
| using sscs.communication.win.InterProcessComm; | ||||
|  | ||||
| namespace sscs.communication.win.NamedPipes { | ||||
| 	#region Comments | ||||
| 	/// <summary> | ||||
| 	/// Holds the operating system native handle and the current state of the pipe connection. | ||||
| 	/// </summary> | ||||
| 	#endregion | ||||
| 	public sealed class PipeHandle { | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// The operating system native handle. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public IntPtr Handle; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// The current state of the pipe connection. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public InterProcessConnectionState State; | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Creates a PipeHandle instance using the passed native handle. | ||||
| 		/// </summary> | ||||
| 		/// <param name="hnd">The native handle.</param> | ||||
| 		#endregion | ||||
| 		public PipeHandle (int hnd) { | ||||
| 			this.Handle = new IntPtr(hnd); | ||||
| 			this.State = InterProcessConnectionState.NotSet; | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Creates a PipeHandle instance using the provided native handle and state. | ||||
| 		/// </summary> | ||||
| 		/// <param name="hnd">The native handle.</param> | ||||
| 		/// <param name="state">The state of the pipe connection.</param> | ||||
| 		#endregion | ||||
| 		public PipeHandle (int hnd, InterProcessConnectionState state) { | ||||
| 			this.Handle = new IntPtr(hnd); | ||||
| 			this.State = state; | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Creates a PipeHandle instance with an invalid native handle. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public PipeHandle () { | ||||
| 			this.Handle = new IntPtr(NamedPipeNative.INVALID_HANDLE_VALUE); | ||||
| 			this.State = InterProcessConnectionState.NotSet; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										145
									
								
								c_micasad/communication/win/NamedPipes/PipeManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								c_micasad/communication/win/NamedPipes/PipeManager.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,145 @@ | ||||
| using System; | ||||
| using System.Collections; | ||||
| using System.Threading; | ||||
| using System.Web; | ||||
| using System.IO; | ||||
| using System.Configuration; | ||||
| using System.Diagnostics; | ||||
|  | ||||
| using sscs.communication.win.InterProcessComm; | ||||
| using sscs.communication.win.NamedPipes; | ||||
|  | ||||
| namespace sscs.communication.win { | ||||
|  | ||||
| 	public class PipeManager : IChannelManager { | ||||
|  | ||||
| 		public Hashtable Pipes; | ||||
|  | ||||
| 		private uint NumberPipes = 5; | ||||
| 		private uint OutBuffer = 65536; //512; | ||||
| 		private uint InBuffer = 65536; //512; | ||||
| 		private const int MAX_READ_BYTES = 5000; | ||||
| 		private bool _listen = true; | ||||
| 		public bool Listen { | ||||
| 			get { | ||||
| 				return _listen; | ||||
| 			} | ||||
| 			set { | ||||
| 				_listen=value; | ||||
| 			} | ||||
| 		} | ||||
| 		private int numChannels = 0; | ||||
| 		private Hashtable _pipes = new Hashtable(); | ||||
| 		//private Thread MainThread; | ||||
| 		//private string PipeName = XTIER_RPC_PIPE; | ||||
| 		private string XTIER_RPC_PIPE = "\\\\.\\PIPE\\SS_RPC_PIPE"; | ||||
| 		private ManualResetEvent Mre; | ||||
| 		private const int PIPE_MAX_STUFFED_TIME = 5000; | ||||
| 		 | ||||
| 		public object SyncRoot = new object(); | ||||
|  | ||||
| 		public void Initialize() { | ||||
| 			Pipes = Hashtable.Synchronized(_pipes); | ||||
| 			Mre = new ManualResetEvent(false); | ||||
| 			/* | ||||
| 			MainThread = new Thread(new ThreadStart(Start)); | ||||
| 			MainThread.IsBackground = true; | ||||
| 			MainThread.Name = "Main Pipe Thread"; | ||||
| 			MainThread.Start(); | ||||
| 			*/ | ||||
| 			Thread.Sleep(1000); | ||||
| 		} | ||||
| 		public string HandleRequest(string request) { | ||||
| 			string returnVal; | ||||
|  | ||||
| 			//Form1.ActivityRef.AppendText(request + Environment.NewLine); | ||||
| 			returnVal = "Response to: " + request; | ||||
|  | ||||
| 			return returnVal; | ||||
| 		} | ||||
|  | ||||
| 		public void Start() { | ||||
| 			try { | ||||
| 				while (_listen) { | ||||
| 					int[] keys = new int[Pipes.Keys.Count]; | ||||
| 					Pipes.Keys.CopyTo(keys,0); | ||||
| 					foreach (int key in keys) { | ||||
| 						ServerNamedPipe serverPipe = (ServerNamedPipe)Pipes[key]; | ||||
| 						if (serverPipe != null && DateTime.Now.Subtract(serverPipe.LastAction).Milliseconds > PIPE_MAX_STUFFED_TIME && serverPipe.PipeConnection.GetState() != InterProcessConnectionState.WaitingForClient) { | ||||
| 							serverPipe.Listen = false; | ||||
| 							serverPipe.PipeThread.Abort(); | ||||
| 							RemoveServerChannel(serverPipe.PipeConnection.NativeHandle); | ||||
| 						} | ||||
| 					} | ||||
| 					if (numChannels <= NumberPipes) { | ||||
| 						ServerNamedPipe pipe = new ServerNamedPipe(XTIER_RPC_PIPE, OutBuffer, InBuffer, MAX_READ_BYTES); | ||||
| 						try { | ||||
| 							pipe.Connect(); | ||||
| 							pipe.LastAction = DateTime.Now; | ||||
| 							System.Threading.Interlocked.Increment(ref numChannels); | ||||
| 							pipe.Start(); | ||||
| 							Pipes.Add(pipe.PipeConnection.NativeHandle, pipe); | ||||
| 						} | ||||
| 						catch (InterProcessIOException) { | ||||
| 							RemoveServerChannel(pipe.PipeConnection.NativeHandle); | ||||
| 							pipe.Dispose(); | ||||
| 						} | ||||
| 					} | ||||
| 					else { | ||||
| 						Mre.Reset(); | ||||
| 						Mre.WaitOne(1000, false); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			catch (Exception e) | ||||
| 			{ | ||||
| 				Console.WriteLine("Exception starting server: "+e.ToString()); | ||||
| 				// Log exception | ||||
| 			} | ||||
| 		} | ||||
| 		public void Stop() { | ||||
| 			_listen = false; | ||||
| 			Mre.Set(); | ||||
| 			try { | ||||
| 				int[] keys = new int[Pipes.Keys.Count]; | ||||
| 				Pipes.Keys.CopyTo(keys,0); | ||||
| 				foreach (int key in keys) { | ||||
| 					((ServerNamedPipe)Pipes[key]).Listen = false; | ||||
| 				} | ||||
| 				int i = numChannels * 3; | ||||
| 				for (int j = 0; j < i; j++) { | ||||
| 					StopServerPipe(); | ||||
| 				} | ||||
| 				Pipes.Clear(); | ||||
| 				Mre.Close(); | ||||
| 				Mre = null; | ||||
| 			}  | ||||
| 			catch {	 | ||||
| 				// Log exception | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		public void WakeUp() { | ||||
| 			if (Mre != null) { | ||||
| 				Mre.Set(); | ||||
| 			} | ||||
| 		} | ||||
| 		private void StopServerPipe() { | ||||
| 			try { | ||||
| 				ClientPipeConnection pipe = new ClientPipeConnection(XTIER_RPC_PIPE); | ||||
| 				if (pipe.TryConnect()) { | ||||
| 					pipe.Close(); | ||||
| 				} | ||||
| 			} catch {	 | ||||
| 				// Log exception | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		public void RemoveServerChannel(object param) { | ||||
| 			int handle = (int)param; | ||||
| 			System.Threading.Interlocked.Decrement(ref numChannels); | ||||
| 			Pipes.Remove(handle); | ||||
| 			this.WakeUp(); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										105
									
								
								c_micasad/communication/win/NamedPipes/ServerNamedPipe.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								c_micasad/communication/win/NamedPipes/ServerNamedPipe.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | ||||
| using System; | ||||
| using System.Threading; | ||||
| using System.IO; | ||||
|  | ||||
| using sscs.communication.win.InterProcessComm; | ||||
| using sscs.communication.win.NamedPipes; | ||||
|  | ||||
| namespace sscs.communication.win { | ||||
|  | ||||
| 	public sealed class ServerNamedPipe : IDisposable { | ||||
| 		internal Thread PipeThread; | ||||
| 		internal ServerPipeConnection PipeConnection; | ||||
| 		internal bool Listen = true; | ||||
| 		internal DateTime LastAction; | ||||
| 		private bool disposed = false; | ||||
|  | ||||
| 		private void PipeListener() { | ||||
| 			CheckIfDisposed(); | ||||
| 			try { | ||||
| 				Listen = true;				 | ||||
| 				while (Listen) { | ||||
| 					LastAction = DateTime.Now; | ||||
|  | ||||
| 					// Service Client (new code) | ||||
| 					IPCChannel ipcChannel = IPCChannel.Create(PipeConnection); | ||||
| 					AppHandler appHandler = new AppHandler(ipcChannel); | ||||
|  | ||||
| 					try | ||||
| 					{ | ||||
| 						int retVal = appHandler.ServiceApp(); | ||||
| 					}  | ||||
| 					catch(Exception) | ||||
| 					{						 | ||||
| 						ipcChannel.Close(); | ||||
| 					} | ||||
|  | ||||
| 					LastAction = DateTime.Now; | ||||
| 					PipeConnection.Disconnect(); | ||||
| 					if (Listen) { | ||||
| 						Connect(); | ||||
| 					} | ||||
| 					WinCommunication.PipeManager.WakeUp(); | ||||
| 				} | ||||
| 			}  | ||||
| 			catch (System.Threading.ThreadAbortException) { } | ||||
| 			catch (System.Threading.ThreadStateException) { } | ||||
| 			catch (Exception) {  | ||||
| 				// Log exception | ||||
| 			 | ||||
| 			} | ||||
| 			finally { | ||||
| 				this.Close(); | ||||
| 			} | ||||
| 		} | ||||
| 		internal void Connect() { | ||||
| 			CheckIfDisposed(); | ||||
| 			PipeConnection.Connect(); | ||||
| 		} | ||||
| 		internal void Close() { | ||||
| 			CheckIfDisposed(); | ||||
| 			this.Listen = false; | ||||
| 			WinCommunication.PipeManager.RemoveServerChannel(this.PipeConnection.NativeHandle); | ||||
| 			this.Dispose(); | ||||
| 		} | ||||
| 		internal void Start() { | ||||
| 			CheckIfDisposed(); | ||||
| 			PipeThread.Start(); | ||||
| 		} | ||||
| 		private void CheckIfDisposed() { | ||||
| 			if(this.disposed) { | ||||
| 				throw new ObjectDisposedException("ServerNamedPipe"); | ||||
| 			} | ||||
| 		} | ||||
| 		public void Dispose() { | ||||
| 			Dispose(true); | ||||
| 			GC.SuppressFinalize(this); | ||||
| 		} | ||||
| 		private void Dispose(bool disposing) { | ||||
| 			if(!this.disposed) { | ||||
| 				PipeConnection.Dispose(); | ||||
| 				if (PipeThread != null) { | ||||
| 					try { | ||||
| 						PipeThread.Abort(); | ||||
| 					}  | ||||
| 					catch (System.Threading.ThreadAbortException) { } | ||||
| 					catch (System.Threading.ThreadStateException) { } | ||||
| 					catch (Exception) { | ||||
| 						// Log exception | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			disposed = true;          | ||||
| 		} | ||||
| 		~ServerNamedPipe() { | ||||
| 			Dispose(false); | ||||
| 		} | ||||
| 		internal ServerNamedPipe(string name, uint outBuffer, uint inBuffer, int maxReadBytes) { | ||||
| 			PipeConnection = new ServerPipeConnection(name, outBuffer, inBuffer, maxReadBytes); | ||||
| 			PipeThread = new Thread(new ThreadStart(PipeListener)); | ||||
| 			PipeThread.IsBackground = true; | ||||
| 			PipeThread.Name = "Pipe Thread " + this.PipeConnection.NativeHandle.ToString(); | ||||
| 			LastAction = DateTime.Now; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,85 @@ | ||||
| ////////////////////////////////////////////////// | ||||
| // Created by Ivan Latunov - IvanWeb.com        // | ||||
| //----------------------------------------------// | ||||
| // This program is free software. You can       // | ||||
| // redistribute it and/or modify it as you wish // | ||||
| ////////////////////////////////////////////////// | ||||
|  | ||||
|  | ||||
| using System; | ||||
| using System.IO; | ||||
|  | ||||
| using sscs.communication.win.InterProcessComm; | ||||
|  | ||||
| namespace sscs.communication.win.NamedPipes { | ||||
| 	#region Comments | ||||
| 	/// <summary> | ||||
| 	/// Used by server applications to communicate with client ones by using named pipes. | ||||
| 	/// </summary> | ||||
| 	#endregion | ||||
| 	public sealed class ServerPipeConnection : APipeConnection { | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Disconnects a client named pipe. | ||||
| 		/// </summary> | ||||
| 		/// <remarks> | ||||
| 		/// When a client named pipe is disconnected, the server one is not closed.  | ||||
| 		/// The latter can later be reused by starting to listen again.<br/><br/> | ||||
| 		/// In a message oriented protocol the server will disconnect the client when the  | ||||
| 		/// response is sent and all the data is flushed. The same server named pipe  | ||||
| 		/// could then be reused by calling the  | ||||
| 		/// <see cref="AppModule.NamedPipes.ServerPipeConnection.Connect">Connect</see> method. | ||||
| 		/// </remarks> | ||||
| 		#endregion | ||||
| 		public void Disconnect() { | ||||
| 			CheckIfDisposed(); | ||||
| 			NamedPipeWrapper.Disconnect(this.Handle); | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Closes the operating system native handle of the named pipe. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		public override void Close() { | ||||
| 			CheckIfDisposed(); | ||||
| 			NamedPipeWrapper.Close(this.Handle); | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Starts listening to client pipe connections. | ||||
| 		/// </summary> | ||||
| 		/// <remarks> | ||||
| 		/// This method will block the program execution until a client pipe attempts | ||||
| 		/// to establish a connection.<br/><br/> | ||||
| 		/// When a client named pipe is disconnected, the server one is not closed.  | ||||
| 		/// The latter can later be reused by starting to listen again.<br/><br/> | ||||
| 		/// </remarks> | ||||
| 		#endregion | ||||
| 		public override void Connect() { | ||||
| 			CheckIfDisposed(); | ||||
| 			NamedPipeWrapper.Connect(this.Handle); | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Creates a ServerPipeConnection instance and the underlying operating system handle. | ||||
| 		/// </summary> | ||||
| 		/// <param name="name">The name of the pipe.</param> | ||||
| 		/// <param name="outBuffer">The outbound buffer.</param> | ||||
| 		/// <param name="inBuffer">The inbound buffer.</param> | ||||
| 		/// <param name="maxReadBytes">The maximum bytes to read from clients.</param> | ||||
| 		#endregion | ||||
| 		public ServerPipeConnection(string name, uint outBuffer, uint inBuffer, int maxReadBytes) { | ||||
| 			this.Name = name; | ||||
| 			this.Handle = NamedPipeWrapper.Create(name, outBuffer, inBuffer); | ||||
| 			this.maxReadBytes = maxReadBytes; | ||||
| 		} | ||||
| 		#region Comments | ||||
| 		/// <summary> | ||||
| 		/// Object destructor. | ||||
| 		/// </summary> | ||||
| 		#endregion | ||||
| 		~ServerPipeConnection() { | ||||
| 			Dispose(false); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user