Abstract NamedPipes code for windows

This commit is contained in:
Jim Norman 2006-01-17 23:07:05 +00:00
parent 12209176e7
commit bacd2e534e
21 changed files with 29 additions and 2463 deletions

View File

@ -2,7 +2,7 @@ using System;
using System.Net;
using System.Net.Sockets;
#if W32
using sscs.communication.win.NamedPipes;
using AppModule.NamedPipes;
#endif
using sscs.common;
namespace sscs.communication

View File

@ -2,8 +2,9 @@ using System;
using sscs.common;
using sscs.constants;
using sscs.communication.win.InterProcessComm;
using sscs.communication.win.NamedPipes;
using AppModule.InterProcessComm;
using AppModule.NamedPipes;
using sscs.communication.win;
namespace sscs.communication
{
@ -17,7 +18,7 @@ namespace sscs.communication
public WinCommunication()
{
PipeManager = new sscs.communication.win.PipeManager();
PipeManager = new PipeManager();
PipeManager.Initialize();
}
@ -27,9 +28,7 @@ namespace sscs.communication
//PipeManager = new PipeManager();
//PipeManager.Initialize();
//PipeManager.Start();
PipeManager.Start();
PipeManager.Start();
}
public void CloseCommunicationEndPoint()

View File

@ -2,7 +2,8 @@ using System;
using System.IO;
using System.Text;
using sscs.communication.win.NamedPipes;
using AppModule.NamedPipes;
using sscs.communication.win;
using sscs.common;
using sscs.verbs;
using sscs.constants;

View File

@ -1,72 +0,0 @@
//////////////////////////////////////////////////
// Created by Ivan Latunov - IvanWeb.com //
//----------------------------------------------//
// This program is free software. You can //
// redistribute it and/or modify it as you wish //
//////////////////////////////////////////////////
using System;
namespace sscs.communication.win.InterProcessComm {
#region Comments
/// <summary>
/// Interface, which defines methods for a Channel Manager class.
/// </summary>
/// <remarks>
/// A Channel Manager is responsible for creating and maintaining channels for inter-process communication. The opened channels are meant to be reusable for performance optimization. Each channel needs to procees requests by calling the <see cref="AppModule.InterProcessComm.IChannelManager.HandleRequest">HandleRequest</see> method of the Channel Manager.
/// </remarks>
#endregion
public interface IChannelManager {
#region Comments
/// <summary>
/// Initializes the Channel Manager.
/// </summary>
#endregion
void Initialize();
#region Comments
/// <summary>
/// Closes all opened channels and stops the Channel Manager.
/// </summary>
#endregion
void Start();
void Stop();
#region Comments
/// <summary>
/// Handles a request.
/// </summary>
/// <remarks>
/// This method currently caters for text based requests. XML strings can be used in case complex request structures are needed.
/// </remarks>
/// <param name="request">The incoming request.</param>
/// <returns>The resulting response.</returns>
#endregion
string HandleRequest(string request);
#region Comments
/// <summary>
/// Indicates whether the Channel Manager is in listening mode.
/// </summary>
/// <remarks>
/// This property is left public so that other classes, like a server channel can start or stop listening based on the Channel Manager mode.
/// </remarks>
#endregion
bool Listen {get; set;}
#region Comments
/// <summary>
/// Forces the Channel Manager to exit a sleeping mode and create a new channel.
/// </summary>
/// <remarks>
/// Normally the Channel Manager will create a number of reusable channels, which will handle the incoming reqiests, and go into a sleeping mode. However if the request load is high, the Channel Manager needs to be asked to create additional channels.
/// </remarks>
#endregion
void WakeUp();
#region Comments
/// <summary>
/// Removes an existing channel.
/// </summary>
/// <param name="param">A parameter identifying the channel.</param>
#endregion
void RemoveServerChannel(object param);
}
}

View File

@ -1,51 +0,0 @@
//////////////////////////////////////////////////
// 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;
namespace sscs.communication.win.InterProcessComm {
#region Comments
/// <summary>
///
/// </summary>
#endregion
public interface IClientChannel : IDisposable {
#region Comments
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
#endregion
string HandleRequest(string request);
#region Comments
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
#endregion
string HandleRequest(Stream request);
#region Comments
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
#endregion
object HandleRequest(object request);
#region Comments
/// <summary>
///
/// </summary>
/// <returns></returns>
#endregion
IClientChannel Create();
}
}

