コード例 #1
0
        /// <summary>
        /// WriteMessage - write an array of bytes and return the response from the
        /// server
        /// </summary>
        /// <param name="buffer">bytes to write</param>
        /// <param name="bytesToWrite">number of bytes to write</param>
        /// <returns>true if written successfully</returns>
        public MemoryStream WriteMessage(byte[] buffer,     // the write buffer
                                         uint bytesToWrite) // number of bytes in the write buffer
        // message responses
        {
            // buffer to get the number of bytes read/written back
            byte[]       _numReadWritten = new byte[4];
            MemoryStream responseStream  = null;

            bool success = false;

            // Write the byte buffer to the pipe
            success = NamedPipeInterop.WriteFile(_handle,
                                                 buffer,
                                                 bytesToWrite,
                                                 _numReadWritten,
                                                 0);

            if (success)
            {
                byte[] responseBuffer = new byte[_responseBufferSize];
                responseStream = new MemoryStream(_responseBufferSize);
                {
                    do
                    {
                        // Read the response from the pipe.
                        success = NamedPipeInterop.ReadFile(
                            _handle,                   // pipe handle
                            responseBuffer,            // buffer to receive reply
                            (uint)_responseBufferSize, // size of buffer
                            _numReadWritten,           // number of bytes read
                            0);                        // not overlapped

                        // failed, not just more data to come
                        if (!success && Marshal.GetLastWin32Error() != NamedPipeInterop.ERROR_MORE_DATA)
                        {
                            break;
                        }

                        // concat response to stream
                        responseStream.Write(responseBuffer,
                                             0,
                                             responseBuffer.Length);
                    } while (!success);
                }
            }
            return(responseStream);
        }
コード例 #2
0
        /// <summary>
        /// CreatePipe - create the named pipe
        /// </summary>
        /// <returns>true is pipe created</returns>
        public bool CreatePipe()
        {
            // make a named pipe in message mode
            _handle = NamedPipeInterop.CreateNamedPipe(_pipeName,
                                                       NamedPipeInterop.PIPE_ACCESS_DUPLEX,
                                                       NamedPipeInterop.PIPE_TYPE_MESSAGE | NamedPipeInterop.PIPE_READMODE_MESSAGE |
                                                       NamedPipeInterop.PIPE_WAIT,
                                                       NamedPipeInterop.PIPE_UNLIMITED_INSTANCES,
                                                       PIPE_SERVER_BUFFER_SIZE,
                                                       PIPE_SERVER_BUFFER_SIZE,
                                                       NamedPipeInterop.NMPWAIT_WAIT_FOREVER,
                                                       IntPtr.Zero);

            // make sure we got a good one
            if (_handle.IsInvalid)
            {
                Debug.WriteLine("Could not create the pipe (" +
                                _pipeName + ") - os returned " +
                                Marshal.GetLastWin32Error());

                return(false);
            }
            return(true);
        }
