/// <summary>
        /// Deep copy constructor.
        /// </summary>
        public SmbWriteAndCloseResponsePacket(SmbWriteAndCloseResponsePacket packet)
            : base(packet)
        {
            this.InitDefaultValue();

            this.smbParameters.WordCount = packet.SmbParameters.WordCount;
            this.smbParameters.CountOfBytesWritten = packet.SmbParameters.CountOfBytesWritten;

            this.smbData.ByteCount = packet.SmbData.ByteCount;
        }
        /// <summary>
        /// Deep copy constructor.
        /// </summary>
        public SmbWriteAndCloseResponsePacket(SmbWriteAndCloseResponsePacket packet)
            : base(packet)
        {
            this.InitDefaultValue();

            this.smbParameters.WordCount           = packet.SmbParameters.WordCount;
            this.smbParameters.CountOfBytesWritten = packet.SmbParameters.CountOfBytesWritten;

            this.smbData.ByteCount = packet.SmbData.ByteCount;
        }
        /// <summary>
        /// decode packet from bytes
        /// </summary>
        /// <param name="connectId">the connection identity.</param>
        /// <param name="messageBytes">bytes contains packet</param>
        /// <param name="consumedLength">the bytes length which are consumed when decode.</param>
        /// <returns>the decoded packet from the bytes array. if failed, return null.</returns>
        protected SmbPacket DecodeSmbResponseFromBytes(
            int connectId,
            byte[] messageBytes,
            out int consumedLength)
        {
            consumedLength = 0;
            SmbPacket smbRequest  = null;
            SmbPacket smbResponse = null;

            using (MemoryStream memoryStream = new MemoryStream(messageBytes, true))
            {
                using (Channel channel = new Channel(null, memoryStream))
                {
                    // read raw response:
                    Collection <SmbPacket> outstandingRequests = this.clientContext.GetOutstandingRequests(connectId);
                    if (outstandingRequests != null && outstandingRequests.Count > 0)
                    {
                        SmbReadRawRequestPacket readRawRequest = outstandingRequests[0] as SmbReadRawRequestPacket;
                        if (readRawRequest != null)
                        {
                            SmbReadRawResponsePacket readRawResponse = this.CreateSmbResponsePacket(
                                readRawRequest, readRawRequest.SmbHeader, channel) as SmbReadRawResponsePacket;
                            if (readRawResponse != null)
                            {
                                byte[] rawData = new byte[messageBytes.Length];
                                Array.Copy(messageBytes, rawData, rawData.Length);
                                readRawResponse.RawData = rawData;
                                consumedLength          = rawData.Length;
                                return(readRawResponse);
                            }
                            else
                            {
                                // discard the none-parsable data silently:
                                consumedLength = messageBytes.Length;
                                return(null);
                            }
                        }
                        else
                        {
                            // No SmbReadRawResponsePacket sent, so the response should not be SmbReadRawResponsePacket.
                            // and do nothing here.
                        }
                    }

                    // read smb header and new SmbPacket:
                    if (channel.Stream.Position < channel.Stream.Length &&
                        messageBytes.Length >= CifsMessageUtils.GetSize <SmbHeader>(new SmbHeader()))
                    {
                        SmbHeader smbHeader = channel.Read <SmbHeader>();
                        smbRequest      = this.clientContext.GetOutstandingRequest(connectId, smbHeader.Mid);
                        smbResponse     = this.CreateSmbResponsePacket(smbRequest, smbHeader, channel);
                        consumedLength += smbResponse.HeaderSize;
                    }
                    else
                    {
                        // The data in the channel is less than the size of SmbHeader. consume nothing and return null:
                        consumedLength = 0;
                        return(null);
                    }

                    // read SmbParameters:
                    consumedLength += smbResponse.ReadParametersFromChannel(channel);

                    // read SmbData:
                    consumedLength += smbResponse.ReadDataFromChannel(channel);

                    // read andx:
                    SmbBatchedResponsePacket smbBatchedResponse = smbResponse as SmbBatchedResponsePacket;
                    if (smbRequest != null && smbBatchedResponse != null)
                    {
                        consumedLength += DecodeBatchedRequest(channel, smbRequest, smbBatchedResponse);
                    }

                    // handle the difference of protocol implementation:
                    SmbWriteAndCloseResponsePacket writeAndCloseResponse = smbResponse as SmbWriteAndCloseResponsePacket;
                    if (writeAndCloseResponse != null)
                    {
                        if (this.clientConfig.IsWriteAndCloseResponseExtraPadding)
                        {
                            // Windows NT Server appends three NULL bytes to this message, following the ByteCount field.
                            // These three bytes are not message data and can safely be discarded.
                            const int PaddingLength = 3;
                            writeAndCloseResponse.PaddingBytes = channel.ReadBytes(PaddingLength);
                            consumedLength += PaddingLength;
                        }
                    }
                }
            }
            return(smbResponse);
        }
        public SmbWriteAndCloseResponsePacket CreateWriteAndCloseResponse(
            CifsServerPerConnection connection,
            SmbWriteAndCloseRequestPacket request)
        {
            SmbWriteAndCloseResponsePacket response = new SmbWriteAndCloseResponsePacket();
            response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request);

            SMB_COM_WRITE_AND_CLOSE_Response_SMB_Parameters smbParameters = response.SmbParameters;
            smbParameters.CountOfBytesWritten = request.SmbParameters.CountOfBytesToWrite;
            smbParameters.WordCount = (byte)(TypeMarshal.GetBlockMemorySize(smbParameters) / 2);
            response.SmbParameters = smbParameters;

            return response;
        }