/// <summary>
 /// to create a Trans2Open2 request packet.
 /// </summary>
 /// <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="open2Flags">This 16-bit field of flags is used to request that the server take certain
 /// actions.</param>
 /// <param name="desiredAccess">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="creationTimeInSeconds">A time value expressed in seconds past Jan 1, 1970 00:00:00:00 to apply
 /// to the file's attributes if the file is created</param> 
 /// <param name="fileAttributes">Attributes to apply to the file if it needs 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 for the file if the file is being created or
 /// truncated. </param>
 /// <param name="name">A buffer containing the name of the file to be opened, created, or truncated. The
 /// string MUST be null terminated</param>
 /// <param name="extendedAttributeList">A list of extended file attribute name / value pairs that are to be
 /// assigned to the file.</param> 
 /// <returns>a Trans2Open2 request packet</returns>
 /// <exception cref="System.NullReferenceException">There is no connection in context. </exception>
 public SmbTrans2Open2RequestPacket CreateTrans2Open2Request(
     ushort uid,
     ushort treeId,
     Trans2Open2Flags open2Flags,
     Trans2Open2DesiredAccess desiredAccess,
     SmbFileAttributes fileAttributes,
     uint creationTimeInSeconds,
     OpenMode openMode,
     uint allocationSize,
     string name,
     SMB_FEA[] extendedAttributeList)
 {
     return this.CreateTrans2Open2Request(this.Context.GetMessageId(this.connectionId),
         uid, treeId, this.defaultParameters.Flag, this.defaultParameters.Flag2, this.defaultParameters.MaxParameterCount,
         this.defaultParameters.MaxDataCount, this.defaultParameters.MaxSetupCount, this.defaultParameters.Trans2SmbParametersFlags,
         this.defaultParameters.Timeout, open2Flags, desiredAccess, fileAttributes, creationTimeInSeconds,
         openMode, allocationSize, name, extendedAttributeList);
 }
        /// <summary>
        /// to create a Trans2Open2 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="allocationSize">The number of bytes to reserve for the file if the file is being created or
        /// truncated. </param>
        /// <param name="creationTimeInSeconds">A time value expressed in seconds past Jan 1, 1970 00:00:00:00 to apply
        /// to the file's attributes if the file is created</param>
        /// <param name="desiredAccess">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="extendedAttributeList">A list of extended file attribute name / value pairs that are to be
        /// assigned to the file.</param>
        /// <param name="fileAttributes">Attributes to apply to the file if it needs to be created.</param>
        /// <param name="name">A buffer containing the name of the file to be opened, created, or truncated. The
        /// string MUST be null terminated</param>
        /// <param name="open2Flags">This 16-bit field of flags is used to request that the server take certain
        /// actions.</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>
        /// <returns>a Trans2Open2 request packet</returns>
        public SmbTrans2Open2RequestPacket CreateTrans2Open2Request(
            ushort messageId,
            ushort uid,
            ushort treeId,
            SmbFlags flags,
            SmbFlags2 flags2,
            ushort maxParameterCount,
            ushort maxDataCount,
            byte maxSetupCount,
            Trans2SmbParametersFlags smbParametersFlags,
            uint timeout,
            Trans2Open2Flags open2Flags,
            Trans2Open2DesiredAccess desiredAccess,
            SmbFileAttributes fileAttributes,
            uint creationTimeInSeconds,
            OpenMode openMode,
            uint allocationSize,
            string name,
            SMB_FEA[] extendedAttributeList)
        {
            if (name == null)
            {
                name = string.Empty;
            }
            if (extendedAttributeList == null)
            {
                extendedAttributeList = new SMB_FEA[0];
            }

            SmbTrans2Open2RequestPacket packet = new SmbTrans2Open2RequestPacket();
            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_OPEN2 };
            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);

            // The size of the preceding SmbParameters part plus Header part is an odd number for all cifs messages
            // Use Name field to judge whether needs to add one 16-bits align pad.
            if ((flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE && smbData.Name.Length
                % twoBytesAlign == 0)
            {
                // pad 1 byte for 16-bits align:
                smbData.Pad1 = new byte[1];
            }
            else
            {
                smbData.Pad1 = new byte[0];
            }

            // Set Trans2_Parameters
            TRANS2_OPEN2_Request_Trans2_Parameters trans2Parameters = new TRANS2_OPEN2_Request_Trans2_Parameters();
            trans2Parameters.Flags = (ushort)open2Flags;
            trans2Parameters.AccessMode = (ushort)desiredAccess;
            trans2Parameters.FileAttributes = fileAttributes;
            trans2Parameters.CreationTime = creationTimeInSeconds;
            trans2Parameters.OpenMode = (ushort)openMode;
            trans2Parameters.AllocationSize = allocationSize;
            trans2Parameters.Reserved = new ushort[5]; // the correct length of Reserved word is always 5.
            trans2Parameters.FileName = CifsMessageUtils.ToSmbStringBytes(name,
                (flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE);

            // Set Trans2_Data
            TRANS2_OPEN2_Request_Trans2_Data trans2Data = new TRANS2_OPEN2_Request_Trans2_Data();
            trans2Data.ExtendedAttributeList.FEAList = extendedAttributeList;
            trans2Data.ExtendedAttributeList.SizeOfListInBytes =
                (uint)CifsMessageUtils.GetSize<uint>(trans2Data.ExtendedAttributeList.SizeOfListInBytes);
            trans2Data.ExtendedAttributeList.SizeOfListInBytes +=
                CifsMessageUtils.GetSmbEAListSize(extendedAttributeList);

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

            return packet;
        }