/// <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 tree disconnect request packet for client to dis connect a share on server. This command can follow 
 /// the tree connect command. 
 /// </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 = "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 = "treeId">the valid tree id to disconnect </param>
 /// <returns>a tree disconnect request packet. </returns>
 private SmbTreeDisconnectRequestPacket CreateTreeDisconnectRequest(
     ushort messageId,
     ushort sessionUid,
     ushort treeId,
     SmbHeader_Flags_Values flags,
     SmbHeader_Flags2_Values flags2
     )
 {
     return new SmbTreeDisconnectRequestPacket(
         this.cifsClient.CreateTreeDisconnectRequest(
         messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2));
 }
 /// <summary>
 /// Create a create request packet for client to create new or open share 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">A string that represents the name of the file to open or create. </param>
 /// <param name = "desiredAccess">
 /// Access wanted. This value MUST be specified in the ACCESS_MASK format, as specified in [CIFS] section 3.7. 
 /// </param>
 /// <param name = "extFileAttributes">Extended attributes and flags for this file or directory. </param>
 /// <param name = "shareAccess">Type of shared access requested for this file or directory. </param>
 /// <param name = "createDisposition">The action to take if a file does or does not exist. </param>
 /// <param name = "createOptions">The options to use if creating the file or directory. </param>
 /// <param name = "impersonationLevel">
 /// This field specifies the information given to the server about the client and how the server MUST   
 /// represent, or impersonate, the client. 
 /// </param>
 /// <param name = "createFlags">
 /// A 32-bit field containing a set of options that specify the security tracking mode. 
 /// </param>
 /// <returns>a create packet </returns>
 private SmbNtCreateAndxRequestPacket CreateCreateRequest(
     ushort messageId,
     ushort sessionUid,
     ushort treeId,
     SmbHeader_Flags_Values flags,
     SmbHeader_Flags2_Values flags2,
     string fileName,
     NtTransactDesiredAccess desiredAccess,
     SMB_EXT_FILE_ATTR extFileAttributes,
     NtTransactShareAccess shareAccess,
     NtTransactCreateDisposition createDisposition,
     NtTransactCreateOptions createOptions,
     NtTransactImpersonationLevel impersonationLevel,
     CreateFlags createFlags)
 {
     return new SmbNtCreateAndxRequestPacket(
         this.cifsClient.CreateNtCreateAndxRequest(
         messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2, (NtTransactFlags)createFlags,
         0, desiredAccess, 0, extFileAttributes, shareAccess, createDisposition,
         (Cifs.NtTransactCreateOptions)createOptions, impersonationLevel, (NtTransactSecurityFlags)0x00,
         fileName, null));
 }
        /// <summary>
        /// Create TransQueryNamedPipeInfo request for client to query the information of named pipe. 
        /// </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 = "informationLevel">
        /// A USHORT value (as specified in [MS-DTYP] section 2.2.54) that describes the information level being  
        /// queried for the pipe. The only supported value is 0x0001. 
        /// </param>
        /// <returns>a query named pipe information request packet </returns>
        /// <exception cref="ArgumentException">The only supported value is 0x0001.</exception>
        private SmbTransQueryNmpipeInfoRequestPacket CreateTransQueryNamedPipeInfoRequest(
            ushort messageId,
            ushort sessionUid,
            ushort treeId,
            SmbHeader_Flags_Values flags,
            SmbHeader_Flags2_Values flags2,
            ushort fileId,
            TransSmbParametersFlags transactOptions,
            uint timeOut,
            NamedPipeInformationLevel informationLevel)
        {
            if (informationLevel != NamedPipeInformationLevel.VALID)
            {
                throw new ArgumentException("The only supported value is 0x0001.", "informationLevel");
            }

            return new SmbTransQueryNmpipeInfoRequestPacket(
                this.cifsClient.CreateTransQueryNmpipeInfoRequest(
                messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2,
                this.capability.MaxParameterCount, this.capability.MaxDataCount, this.capability.MaxSetupCount,
                transactOptions, timeOut, fileId, ""));
        }
 /// <summary>
 /// Create TransWriteNamedPipe request for client to write data to named pipe. 
 /// </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 = "writeData">The data to write to named pipe. </param>
 /// <returns>a write named pipe request packet </returns>
 private SmbTransWriteNmpipeRequestPacket CreateTransWriteNamedPipeRequest(
     ushort messageId,
     ushort sessionUid,
     ushort treeId,
     SmbHeader_Flags_Values flags,
     SmbHeader_Flags2_Values flags2,
     ushort fileId,
     TransSmbParametersFlags transactOptions,
     uint timeOut,
     byte[] writeData)
 {
     return new SmbTransWriteNmpipeRequestPacket(
         this.cifsClient.CreateTransWriteNmpipeRequest(
         messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2,
         this.capability.MaxParameterCount, this.capability.MaxDataCount, this.capability.MaxSetupCount,
         transactOptions, timeOut, fileId, writeData, ""));
 }
        /// <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 TransMailslotWrite request for client to write data to mailslot 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 = "mailslotName">The name of maislot to write to. </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 = "writeData">The data to write to mailslot. </param>
        /// <param name = "priority">
        /// This field MUST be in the range of 0 to 9. The larger value being the higher priority. 
        /// </param>
        /// <param name = "className">
        /// The third setup word and the class of the mailslot request. This value MUST be set to one of the following 
        /// values. 
        /// </param>
        /// <returns>a write mailslot request packet </returns>
        private SmbTransMailslotWriteRequestPacket CreateTransMailslotWriteRequest(
            ushort messageId,
            ushort sessionUid,
            ushort treeId,
            SmbHeader_Flags_Values flags,
            SmbHeader_Flags2_Values flags2,
            string mailslotName,
            TransSmbParametersFlags transactOptions,
            uint timeOut,
            byte[] writeData,
            ushort priority,
            SmbTransMailslotClass className)
        {
            if (mailslotName == null)
            {
                mailslotName = string.Empty;
            }

            SmbTransMailslotWriteRequestPacket packet = new SmbTransMailslotWriteRequestPacket();
            packet.SmbHeader = CifsMessageUtils.CreateSmbHeader(SmbCommand.SMB_COM_TRANSACTION,
                messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2);

            // Set Smb Parameters
            SMB_COM_TRANSACTION_Request_SMB_Parameters smbParameters =
                new SMB_COM_TRANSACTION_Request_SMB_Parameters();
            smbParameters.MaxParameterCount = this.capability.MaxParameterCount;
            smbParameters.MaxDataCount = this.capability.MaxDataCount;
            smbParameters.MaxSetupCount = this.capability.MaxSetupCount;
            smbParameters.Flags = transactOptions;
            smbParameters.Timeout = timeOut;
            smbParameters.SetupCount = 3; // the correct count in word of the Setup is always 3.
            smbParameters.Setup = new ushort[3];
            smbParameters.Setup[0] = (ushort)TransSubCommand.TRANS_MAILSLOT_WRITE;
            smbParameters.Setup[1] = (ushort)priority;
            smbParameters.Setup[2] = (ushort)className;
            smbParameters.WordCount = (byte)(CifsMessageUtils.GetSize<SMB_COM_TRANSACTION_Request_SMB_Parameters>(
                smbParameters) / SmbCapability.NUM_BYTES_OF_WORD);

            // Set Smb Data
            SMB_COM_TRANSACTION_Request_SMB_Data smbData = new SMB_COM_TRANSACTION_Request_SMB_Data();
            smbData.Name = CifsMessageUtils.ToSmbStringBytes(mailslotName, this.capability.IsUnicode);
            smbData.Trans_Data = writeData;

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

            // update TransactionSubCommand in SmbGlobalContext, record the transact action
            this.capability.TransactionSubCommand = TransSubCommandExtended.TRANS_EXT_MAILSLOT_WRITE;

            return packet;
        }
 /// <summary>
 /// Create NTTransIOCtlRequestResumeKey request for client to resume key from server file. 
 /// </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 = "isFsctl">
 /// This field is TRUE if the command is a file system control command and the FID is a file system control  
 /// device. Otherwise, the command is a device control command and FID is an I/O device. 
 /// </param>
 /// <param name = "isFlags">
 /// If bit 0 is set, the command is to be applied to a share root handle. The share MUST be a Distributed File 
 ///  System (DFS) type 
 /// </param>
 /// <returns>a nt transaction IO control to resume key request packet </returns>
 private SmbNtTransFsctlSrvRequestResumeKeyRequestPacket CreateNTTransIOCtlRequestResumeKeyRequest(
     ushort messageId,
     ushort sessionUid,
     ushort treeId,
     SmbHeader_Flags_Values flags,
     SmbHeader_Flags2_Values flags2,
     ushort fileId,
     bool isFsctl,
     byte isFlags
     )
 {
     return new SmbNtTransFsctlSrvRequestResumeKeyRequestPacket(
             this.cifsClient.CreateNtTransactIoctlRequest(
             messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2,
             this.capability.MaxSetupCount, this.capability.MaxParameterCount, this.capability.MaxDataCount,
             (uint)NtTransFunctionCode.FSCTL_SRV_REQUEST_RESUME_KEY, fileId, isFsctl, isFlags, null));
 }
        /// <summary>
        /// Create NTTransQueryQuota request for client to query quota 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 = "isReturnSingleEntry">
        /// Indicates only a single entry is to be returned instead of filling the entire buffer. 
        /// </param>
        /// <param name = "isRestartScan">Indicates that the scan of the quota information is to be restarted. </param>
        /// <param name = "sidListLength">
        /// Supplies the length in bytes of the SidList (see below), or 0 if there is no SidList. 
        /// </param>
        /// <param name = "startSidLength">
        /// Supplies the length in bytes of the StartSid (see below), or 0 if there is no StartSid. MUST be ignored by 
        /// the receiver if SidListLength is non-zero. 
        /// </param>
        /// <param name = "startSidOffset">
        /// Supplies the offset, in bytes, to the StartSid in the Parameter buffer 
        /// </param>
        /// <returns>a nt transaction query quota request packet </returns>
        private SmbNtTransQueryQuotaRequestPacket CreateNTTransQueryQuotaRequest(
            ushort messageId,
            ushort sessionUid,
            ushort treeId,
            SmbHeader_Flags_Values flags,
            SmbHeader_Flags2_Values flags2,
            ushort fileId,
            bool isReturnSingleEntry,
            bool isRestartScan,
            int sidListLength,
            int startSidLength,
            int startSidOffset)
        {
            SmbNtTransQueryQuotaRequestPacket packet = new SmbNtTransQueryQuotaRequestPacket();
            packet.SmbHeader = CifsMessageUtils.CreateSmbHeader(SmbCommand.SMB_COM_NT_TRANSACT,
                messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2);

            // Set Smb_Parameters
            SMB_COM_NT_TRANSACT_Request_SMB_Parameters smbParameters =
                new SMB_COM_NT_TRANSACT_Request_SMB_Parameters();
            smbParameters.MaxSetupCount = this.capability.MaxSetupCount;
            smbParameters.MaxParameterCount = this.capability.MaxParameterCount;
            smbParameters.MaxDataCount = this.capability.MaxDataCount;
            smbParameters.SetupCount = 0; // the correct count in word of the Setup is always 0.
            smbParameters.Function = (NtTransSubCommand)SmbNtTransSubCommand.NT_TRANSACT_QUERY_QUOTA;
            smbParameters.Setup = new ushort[0];
            smbParameters.WordCount = (byte)(CifsMessageUtils.GetSize<SMB_COM_NT_TRANSACT_Request_SMB_Parameters>(
                smbParameters) / SmbCapability.NUM_BYTES_OF_WORD);

            // Set Smb_Data
            SMB_COM_NT_TRANSACT_Request_SMB_Data smbData = new SMB_COM_NT_TRANSACT_Request_SMB_Data();

            // Set Nt Transaction Parameters
            NT_TRANSACT_QUERY_QUOTA_Request_NT_Trans_Parameters
                ntTransParameters = new NT_TRANSACT_QUERY_QUOTA_Request_NT_Trans_Parameters();
            ntTransParameters.Fid = fileId;
            if (isReturnSingleEntry)
            {
                ntTransParameters.ReturnSingleEntry = 0x01;
            }
            if (isRestartScan)
            {
                ntTransParameters.RestartScan = 0x01;
            }
            ntTransParameters.SidListLength = (uint)sidListLength;
            ntTransParameters.StartSidLength = (uint)startSidLength;
            ntTransParameters.StartSidOffset = (uint)startSidOffset;

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

            return packet;
        }
 /// <summary>
 /// Create NTTransIOCtlEnumerateSnapShots request for client to enumerate snapshots 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 = "isFsctl">
 /// This field is TRUE if the command is a file system control command and the FID is a file system control  
 /// device. Otherwise, the command is a device control command and FID is an I/O device. 
 /// </param>
 /// <param name = "isFlags">
 /// If bit 0 is set, the command is to be applied to a share root handle. The share MUST be a Distributed File 
 ///  System (DFS) type 
 /// </param>
 /// <param name = "maxDataCount">The max size of data to query. </param>
 /// <returns>a nt transaction IO control to enumerate snap shots request packet </returns>
 private SmbNtTransFsctlSrvEnumerateSnapshotsRequestPacket CreateNTTransIOCtlEnumerateSnapShotsRequest(
     ushort messageId,
     ushort sessionUid,
     ushort treeId,
     SmbHeader_Flags_Values flags,
     SmbHeader_Flags2_Values flags2,
     ushort fileId,
     bool isFsctl,
     byte isFlags,
     int maxDataCount)
 {
     return new SmbNtTransFsctlSrvEnumerateSnapshotsRequestPacket(
             this.cifsClient.CreateNtTransactIoctlRequest(
         messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2,
         this.capability.MaxSetupCount, this.capability.MaxParameterCount, (uint)maxDataCount,
         (uint)NtTransFunctionCode.FSCTL_SRV_ENUMERATE_SNAPSHOTS, fileId, isFsctl, isFlags, null));
 }
 /// <summary>
 /// Create NTTransIOCtl request for the client to request an IO control 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 = "isFsctl">
 /// This field is TRUE if the command is a file system control command and the FID is a file system control  
 /// device. Otherwise, the command is a device control command and FID is an I/O device. 
 /// </param>
 /// <param name = "isFlags">
 /// If bit 0 is set, the command is to be applied to a share root handle. The share MUST be a Distributed File 
 ///  System (DFS) type 
 /// </param>
 /// <param name = "FunctionCode">The code for the sub function. </param>
 /// <param name = "data">
 /// The raw bytes that are passed to the fsctl or ioctl function as the input buffer. 
 /// </param>
 /// <returns>a nt transaction rename request packet </returns>
 /// <remarks>
 /// If an application running on a client requests an FSCTL or IOCTL of which the SMB implementation is  
 /// unaware, the format of the data is not well-known outside of the caller. The SMB protocol SHOULD pass  
 /// through the request. A server that receives an unexpected FSCTL or IOCTL SHOULD fail the operation by  
 /// returning STATUS_NOT_SUPPORTED. 
 /// </remarks>
 private SmbNtTransactIoctlRequestPacket CreateNTTransIOCtlRequest(
     ushort messageId,
     ushort sessionUid,
     ushort treeId,
     SmbHeader_Flags_Values flags,
     SmbHeader_Flags2_Values flags2,
     ushort fileId,
     bool isFsctl,
     byte isFlags,
     NtTransFunctionCode FunctionCode,
     byte[] data)
 {
     return this.cifsClient.CreateNtTransactIoctlRequest(
         messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2,
         this.capability.MaxSetupCount, this.capability.MaxParameterCount, this.capability.MaxDataCount,
         (uint)FunctionCode, fileId, isFsctl, isFlags, data);
 }
        /// <summary>
        /// Create NTTransIOCtlCopyChunk request for client to copy chunk to server file. 
        /// </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 = "isFsctl">
        /// This field is TRUE if the command is a file system control command and the FID is a file system control  
        /// device. Otherwise, the command is a device control command and FID is an I/O device. 
        /// </param>
        /// <param name = "isFlags">
        /// If bit 0 is set, the command is to be applied to a share root handle. The share MUST be a Distributed File 
        ///  System (DFS) type 
        /// </param>
        /// <param name = "copychunkResumeKey">
        /// A 24-byte resume key generated by the SMB server that can be subsequently used by the client to uniquely  
        /// identify the open source file in a FSCTL_SRV_COPYCHUNK request. 
        /// </param>
        /// <param name = "list">
        /// A concatenated list of copychunk blocks. This field is as specified in section 2.2.14.7.3.1. 
        /// </param>
        /// <returns>a nt transaction rename request packet </returns>
        /// <exception cref = "ArgumentNullException">list must not be null </exception>
        /// <exception cref = "ArgumentException">
        /// The number of entries in the copychunk list. MUST NOT be 0. 
        /// </exception>
        private SmbNtTransFsctlSrvCopyChunkRequestPacket CreateNTTransIOCtlCopyChunkRequest(
            ushort messageId,
            ushort sessionUid,
            ushort treeId,
            SmbHeader_Flags_Values flags,
            SmbHeader_Flags2_Values flags2,
            ushort fileId,
            bool isFsctl,
            byte isFlags,
            byte[] copychunkResumeKey,
            NT_TRANSACT_COPY_CHUNK_List[] list)
        {
            if (list == null)
            {
                throw new ArgumentNullException("list");
            }

            if (list.Length == 0)
            {
                throw new ArgumentException(
                    "The number of entries in the copychunk list. MUST NOT be 0.", "list");
            }

            SmbNtTransFsctlSrvCopyChunkRequestPacket request = new SmbNtTransFsctlSrvCopyChunkRequestPacket(
                this.cifsClient.CreateNtTransactIoctlRequest(
                messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2,
                this.capability.MaxSetupCount, this.capability.MaxParameterCount, this.capability.MaxDataCount,
                (uint)NtTransFunctionCode.FSCTL_SRV_COPYCHUNK, fileId, isFsctl, isFlags, null));

            // update the copy chunk trans data.
            NT_TRANSACT_COPY_CHUNK_Request_NT_Trans_Data ntTransData = request.NtTransData;

            ntTransData.CopyChunkResumeKey = copychunkResumeKey;
            ntTransData.ChunkCount = (uint)list.Length;
            ntTransData.List = list;

            request.NtTransData = ntTransData;

            request.UpdateCountAndOffset();

            return request;
        }
        /// <summary>
        /// create negotiate request packet. client sends this packet to server to negotiate the dialects. 
        /// </summary>
        /// <param name = "messageId">
        /// This field SHOULD be the multiplex ID that is used to associate a response with a request, as specified in 
        ///  [CIFS] sections 2.4.2 and 3.1.5. 
        /// </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 = "dialects">
        /// Array of null-terminated ASCII strings that indicate the SMB dialects supported by the client. 
        /// </param>
        /// <returns>a smb negotiate packet. </returns>
        private SmbNegotiateRequestPacket CreateNegotiateRequest(
            ushort messageId,
            SmbHeader_Flags_Values flags,
            SmbHeader_Flags2_Values flags2,
            params string[] dialects)
        {
            // update global context using flags2
            this.capability.IsSupportsExtendedSecurity =
                (flags2 & SmbHeader_Flags2_Values.SMB_FLAGS2_EXTENDED_SECURITY)
                == SmbHeader_Flags2_Values.SMB_FLAGS2_EXTENDED_SECURITY;

            this.capability.IsUnicode =
                (flags2 & SmbHeader_Flags2_Values.SMB_FLAGS2_UNICODE)
                == SmbHeader_Flags2_Values.SMB_FLAGS2_UNICODE;

            this.capability.IsKnowEAS =
                (flags2 & SmbHeader_Flags2_Values.SMB_FLAGS2_KNOWS_EAS)
                == SmbHeader_Flags2_Values.SMB_FLAGS2_KNOWS_EAS;

            // initialize the dialects
            SMB_Dialect[] smbDialects = new SMB_Dialect[dialects.Length];

            for (int i = 0; i < smbDialects.Length; i++)
            {
                SMB_Dialect dialect = new SMB_Dialect();

                // Each string MUST be prefixed with ASCII code 0x02
                dialect.BufferFormat = 0x02;
                dialect.DialectString = dialects[i];

                smbDialects[i] = dialect;
            }

            return new SmbNegotiateRequestPacket(
                this.cifsClient.CreateNegotiateRequest(messageId, (SmbFlags)flags, (SmbFlags2)flags2, smbDialects));
        }
 /// <summary>
 /// Create logoff request packet for client to log off server. This command can follow the session setup 
 /// success. 
 /// </summary>
 /// <param name = "messageId">the id of message, used to identity the request and the server response. </param>
 /// <param name = "sessionUid">the session id to logoff </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>
 /// <returns>a log off packet </returns>
 private SmbLogoffAndxRequestPacket CreateLogoffRequest(
     ushort messageId,
     ushort sessionUid,
     SmbHeader_Flags_Values flags,
     SmbHeader_Flags2_Values flags2
     )
 {
     return new SmbLogoffAndxRequestPacket(
         this.cifsClient.CreateLogoffAndxRequest(messageId, sessionUid,
         (SmbFlags)flags, (SmbFlags2)flags2, null));
 }
 /// <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 NTTransRename request for client to rename 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 = "fileId">the valid file id to operation on, response by server. </param>
        /// <param name = "isReplaceIfExists">
        /// If this param is true and the target exists, the server SHOULD attempt to replace the target. 
        /// </param>
        /// <param name = "newFileName">The new name of file. </param>
        /// <returns>a nt transaction rename request packet </returns>
        private SmbNtTransRenameRequestPacket CreateNTTransRenameRequest(
            ushort messageId,
            ushort sessionUid,
            ushort treeId,
            SmbHeader_Flags_Values flags,
            SmbHeader_Flags2_Values flags2,
            ushort fileId,
            bool isReplaceIfExists,
            string newFileName)
        {
            SmbNtTransRenameRequestPacket packet = new SmbNtTransRenameRequestPacket(
                this.cifsClient.CreateNtTransactRenameRequest(
                messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2,
                this.capability.MaxSetupCount, this.capability.MaxParameterCount, this.capability.MaxDataCount));

            NT_TRANSACT_RENAME_Request_NT_Trans_Parameters ntTransParameters =
                packet.NtTransParameters;
            ntTransParameters.Fid = fileId;
            if (isReplaceIfExists)
            {
                ntTransParameters.RenameFlags = 0x01;
            }
            if (Capability.IsUnicode)
            {
                ntTransParameters.Pad1 = new byte[1];
            }
            ntTransParameters.NewName = CifsMessageUtils.ToSmbStringBytes(newFileName, this.capability.IsUnicode);

            packet.NtTransParameters = ntTransParameters;
            packet.UpdateCountAndOffset();

            return packet;
        }
        /// <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 NTTransSetQuota request for client to set quota 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 = "nextEntryOffset">
        /// An offset to the start of the subsequent entry from the start of this entry, or 0 for the final entry. 
        /// </param>
        /// <param name = "changeTime">This value MUST be the time the quota was last changed, in TIME format. </param>
        /// <param name = "quotaUsed">
        /// The amount of quota, in bytes, used by this user. This field is formatted as a LARGE_INTEGER, as specified 
        ///  in [CIFS] section 2.4.2. 
        /// </param>
        /// <param name = "quotaThreshold">
        /// The quota warning limit, in bytes, for this user. This field is formatted as a LARGE_INTEGER, as specified 
        ///  in [CIFS] section 2.4.2. 
        /// </param>
        /// <param name = "quotaLimit">
        /// The quota limit, in bytes, for this user. This field is formatted as a LARGE_INTEGER, as specified in  
        /// [CIFS] section 2.4.2. 
        /// </param>
        /// <param name = "sid">
        /// The security identifier of this user. For details, see [MS-DTYP] section 2.4.2. Note that [CIFS] sections  
        /// 4.3.4, 4.3.4.7, 4.3.5, and 4.3.5.6 use Sid as the field name for a search handle. In [XOPEN-SMB], the  
        /// search handle field is called a findfirst_dirhandle or findnext_dirhandle. These are better field names 
        /// for a search handle. this param can not be null.
        /// </param>
        /// <returns>a nt transaction set quota request packet </returns>
        /// <exception cref="ArgumentNullException">sid can not be null.</exception>
        private SmbNtTransSetQuotaRequestPacket CreateNTTransSetQuotaRequest(
            ushort messageId,
            ushort sessionUid,
            ushort treeId,
            SmbHeader_Flags_Values flags,
            SmbHeader_Flags2_Values flags2,
            ushort fileId,
            uint nextEntryOffset,
            ulong changeTime,
            ulong quotaUsed,
            ulong quotaThreshold,
            ulong quotaLimit,
            byte[] sid)
        {
            if (sid == null)
            {
                throw new ArgumentNullException("sid");
            }

            SmbNtTransSetQuotaRequestPacket packet = new SmbNtTransSetQuotaRequestPacket();
            packet.SmbHeader = CifsMessageUtils.CreateSmbHeader(SmbCommand.SMB_COM_NT_TRANSACT,
                messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2);

            // Set Smb_Parameters
            SMB_COM_NT_TRANSACT_Request_SMB_Parameters smbParameters =
                new SMB_COM_NT_TRANSACT_Request_SMB_Parameters();
            smbParameters.MaxSetupCount = this.capability.MaxSetupCount;
            smbParameters.MaxParameterCount = this.capability.MaxParameterCount;
            smbParameters.MaxDataCount = this.capability.MaxDataCount;
            smbParameters.SetupCount = 0; // the correct count in word of the Setup is always 0.
            smbParameters.Function = (NtTransSubCommand)SmbNtTransSubCommand.NT_TRANSACT_SET_QUOTA;
            smbParameters.Setup = new ushort[0];
            smbParameters.WordCount = (byte)(CifsMessageUtils.GetSize<SMB_COM_NT_TRANSACT_Request_SMB_Parameters>(
                smbParameters) / SmbCapability.NUM_BYTES_OF_WORD);

            // Set Smb_Data
            SMB_COM_NT_TRANSACT_Request_SMB_Data smbData = new SMB_COM_NT_TRANSACT_Request_SMB_Data();

            // Set Nt Transaction Parameters
            NT_TRANSACT_SET_QUOTA_Request_NT_Trans_Parameters
                ntTransParameters = new NT_TRANSACT_SET_QUOTA_Request_NT_Trans_Parameters();
            ntTransParameters.Fid = fileId;

            // Set Nt Transaction Data
            NT_TRANSACT_SET_QUOTA_Request_NT_Trans_Data
                ntTransData = new NT_TRANSACT_SET_QUOTA_Request_NT_Trans_Data();
            ntTransData.NextEntryOffset = nextEntryOffset;
            ntTransData.SidLength = (uint)sid.Length;
            ntTransData.ChangeTime = changeTime;
            ntTransData.QuotaUsed = quotaUsed;
            ntTransData.QuotaThreshold = quotaThreshold;
            ntTransData.QuotaLimit = quotaLimit;
            ntTransData.Sid = sid;

            packet.SmbParameters = smbParameters;
            packet.SmbData = smbData;
            packet.NtTransParameters = ntTransParameters;
            packet.NtTransData = ntTransData;
            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 a open request packet for client to open a share 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 = "shareName">the file name to open </param>
 /// <param name = "fileOpenMode">file open mode </param>
 /// <param name = "fileOpenFunction">
 /// 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 = "extFileAttributes">the extend file attributes </param>
 /// <param name = "extSearchAttributes">the search attributes of file </param>
 /// <param name = "allocationSize">Bytes to reserve on create or truncate </param>
 /// <param name = "openFlags">A 16-bit field of flags for requesting attribute data and locking </param>
 /// <returns>a open request packet </returns>
 private SmbOpenAndxRequestPacket CreateOpenRequest(
     ushort messageId,
     ushort sessionUid,
     ushort treeId,
     SmbHeader_Flags_Values flags,
     SmbHeader_Flags2_Values flags2,
     string shareName,
     AccessMode fileOpenMode,
     OpenMode fileOpenFunction,
     SmbFileAttributes extFileAttributes,
     SmbFileAttributes extSearchAttributes,
     uint allocationSize,
     OpenFlags openFlags)
 {
     return new SmbOpenAndxRequestPacket(
         this.cifsClient.CreateOpenAndxRequest(messageId, sessionUid, treeId,
         (SmbFlags)flags, (SmbFlags2)flags2, (Flags)openFlags, fileOpenMode,
         extSearchAttributes, extFileAttributes, new UTime(), fileOpenFunction,
         allocationSize, this.capability.Timeout, shareName, null));
 }
        /// <summary>
        /// Create TransNamedRap request for client to send a rap request to 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="rapOPCode">
        /// The operation code for the particular operation. For more information on valid operation codes, see 2.5.4.
        /// </param>
        /// <param name="paramDesc">
        /// This value MUST be a null-terminated ASCII descriptor string. The server SHOULD validate that the ParamDesc
        /// value passed by the client matches what is specified by the RAPOpcode. The following table specifies the
        /// descriptor character and the notation for each data type.
        /// </param>
        /// <param name="dataDesc">
        /// (Optional) If this value is specified, it MUST be a null-terminated ASCII descriptor string that describes
        /// the contents of the data returned to the client. Certain RAPOpcodes specify a DataDesc field; for a list
        /// of Remote Administration Protocol commands that specify a DataDesc field, see section 2.5.5.
        /// </param>
        /// <param name="rapParamsAndAuxDesc">
        /// This field combines the following fields, because each of their length is unknown:<para/>
        /// RAPParams: Remote Administration Protocol command-specific parameters, as specified in sections 2.5.5, 2.5.6, 2.5.7,
        /// 2.5.8, and 2.5.9.<para/>
        /// AuxDesc: (Optional) If this value is specified, it MUST be a null-terminated ASCII descriptor string that describes
        /// auxiliary data returned to the client. If no AuxDesc field is specified for the Remote Administration
        /// Protocol command, this field MUST NOT be present. For the origin of the descriptor string values, see
        /// section 4.2.
        /// </param>
        /// <param name="rapInData">
        /// Additional data for the Remote Administration Protocol request. This field MUST be present in the
        /// NetPrintJobSetInfoRequest command. This field cannot be present in any other command.
        /// </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>
        /// <returns>a named rap request packet </returns>
        private SmbTransRapRequestPacket CreateTransNamedRapRequest(
            ushort messageId,
            ushort sessionUid,
            ushort treeId,
            SmbHeader_Flags_Values flags,
            SmbHeader_Flags2_Values flags2,
            TransSmbParametersFlags transactOptions,
            ushort rapOPCode,
            byte[] paramDesc,
            byte[] dataDesc,
            byte[] rapParamsAndAuxDesc,
            byte[] rapInData,
            uint timeOut)
        {
            SmbTransRapRequestPacket packet = new SmbTransRapRequestPacket();
            packet.SmbHeader = CifsMessageUtils.CreateSmbHeader(SmbCommand.SMB_COM_TRANSACTION,
                messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2);

            // Set Smb Parameters
            SMB_COM_TRANSACTION_Request_SMB_Parameters smbParameters =
                new SMB_COM_TRANSACTION_Request_SMB_Parameters();
            smbParameters.MaxParameterCount = this.capability.MaxParameterCount;
            smbParameters.MaxDataCount = this.capability.MaxDataCount;
            smbParameters.MaxSetupCount = this.capability.MaxSetupCount;
            smbParameters.Flags = transactOptions;
            smbParameters.Timeout = timeOut;
            smbParameters.SetupCount = 0; // the correct count in word of the Setup is always 0.
            smbParameters.Setup = new ushort[0];
            smbParameters.WordCount = (byte)(CifsMessageUtils.GetSize<SMB_COM_TRANSACTION_Request_SMB_Parameters>(
                smbParameters) / SmbCapability.NUM_BYTES_OF_WORD);

            // Set Smb Data
            SMB_COM_TRANSACTION_Request_SMB_Data smbData = new SMB_COM_TRANSACTION_Request_SMB_Data();
            smbData.Name = CifsMessageUtils.ToSmbStringBytes("", this.capability.IsUnicode);

            // Set Transaction Parameters
            TRANSACTION_Rap_Request_Trans_Parameters transParameters = new TRANSACTION_Rap_Request_Trans_Parameters();
            transParameters.RapOPCode = rapOPCode;
            transParameters.ParamDesc = paramDesc;
            transParameters.DataDesc = dataDesc;
            transParameters.RAPParamsAndAuxDesc = rapParamsAndAuxDesc;

            // Set Transaction Data
            TRANSACTION_Rap_Request_Trans_Data transData = new TRANSACTION_Rap_Request_Trans_Data();
            transData.RAPInData = rapInData;

            packet.SmbParameters = smbParameters;
            packet.SmbData = smbData;
            packet.TransParameters = transParameters;
            packet.TransData = transData;
            packet.UpdateCountAndOffset();

            // update TransactionSubCommand in SmbGlobalContext, record the transact action
            this.capability.TransactionSubCommand = TransSubCommandExtended.TRANS_EXT_RAP;

            return packet;
        }
 /// <summary>
 /// Create read request for client to read data 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 = "fileId">the valid file id to operation on, response by server. </param>
 /// <param name = "maxCount">the max count to read </param>
 /// <param name = "minCount">the min count to read </param>
 /// <param name = "offsetHigh">the high offset to write to file </param>
 /// <param name = "offset">the offset to write to file </param>
 /// <returns>a read request packet. </returns>
 private SmbReadAndxRequestPacket CreateReadRequest(
     ushort messageId,
     ushort sessionUid,
     ushort treeId,
     SmbHeader_Flags_Values flags,
     SmbHeader_Flags2_Values flags2,
     ushort fileId,
     ushort maxCount,
     ushort minCount,
     uint offsetHigh,
     uint offset)
 {
     return new SmbReadAndxRequestPacket(
         this.cifsClient.CreateReadAndxRequest(
         messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2, fileId, offset,
         maxCount, minCount, this.capability.Timeout, offsetHigh, null));
 }
 /// <summary>
 /// Create TransWaitNamedPipe request for client to wait named pipe 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 = "priority">
 /// This field MUST be in the range of 0 to 9. The larger value being the higher priority. 
 /// </param>
 /// <param name = "name">
 /// The pathname of the mailslot or named pipe to which the transaction subcommand applies or a client 
 /// supplied identifier that provides a name for the transaction. 
 /// </param>
 /// <returns>a wait named pipe request packet </returns>
 private SmbTransWaitNmpipeRequestPacket CreateTransWaitNamedPipeRequest(
     ushort messageId,
     ushort sessionUid,
     ushort treeId,
     SmbHeader_Flags_Values flags,
     SmbHeader_Flags2_Values flags2,
     TransSmbParametersFlags transactOptions,
     uint timeOut,
     ushort priority,
     string name)
 {
     return new SmbTransWaitNmpipeRequestPacket(
         this.cifsClient.CreateTransWaitNmpipeRequest(
         messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2,
         this.capability.MaxParameterCount, this.capability.MaxDataCount, this.capability.MaxSetupCount,
         transactOptions, timeOut, priority, name));
 }
        /// <summary>
        /// create the implicit NTLM SessionSetup request packet 
        /// </summary>
        /// <param name = "messageId">the id of message, used to identity the request and the server response. </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 = "capabilities">
        /// A set of client capabilities. These flags are a subset of those specified in section for the server   
        /// capabilities returned in the SMB_COM_NEGOTIATE response. 
        /// </param>
        /// <param name = "maxBufferSize">
        /// The maximum size, in bytes, of the client buffer for sending and receiving SMB messages. 
        /// </param>
        /// <param name = "maxMpxCount">
        /// The maximum number of pending multiplexed requests supported by the client. This value MUST be less than 
        /// or equal to the MaxMpxCount value provided by the server in the SMB_COM_NEGOTIATE response 
        /// </param>
        /// <param name = "implicitNtlmVersion">
        /// the version of smb to using: PlainTextPassword: transport password as plain-text.     the 
        /// NEGOTIATE_ENCRYPT_PASSWORDS of SecurityMode in negotiate response should set to 0. NtlmVersion1:using ntlm 
        /// v1 NtlmVersion2:using ntlm v2 
        /// </param>
        /// <param name = "domainName">the domain name of user credential </param>
        /// <param name = "userName">the name of user credential </param>
        /// <param name = "password">the password of user credential </param>
        /// <returns>A session setup packet. </returns>
        /// <exception cref = "InvalidOperationException">
        /// the implicit NTLM only support when ExtendedSessionSecurity is set to 0 
        /// </exception>
        private SmbSessionSetupImplicitNtlmAndxRequestPacket CreateSessionSetupImplicitNtlmRequest(
            ushort messageId,
            SmbHeader_Flags_Values flags,
            SmbHeader_Flags2_Values flags2,
            Capabilities capabilities,
            ushort maxBufferSize,
            ushort maxMpxCount,
            ImplicitNtlmVersion implicitNtlmVersion,
            string domainName,
            string userName,
            string password)
        {
            if (Capability.IsSupportsExtendedSecurity)
            {
                throw new InvalidOperationException(
                    "the implicit NTLM only support when ExtendedSessionSecurity is set to 0");
            }

            NTLMAuthenticationPolicyValues ntlmAuthenticationPolicyValues;
            LMAuthenticationPolicyValues lmAuthenticationPolicyValues;

            if (implicitNtlmVersion == ImplicitNtlmVersion.PlainTextPassword)
            {
                ntlmAuthenticationPolicyValues = NTLMAuthenticationPolicyValues.Disabled;
                lmAuthenticationPolicyValues = LMAuthenticationPolicyValues.Disabled;
            }
            else if (implicitNtlmVersion == ImplicitNtlmVersion.NtlmVersion1)
            {
                ntlmAuthenticationPolicyValues = NTLMAuthenticationPolicyValues.Disabled;
                lmAuthenticationPolicyValues = LMAuthenticationPolicyValues.LmEnabled;
            }
            // ntlm version 2
            else
            {
                ntlmAuthenticationPolicyValues = NTLMAuthenticationPolicyValues.NtlmV2Enabled;
                lmAuthenticationPolicyValues = LMAuthenticationPolicyValues.LmV2Enabled;
            }

            return new SmbSessionSetupImplicitNtlmAndxRequestPacket(
                this.cifsClient.CreateSessionSetupAndxRequest(
                messageId, (SmbFlags)flags, (SmbFlags2)flags2, maxBufferSize, maxMpxCount, 0, 0,
                (Cifs.Capabilities)capabilities, new CifsUserAccount(domainName, userName, password), "\0", "\0", null,
                ntlmAuthenticationPolicyValues, lmAuthenticationPolicyValues));
        }
 /// <summary>
 /// Create tree connect request for client to access share of server. This command match all device type, and 
 /// must following the session setup. 
 /// </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 = "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 = "path">the share name to treeconnect to </param>
 /// <param name = "services">
 /// The type of resource that the client intends to access. This field MUST be a null-terminated array of OEM  
 /// characters even if the client and server have negotiated to use Unicode strings. 
 /// </param>
 /// <param name = "treeConnectFlags">
 /// A 16-bit field used to modify the SMB_COM_TREE_CONNECT_ANDX request. 
 /// </param>
 /// <returns>a tree connect request packet. </returns>
 private SmbTreeConnectAndxRequestPacket CreateTreeConnectRequest(
     ushort messageId,
     ushort sessionUid,
     SmbHeader_Flags_Values flags,
     SmbHeader_Flags2_Values flags2,
     string path,
     string services,
     TreeConnectFlags treeConnectFlags)
 {
     return new SmbTreeConnectAndxRequestPacket(
         this.cifsClient.CreateTreeConnectAndxRequest(
         messageId, sessionUid, (SmbFlags)flags, (SmbFlags2)flags2,
         (TreeConnectAndxFlags)treeConnectFlags, path, services, new byte[1], // null-terminated.
         null));
 }
        /// <summary>
        /// Create session setup request packet. Using the Extended Session Security mechanism. This is the long 
        /// parameter packet Api for creating all Extended Security authenticate packet. 
        /// </summary>
        /// <param name = "messageId">the id of message, used to identity the request and the server response. </param>
        /// <param name = "sessionUid">
        /// Set this value to 0 to request a new session setup, or set this value to a previously established session  
        /// identifier to request reauthenticating an existing session. 
        /// </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 = "capabilities">
        /// A set of client capabilities. These flags are a subset of those specified in section for the server   
        /// capabilities returned in the SMB_COM_NEGOTIATE response. 
        /// </param>
        /// <param name = "maxBufferSize">
        /// The maximum size, in bytes, of the client buffer for sending and receiving SMB messages. 
        /// </param>
        /// <param name = "securityPackage">the package name of security. </param>
        /// <param name = "serverName">the server name to authenticate </param>
        /// <param name = "domainName">the domain name of user credential </param>
        /// <param name = "userName">the name of user credential </param>
        /// <param name = "password">the password of user credential </param>
        /// <returns>A session setup packet. </returns>
        /// <exception cref = "InvalidOperationException">the ExtendedSessionSecurity must set to 1 </exception>
        private SmbSessionSetupAndxRequestPacket CreateSessionSetupRequest(
            ushort messageId,
            ushort sessionUid,
            SmbHeader_Flags_Values flags,
            SmbHeader_Flags2_Values flags2,
            Capabilities capabilities,
            ushort maxBufferSize,
            SmbSecurityPackage securityPackage,
            string serverName,
            string domainName,
            string userName,
            string password)
        {
            if (!Capability.IsSupportsExtendedSecurity)
            {
                throw new InvalidOperationException("the ExtendedSessionSecurity must set to 1");
            }

            SmbSessionSetupAndxRequestPacket packet = new SmbSessionSetupAndxRequestPacket();

            // create smb packet header
            packet.SmbHeader = CifsMessageUtils.CreateSmbHeader(
                SmbCommand.SMB_COM_SESSION_SETUP_ANDX, messageId, sessionUid, 0, (SmbFlags)flags, (SmbFlags2)flags2);

            // update smb parameters
            SMB_COM_SESSION_SETUP_ANDX_Request_SMB_Parameters smbParameters = packet.SmbParameters;

            smbParameters.MaxBufferSize = maxBufferSize;
            smbParameters.Capabilities = (uint)capabilities;

            // update smb data
            SMB_COM_SESSION_SETUP_ANDX_Request_SMB_Data smbData = packet.SmbData;

            #region Generate the security blob, using Negotiate, Kerberos or Ntlm

            // get the default connection
            SmbClientConnection connection =
                this.Context.GetConnection(this.ConnectionId) as SmbClientConnection;
            if (connection == null)
            {
                return null;
            }

            // initialize gss api.
            if (connection.GssApi == null)
            {
                string serverPrincipal = GSS_API_TARGET_NAME_PREFIX + serverName;

                switch (securityPackage)
                {
                    case SmbSecurityPackage.NTLM:
                        connection.GssApi = new NlmpClientSecurityContext(
                            new NlmpClientCredential(serverPrincipal, domainName, userName, password));
                        break;

                    case SmbSecurityPackage.Kerberos:
                        connection.GssApi = new SspiClientSecurityContext(
                            SecurityPackageType.Kerberos,
                            new AccountCredential(domainName, userName, password),
                            serverPrincipal, ClientSecurityContextAttribute.Connection,
                            SecurityTargetDataRepresentation.SecurityNetworkDrep);
                        break;

                    default:
                        connection.GssApi = new SspiClientSecurityContext(
                            SecurityPackageType.Negotiate,
                            new AccountCredential(domainName, userName, password),
                            serverPrincipal, ClientSecurityContextAttribute.Connection,
                            SecurityTargetDataRepresentation.SecurityNetworkDrep);
                        break;
                }
            }

            // initialize the token.
            // if ntlm, this is used to generate the negotiate and authenticate token.
            // if kerberos, this is used to generate the token which is sent to server.
            connection.GssApi.Initialize(connection.SecurityBlob);

            // update connection
            this.Context.AddOrUpdateConnection(connection);

            // store token to security blob of packet
            byte[] securityBlob = connection.GssApi.Token;
            smbParameters.SecurityBlobLength = (ushort)securityBlob.Length;
            smbData.SecurityBlob = new byte[securityBlob.Length];
            Array.Copy(securityBlob, smbData.SecurityBlob, securityBlob.Length);

            #endregion

            // initialize default values
            smbData.Pad = new byte[0];
            if (Capability.IsUnicode && smbParameters.SecurityBlobLength % SmbCapability.TWO_BYTES_ALIGN == 0)
            {
                smbData.Pad = new byte[1];
            }
            // null terminate.
            smbData.NativeOS = new byte[2];
            smbData.NativeLanMan = new byte[2];

            // update smbData.ByteCount
            smbData.ByteCount = 0;
            if (smbData.SecurityBlob != null)
            {
                smbData.ByteCount += (ushort)smbData.SecurityBlob.Length;
            }
            if (smbData.Pad != null)
            {
                smbData.ByteCount += (ushort)smbData.Pad.Length;
            }
            if (smbData.NativeOS != null)
            {
                smbData.ByteCount += (ushort)smbData.NativeOS.Length;
            }
            if (smbData.NativeLanMan != null)
            {
                smbData.ByteCount += (ushort)smbData.NativeLanMan.Length;
            }

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

            // upate context
            this.Context.SetSecurityPackage(securityPackage);

            return packet;
        }
 /// <summary>
 /// Create write request packet for client to write data to 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 = "offsetHigh">the high offset to write to file </param>
 /// <param name = "offset">the offset to write to file </param>
 /// <param name = "data">the data to write to file </param>
 /// <returns>a write request packet. </returns>
 private SmbWriteAndxRequestPacket CreateWriteRequest(
     ushort messageId,
     ushort sessionUid,
     ushort treeId,
     SmbHeader_Flags_Values flags,
     SmbHeader_Flags2_Values flags2,
     ushort fileId,
     uint offsetHigh,
     uint offset,
     byte[] data)
 {
     return new SmbWriteAndxRequestPacket(
         this.cifsClient.CreateWriteAndxRequest(
         messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2,
         fileId, offset, this.capability.Timeout, WriteAndxWriteMode.NONE, offsetHigh, data, null));
 }
 /// <summary>
 /// Create a close request packet for client to close a opened share. 
 /// </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 id of file to close </param>
 /// <returns>a close request packet </returns>
 private SmbCloseRequestPacket CreateCloseRequest(
     ushort messageId,
     ushort sessionUid,
     ushort treeId,
     SmbHeader_Flags_Values flags,
     SmbHeader_Flags2_Values flags2,
     ushort fileId)
 {
     return new SmbCloseRequestPacket(
         this.cifsClient.CreateCloseRequest(
         messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2, fileId, new UTime()));
 }