View File

@ -1,72 +0,0 @@
//////////////////////////////////////////////////
// Created by Ivan Latunov - IvanWeb.com //
//----------------------------------------------//
// This program is free software. You can //
// redistribute it and/or modify it as you wish //
//////////////////////////////////////////////////
using System;
namespace sscs.communication.win.InterProcessComm {
#region Comments
/// <summary>
///
/// </summary>
#endregion
public interface IInterProcessConnection : IDisposable {
#region Comments
/// <summary>
///
/// </summary>
#endregion
int NativeHandle{get;}
#region Comments
/// <summary>
///
/// </summary>
#endregion
void Connect();
#region Comments
/// <summary>
///
/// </summary>
#endregion
void Close();
#region Comments
/// <summary>
///
/// </summary>
/// <returns></returns>
#endregion
string Read();
#region Comments
/// <summary>
///
/// </summary>
/// <returns></returns>
#endregion
byte[] ReadBytes();
#region Comments
/// <summary>
///
/// </summary>
/// <param name="text"></param>
#endregion
void Write(string text);
#region Comments
/// <summary>
///
/// </summary>
/// <param name="bytes"></param>
#endregion
void WriteBytes(byte[] bytes);
#region Comments
/// <summary>
///
/// </summary>
/// <returns></returns>
#endregion
InterProcessConnectionState GetState();
}
}

View File

@ -1,127 +0,0 @@
//////////////////////////////////////////////////
// Created by Ivan Latunov - IvanWeb.com //
//----------------------------------------------//
// This program is free software. You can //
// redistribute it and/or modify it as you wish //
//////////////////////////////////////////////////
using System;
namespace sscs.communication.win.InterProcessComm {
#region Comments
/// <summary>
///
/// </summary>
#endregion
public enum InterProcessConnectionState {
#region Comments
/// <summary>
///
/// </summary>
#endregion
NotSet = 0,
#region Comments
/// <summary>
///
/// </summary>
#endregion
Error = 1,
#region Comments
/// <summary>
///
/// </summary>
#endregion
Creating = 2,
#region Comments
/// <summary>
///
/// </summary>
#endregion
Created = 3,
#region Comments
/// <summary>
///
/// </summary>
#endregion
WaitingForClient = 4,
#region Comments
/// <summary>
///
/// </summary>
#endregion
ConnectedToClient = 5,
#region Comments
/// <summary>
///
/// </summary>
#endregion
ConnectingToServer = 6,
#region Comments
/// <summary>
///
/// </summary>
#endregion
ConnectedToServer = 7,
#region Comments
/// <summary>
///
/// </summary>
#endregion
Reading = 8,
#region Comments
/// <summary>
///
/// </summary>
#endregion
ReadData = 9,
#region Comments
/// <summary>
///
/// </summary>
#endregion
Writing = 10,
#region Comments
/// <summary>
///
/// </summary>
#endregion
WroteData = 11,
#region Comments
/// <summary>
///
/// </summary>
#endregion
Flushing = 12,
#region Comments
/// <summary>
///
/// </summary>
#endregion
FlushedData = 13,
#region Comments
/// <summary>
///
/// </summary>
#endregion
Disconnecting = 14,
#region Comments
/// <summary>
///
/// </summary>
#endregion
Disconnected = 15,
#region Comments
/// <summary>
///
/// </summary>
#endregion
Closing = 16,
#region Comments
/// <summary>
///
/// </summary>
#endregion
Closed = 17,
}
}

View File

@ -1,49 +0,0 @@
//////////////////////////////////////////////////
// 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;
namespace sscs.communication.win.InterProcessComm {
#region Comments
/// <summary>
///
/// </summary>
#endregion
public class InterProcessIOException : Exception {
#region Comments
/// <summary>
///
/// </summary>
#endregion
public bool IsServerAvailable = true;
#region Comments
/// <summary>
///
/// </summary>
#endregion
public uint ErrorCode = 0;
#region Comments
/// <summary>
///
/// </summary>
/// <param name="text"></param>
#endregion
public InterProcessIOException(String text) : base(text) {
}
#region Comments
/// <summary>
///
/// </summary>
/// <param name="info"></param>
/// <param name="context"></param>
#endregion
protected InterProcessIOException(SerializationInfo info, StreamingContext context) : base(info, context) {
}
}
}

