public WindowsPrincipal GetClientPrincipal() { // check object state if (!_isConnected) { throw new InvalidOperationException("Pipe is not connected"); } // impersonate client if (!PipeNative.ImpersonateNamedPipeClient(_handle)) { throw new PipeIOException(Marshal.GetLastWin32Error(), "Could not impersonate client"); } try { // get client identity return(new WindowsPrincipal(WindowsIdentity.GetCurrent())); } finally { // undo impersonation PipeNative.RevertToSelf(); } }
/// <summary> /// Returns information about data in the pipe /// </summary> public int GetBytesAvailable() { // check object state if (_disposed) { throw new ObjectDisposedException(GetType().FullName); } if (_instance == null) { throw new InvalidOperationException("Pipe is not connected"); } // check pipe buffer int bytesRead; int totalBytes; int bytesLeftThisMessage; bool error = PipeNative.PeekNamedPipe( _instance.Handle, IntPtr.Zero, 0, out bytesRead, out totalBytes, out bytesLeftThisMessage); if (!error) { // error occured throw new PipeIOException(Marshal.GetLastWin32Error(), "Could not read data from the pipe: " + _instance.Name); } return(totalBytes); }
public static PipeInstance Create(PipeName pipeName, bool firstInstance, SecurityDescriptor securityDescriptor) { // parameters validation if (pipeName == null) { throw new ArgumentNullException("pipeName", "Pipe name must be specified"); } if (!pipeName.IsLocal) { throw new ArgumentException("Could not bind to the remote pipe"); } PipeNative.SecurityAttributes secAttrs = new PipeNative.SecurityAttributes(); secAttrs.SecurityDescriptor = (securityDescriptor == null ? IntPtr.Zero : securityDescriptor.Handle); secAttrs.InheritHandle = true; // try to create pipe IntPtr handle = PipeNative.CreateNamedPipe(pipeName.ToString(), PipeNative.PIPE_ACCESS_DUPLEX | PipeNative.FILE_FLAG_OVERLAPPED | (firstInstance ? PipeNative.FILE_FLAG_FIRST_PIPE_INSTANCE : 0), PipeNative.PIPE_TYPE_BYTE | PipeNative.PIPE_READMODE_BYTE | PipeNative.PIPE_WAIT, PipeNative.PIPE_UNLIMITED_INSTANCES, OutBufferSize, InBufferSize, PipeNative.NMPWAIT_USE_DEFAULT_WAIT, secAttrs); if (handle == Win32.InvalidHandle) { throw new PipeIOException(Marshal.GetLastWin32Error(), "Could not create pipe: " + pipeName); } else { return(new PipeInstance(pipeName, handle, false)); } }
/// <summary> /// Initiates send operation /// </summary> public IAsyncResult BeginSend(byte[] buffer, int offset, int size, AsyncCallback callback, object state) { // check object state if (_disposed) { throw new ObjectDisposedException(GetType().FullName); } if (_instance == null) { throw new InvalidOperationException("Pipe is not connected"); } // parameters validation if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0 || offset > buffer.Length) { throw new ArgumentOutOfRangeException("offset"); } if (size < 0 || size > buffer.Length - offset) { throw new ArgumentOutOfRangeException("size"); } // write data to the pipe GCHandle gcBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned); PipeOverlappedAsyncResult asyncResult = new PipeOverlappedAsyncResult(gcBuffer, callback, state); int error = asyncResult.CheckForCompletion(PipeNative.WriteFile( _instance.Handle, Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset), size, IntPtr.Zero, asyncResult.OverlappedHandle)); switch (error) { case Win32.ERROR_SUCCESS: // operation completed synchronously break; case PipeNative.ERROR_IO_PENDING: // async operation was pended break; default: // error occured asyncResult.Dispose(); throw new PipeIOException(error, "Could not write data to the pipe: " + _instance.Name); } return(asyncResult); }
public void Close() { if (_isConnected) { // flush the pipe to allow the client to read the pipe's contents // before disconnecting PipeNative.FlushFileBuffers(_handle); PipeNative.DisconnectNamedPipe(_handle); } // close handle _handle.Dispose(); }
/// <summary> /// Copies data into a buffer without removing it from the pipe /// </summary> public int Peek(byte[] buffer, int offset, int size) { // check object state if (_disposed) { throw new ObjectDisposedException(GetType().FullName); } if (_instance == null) { throw new InvalidOperationException("Pipe is not connected"); } // parameters validation if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0 || offset > buffer.Length) { throw new ArgumentOutOfRangeException("offset"); } if (size < 0 || size > buffer.Length - offset) { throw new ArgumentOutOfRangeException("size"); } // read data from the pipe GCHandle gcBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned); int bytesRead; int totalBytes; int bytesLeftThisMessage; bool error = PipeNative.PeekNamedPipe( _instance.Handle, Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset), size, out bytesRead, out totalBytes, out bytesLeftThisMessage); gcBuffer.Free(); if (!error) { // error occured throw new PipeIOException(Marshal.GetLastWin32Error(), "Could not read data from the pipe: " + _instance.Name); } return(bytesRead); }
private void SetCompleted(bool completedSynchronously) { if (Interlocked.CompareExchange(ref _completed, 1, 0) == 0) { // store result _result = PipeNative.HackedGetOverlappedResult(_pOverlapped, out _totalBytes); _completedSynchronously = completedSynchronously; if (completedSynchronously) { // signal completion _asyncEvent.Set(); } // free unmanaged resources Dispose(); } }
/// <summary> /// Flushes internal pipe buffers /// </summary> public void Flush() { // check object state if (_disposed) { throw new ObjectDisposedException(GetType().FullName); } if (_instance == null) { throw new InvalidOperationException("Pipe is not connected"); } // flush buffers if (!PipeNative.FlushFileBuffers(_instance.Handle)) { throw new PipeIOException(); } }
public void DisconnectFromClient() { // check object state if (!_isConnected) { throw new InvalidOperationException("Pipe is not connected"); } // flush internal buffers if (!PipeNative.FlushFileBuffers(_handle)) { throw new PipeIOException(); } // disconnect from the client if (!PipeNative.DisconnectNamedPipe(_handle)) { throw new PipeIOException(); } _isConnected = false; }
public static PipeInstance Connect(PipeName pipeName) { // parameters validation if (pipeName == null) { throw new ArgumentNullException("pipeName", "Pipe name must be specified"); } while (true) { // try to connect to the pipe IntPtr handle = PipeNative.CreateFile(pipeName.ToString(), PipeNative.GENERIC_READ | PipeNative.GENERIC_WRITE, PipeNative.FILE_SHARE_NONE, null, PipeNative.OPEN_EXISTING, PipeNative.FILE_FLAG_OVERLAPPED, IntPtr.Zero); if (handle == Win32.InvalidHandle) { int errorCode = Marshal.GetLastWin32Error(); if (errorCode != PipeNative.ERROR_PIPE_BUSY) { throw new PipeIOException(errorCode, "Could not open pipe: " + pipeName); } if (!PipeNative.WaitNamedPipe(pipeName.ToString(), PipeNative.NMPWAIT_USE_DEFAULT_WAIT)) { throw new PipeIOException(errorCode, "Specified pipe was over-burdened: " + pipeName); } } else { return(new PipeInstance(pipeName, handle, true)); } } }
public void WaitForClientConnection() { // check object state if (_isConnected) { throw new InvalidOperationException("Pipe is already connected"); } // connect to the client PipeOverlappedAsyncResult asyncResult = new PipeOverlappedAsyncResult(); int error = asyncResult.CheckForCompletion(PipeNative.ConnectNamedPipe( _handle, asyncResult.OverlappedHandle)); switch (error) { case Win32.ERROR_SUCCESS: // operation completed synchronously break; case PipeNative.ERROR_PIPE_CONNECTED: // client already connected break; case PipeNative.ERROR_IO_PENDING: // async operation was pended asyncResult.WaitForCompletion(); break; default: // error occured throw new PipeIOException(error, "Unable to connect client to the pipe: " + _pipeName); } _isConnected = true; }