Пример #1
0
        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();
            }
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        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));
            }
        }
Пример #4
0
        /// <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);
        }
Пример #5
0
        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();
        }
Пример #6
0
        /// <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();
            }
        }
Пример #8
0
        /// <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();
            }
        }
Пример #9
0
        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;
        }
Пример #10
0
        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));
                }
            }
        }
Пример #11
0
        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;
        }