/// <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>
        /// find the target packet.
        /// </summary>
        /// <param name="smbHeader">the header of smb packet</param>
        /// <param name="channel">the channel to access bytes</param>
        /// <returns>the target packet</returns>
        private static SmbPacket FindTheTargetPacket(SmbHeader smbHeader, Channel channel)
        {
            SmbPacket smbPacket = null;

            switch (smbHeader.Command)
            {
                case SmbCommand.SMB_COM_NEGOTIATE:
                        smbPacket = new SmbNegotiateRequestPacket();
                    break;

                case SmbCommand.SMB_COM_SESSION_SETUP_ANDX:
                    SmbHeader_Flags2_Values flags2 = (SmbHeader_Flags2_Values)smbHeader.Flags2;
                    if ((flags2 & SmbHeader_Flags2_Values.SMB_FLAGS2_EXTENDED_SECURITY)
                        == SmbHeader_Flags2_Values.SMB_FLAGS2_EXTENDED_SECURITY)
                    {
                        smbPacket = new Smb.SmbSessionSetupAndxRequestPacket();
                    }
                    else
                    {
                        smbPacket = new Cifs.SmbSessionSetupAndxRequestPacket();
                    }
                    break;

                case SmbCommand.SMB_COM_TREE_CONNECT_ANDX:
                    smbPacket = new SmbTreeConnectAndxRequestPacket();
                    break;

                case SmbCommand.SMB_COM_NT_CREATE_ANDX:
                    smbPacket = new SmbNtCreateAndxRequestPacket();
                    break;

                case SmbCommand.SMB_COM_OPEN_ANDX:
                    smbPacket = new SmbOpenAndxRequestPacket();
                    break;

                case SmbCommand.SMB_COM_WRITE_ANDX:
                    smbPacket = new SmbWriteAndxRequestPacket();
                    break;

                case SmbCommand.SMB_COM_READ_ANDX:
                    smbPacket = new SmbReadAndxRequestPacket();
                    break;

                case SmbCommand.SMB_COM_CLOSE:
                    smbPacket = new SmbCloseRequestPacket();
                    break;

                case SmbCommand.SMB_COM_TREE_DISCONNECT:
                    smbPacket = new SmbTreeDisconnectRequestPacket();
                    break;

                case SmbCommand.SMB_COM_LOGOFF_ANDX:
                    smbPacket = new SmbLogoffAndxRequestPacket();
                    break;

                case SmbCommand.SMB_COM_TRANSACTION:
                    SMB_COM_TRANSACTION_Request_SMB_Parameters transaction =
                        channel.Read<SMB_COM_TRANSACTION_Request_SMB_Parameters>();
                    if (transaction.SetupCount == 0)
                    {
                        smbPacket = new SmbTransRapRequestPacket();
                    }
                    else
                    {
                        smbPacket = FindTheTransactionPacket(
                            transaction.SetupCount, (TransSubCommand)transaction.Setup[0]);
                    }
                    break;

                case SmbCommand.SMB_COM_TRANSACTION2:
                    SMB_COM_TRANSACTION2_Request_SMB_Parameters transaction2 =
                        channel.Read<SMB_COM_TRANSACTION2_Request_SMB_Parameters>();
                    smbPacket = FindTheTrans2Packet((Trans2SubCommand)transaction2.Subcommand);
                    break;

                case SmbCommand.SMB_COM_NT_TRANSACT:
                    SMB_COM_NT_TRANSACT_Request_SMB_Parameters ntTransactoin =
                        channel.Read<SMB_COM_NT_TRANSACT_Request_SMB_Parameters>();
                    smbPacket = FindTheNtTransPacket(ntTransactoin.Function, CifsMessageUtils.ToBytesArray<ushort>(ntTransactoin.Setup));
                    break;

                default:
                    break;
            }

            return smbPacket;
        }
        public void TraditionalTestCase_NetServerEnum3_06()
        {
            #region Connect to the specified server

            smbClientStack.Connect(serverName, serverPort, ipVersion, bufferSize);

            #endregion

            #region Send the Negotiate request

            // Create a SMB_COM_NEGOTIATE request.
            SmbNegotiateRequestPacket negotiateRequest =
                smbClientStack.CreateNegotiateRequest(
                    StackSmb.SignState.NONE,
                    new string[] {
                DialectNameString.PCNET1,
                DialectNameString.LANMAN10,
                DialectNameString.WFW10,
                DialectNameString.LANMAN12,
                DialectNameString.LANMAN21,
                DialectNameString.NTLANMAN
            });

            // Send the SMB_COM_NEGOTIATE request and expect the response in timeout milliseconds.
            smbClientStack.SendPacket(negotiateRequest);
            StackPacket response = smbClientStack.ExpectPacket(timeout);

            // Check whether server return a response.
            Site.Assert.IsNotNull(
                response,
                "SMB_COM_NEGOTIATE response should not be null.");

            // Check whether server returns a SMB_COM_NEGOTIATE response.
            Site.Assert.IsInstanceOfType(
                response,
                typeof(SmbNegotiateResponsePacket),
                "SMB_COM_NEGOTIATE response should be received.");

            // Check the response validity by verifying the Status field in the SMB Header packet.
            SmbNegotiateResponsePacket negotiateResponse = (SmbNegotiateResponsePacket)response;
            Site.Assert.AreEqual <uint>(
                (uint)SmbStatus.STATUS_SUCCESS,
                negotiateRequest.SmbHeader.Status,
                "SMB_COM_NEGOTIATE response status should be SUCCESS.");

            #endregion

            #region Send the first SMB_COM_SESSION_SETUP_ANDX  Request

            SmbSecurityPackage smbSecurityPackage = (SmbSecurityPackage)Enum.Parse(
                typeof(SmbSecurityPackage),
                Site.Properties["SmbSecurityPackageType"] as string,
                true);

            // Create the first SMB_COM_SESSION_SETUP_ANDX request.
            SmbSessionSetupAndxRequestPacket sessionSetupAndxRequest =
                smbClientStack.CreateFirstSessionSetupRequest(
                    smbSecurityPackage,
                    serverName,
                    domainName,
                    userName,
                    password);

            // Send the first SMB_COM_SESSION_SETUP_ANDX request and expect the response in timeout milliseconds.
            smbClientStack.SendPacket(sessionSetupAndxRequest);
            response = smbClientStack.ExpectPacket(timeout);

            // Check whether server return a response.
            Site.Assert.IsNotNull(
                response,
                "SMB_COM_SESSION_SETUP_ANDX response should not be null.");

            // Check whether server returns a the SMB_COM_SESSION_SETUP_ANDX response.
            Site.Assert.IsInstanceOfType(
                response,
                typeof(SmbSessionSetupAndxResponsePacket),
                "SMB_COM_SESSION_SETUP_ANDX response should be received.");

            // Check the response validity by verifying the Status field in the SMB Header packet.
            // If SMB SecurityPackage type is NTLM, the expected SUCCESS response status is STATUS_MORE_PROCESSING_REQUIRED,
            // else if SMB SecurityPackage type is Kerberos, the expected SUCCESS response status is STATUS_SUCCESS.
            SmbSessionSetupAndxResponsePacket sessionSetupResponse = (SmbSessionSetupAndxResponsePacket)response;
            Site.Assert.IsTrue(
                (int)sessionSetupResponse.SmbHeader.Status == (int)SmbStatus.STATUS_MORE_PROCESSING_REQUIRED ||
                (int)sessionSetupResponse.SmbHeader.Status == (int)SmbStatus.STATUS_SUCCESS,
                "SMB_COM_SESSION_SETUP_ANDX response status should be SUCCESS.");

            #endregion

            #region Send the second SMB_COM_SESSION_SETUP_ANDX  request

            // Create the second SMB_COM_SESSION_SETUP_ANDX request.
            ushort sessionUid = sessionSetupResponse.SmbHeader.Uid;

            if ((int)sessionSetupResponse.SmbHeader.Status == (int)SmbStatus.STATUS_MORE_PROCESSING_REQUIRED)
            {
                SmbSessionSetupAndxRequestPacket secondSessionSetupRequest =
                    smbClientStack.CreateSecondSessionSetupRequest(sessionUid, smbSecurityPackage);

                // Send the second SMB_COM_SESSION_SETUP_ANDX request and expect the response in timeout milliseconds.
                smbClientStack.SendPacket(secondSessionSetupRequest);
                response = smbClientStack.ExpectPacket(timeout);

                // Check whether server return a response.
                Site.Assert.IsNotNull(
                    response,
                    "SMB_COM_SESSION_SETUP_ANDX response should not be null.");

                // Check whether server returns a the SMB_COM_SESSION_SETUP_ANDX response.
                Site.Assert.IsInstanceOfType(
                    response,
                    typeof(SmbSessionSetupAndxResponsePacket),
                    "SMB_COM_SESSION_SETUP_ANDX response should be received.");

                // Check the response validity by verifying the Status field in the SMB Header packet.
                sessionSetupResponse = (SmbSessionSetupAndxResponsePacket)response;
                Site.Assert.AreEqual <uint>(
                    (uint)SmbStatus.STATUS_SUCCESS,
                    sessionSetupResponse.SmbHeader.Status,
                    "SMB_COM_SESSION_SETUP_ANDX response status should be SUCCESS.");
            }

            #endregion

            #region Send the SMB_COM_TREE_CONNECT_ANDX request

            string path = Site.Properties["SutNamedPipeFullName"];

            SmbTreeConnectAndxRequestPacket treeconnectRequest =
                smbClientStack.CreateTreeConnectRequest(sessionUid, path);

            smbClientStack.SendPacket(treeconnectRequest);
            response = smbClientStack.ExpectPacket(timeout);

            SmbTreeConnectAndxResponsePacket treeConnectResponse = (SmbTreeConnectAndxResponsePacket)response;
            #endregion

            #region SMB transaction
            // System.Text.ASCIIEncoding.ASCII.GetBytes("WrLehDZz");
            byte[] paramDesc = new byte[] { 0x57, 0x72, 0x4c, 0x65, 0x68, 0x44, 0x7a, 0x7a, 0x00 };

            byte[] dataDesc            = new byte[] { 0x42, 0x31, 0x36, 0x42, 0x42, 0x44, 0x7a, 0x00 };
            byte[] rapParamsAndAuxDesc = new byte[] { 0x01, 0x00, 0xFF, 0xFF };

            byte[] rapInData = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0x45, 0x4e, 0x44, 0x50,
                                            0x4f, 0x49, 0x4e, 0x54, 0x30, 0x31, 0x00 };

            SmbTransRapRequestPacket netServerEnmum2Request =
                smbClientStack.CreateTransNamedRapRequest(treeConnectResponse.SmbHeader.Tid,
                                                          StackCifs.TransSmbParametersFlags.NONE,
                                                          (ushort)0x00D7,
                                                          paramDesc,
                                                          dataDesc,
                                                          rapParamsAndAuxDesc, rapInData);
            smbClientStack.SendPacket(netServerEnmum2Request);
            response = smbClientStack.ExpectPacket(timeout);
            #endregion
        }
 /// <summary>
 /// Deep copy constructor. 
 /// </summary>
 public SmbTransRapRequestPacket(SmbTransRapRequestPacket packet)
     : base(packet)
 {
 }