View File

@ -1,184 +0,0 @@
//////////////////////////////////////////////////
// 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);
}
}
}

View File

@ -1,110 +0,0 @@
//////////////////////////////////////////////////
// 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);
}
}
}

View File

@ -1,52 +0,0 @@
//////////////////////////////////////////////////
// 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) {
}
}
}

View File

@ -1,641 +0,0 @@
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 {
}
}

View File

@ -1,628 +0,0 @@
//////////////////////////////////////////////////
// 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;
}
}
}

View File

@ -1,63 +0,0 @@
//////////////////////////////////////////////////
// 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;
}
}
}

View File

@ -1,145 +0,0 @@
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();
}
}
}

View File

@ -1,105 +0,0 @@
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;
}
}
}

View File

@ -1,85 +0,0 @@
//////////////////////////////////////////////////
// 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);
}
}
}

View File

@ -80,14 +80,14 @@
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
/>
<Reference
Name = "AppModule.NamedPipes"
AssemblyName = "AppModule.NamedPipes"
HintPath = "..\..\extern\w32\namedpipes\AppModule.NamedPipes.dll"
Name = "AppModule.InterProcessComm"
Project = "{E98F1F7E-40B6-44C8-AC66-EC867B141FA1}"
Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
/>
<Reference
Name = "AppModule.InterProcessComm"
AssemblyName = "AppModule.InterProcessComm"
HintPath = "..\..\extern\w32\namedpipes\AppModule.InterProcessComm.dll"
Name = "AppModule.NamedPipes"
Project = "{077B53BB-404A-4B2F-BA17-AAE98C5E9C66}"
Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
/>
</References>
</Build>

View File

@ -1,7 +1,7 @@
<VisualStudioProject>
<CSHARP LastOpenVersion = "7.10.3077" >
<Build>
<Settings ReferencePath = "D:\csharp\namedpipe2\AppModule.InterProcessComm\bin\Debug\;D:\csharp\namedpipe2\AppModule.NamedPipes\bin\Debug\;D:\casatest\extern\w32\namedpipes\;D:\casaoutside\extern\w32\namedpipes\" >
<Settings ReferencePath = "D:\csharp\namedpipe2\AppModule.InterProcessComm\bin\Debug\;D:\csharp\namedpipe2\AppModule.NamedPipes\bin\Debug\;D:\casatest\extern\w32\namedpipes\;D:\casaoutside\extern\w32\namedpipes\;D:\casaAll\trunk\extern\w32\namedpipes\" >
<Config
Name = "Debug"
EnableASPDebugging = "false"

View File

@ -9,8 +9,8 @@ namespace Novell.CASA.MiCasa.Common
[Serializable]
public class LinkedKeyInfo
{
private string m_sDestStoreID = null;
private string m_sDestKeychainID = null;
//private string m_sDestStoreID = null;
//private string m_sDestKeychainID = null;
private string m_sDestSecretID = null;
private string m_sDestKeyID = null;

View File

@ -119,6 +119,16 @@
Project = "{57CD94A2-5B4A-40C3-8189-CB760FB78357}"
Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
/>
<Reference
Name = "AppModule.InterProcessComm"
Project = "{E98F1F7E-40B6-44C8-AC66-EC867B141FA1}"
Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
/>
<Reference
Name = "AppModule.NamedPipes"
Project = "{077B53BB-404A-4B2F-BA17-AAE98C5E9C66}"
Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
/>
</References>
</Build>
<Files>
@ -229,72 +239,12 @@
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\InterProcessComm\IChannelManager.cs"
RelPath = "communication\win\PipeManager.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\InterProcessComm\IClientChannel.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\InterProcessComm\IInterProcessConnection.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\InterProcessComm\InterProcessConnectionState.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\InterProcessComm\InterProcessIOException.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\NamedPipes\APipeConnection.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\NamedPipes\ClientPipeConnection.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\NamedPipes\NamedPipeIOException.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\NamedPipes\NamedPipeNative.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\NamedPipes\NamedPipeWrapper.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\NamedPipes\PipeHandle.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\NamedPipes\PipeManager.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\NamedPipes\ServerNamedPipe.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\NamedPipes\ServerPipeConnection.cs"
RelPath = "communication\win\ServerNamedPipe.cs"
SubType = "Code"
BuildAction = "Compile"
/>