/// <summary>
 /// to decode the smb parameters: from the general SmbParameters to the concrete Smb Parameters.
 /// </summary>
 protected override void DecodeParameters()
 {
     if (this.smbParametersBlock.WordCount > 0)
     {
         this.smbParameters = TypeMarshal.ToStruct <SMB_COM_READ_ANDX_Response_SMB_Parameters>(
             TypeMarshal.ToBytes(this.smbParametersBlock));
     }
 }
        /// <summary>
        /// Create SMB_COM_READ_ANDX packet 
        /// </summary>
        /// <param name="connection">the connection identified the client</param>
        /// <param name = "available">
        /// This field is valid when reading from named pipes or I/O devices. This field indicates the number of bytes 
        /// remaining to be read after the requested read was completed. If the client reads from a disk file, this 
        /// field MUST be set to -1 (0xFFFF). 
        /// </param>
        /// <param name = "data">The actual bytes read in response to the request </param>
        /// <returns>SmbReadAndXResponsePacket </returns>
        /// <exception cref="ArgumentNullException">connection must not be null</exception>
        public virtual SmbReadAndxResponsePacket CreateSmbComReadResponse(
            SmbServerConnection connection,
            ushort available,
            byte[] data)
        {
            if (connection == null)
            {
                throw new ArgumentNullException("connection");
            }

            if (data == null)
            {
                data = new byte[0];
            }

            SmbReadAndxResponsePacket packet = new SmbReadAndxResponsePacket();

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

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

            // update smb parameters
            SMB_COM_READ_ANDX_Response_SMB_Parameters smbParameters = new SMB_COM_READ_ANDX_Response_SMB_Parameters();

            smbParameters.AndXCommand = SmbCommand.SMB_COM_NO_ANDX_COMMAND;
            smbParameters.Available = available;
            smbParameters.DataLength = (ushort)data.Length;
            smbParameters.DataLengthHigh =(ushort)(data.Length >> 16);
            smbParameters.Reserved2 = new ushort[4];

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

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

            smbData.Pad = new byte[1];
            smbData.Data = data;

            // update smbData.ByteCount
            smbData.ByteCount = 0;
            smbData.ByteCount += (ushort)smbData.Pad.Length;
            smbData.ByteCount += (ushort)smbData.Data.Length;

            smbParameters.DataOffset = (ushort)(
                CifsMessageUtils.GetSize(packet.SmbHeader) +
                CifsMessageUtils.GetSize(smbParameters) +
                CifsMessageUtils.GetSize(smbData.ByteCount) + smbData.Pad.Length);

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

            return packet;
        }