/// <summary>
        /// Execute a transacted exchange against a named pipe.
        /// </summary>
        /// <param name="timeout">The pending time to get server's response</param>
        /// <param name="writeData">the written data to the named pipe</param>
        /// <param name="readData">The read data from the named pipe</param>
        /// <returns>
        /// a uint value that specifies the status of response packet.
        /// </returns>
        /// <exception cref="System.InvalidOperationException">Thrown if there is any error occurred</exception>
        public uint Transaction(TimeSpan timeout, byte[] writeData, out byte[] readData)
        {
            this.internalTimeout = timeout;

            SmbTransTransactNmpipeRequestPacket request = smbClient.CreateTransTransactNamedPipeRequest(this.fid, TransSmbParametersFlags.NONE, writeData, smbClient.Capability.MaxDataCount);

            if (this.isSignRequired)
            {
                request.Sign(this.NextSequenceNumber, this.sessionKey);
            }

            uint status = 0;
            SmbTransTransactNmpipeResponsePacket response =
                this.SendAndExpectSmbPacket(request, internalTimeout, out status) as SmbTransTransactNmpipeResponsePacket;

            readData = ArrayUtility.SubArray <byte>(response.TransData.ReadData, 0);

            return(SmbMessageUtils.CheckStatus(status));
        }
        /// <summary>
        /// Create TRANS_TRANSACT_NMPIPE Response 
        /// </summary>
        /// <param name="connection">the connection identified the client</param>
        /// <param name = "data">The Data buffer that contains the data read from the named pipe </param>
        /// <returns>The SmbTransTransactNmpipeResponsePacket </returns>
        /// <exception cref="ArgumentNullException">connection must not be null</exception>
        public virtual SmbTransTransactNmpipeResponsePacket CreateTransTransactNmpipeResponse(
            SmbServerConnection connection,
            byte[] data)
        {
            if (connection == null)
            {
                throw new ArgumentNullException("connection");
            }

            SmbTransTransactNmpipeResponsePacket packet = new SmbTransTransactNmpipeResponsePacket();

            // get the request packet
            SmbPacket request = connection.GetRequestPacket(connection.MessageId);

            // create smb packet header
            packet.SmbHeader = CifsMessageUtils.CreateSmbHeader(
                SmbCommand.SMB_COM_TRANSACTION,
                connection.ProcessId, connection.MessageId, request.SmbHeader.Uid, request.SmbHeader.Tid,
                (SmbFlags)connection.Capability.Flag, (SmbFlags2)connection.Capability.Flags2);

            // update smb parameters
            SMB_COM_TRANSACTION_SuccessResponse_SMB_Parameters smbParameters = packet.SmbParameters;

            smbParameters.Setup = new ushort[0];

            smbParameters.WordCount = (byte)(CifsMessageUtils.GetSize<SMB_COM_TRANSACTION_SuccessResponse_SMB_Parameters>(
                smbParameters) / SmbCapability.NUM_BYTES_OF_WORD);

            // update smb data
            SMB_COM_TRANSACTION_SuccessResponse_SMB_Data smbData = packet.SmbData;

            // update trans data
            TRANS_TRANSACT_NMPIPE_Response_Trans_Data transData = packet.TransData;

            transData.ReadData = data;

            // store the parameters and data to packet.
            packet.TransData = transData;
            packet.SmbParameters = smbParameters;
            packet.SmbData = smbData;

            packet.UpdateCountAndOffset();

            return packet;
        }
        /// <summary>
        /// createt the transactions packet
        /// </summary>
        /// <param name="request">the request packet</param>
        /// <param name="smbHeader">the smb header of response packet</param>
        /// <param name="channel">the channel contains the packet bytes</param>
        /// <returns>the response packet</returns>
        private SmbPacket CreateTransactionResponsePacket(SmbPacket request, SmbHeader smbHeader, Channel channel)
        {
            SmbPacket smbPacket = null;

            if (smbHeader.Status == 0 && channel.Peek<byte>(0) == 0 && channel.Peek<ushort>(1) == 0)
            {
                return smbPacket;
            }

            SmbTransactionRequestPacket transactionRequest = request as SmbTransactionRequestPacket;
            if (transactionRequest == null)
            {
                return smbPacket;
            }
            switch (smbClient.Capability.TransactionSubCommand)
            {
                case TransSubCommandExtended.TRANS_EXT_MAILSLOT_WRITE:
                    smbPacket = new SmbTransMailslotWriteResponsePacket();
                    break;

                case TransSubCommandExtended.TRANS_EXT_RAP:
                    smbPacket = new SmbTransRapResponsePacket();
                    break;

                default:
                    break;

            }

            // the packet is find
            if (smbPacket != null)
            {
                return smbPacket;
            }

            // if no setup command. break
            if (transactionRequest.SmbParameters.SetupCount == 0)
            {
                return smbPacket;
            }

            // decode packet using the setup command
            switch ((TransSubCommand)transactionRequest.SmbParameters.Setup[0])
            {
                case TransSubCommand.TRANS_SET_NMPIPE_STATE:
                    smbPacket = new SmbTransSetNmpipeStateResponsePacket();
                    break;

                case TransSubCommand.TRANS_QUERY_NMPIPE_STATE:
                    smbPacket = new SmbTransQueryNmpipeStateResponsePacket();
                    break;

                case TransSubCommand.TRANS_RAW_READ_NMPIPE:
                    smbPacket = new SmbTransRawReadNmpipeResponsePacket();
                    break;

                case TransSubCommand.TRANS_QUERY_NMPIPE_INFO:
                    smbPacket = new SmbTransQueryNmpipeInfoResponsePacket();
                    break;

                case TransSubCommand.TRANS_PEEK_NMPIPE:
                    smbPacket = new SmbTransPeekNmpipeResponsePacket();
                    break;

                case TransSubCommand.TRANS_TRANSACT_NMPIPE:
                    smbPacket = new SmbTransTransactNmpipeResponsePacket();
                    break;

                case TransSubCommand.TRANS_READ_NMPIPE:
                    smbPacket = new SmbTransReadNmpipeResponsePacket();
                    break;

                case TransSubCommand.TRANS_WRITE_NMPIPE:
                    smbPacket = new SmbTransWriteNmpipeResponsePacket();
                    break;

                case TransSubCommand.TRANS_WAIT_NMPIPE:
                    smbPacket = new SmbTransWaitNmpipeResponsePacket();
                    break;

                case TransSubCommand.TRANS_CALL_NMPIPE:
                    smbPacket = new SmbTransCallNmpipeResponsePacket();
                    break;

                default:
                    break;
            }

            return smbPacket;
        }
        /// <summary>
        /// createt the transactions packet
        /// </summary>
        /// <param name="request">the request packet</param>
        /// <param name="smbHeader">the smb header of response packet</param>
        /// <param name="channel">the channel contains the packet bytes</param>
        /// <returns>the response packet</returns>
        private SmbPacket CreateTransactionResponsePacket(SmbPacket request, SmbHeader smbHeader, Channel channel)
        {
            SmbPacket smbPacket = null;

            if (smbHeader.Status == 0 && channel.Peek <byte>(0) == 0 && channel.Peek <ushort>(1) == 0)
            {
                return(smbPacket);
            }

            SmbTransactionRequestPacket transactionRequest = request as SmbTransactionRequestPacket;

            if (transactionRequest == null)
            {
                return(smbPacket);
            }
            switch (smbClient.Capability.TransactionSubCommand)
            {
            case TransSubCommandExtended.TRANS_EXT_MAILSLOT_WRITE:
                smbPacket = new SmbTransMailslotWriteResponsePacket();
                break;

            case TransSubCommandExtended.TRANS_EXT_RAP:
                smbPacket = new SmbTransRapResponsePacket();
                break;

            default:
                break;
            }

            // the packet is find
            if (smbPacket != null)
            {
                return(smbPacket);
            }

            // if no setup command. break
            if (transactionRequest.SmbParameters.SetupCount == 0)
            {
                return(smbPacket);
            }

            // decode packet using the setup command
            switch ((TransSubCommand)transactionRequest.SmbParameters.Setup[0])
            {
            case TransSubCommand.TRANS_SET_NMPIPE_STATE:
                smbPacket = new SmbTransSetNmpipeStateResponsePacket();
                break;

            case TransSubCommand.TRANS_QUERY_NMPIPE_STATE:
                smbPacket = new SmbTransQueryNmpipeStateResponsePacket();
                break;

            case TransSubCommand.TRANS_RAW_READ_NMPIPE:
                smbPacket = new SmbTransRawReadNmpipeResponsePacket();
                break;

            case TransSubCommand.TRANS_QUERY_NMPIPE_INFO:
                smbPacket = new SmbTransQueryNmpipeInfoResponsePacket();
                break;

            case TransSubCommand.TRANS_PEEK_NMPIPE:
                smbPacket = new SmbTransPeekNmpipeResponsePacket();
                break;

            case TransSubCommand.TRANS_TRANSACT_NMPIPE:
                smbPacket = new SmbTransTransactNmpipeResponsePacket();
                break;

            case TransSubCommand.TRANS_READ_NMPIPE:
                smbPacket = new SmbTransReadNmpipeResponsePacket();
                break;

            case TransSubCommand.TRANS_WRITE_NMPIPE:
                smbPacket = new SmbTransWriteNmpipeResponsePacket();
                break;

            case TransSubCommand.TRANS_WAIT_NMPIPE:
                smbPacket = new SmbTransWaitNmpipeResponsePacket();
                break;

            case TransSubCommand.TRANS_CALL_NMPIPE:
                smbPacket = new SmbTransCallNmpipeResponsePacket();
                break;

            default:
                break;
            }

            return(smbPacket);
        }
 /// <summary>
 /// Deep copy constructor.
 /// </summary>
 public SmbTransTransactNmpipeResponsePacket(SmbTransTransactNmpipeResponsePacket packet)
     : base(packet)
 {
 }
 /// <summary>
 /// Deep copy constructor. 
 /// </summary>
 public SmbTransTransactNmpipeResponsePacket(SmbTransTransactNmpipeResponsePacket packet)
     : base(packet)
 {
 }