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

            this.trans2Parameters.SID = packet.trans2Parameters.SID;
            this.trans2Parameters.SearchCount = packet.trans2Parameters.SearchCount;
            this.trans2Parameters.InformationLevel = packet.trans2Parameters.InformationLevel;
            this.trans2Parameters.ResumeKey = packet.trans2Parameters.ResumeKey;
            this.trans2Parameters.Flags = packet.trans2Parameters.Flags;

            if (packet.trans2Parameters.FileName != null)
            {
                this.trans2Parameters.FileName = new byte[packet.trans2Parameters.FileName.Length];
                Array.Copy(packet.trans2Parameters.FileName,
                    this.trans2Parameters.FileName, packet.trans2Parameters.FileName.Length);
            }
            else
            {
                this.trans2Parameters.FileName = new byte[0];
            }

            this.trans2Data.GetExtendedAttributeList.SizeOfListInBytes =
                packet.trans2Data.GetExtendedAttributeList.SizeOfListInBytes;

            if (packet.trans2Data.GetExtendedAttributeList.GEAList!= null)
            {
                this.trans2Data.GetExtendedAttributeList.GEAList =
                    new SMB_GEA[packet.trans2Data.GetExtendedAttributeList.GEAList.Length];
                Array.Copy(packet.trans2Data.GetExtendedAttributeList.GEAList,
                    this.trans2Data.GetExtendedAttributeList.GEAList,
                    packet.trans2Data.GetExtendedAttributeList.GEAList.Length);
            }
            else
            {
                this.trans2Data.GetExtendedAttributeList.GEAList = new SMB_GEA[0];
            }
        }
        /// <summary>
        /// Deep copy constructor.
        /// </summary>
        public SmbTrans2FindNext2RequestPacket(SmbTrans2FindNext2RequestPacket packet)
            : base(packet)
        {
            this.InitDefaultValue();

            this.trans2Parameters.SID              = packet.trans2Parameters.SID;
            this.trans2Parameters.SearchCount      = packet.trans2Parameters.SearchCount;
            this.trans2Parameters.InformationLevel = packet.trans2Parameters.InformationLevel;
            this.trans2Parameters.ResumeKey        = packet.trans2Parameters.ResumeKey;
            this.trans2Parameters.Flags            = packet.trans2Parameters.Flags;

            if (packet.trans2Parameters.FileName != null)
            {
                this.trans2Parameters.FileName = new byte[packet.trans2Parameters.FileName.Length];
                Array.Copy(packet.trans2Parameters.FileName,
                           this.trans2Parameters.FileName, packet.trans2Parameters.FileName.Length);
            }
            else
            {
                this.trans2Parameters.FileName = new byte[0];
            }

            this.trans2Data.GetExtendedAttributeList.SizeOfListInBytes =
                packet.trans2Data.GetExtendedAttributeList.SizeOfListInBytes;

            if (packet.trans2Data.GetExtendedAttributeList.GEAList != null)
            {
                this.trans2Data.GetExtendedAttributeList.GEAList =
                    new SMB_GEA[packet.trans2Data.GetExtendedAttributeList.GEAList.Length];
                Array.Copy(packet.trans2Data.GetExtendedAttributeList.GEAList,
                           this.trans2Data.GetExtendedAttributeList.GEAList,
                           packet.trans2Data.GetExtendedAttributeList.GEAList.Length);
            }
            else
            {
                this.trans2Data.GetExtendedAttributeList.GEAList = new SMB_GEA[0];
            }
        }
        /// <summary>
        /// to create a Trans2FindNext2 request packet.
        /// </summary>
        /// <param name="messageId">This field SHOULD be the multiplex ID that is used to associate a response with a
        /// request.</param>
        /// <param name="uid">This field SHOULD identify the authenticated instance of the user.</param>
        /// <param name="treeId">This field identifies the subdirectory (or tree) on the server that the client is
        /// accessing.</param>
        /// <param name="flags">An 8-bit field of 1-bit flags describing various features in effect for the
        /// message</param>
        /// <param name="flags2">A 16-bit field of 1-bit flags that represent various features in effect for the
        /// message. Unspecified bits are reserved and MUST be zero.</param>
        /// <param name="maxParameterCount">The maximum number of parameter bytes that the client will accept in the
        /// transaction reply. The server MUST NOT return more than this number of parameter bytes.</param>
        /// <param name="maxDataCount">The maximum number of data bytes that the client will accept in the transaction
        /// reply. The server MUST NOT return more than this number of data bytes.</param>
        /// <param name="maxSetupCount">Maximum number of setup bytes that the client will accept in the transaction
        /// reply. The server MUST NOT return more than this number of setup bytes</param>
        /// <param name="smbParametersFlags">A set of bit flags that alter the behavior of the requested operation.
        /// Unused bit fields MUST be set to zero by the client sending the request, and MUST be ignored by the server
        /// receiving the request. The client MAY set either or both of the following bit flags</param>
        /// <param name="timeout">The number of milliseconds the server SHOULD wait for completion of the transaction
        /// before generating a timeout. A value of zero indicates that the operation MUST NOT block.</param>
        /// <param name="sid">This field MUST be the search identifier (SID) returned in TRANS2_FIND_FIRST2
        /// response.</param>
        /// <param name="searchCount">The server MUST NOT return more entries than indicated by the value of this
        /// field.</param>
        /// <param name="informationLevel">This field contains an information level code, which determines the
        /// information contained in the response.</param>
        /// <param name="resumeKey">This field MUST be the value of a ResumeKey field returned in the response from a
        /// TRANS2_FIND_FIRST2 or TRANS2_FIND_NEXT2 that is part of the same search (same SID).</param>
        /// <param name="findFlags">This 16-bit field of flags is used to request that the server take
        /// certain actions.</param>
        /// <param name="name">This field is present but not used in SMB_COM_TRANSACTION2 requests. If Unicode support
        /// has been negotiated, then this field MUST be aligned to a 16-bit boundary and MUST consist of two null bytes
        /// (a null-terminator). If Unicode support has not been negotiated this field will contain only one null
        /// byte.</param>
        /// <param name="extendedAttributeList">Array of SMB_EA A list of extended file attribute name/value pairs.
        /// </param>
        /// <returns>a Trans2FindNext2 request packet</returns>
        public SmbTrans2FindNext2RequestPacket CreateTrans2FindNext2Request(
            ushort messageId,
            ushort uid,
            ushort treeId,
            SmbFlags flags,
            SmbFlags2 flags2,
            ushort maxParameterCount,
            ushort maxDataCount,
            byte maxSetupCount,
            Trans2SmbParametersFlags smbParametersFlags,
            uint timeout,
            ushort sid,
            ushort searchCount,
            FindInformationLevel informationLevel,
            uint resumeKey,
            Trans2FindFlags findFlags,
            string name,
            SMB_GEA[] extendedAttributeList)
        {
            if (name == null)
            {
                name = string.Empty;
            }
            if (extendedAttributeList == null)
            {
                extendedAttributeList = new SMB_GEA[0];
            }

            SmbTrans2FindNext2RequestPacket packet = new SmbTrans2FindNext2RequestPacket();
            packet.SmbHeader = CifsMessageUtils.CreateSmbHeader(SmbCommand.SMB_COM_TRANSACTION2,
                messageId, uid, treeId, flags, flags2);

            // Set Smb_Parameters
            SMB_COM_TRANSACTION2_Request_SMB_Parameters smbParameters =
                new SMB_COM_TRANSACTION2_Request_SMB_Parameters();
            smbParameters.MaxParameterCount = maxParameterCount;
            smbParameters.MaxDataCount = maxDataCount;
            smbParameters.MaxSetupCount = maxSetupCount;
            smbParameters.Flags = (ushort)smbParametersFlags;
            smbParameters.Timeout = timeout;
            smbParameters.SetupCount = 1; // the correct count in word of the Setup is always 1.
            smbParameters.Setup = new ushort[] { (ushort)Trans2SubCommand.TRANS2_FIND_NEXT2 };
            smbParameters.WordCount = (byte)(CifsMessageUtils.GetSize<SMB_COM_TRANSACTION2_Request_SMB_Parameters>(
                smbParameters) / NumBytesOfWord);

            // Set Smb_Data
            SMB_COM_TRANSACTION2_Request_SMB_Data smbData = new SMB_COM_TRANSACTION2_Request_SMB_Data();
            smbData.Name = CifsMessageUtils.ToSmbStringBytes(name,
                (flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE);

            // Set Trans2_Parameters
            TRANS2_FIND_NEXT2_Request_Trans2_Parameters trans2Parameters =
                new TRANS2_FIND_NEXT2_Request_Trans2_Parameters();
            trans2Parameters.SID = sid;
            trans2Parameters.SearchCount = searchCount;
            trans2Parameters.InformationLevel = informationLevel;
            trans2Parameters.ResumeKey = resumeKey;
            trans2Parameters.Flags = findFlags;
            trans2Parameters.FileName = CifsMessageUtils.ToSmbStringBytes(name,
                (flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE);

            // Set Trans2_Data
            TRANS2_FIND_NEXT2_Request_Trans2_Data trans2Data = new TRANS2_FIND_NEXT2_Request_Trans2_Data();
            trans2Data.GetExtendedAttributeList.GEAList = extendedAttributeList;
            trans2Data.GetExtendedAttributeList.SizeOfListInBytes =
                (uint)CifsMessageUtils.GetSize<uint>(trans2Data.GetExtendedAttributeList.SizeOfListInBytes);
            trans2Data.GetExtendedAttributeList.SizeOfListInBytes +=
                CifsMessageUtils.GetSmbQueryEAListSize(extendedAttributeList);

            packet.SmbParameters = smbParameters;
            packet.SmbData = smbData;
            packet.Trans2Parameters = trans2Parameters;
            packet.Trans2Data = trans2Data;
            packet.UpdateCountAndOffset();

            return packet;
        }
        public SmbTrans2FindNext2FinalResponsePacket CreateTrans2FindNext2FinalResponse(
            CifsServerPerConnection connection,
            SmbTrans2FindNext2RequestPacket request,
            ushort endOfSearch,
            Array findInformationLevel)
        {
            if (findInformationLevel != null &&
                !CheckInformationLevel(request.Trans2Parameters.InformationLevel, findInformationLevel))
            {
                throw new InvalidCastException("The findInformationLevel must correspond with "
                    + request.Trans2Parameters.InformationLevel);
            }
            bool isResumeKeyExisted = (request.Trans2Parameters.Flags & Trans2FindFlags.SMB_FIND_RETURN_RESUME_KEYS)
                == Trans2FindFlags.SMB_FIND_RETURN_RESUME_KEYS;
            SmbTrans2FindNext2FinalResponsePacket response = new SmbTrans2FindNext2FinalResponsePacket(
                request.Trans2Parameters.InformationLevel, isResumeKeyExisted);
            response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request);

            TRANS2_FIND_NEXT2_Response_Trans2_Parameters trans2Parameters = response.Trans2Parameters;
            trans2Parameters.SearchCount = (ushort)(findInformationLevel != null ? findInformationLevel.Length : 0);
            trans2Parameters.EndOfSearch = endOfSearch;
            response.Trans2Parameters = trans2Parameters;

            TRANS2_FIND_NEXT2_Response_Trans2_Data trans2Data = response.Trans2Data;
            trans2Data.Data = findInformationLevel;
            response.Trans2Data = trans2Data;

            response.UpdateCountAndOffset();

            return response;
        }