コード例 #3
0
        /// <summary>
        /// Connect - connect to an existing pipe
        /// </summary>
        /// <returns>true if connected</returns>
        public void Connect()
        {
            if (!_handle.IsInvalid)
            {
                throw new InvalidOperationException("Pipe is already connected!");
            }

            string errMsg        = "";
            int    errCode       = 0;
            int    retryAttempts = _retryConnect;

            // keep trying to connect
            while (retryAttempts > 0)
            {
                // mark off one attempt
                retryAttempts--;

                // connect to existing pipe
                _handle = NamedPipeInterop.CreateFile(_pipeName,
                                                      NamedPipeInterop.GENERIC_READ |
                                                      NamedPipeInterop.GENERIC_WRITE,
                                                      0,
                                                      IntPtr.Zero,
                                                      NamedPipeInterop.OPEN_EXISTING,
                                                      0,
                                                      0);

                // check to see if we connected
                if (!_handle.IsInvalid)
                {
                    break;
                }

                // the pipe could not be opened as all instances are busy
                // any other error we bail for
                errCode = Marshal.GetLastWin32Error();
                if (errCode !=
                    NamedPipeInterop.ERROR_PIPE_BUSY)
                {
                    errMsg = string.Format("Could not open pipe {0} with error {1}", _pipeName, errCode);
                    Trace.WriteLine(errMsg);
                    throw new Win32Exception(errCode, errMsg);
                }
                // if it was busy, see if we can wait it out
                else if (!NamedPipeInterop.WaitNamedPipe(_pipeName, (uint)_retryTimeout))
                {
                    errCode = Marshal.GetLastWin32Error();
                    errMsg  =
                        string.Format("Wait for pipe {0} timed out after {1} milliseconds with error code {2}.",
                                      _pipeName, _retryTimeout, errCode);
                    Trace.WriteLine(errMsg);
                    throw new Win32Exception(errCode, errMsg);
                }
            }
            // indicate connection in debug
            Trace.WriteLine("Connected to pipe: " + _pipeName);

            // The pipe connected; change to message-read mode.
            bool success = false;
            int  mode    = (int)NamedPipeInterop.PIPE_READMODE_MESSAGE;

            // set to message mode
            success = NamedPipeInterop.SetNamedPipeHandleState(
                _handle,      // pipe handle
                ref mode,     // new pipe mode
                IntPtr.Zero,  // don't set maximum bytes
                IntPtr.Zero); // don't set maximum time

            // currently implemented for just synchronous, message based pipes
            // so bail if we couldn't set the client up properly
            if (false == success)
            {
                errCode = Marshal.GetLastWin32Error();
                errMsg  =
                    string.Format("Could not change pipe mode to message with error code {0}",
                                  errCode);
                Trace.WriteLine(errMsg);
                Dispose();
                throw new Win32Exception(errCode, errMsg);
            }
        }
コード例 #4
0
        /// <summary>
        /// WaitForMessage - have the server wait for a message
        /// </summary>
        /// <returns>a non-null MessageStream if it got a message, null if timed out or error</returns>
        public MemoryStream WaitForMessage()
        {
            bool   fullyRead = false;
            string errMsg    = "";
            int    errCode   = 0;
            // they want to talk to us, read their messages and write
            // replies
            MemoryStream receiveStream = new MemoryStream();

            byte[] buffer          = new byte[_receiveBufferSize];
            byte[] _numReadWritten = new byte[4];

            // need to read the whole message and put it in one message
            // byte buffer
            do
            {
                // Read the response from the pipe.
                if (!NamedPipeInterop.ReadFile(
                        _handle,                  // pipe handle
                        buffer,                   // buffer to receive reply
                        (uint)_receiveBufferSize, // size of buffer
                        _numReadWritten,          // number of bytes read
                        0))                       // not overlapped
                {
                    // failed, not just more data to come
                    errCode = Marshal.GetLastWin32Error();
                    if (errCode != NamedPipeInterop.ERROR_MORE_DATA)
                    {
                        break;
                    }
                    else
                    {
                        errMsg = string.Format("Could not read from pipe with error {0}", errCode);
                        Trace.WriteLine(errMsg);
                        throw new Win32Exception(errCode, errMsg);
                    }
                }
                else
                {
                    // we succeeded and no more data is coming
                    fullyRead = true;
                }
                // concat the message bytes to the stream
                receiveStream.Write(buffer, 0, buffer.Length);
            } while (!fullyRead);

            if (receiveStream.Length > 0)
            {
                // now set up response with a polite response using the same
                // Unicode string protocol
                string reply    = "Thanks for the message!";
                byte[] msgBytes = Encoding.Unicode.GetBytes(reply);

                uint len = (uint)msgBytes.Length;
                // write the response message provided
                // by the delegate
                if (!NamedPipeInterop.WriteFile(_handle,
                                                msgBytes,
                                                len,
                                                _numReadWritten,
                                                0))
                {
                    errCode = Marshal.GetLastWin32Error();
                    errMsg  = string.Format("Could not write response with error {0}", errCode);
                    Trace.WriteLine(errMsg);
                    throw new Win32Exception(errCode, errMsg);
                }

                // return the message we received
                return(receiveStream);
            }
            else // didn't receive anything
            {
                return(null);
            }
        }
コード例 #5
0
 /// <summary>
 /// WaitForClientConnect - wait for a client to connect to this pipe
 /// </summary>
 /// <returns>true if connected, false if timed out</returns>
 public bool WaitForClientConnect()
 {
     // wait for someone to talk to us
     return(NamedPipeInterop.ConnectNamedPipe(_handle, IntPtr.Zero));
 }