/// <summary> /// Connects to a local Named Pipe server. /// </summary> /// <param name="timeout">Timeout in millisecons to wait for the connection.</param> /// <returns></returns> public NamedPipeSocket Connect(int timeout) { while (true) { IntPtr hPipe = NamedPipeHelper.CreateFile( pipeName, NamedPipeHelper.GENERIC_READ | NamedPipeHelper.GENERIC_WRITE, 0, IntPtr.Zero, NamedPipeHelper.OPEN_EXISTING, 0, IntPtr.Zero ); if (hPipe.ToInt32() == NamedPipeHelper.INVALID_HANDLE_VALUE) { int lastError = Marshal.GetLastWin32Error(); if (lastError != NamedPipeHelper.ERROR_PIPE_BUSY) { throw new NamedPipeException(lastError); } if (!NamedPipeHelper.WaitNamedPipe(pipeName, timeout)) { throw new NamedPipeException(); } } else { return(new NamedPipeSocket(hPipe)); } } }
/// <summary> /// Flushes the socket. /// </summary> public void Flush() { if (hPipe == IntPtr.Zero) { throw new ObjectDisposedException(GetType().FullName); } NamedPipeHelper.FlushFileBuffers(hPipe); }
/// <summary> /// Accepts a pending connection request /// </summary> /// <remarks> /// Accept is a blocking method that returns a NamedPipeSocket you can use to send and receive data. /// </remarks> /// <returns>The NamedPipeSocket.</returns> public NamedPipeSocket Accept() { IntPtr hPipe = NamedPipeHelper.CreateNamedPipe( pipeName, NamedPipeHelper.PIPE_ACCESS_DUPLEX | NamedPipeHelper.FILE_FLAG_OVERLAPPED, NamedPipeHelper.PIPE_TYPE_MESSAGE | NamedPipeHelper.PIPE_READMODE_MESSAGE | NamedPipeHelper.PIPE_WAIT, NamedPipeHelper.PIPE_UNLIMITED_INSTANCES, DefaultBufferSize, DefaultBufferSize, NamedPipeHelper.NMPWAIT_USE_DEFAULT_WAIT, IntPtr.Zero ); if (hPipe.ToInt32() == NamedPipeHelper.INVALID_HANDLE_VALUE) { throw new NamedPipeException(Marshal.GetLastWin32Error()); } // Connect the named pipe with overlapped structure // in order to make it altertable. This way we will // wake up when someone aborts a thread waiting // for this pipe. NativeOverlapped overlapped = new NativeOverlapped(); bool canConnect = NamedPipeHelper.ConnectNamedPipe(hPipe, ref overlapped); int lastError = Marshal.GetLastWin32Error(); if (!canConnect) { if (lastError == NamedPipeHelper.ERROR_IO_PENDING) { uint bytesTransferred = 0; if (!GetOverlappedResultEx(hPipe, ref overlapped, out bytesTransferred, Timeout.Infinite, true)) { lastError = Marshal.GetLastWin32Error(); NamedPipeHelper.CloseHandle(hPipe); throw new NamedPipeException(lastError); } canConnect = true; } else if (lastError == NamedPipeHelper.ERROR_PIPE_CONNECTED) { canConnect = true; } } if (!canConnect) { NamedPipeHelper.CloseHandle(hPipe); throw new NamedPipeException(lastError); } return(new NamedPipeSocket(hPipe)); }
internal NamedPipeSocketInfo(IntPtr hPipe) { bool res = NamedPipeHelper.GetNamedPipeInfo( hPipe, out Flags, out OutBufferSize, out InBufferSize, out MaxInstances ); if (!res) { throw new NamedPipeException(); } }
/// <summary> /// Impersonates the client. /// </summary> public void Impersonate() { if (hPipe == IntPtr.Zero) { throw new ObjectDisposedException(GetType().FullName); } if (Info.IsServer) { if (!NamedPipeHelper.ImpersonateNamedPipeClient(hPipe)) { throw new NamedPipeException(); } } }
/// <summary> /// Receives the specified number of bytes from a socket into /// the specified offset position of the receive buffer. /// </summary> /// <param name="buffer">An array of type Byte that is the storage /// location for received data.</param> /// <param name="offset">The location in buffer to store the received data.</param> /// <param name="count">The number of bytes to receive.</param> /// <returns>The number of bytes received.</returns> public int Receive(byte[] buffer, int offset, int count) { if (hPipe == IntPtr.Zero) { throw new ObjectDisposedException(GetType().FullName); } if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0 || count < 0) { throw new ArgumentOutOfRangeException("offset and/or count"); } if (buffer.Length - offset < count) { throw new ArgumentException(); } uint read = 0; GCHandle gch = GCHandle.Alloc(buffer, GCHandleType.Pinned); try { bool res = NamedPipeHelper.ReadFile( hPipe, Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset), (uint)count, out read, IntPtr.Zero ); if (!res && read == 0) { throw new NamedPipeException(); } return((int)read); } finally { gch.Free(); } }
/// <summary> /// Disposes the object. /// </summary> void IDisposable.Dispose() { if (hPipe != IntPtr.Zero) { try { // disconnect the pipe if (Info.IsServer) { NamedPipeHelper.FlushFileBuffers(hPipe); NamedPipeHelper.DisconnectNamedPipe(hPipe); } } catch (NamedPipeException) { } NamedPipeHelper.CloseHandle(hPipe); hPipe = IntPtr.Zero; GC.SuppressFinalize(this); } }
internal NamedPipeSocketState(IntPtr hPipe) { StringBuilder userName = new StringBuilder(256); bool res = NamedPipeHelper.GetNamedPipeHandleState( hPipe, out State, out CurrentInstances, out MaxCollectionCount, out CollectDataTimeout, userName, userName.Capacity ); if (res) { UserName = userName.ToString(); } else { throw new NamedPipeException(); } }
/// <summary> /// Accepts a pending connection request /// </summary> /// <remarks> /// Accept is a blocking method that returns a NamedPipeSocket you can use to send and receive data. /// </remarks> /// <returns>The NamedPipeSocket.</returns> public NamedPipeSocket Accept() { IntPtr hPipe = NamedPipeHelper.CreateNamedPipe( pipeName, NamedPipeHelper.PIPE_ACCESS_DUPLEX, NamedPipeHelper.PIPE_TYPE_MESSAGE | NamedPipeHelper.PIPE_READMODE_MESSAGE | NamedPipeHelper.PIPE_WAIT, NamedPipeHelper.PIPE_UNLIMITED_INSTANCES, DefaultBufferSize, DefaultBufferSize, NamedPipeHelper.NMPWAIT_USE_DEFAULT_WAIT, IntPtr.Zero ); if (hPipe.ToInt32() == NamedPipeHelper.INVALID_HANDLE_VALUE) { throw new NamedPipeException(); } bool canConnect = NamedPipeHelper.ConnectNamedPipe(hPipe, IntPtr.Zero); int lastError = Marshal.GetLastWin32Error(); if (!canConnect && lastError == NamedPipeHelper.ERROR_PIPE_CONNECTED) { canConnect = true; } if (canConnect) { return(new NamedPipeSocket(hPipe)); } else { NamedPipeHelper.CloseHandle(hPipe); throw new NamedPipeException(lastError); } }
/// <summary> /// Creates a new listener with the specified name. /// </summary> /// <param name="pipeName">The pipe name omiting the leading <c>\\.\pipe\</c></param> public NamedPipeListener(string pipeName) { this.pipeName = NamedPipeHelper.FormatPipeName(pipeName); }
/// <summary> /// Reverts the impersonation. /// </summary> public static bool RevertToSelf() { return(NamedPipeHelper.RevertToSelf()); }
/// <summary> /// Creates a new instance for the specified pipe name. /// </summary> /// <param name="pipeName">The pipe name omiting the leading <c>\\.\pipe\</c></param> public NamedPipeClient(string pipeName) { this.pipeName = NamedPipeHelper.FormatPipeName(pipeName); }