/// <summary>
        /// Create SMB_COM_NEGOTIATE response 
        /// </summary>
        /// <param name="connection">the connection identified the client</param>
        /// <param name = "securityMode">
        /// An 8-bit field, indicating the security modes supported or REQUIRED by the server 
        /// </param>
        /// <param name = "maxBufferSize">
        /// The maximum size, in bytes, of the largest SMB message the servercan receive. This is the size of the  SMB 
        /// message that the clientMAY send to the server. SMB message size includes the size of the SMB header,  and 
        /// data blocks. This size does not include any transport-layer framing or other transport-layer data.  server 
        /// MUSTprovide a MaxBufferSize of 1024 bytes (1Kbyte) or larger.If CAP_RAW_MODE is negotiated, then  
        /// SMB_COM_WRITE_RAW commandcan bypass the MaxBufferSize limit. Otherwise, SMB messages sent to the server  
        /// have a total size less than or equal to the MaxBufferSize value.This includes AndX chained  default 
        /// MaxBufferSize on Windows NT server is 4356 bytes(4KB + 260Bytes) if the server has 512MB of  or less. If 
        /// the server has more than 512MB of memory, then the default MaxBufferSize is 16644 bytes (16KB  260Bytes). 
        /// Windows NT servers always use a MaxBufferSize value that is a multiple of four (4). The  can be configured 
        /// through the following registry setting: 
        /// </param>
        /// <param name="maxMpxCount">
        /// The maximum number of outstanding SMB operations the server
        /// supports. This value includes existing OpLocks, 
        /// the NT_TRANSACT_NOTIFY_CHANGE subcommand, and any other command 
        /// that are pending on the server. If the negotiated MaxMpxCount is one, 
        /// then OpLock support MUST be disabled for this session. The MaxMpxCount
        /// MUST be greater than zero. This parameter has no specific 
        /// relationship to the SMB_COM_READ_MPX and SMB_COM_WRITE_MPX commands. 
        /// </param>
        /// <returns>a smb implicit ntlm negotiate response packet </returns>
        /// <exception cref="ArgumentNullException">connection must not be null</exception>
        public virtual SmbNegotiateImplicitNtlmResponsePacket CreateSmbComNegotiateImplicitNtlmResponse(
            SmbServerConnection connection,
            SecurityModes securityMode,
            uint maxBufferSize,
            ushort maxMpxCount)
        {
            if (connection == null)
            {
                throw new ArgumentNullException("connection");
            }

            Cifs.SmbNegotiateResponsePacket packet = new Cifs.SmbNegotiateResponsePacket();

            // create smb packet header
            packet.SmbHeader = CifsMessageUtils.CreateSmbHeader(
                SmbCommand.SMB_COM_NEGOTIATE, connection.ProcessId, connection.MessageId, 0, 0,
                (SmbFlags)connection.Capability.Flag, (SmbFlags2)connection.Capability.Flags2);

            // update smb parameters
            Cifs.SMB_COM_NEGOTIATE_NtLanManagerResponse_SMB_Parameters smbParameters = packet.SmbParameters;

            ushort dialectIndex = 0x00;
            byte wordCount = 0x00;
            connection.GetPreferedDialectIndex(out dialectIndex, out wordCount);

            smbParameters.WordCount = wordCount;
            smbParameters.DialectIndex = dialectIndex;
            smbParameters.SecurityMode = securityMode;
            smbParameters.MaxBufferSize = maxBufferSize;
            smbParameters.MaxMpxCount = maxMpxCount;
            smbParameters.Capabilities = (Cifs.Capabilities)connection.ServerCapabilities;
            smbParameters.SystemTime.Time = (ulong)connection.SystemTime;
            smbParameters.ChallengeLength = (byte)connection.NtlmEncryptionKey.Length;

            // update smb data
            Cifs.SMB_COM_NEGOTIATE_NtLanManagerResponse_SMB_Data smbData = packet.SmbData;

            smbData.Challenge = connection.NtlmEncryptionKey;

            // update smbData.ByteCount
            smbData.ByteCount = 0;
            if (smbData.Challenge != null)
            {
                smbData.ByteCount += (ushort)smbData.Challenge.Length;
            }
            if (smbData.DomainName != null)
            {
                smbData.ByteCount += (ushort)smbData.DomainName.Length;
            }

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

            return new SmbNegotiateImplicitNtlmResponsePacket(packet);
        }
 /// <summary>
 /// initialize packet from base packet.
 /// </summary>
 /// <param name = "packet">the base packet to initialize this packet. </param>
 public SmbNegotiateImplicitNtlmResponsePacket(Cifs.SmbNegotiateResponsePacket packet)
     : base(packet)
 {
 }