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

            this.smbParameters.WordCount = packet.SmbParameters.WordCount;
            this.smbParameters.AndXCommand = packet.SmbParameters.AndXCommand;
            this.smbParameters.AndXReserved = packet.SmbParameters.AndXReserved;
            this.smbParameters.AndXOffset = packet.SmbParameters.AndXOffset;
            this.smbParameters.Flags = packet.SmbParameters.Flags;
            this.smbParameters.AccessMode = packet.SmbParameters.AccessMode;
            this.smbParameters.SearchAttrs = packet.SmbParameters.SearchAttrs;
            this.smbParameters.FileAttrs = packet.SmbParameters.FileAttrs;
            this.smbParameters.CreationTime = new UTime();
            this.smbParameters.CreationTime.Time = packet.SmbParameters.CreationTime.Time;
            this.smbParameters.OpenMode = packet.SmbParameters.OpenMode;
            this.smbParameters.AllocationSize = packet.SmbParameters.AllocationSize;
            this.smbParameters.Timeout = packet.SmbParameters.Timeout;

            if (packet.smbParameters.Reserved != null)
            {
                this.smbParameters.Reserved = new ushort[packet.smbParameters.Reserved.Length];
                Array.Copy(packet.smbParameters.Reserved,
                    this.smbParameters.Reserved, packet.smbParameters.Reserved.Length);
            }
            else
            {
                this.smbParameters.Reserved = new ushort[0];
            }
            this.smbData.ByteCount = packet.SmbData.ByteCount;

            if (packet.smbData.FileName != null)
            {
                this.smbData.FileName = new byte[packet.smbData.FileName.Length];
                Array.Copy(packet.smbData.FileName, this.smbData.FileName, packet.smbData.FileName.Length);
            }
            else
            {
                this.smbData.FileName = new byte[0];
            }
        }
        /// <summary>
        /// Deep copy constructor.
        /// </summary>
        public SmbOpenAndxRequestPacket(SmbOpenAndxRequestPacket packet)
            : base(packet)
        {
            this.InitDefaultValue();

            this.smbParameters.WordCount         = packet.SmbParameters.WordCount;
            this.smbParameters.AndXCommand       = packet.SmbParameters.AndXCommand;
            this.smbParameters.AndXReserved      = packet.SmbParameters.AndXReserved;
            this.smbParameters.AndXOffset        = packet.SmbParameters.AndXOffset;
            this.smbParameters.Flags             = packet.SmbParameters.Flags;
            this.smbParameters.AccessMode        = packet.SmbParameters.AccessMode;
            this.smbParameters.SearchAttrs       = packet.SmbParameters.SearchAttrs;
            this.smbParameters.FileAttrs         = packet.SmbParameters.FileAttrs;
            this.smbParameters.CreationTime      = new UTime();
            this.smbParameters.CreationTime.Time = packet.SmbParameters.CreationTime.Time;
            this.smbParameters.OpenMode          = packet.SmbParameters.OpenMode;
            this.smbParameters.AllocationSize    = packet.SmbParameters.AllocationSize;
            this.smbParameters.Timeout           = packet.SmbParameters.Timeout;

            if (packet.smbParameters.Reserved != null)
            {
                this.smbParameters.Reserved = new ushort[packet.smbParameters.Reserved.Length];
                Array.Copy(packet.smbParameters.Reserved,
                           this.smbParameters.Reserved, packet.smbParameters.Reserved.Length);
            }
            else
            {
                this.smbParameters.Reserved = new ushort[0];
            }
            this.smbData.ByteCount = packet.SmbData.ByteCount;

            if (packet.smbData.FileName != null)
            {
                this.smbData.FileName = new byte[packet.smbData.FileName.Length];
                Array.Copy(packet.smbData.FileName, this.smbData.FileName, packet.smbData.FileName.Length);
            }
            else
            {
                this.smbData.FileName = new byte[0];
            }
        }
        /// <summary>
        /// to create a OpenAndx 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="smbParametersFlags">A 16-bit field of flags for requesting attribute data and locking</param>
        /// <param name="accessMode">A 16-bit field for encoding the requested access mode. See section 3.2.4.5.1 for a
        /// discussion on sharing modes</param>
        /// <param name="searchAttrs">ATTRIBUTES The set of attributes that the file MUST have in order to be found
        /// while searching to see if it exists. If none of the attribute bytes are set, the file attributes MUST refer
        /// to a regular file.</param>
        /// <param name="fileAttrs">The set of attributes that the file is to have if the file needs to be created. If
        /// none of the attribute bytes are set, the file attributes MUST refer to a regular file.</param>
        /// <param name="creationTime">32-bit integer time value to be assigned to the file as a time of creation if
        /// the file is to be created. </param>
        /// <param name="openMode">A 16-bit field that controls the way a file SHOULD be treated when it is opened for
        /// use by certain extended SMB requests</param>
        /// <param name="allocationSize">The number of bytes to reserve on file creation or truncation. This field MAY
        /// be ignored by the server</param>
        /// <param name="timeout">This field is a 32-bit unsigned integer value containing the number of milliseconds
        /// to wait on a blocked open request before returning without successfully opening the file.</param>
        /// <param name="fileName">A buffer containing the name of the file to be opened. </param>
        /// <param name="andxPacket">the andx packet.</param>
        /// <returns>a OpenAndx request packet</returns>
        public SmbOpenAndxRequestPacket CreateOpenAndxRequest(
            ushort messageId,
            ushort uid,
            ushort treeId,
            SmbFlags flags,
            SmbFlags2 flags2,
            Flags smbParametersFlags,
            AccessMode accessMode,
            SmbFileAttributes searchAttrs,
            SmbFileAttributes fileAttrs,
            UTime creationTime,
            OpenMode openMode,
            uint allocationSize,
            uint timeout,
            string fileName,
            SmbPacket andxPacket)
        {
            if (fileName == null)
            {
                fileName = string.Empty;
            }

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

            SMB_COM_OPEN_ANDX_Request_SMB_Parameters smbParameters = new SMB_COM_OPEN_ANDX_Request_SMB_Parameters();
            smbParameters.AndXReserved = 0;
            smbParameters.Reserved = new ushort[2]; // the correct length of Reserved word is always 2.
            if (andxPacket == null)
            {
                smbParameters.AndXCommand = SmbCommand.SMB_COM_NO_ANDX_COMMAND;
            }
            else
            {
                smbParameters.AndXCommand = andxPacket.SmbHeader.Command;
            }
            smbParameters.Flags = smbParametersFlags;
            smbParameters.AccessMode = accessMode;
            smbParameters.SearchAttrs = searchAttrs;
            smbParameters.FileAttrs = fileAttrs;
            smbParameters.CreationTime = creationTime;
            smbParameters.OpenMode = openMode;
            smbParameters.AllocationSize = allocationSize;
            smbParameters.Timeout = timeout;
            smbParameters.WordCount = (byte)(CifsMessageUtils.GetSize<SMB_COM_OPEN_ANDX_Request_SMB_Parameters>(
                smbParameters) / NumBytesOfWord);

            SMB_COM_OPEN_ANDX_Request_SMB_Data smbData = new SMB_COM_OPEN_ANDX_Request_SMB_Data();
            if ((flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE)
            {
                // if Unicode, add 1 byte pad for align on 16-bits.
                smbData.FileName = new byte[1 + (fileName.Length + 1) * 2];
                Array.Copy(CifsMessageUtils.ToSmbStringBytes(fileName, true), 0, smbData.FileName, 1,
                    (fileName.Length + 1) * 2);
            }
            else
            {
                smbData.FileName = CifsMessageUtils.ToSmbStringBytes(fileName, false);
            }
            smbData.ByteCount = (ushort)smbData.FileName.Length;

            packet.SmbParameters = smbParameters;
            packet.SmbData = smbData;
            packet.AndxPacket = andxPacket;

            return packet;
        }
        public SmbOpenAndxResponsePacket CreateOpenAndxResponse(
            CifsServerPerConnection connection,
            SmbOpenAndxRequestPacket request,
            UTime lastWriteTime,
            uint fileDataSize,
            AccessRightsValue accessRights,
            ResourceTypeValue resourceType,
            SMB_NMPIPE_STATUS nmPipeStatus,
            OpenResultsValues openResults,
            SmbPacket andxPacket)
        {
            SmbOpenAndxResponsePacket response = new SmbOpenAndxResponsePacket();
            response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request);

            SMB_COM_OPEN_ANDX_Response_SMB_Parameters smbParameters = response.SmbParameters;
            smbParameters.AndXCommand =
                andxPacket != null ? andxPacket.SmbHeader.Command : SmbCommand.SMB_COM_NO_ANDX_COMMAND;
            smbParameters.AndXReserved = 0x00;
            smbParameters.FID = (ushort)(connection.GenerateFID());
            smbParameters.FileAttrs = request.SmbParameters.FileAttrs;
            smbParameters.LastWriteTime = lastWriteTime;
            smbParameters.FileDataSize = fileDataSize;
            smbParameters.AccessRights = accessRights;
            smbParameters.ResourceType = resourceType;
            smbParameters.NMPipeStatus = nmPipeStatus;
            smbParameters.OpenResults = openResults;
            smbParameters.Reserved = new ushort[3];
            smbParameters.AndXOffset = (ushort)(response.HeaderSize + Marshal.SizeOf(response.SmbParameters)
                    + Marshal.SizeOf(response.SmbData));
            smbParameters.WordCount = (byte)(TypeMarshal.GetBlockMemorySize(smbParameters) / 2);
            response.SmbParameters = smbParameters;

            response.AndxPacket = andxPacket;
            response.UpdateHeader();

            return response;
        }