/// <summary>
        /// Create Trans2FindFirst2 request for the client to find file on server. 
        /// </summary>
        /// <param name = "treeId">the valid tree connect id, must be response by server of the tree connect. </param>
        /// <param name = "fileName">The file name to find. </param>
        /// <param name = "transactOptions">
        /// 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 = "searchCount">
        /// The server MUST NOT return more entries than indicated by the value of this field. 
        /// </param>
        /// <param name = "findFlags">
        /// This 16-bit field of flags is used to request that the server take certain actions. 
        /// </param>
        /// <param name = "searchAttributes">File attributes to apply as a constraint to the file search. </param>
        /// <param name = "searchStorageType">
        /// This field specifies if the find is searching for directories or for files. This field MUST be one of two  
        /// values 
        /// </param>
        /// <param name = "isReparsePath">If true, the path in the request MUST contain an @GMT token. </param>
        /// <param name = "isKnowsLongName">
        /// is used to indicate to set the SMB_FLAGS2_KNOWS_LONG_NAMES flag in smb header or not. 
        /// </param>
        /// <param name = "informationLevel">
        /// Indicates that client specifies the information it is requesting. Server return different data based on 
        /// the client's request. 
        /// </param>
        /// <returns>a find file for the first request packet </returns>
        public virtual SmbTrans2FindFirst2RequestPacket CreateTrans2FindFirst2Request(
            ushort treeId,
            string fileName,
            Trans2SmbParametersFlags transactOptions,
            ushort searchCount,
            Trans2FindFlags findFlags,
            SmbFileAttributes searchAttributes,
            Trans2FindFirst2SearchStorageType searchStorageType,
            bool isReparsePath,
            bool isKnowsLongName,
            FindInformationLevel informationLevel)
        {
            SmbHeader_Flags2_Values flags2 = this.capability.Flags2;
            // update flags2 of header
            if (isReparsePath)
            {
                flags2 |= SmbHeader_Flags2_Values.SMB_FLAGS2_REPARSE_PATH;
            }

            if (isKnowsLongName)
            {
                flags2 |= SmbHeader_Flags2_Values.SMB_FLAGS2_KNOWS_LONG_NAMES;
            }
            return CreateTrans2FindFirst2Request(this.MessageId,
                this.GetSessionIdByTreeId(treeId), treeId,
               this.capability.Flag, flags2, fileName, transactOptions,
                this.capability.Timeout, searchCount, findFlags, searchAttributes, searchStorageType,
                informationLevel);
        }
        /// <summary>
        /// Create Trans2SetFileSystemInformation requestfor client to set the file system information on server. 
        /// </summary>
        /// <param name = "messageId">the id of message, used to identity the request and the server response. </param>
        /// <param name = "sessionUid">the valid session id, must be response by server of the session setup request. </param>
        /// <param name = "treeId">the valid tree connect id, must be response by server of the tree connect. </param>
        /// <param name = "flags">
        /// The Flags field contains individual flags, as specified in [CIFS] sections 2.4.2 and 3.1.1. 
        /// </param>
        /// <param name = "flags2">
        /// The Flags2 field contains individual bit flags that, depending on the negotiated SMB dialect, indicate   
        /// various client and server capabilities. 
        /// </param>
        /// <param name = "fileId">the valid file id to operation on, response by server. </param>
        /// <param name = "transactOptions">
        /// 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 maximum amount of time in milliseconds to wait for the operation to complete. The client SHOULD set  
        /// this to 0 to indicate that no time-out is given. If the operation does not complete within the specified  
        /// time, the server MAY abort the request and send a failure response. 
        /// </param>
        /// <param name = "isUsePathThrough">
        /// Indicates that the client is requesting a native Microsoft Windows® NT operating system information level, 
        /// as specified in section 3.2.4.7 and in [MS-FSCC] section 2.4. 
        /// </param>
        /// <param name = "informationLevel">
        /// Indicates that client specifies the information it is requesting. Server return different data based on 
        /// the client's request. 
        /// </param>
        /// <param name = "data">the information data to be set. </param>
        /// <returns>a set file information request packet </returns>
        private SmbTrans2SetFsInformationRequestPacket CreateTrans2SetFileSystemInformationRequest(
            ushort messageId,
            ushort sessionUid,
            ushort treeId,
            SmbHeader_Flags_Values flags,
            SmbHeader_Flags2_Values flags2,
            ushort fileId,
            Trans2SmbParametersFlags transactOptions,
            uint timeOut,
            bool isUsePathThrough,
            QueryFSInformationLevel informationLevel,
            byte[] data)
        {
            if (isUsePathThrough)
            {
                informationLevel = (QueryFSInformationLevel)
                    (informationLevel + SmbCapability.CONST_SMB_INFO_PASSTHROUGH);
            }

            SmbTrans2SetFsInformationRequestPacket packet =
                new SmbTrans2SetFsInformationRequestPacket(
                this.cifsClient.CreateTrans2SetFsInformationRequest(
                messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2,
                this.capability.MaxParameterCount, this.capability.MaxDataCount, this.capability.MaxSetupCount,
                transactOptions, timeOut, ""));

            // Set Trans2_Parameters
            TRANS2_SET_FILE_SYSTEM_INFORMATION_Request_Trans2_Parameters trans2Parameters =
                new TRANS2_SET_FILE_SYSTEM_INFORMATION_Request_Trans2_Parameters();
            trans2Parameters.FID = fileId;
            trans2Parameters.InformationLevel = informationLevel;

            // Set Trans2_Data
            TRANS2_SET_FILE_SYSTEM_INFORMATION_Request_Trans2_Data trans2Data =
                new TRANS2_SET_FILE_SYSTEM_INFORMATION_Request_Trans2_Data();
            trans2Data.Data = data;

            packet.Trans2Parameters = trans2Parameters;
            packet.Trans2Data = trans2Data;

            packet.UpdateCountAndOffset();

            return packet;
        }
        /// <summary>
        /// Create Trans2SetPathInformation request for client to set the path information on server. 
        /// </summary>
        /// <param name = "messageId">the id of message, used to identity the request and the server response. </param>
        /// <param name = "sessionUid">the valid session id, must be response by server of the session setup request. </param>
        /// <param name = "treeId">the valid tree connect id, must be response by server of the tree connect. </param>
        /// <param name = "flags">
        /// The Flags field contains individual flags, as specified in [CIFS] sections 2.4.2 and 3.1.1. 
        /// </param>
        /// <param name = "flags2">
        /// The Flags2 field contains individual bit flags that, depending on the negotiated SMB dialect, indicate   
        /// various client and server capabilities. 
        /// </param>
        /// <param name = "fileName">The name of path to set the information on server. </param>
        /// <param name = "isUsePathThrough">
        /// Indicates that the client is requesting a native Microsoft Windows® NT operating system information level, 
        /// as specified in section 3.2.4.7 and in [MS-FSCC] section 2.4. 
        /// </param>
        /// <param name = "transactOptions">
        /// 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 maximum amount of time in milliseconds to wait for the operation to complete. The client SHOULD set  
        /// this to 0 to indicate that no time-out is given. If the operation does not complete within the specified  
        /// time, the server MAY abort the request and send a failure response. 
        /// </param>
        /// <param name = "informationLevel">
        /// Indicates that client specifies the information it is requesting. Server return different data based on 
        /// the client's request. 
        /// </param>
        /// <param name = "data">the information data to be set. </param>
        /// <returns>a set path information request packet </returns>
        private SmbTrans2SetPathInformationRequestPacket CreateTrans2SetPathInformationRequest(
            ushort messageId,
            ushort sessionUid,
            ushort treeId,
            SmbHeader_Flags_Values flags,
            SmbHeader_Flags2_Values flags2,
            string fileName,
            bool isUsePathThrough,
            Trans2SmbParametersFlags transactOptions,
            uint timeOut,
            SetInformationLevel informationLevel,
            byte[] data)
        {
            if (isUsePathThrough)
            {
                informationLevel = (SetInformationLevel)
                    (informationLevel + SmbCapability.CONST_SMB_INFO_PASSTHROUGH);
            }

            SmbTrans2SetPathInformationRequestPacket packet = new SmbTrans2SetPathInformationRequestPacket(
                this.cifsClient.CreateTrans2SetPathInformationRequest(
                messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2,
                this.capability.MaxParameterCount, this.capability.MaxDataCount, this.capability.MaxSetupCount,
                transactOptions, timeOut, informationLevel, fileName, data));

            packet.UpdateCountAndOffset();

            return packet;
        }
 /// <summary>
 /// Create Trans2GetDFSReferral request for client to get the dfs referral on server. 
 /// </summary>
 /// <param name = "messageId">the id of message, used to identity the request and the server response. </param>
 /// <param name = "sessionUid">the valid session id, must be response by server of the session setup request. </param>
 /// <param name = "treeId">the valid tree connect id, must be response by server of the tree connect. </param>
 /// <param name = "flags">
 /// The Flags field contains individual flags, as specified in [CIFS] sections 2.4.2 and 3.1.1. 
 /// </param>
 /// <param name = "flags2">
 /// The Flags2 field contains individual bit flags that, depending on the negotiated SMB dialect, indicate   
 /// various client and server capabilities. 
 /// </param>
 /// <param name = "transactOptions">
 /// 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 maximum amount of time in milliseconds to wait for the operation to complete. The client SHOULD set  
 /// this to 0 to indicate that no time-out is given. If the operation does not complete within the specified  
 /// time, the server MAY abort the request and send a failure response. 
 /// </param>
 /// <param name = "dfsPathName">use to indicate the REQ_GET_DFS_REFERRAL([MS-DFSC] section 2.2.2). </param>
 /// <param name = "referralRequest">This field MUST be a properly formatted DFS referral request </param>
 /// <returns>a get dfs referral request packet </returns>
 private SmbTrans2GetDfsReferralRequestPacket CreateTrans2GetDFSReferralRequest(
     ushort messageId,
     ushort sessionUid,
     ushort treeId,
     SmbHeader_Flags_Values flags,
     SmbHeader_Flags2_Values flags2,
     Trans2SmbParametersFlags transactOptions,
     uint timeOut,
     string dfsPathName,
     REQ_GET_DFS_REFERRAL referralRequest)
 {
     return new SmbTrans2GetDfsReferralRequestPacket(
         this.cifsClient.CreateTrans2GetDfsReferalRequest(
         messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2,
         this.capability.MaxParameterCount, this.capability.MaxDataCount, this.capability.MaxSetupCount,
         transactOptions, timeOut, dfsPathName, referralRequest));
 }
        /// <summary>
        /// Create Trans2QueryPathInformation request for client to query path information from server. 
        /// </summary>
        /// <param name = "messageId">the id of message, used to identity the request and the server response. </param>
        /// <param name = "sessionUid">the valid session id, must be response by server of the session setup request. </param>
        /// <param name = "treeId">the valid tree connect id, must be response by server of the tree connect. </param>
        /// <param name = "flags">
        /// The Flags field contains individual flags, as specified in [CIFS] sections 2.4.2 and 3.1.1. 
        /// </param>
        /// <param name = "flags2">
        /// The Flags2 field contains individual bit flags that, depending on the negotiated SMB dialect, indicate   
        /// various client and server capabilities. 
        /// </param>
        /// <param name = "fileName">The name of path to query information from. </param>
        /// <param name = "transactOptions">
        /// 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 maximum amount of time in milliseconds to wait for the operation to complete. The client SHOULD set  
        /// this to 0 to indicate that no time-out is given. If the operation does not complete within the specified  
        /// time, the server MAY abort the request and send a failure response. 
        /// </param>
        /// <param name="isUsePathThrough">
        /// Indicates that the client is requesting a native Microsoft Windows庐 NT operating system information level, 
        /// as specified in section 3.2.4.7 and in [MS-FSCC] section 2.4. 
        /// </param>
        /// <param name = "informationLevel">
        /// Indicates that client specifies the information it is requesting. Server return different data based on 
        /// the client's request. 
        /// </param>
        /// <param name = "maxDataCount">The max size to query path information. </param>
        /// <returns>a query path information request packet </returns>
        private SmbTrans2QueryPathInformationRequestPacket CreateTrans2QueryPathInformationRequest(
            ushort messageId,
            ushort sessionUid,
            ushort treeId,
            SmbHeader_Flags_Values flags,
            SmbHeader_Flags2_Values flags2,
            string fileName,
            Trans2SmbParametersFlags transactOptions,
            uint timeOut,
            bool isUsePathThrough,
            QueryInformationLevel informationLevel,
            ushort maxDataCount)
        {
            // update information level
            if (isUsePathThrough)
            {
                informationLevel = (QueryInformationLevel)
                    (informationLevel + SmbCapability.CONST_SMB_INFO_PASSTHROUGH);
            }

            return new SmbTrans2QueryPathInformationRequestPacket(
                this.cifsClient.CreateTrans2QueryPathInformationRequest(
                messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2,
                this.capability.MaxParameterCount, maxDataCount, this.capability.MaxSetupCount,
                transactOptions, timeOut, informationLevel, fileName, null));
        }
        /// <summary>
        /// Create Trans2SetPathInformation request for client to set the path information on server. 
        /// </summary>
        /// <param name = "treeId">the valid tree connect id, must be response by server of the tree connect. </param>
        /// <param name = "fileName">The name of path to set the information on server. </param>
        /// <param name = "transactOptions">
        /// 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 = "informationLevel">
        /// Indicates that client specifies the information it is requesting. Server return different data based on 
        /// the client's request. 
        /// </param>
        /// <param name = "isReparsePath">If true, the path in the request MUST contain an @GMT token. </param>
        /// <param name = "data">the information data to be set. </param>
        /// <returns>a set path information request packet </returns>
        public virtual SmbTrans2SetPathInformationRequestPacket CreateTrans2SetPathInformationRequest(
            ushort treeId,
            string fileName,
            Trans2SmbParametersFlags transactOptions,
            SetInformationLevel informationLevel,
            bool isReparsePath,
            byte[] data)
        {
            SmbHeader_Flags2_Values flags2 = this.capability.Flags2;
            // update flags2 of header
            if (isReparsePath)
            {
                flags2 |= SmbHeader_Flags2_Values.SMB_FLAGS2_REPARSE_PATH;
            }

            return CreateTrans2SetPathInformationRequest(
                this.MessageId, this.GetSessionIdByTreeId(treeId), treeId, this.capability.Flag,
                flags2, fileName, this.capability.IsUsePathThrough, transactOptions, this.capability.Timeout, informationLevel, data);
        }
 /// <summary>
 /// Create Trans2FindNext2 request for client to find next file on server. 
 /// </summary>
 /// <param name = "messageId">the id of message, used to identity the request and the server response. </param>
 /// <param name = "sessionUid">the valid session id, must be response by server of the session setup request. </param>
 /// <param name = "treeId">the valid tree connect id, must be response by server of the tree connect. </param>
 /// <param name = "flags">
 /// The Flags field contains individual flags, as specified in [CIFS] sections 2.4.2 and 3.1.1. 
 /// </param>
 /// <param name = "flags2">
 /// The Flags2 field contains individual bit flags that, depending on the negotiated SMB dialect, indicate   
 /// various client and server capabilities. 
 /// </param>
 /// <param name = "fileName">The file name to find. </param>
 /// <param name = "transactOptions">
 /// 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 maximum amount of time in milliseconds to wait for the operation to complete. The client SHOULD set  
 /// this to 0 to indicate that no time-out is given. If the operation does not complete within the specified  
 /// time, the server MAY abort the request and send a failure response. 
 /// </param>
 /// <param name = "searchCount">
 /// The server MUST NOT return more entries than indicated by the value of this field. 
 /// </param>
 /// <param name = "findFlags">
 /// This 16-bit field of flags is used to request that the server take certain actions. 
 /// </param>
 /// <param name = "sid">used to set the field Trans2FindNext2RequestHeader.Sid (Search handle). </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 = "informationLevel">
 /// Indicates that client specifies the information it is requesting. Server return different data based on 
 /// the client's request. 
 /// </param>
 /// <returns>a find file the next request packet </returns>
 private SmbTrans2FindNext2RequestPacket CreateTrans2FindNext2Request(
     ushort messageId,
     ushort sessionUid,
     ushort treeId,
     SmbHeader_Flags_Values flags,
     SmbHeader_Flags2_Values flags2,
     string fileName,
     Trans2SmbParametersFlags transactOptions,
     uint timeOut,
     ushort searchCount,
     ushort sid,
     uint resumeKey,
     Trans2FindFlags findFlags,
     FindInformationLevel informationLevel)
 {
     return new SmbTrans2FindNext2RequestPacket(
         this.cifsClient.CreateTrans2FindNext2Request(
         messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2,
         this.capability.MaxParameterCount, this.capability.MaxDataCount, this.capability.MaxSetupCount,
         transactOptions, timeOut, sid, searchCount, (Cifs.FindInformationLevel)informationLevel, resumeKey,
         findFlags, fileName, null));
 }
 /// <summary>
 /// Create Trans2QueryFileSystemInformation request for client to query the file system information on server. 
 /// </summary>
 /// <param name = "treeId">the valid tree connect id, must be response by server of the tree connect. </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 = "transactOptions">
 /// 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 = "informationLevel">
 /// Indicates that client specifies the information it is requesting. Server return different data based on 
 /// the client's request. 
 /// </param>
 /// <returns>a query file system information request packet </returns>
 public virtual SmbTrans2QueryFsInformationRequestPacket CreateTrans2QueryFileSystemInformationRequest(
     ushort treeId,
     ushort maxDataCount,
     Trans2SmbParametersFlags transactOptions,
     QueryFSInformationLevel informationLevel)
 {
     return CreateTrans2QueryFileSystemInformationRequest(
         this.MessageId, this.GetSessionIdByTreeId(treeId), treeId, this.capability.Flag,
         this.capability.Flags2, this.capability.IsUsePathThrough,
         maxDataCount, transactOptions, this.capability.Timeout, informationLevel);
 }
 /// <summary>
 /// Create Trans2SetFileSystemInformation requestor client to set the file system information on server. 
 /// </summary>
 /// <param name = "fileId">the valid file id to operation on, response by server. </param>
 /// <param name = "transactOptions">
 /// 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 = "informationLevel">
 /// Indicates that client specifies the information it is requesting. Server return different data based on 
 /// the client's request. 
 /// </param>
 /// <param name = "data">the information data to be set. </param>
 /// <returns>a set file information request packet </returns>
 public virtual SmbTrans2SetFsInformationRequestPacket CreateTrans2SetFileSystemInformationRequest(
     ushort fileId,
     Trans2SmbParametersFlags transactOptions,
     QueryFSInformationLevel informationLevel,
     byte[] data)
 {
     return CreateTrans2SetFileSystemInformationRequest(
         this.MessageId,
         this.GetSessionIdByFileId(fileId), this.GetTreeIdByFileId(fileId), this.capability.Flag,
         this.capability.Flags2, fileId, transactOptions, this.capability.Timeout,
         this.capability.IsUsePathThrough,
         informationLevel, data);
 }
 /// <summary>
 /// Create Trans2GetDFSReferral request for client to get the Dfs referral on server. 
 /// </summary>
 /// <param name = "treeId">the valid tree connect id, must be response by server of the tree connect. </param>
 /// <param name = "transactOptions">
 /// 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 = "dfsPathName">use to indicate the REQ_GET_DFS_REFERRAL([MS-DFSC] section 2.2.2). </param>
 /// <param name = "referralRequest">This field MUST be a properly formatted DFS referral request </param>
 /// <returns>a get dfs referral request packet </returns>
 public virtual SmbTrans2GetDfsReferralRequestPacket CreateTrans2GetDFSReferralRequest(
     ushort treeId,
     Trans2SmbParametersFlags transactOptions,
     string dfsPathName,
     REQ_GET_DFS_REFERRAL referralRequest)
 {
     return CreateTrans2GetDFSReferralRequest(
         this.MessageId, this.GetSessionIdByTreeId(treeId), treeId,
        this.capability.Flag, this.capability.Flags2,
         transactOptions, this.capability.Timeout,
         dfsPathName, referralRequest);
 }
 /// <summary>
 /// Create Trans2QueryFileInformation request for client to query information of file on server. 
 /// </summary>
 /// <param name = "fileId">the valid file id to operation on, response by server. </param>
 /// <param name = "transactOptions">
 /// 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 = "maxDataCount">
 /// This value MUST be the number of bytes that the client requests  to read from the file on server. 
 /// </param>
 /// <param name = "informationLevel">
 /// Indicates that client specifies the information it is requesting. Server return different data based on 
 /// the client's request. 
 /// </param>
 /// <param name = "extendedAttributeList">
 /// This field MUST contain an array of extended file attribute name value pairs. 
 /// </param>
 /// <returns>a query file information request packet </returns>
 public virtual SmbTrans2QueryFileInformationRequestPacket CreateTrans2QueryFileInformationRequest(
     ushort fileId,
     Trans2SmbParametersFlags transactOptions,
     ushort maxDataCount,
     QueryInformationLevel informationLevel,
     params SMB_GEA[] extendedAttributeList)
 {
     return CreateTrans2QueryFileInformationRequest(
         this.MessageId,
         this.GetSessionIdByFileId(fileId), this.GetTreeIdByFileId(fileId),
         this.capability.Flag, this.capability.Flags2,
         fileId, transactOptions, this.capability.Timeout, this.capability.IsUsePathThrough,
         maxDataCount, informationLevel, extendedAttributeList);
 }
        /// <summary>
        /// to create a Trans2SetPathInformation 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="informationLevel">This field contains an information level code, which determines the
        /// information contained in the response.</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="data">the information data to be set.</param>
        /// <returns>a Trans2SetPathInformation request packet</returns>
        public SmbTrans2SetPathInformationRequestPacket CreateTrans2SetPathInformationRequest(
            ushort messageId,
            ushort uid,
            ushort treeId,
            SmbFlags flags,
            SmbFlags2 flags2,
            ushort maxParameterCount,
            ushort maxDataCount,
            byte maxSetupCount,
            Trans2SmbParametersFlags smbParametersFlags,
            uint timeout,
            SetInformationLevel informationLevel,
            string name,
            Object data)
        {
            if (name == null)
            {
                name = string.Empty;
            }

            SmbTrans2SetPathInformationRequestPacket packet = new SmbTrans2SetPathInformationRequestPacket();
            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_SET_PATH_INFORMATION };
            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_SET_PATH_INFORMATION_Request_Trans2_Parameters trans2Parameters =
                new TRANS2_SET_PATH_INFORMATION_Request_Trans2_Parameters();
            trans2Parameters.InformationLevel = informationLevel;
            trans2Parameters.FileName = 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_Data
            TRANS2_SET_PATH_INFORMATION_Request_Trans2_Data trans2Data =
                new TRANS2_SET_PATH_INFORMATION_Request_Trans2_Data();

            if (data != null)
            {
                if (data.GetType() == typeof(SMB_INFO_SET_EAS))
                {
                    SMB_INFO_SET_EAS info = (SMB_INFO_SET_EAS)data;

                    if (info.ExtendedAttributeList == null)
                    {
                        info.ExtendedAttributeList = new SMB_FEA[0];
                    }
                    info.SizeOfListInBytes = (uint)CifsMessageUtils.GetSize<uint>(info.SizeOfListInBytes);
                    info.SizeOfListInBytes += CifsMessageUtils.GetSmbEAListSize(info.ExtendedAttributeList);
                    data = info;
                }
                else if (data.GetType() == typeof(SMB_INFO_STANDARD_OF_TRANS2_SET_PATH_INFORMATION))
                {
                    SMB_INFO_STANDARD_OF_TRANS2_SET_PATH_INFORMATION info =
                        (SMB_INFO_STANDARD_OF_TRANS2_SET_PATH_INFORMATION)data;
                    {
                        // Reserved (10 bytes): MUST be set to zero when sent and MUST be ignored on receipt.
                        info.Reserved = new byte[10];
                        data = info;
                    }
                }
                else
                {
                    // Nothing needs to do.
                }
            }
            trans2Data.Data = data;

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

            return packet;
        }
        /// <summary>
        /// to create a Trans2SetFsInformation 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="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>
        /// <returns>a Trans2SetFsInformation request packet</returns>
        public SmbTrans2SetFsInformationRequestPacket CreateTrans2SetFsInformationRequest(
            ushort messageId,
            ushort uid,
            ushort treeId,
            SmbFlags flags,
            SmbFlags2 flags2,
            ushort maxParameterCount,
            ushort maxDataCount,
            byte maxSetupCount,
            Trans2SmbParametersFlags smbParametersFlags,
            uint timeout,
            string name)
        {
            if (name == null)
            {
                name = string.Empty;
            }

            SmbTrans2SetFsInformationRequestPacket packet = new SmbTrans2SetFsInformationRequestPacket();
            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_SET_FS_INFORMATION };
            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);

            packet.SmbParameters = smbParameters;
            packet.SmbData = smbData;
            packet.UpdateCountAndOffset();

            return packet;
        }
        /// <summary>
        /// to create a Trans2QueryPathInformation 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="informationLevel">This field contains an information level code, which determines the
        /// information contained in the response.</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">This field MUST contain an array of extended file attribute name value
        /// pairs. </param>
        /// <returns>a Trans2QueryPathInformation request packet</returns>
        public SmbTrans2QueryPathInformationRequestPacket CreateTrans2QueryPathInformationRequest(
            ushort messageId,
            ushort uid,
            ushort treeId,
            SmbFlags flags,
            SmbFlags2 flags2,
            ushort maxParameterCount,
            ushort maxDataCount,
            byte maxSetupCount,
            Trans2SmbParametersFlags smbParametersFlags,
            uint timeout,
            QueryInformationLevel informationLevel,
            string name,
            SMB_GEA[] extendedAttributeList)
        {
            if (name == null)
            {
                name = string.Empty;
            }
            if (extendedAttributeList == null)
            {
                extendedAttributeList = new SMB_GEA[0];
            }

            SmbTrans2QueryPathInformationRequestPacket packet = new SmbTrans2QueryPathInformationRequestPacket();
            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_QUERY_PATH_INFORMATION };
            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_QUERY_PATH_INFORMATION_Request_Trans2_Parameters trans2Parameters =
                new TRANS2_QUERY_PATH_INFORMATION_Request_Trans2_Parameters();
            trans2Parameters.InformationLevel = informationLevel;
            trans2Parameters.FileName = 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_Data
            TRANS2_QUERY_PATH_INFORMATION_Request_Trans2_Data trans2Data =
                new TRANS2_QUERY_PATH_INFORMATION_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;
        }
        /// <summary>
        /// to create a Trans2QueryFileInformation 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="informationLevel">This field contains an information level code, which determines the
        /// information contained in the response.</param>
        /// <param name="fid">This field MUST contain a valid FID returned from a previously successful SMB open
        /// command</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">This field MUST contain an array of extended file attribute name value
        /// pairs.</param>
        /// <returns>a Trans2QueryFileInformation request packet</returns>
        public SmbTrans2QueryFileInformationRequestPacket CreateTrans2QueryFileInformationRequest(
            ushort messageId,
            ushort uid,
            ushort treeId,
            SmbFlags flags,
            SmbFlags2 flags2,
            ushort maxParameterCount,
            ushort maxDataCount,
            byte maxSetupCount,
            Trans2SmbParametersFlags smbParametersFlags,
            uint timeout,
            string name,
            ushort fid,
            QueryInformationLevel informationLevel,
            SMB_GEA[] extendedAttributeList)
        {
            if (name == null)
            {
                name = string.Empty;
            }
            if (extendedAttributeList == null)
            {
                extendedAttributeList = new SMB_GEA[0];
            }

            SmbTrans2QueryFileInformationRequestPacket packet = new SmbTrans2QueryFileInformationRequestPacket();
            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_QUERY_FILE_INFORMATION };
            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_QUERY_FILE_INFORMATION_Request_Trans2_Parameters trans2Parameters =
                new TRANS2_QUERY_FILE_INFORMATION_Request_Trans2_Parameters();
            trans2Parameters.FID = fid;
            trans2Parameters.InformationLevel = informationLevel;

            // Set Trans2_Data
            TRANS2_QUERY_PATH_INFORMATION_Request_Trans2_Data trans2Data =
                new TRANS2_QUERY_PATH_INFORMATION_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;
        }
        /// <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;
        }