/// <summary>
        /// Verify FSCTL_SRV_REQUEST_RESUME_KEY Response.
        /// </summary>
        /// <param name="response">The FSCTL_SRV_REQUEST_RESUME_KEY Response.</param>
        private void VerifyMessageSyntaxFsctlSrvRequestResumeKeyResponse(
            SmbNtTransFsctlSrvRequestResumeKeyResponsePacket response)
        {
            //
            // Verify requirement MS-SMB_R9418 and MS-SMB_R109418
            //
            string isR9418Implementated = Site.Properties.Get("SHOULDMAYR9418Implementation");
            bool isR109418Satisfied = (4 == Marshal.SizeOf(response.NtTransData.ContextLength))
                && (0 == response.NtTransData.ContextLength);

            if (isWindows)
            {
                //
                // The following statement code will be run only when debugging.
                //
                Site.Log.Add(LogEntryKind.Debug,
                    @"Verify MS-SMB_R109418, ContextLength:{0}",
                    response.NtTransData.ContextLength);

                //
                // Verify MS-SMB requirement: MS-SMB_R109418.
                //
                Site.CaptureRequirementIfIsTrue(
                    isR109418Satisfied,
                    109418,
                    @"[In FSCTL_SRV_REQUEST_RESUME_KEY Response]ContextLength (4 bytes):  Since this feature is not
                    used, this field is set to zero by the server in Windows.");

                if (null == isR9418Implementated)
                {
                    Site.Properties.Add("SHOULDMAYR9418Implementation", Boolean.TrueString);
                    isR9418Implementated = Boolean.TrueString;
                }
            }

            if (null != isR9418Implementated)
            {
                bool implemented = Boolean.Parse(isR9418Implementated);
                bool isSatisfied = isR109418Satisfied;

                //
                // The following statement code will be run only when debugging.
                //
                Site.Log.Add(LogEntryKind.Debug,
                    @"Verify MS-SMB_R9418, ContextLength:{0}",
                    response.NtTransData.ContextLength);

                //
                // Verify MS-SMB requirement: MS-SMB_R9418.
                //
                Site.CaptureRequirementIfAreEqual<Boolean>(
                    implemented,
                    isSatisfied,
                    9418,
                    String.Format("[In FSCTL_SRV_REQUEST_RESUME_KEY Response]ContextLength (4 bytes):  Since this " +
                    "feature is not used,this field SHOULD be set to zero by the server. " +
                    "This requirement is {0}implemented", implemented ? "" : "not "));
            }

            //
            // Verify requirement MS-SMB_R9421 and MS-SMB_R9578
            //
            string isR9421Implementated = Site.Properties.Get("SHOULDMAYR9421Implementation");

            // If Context.length=0, it means that Context is contained in the packet and is initialized.
            bool isR9578Satisfied = (response.NtTransData.Context.Length == 0);

            if (isWindows)
            {
                //
                // The following statement code will be run only when debugging.
                //
                Site.Log.Add(LogEntryKind.Debug,
                    @"Verify MS-SMB_R9578,Context.Length:{0}",
                    response.NtTransData.Context.Length);

                //
                // Verify MS-SMB requirement: MS-SMB_R9578.
                //
                Site.CaptureRequirementIfIsTrue(
                    isR9578Satisfied,
                    9578,
                    @"<73> Section 2.2.7.2.2.2: Windows based servers include the Context field but do not initialize
                    it.");

                if (null == isR9421Implementated)
                {
                    Site.Properties.Add("SHOULDMAYR9421Implementation", Boolean.TrueString);
                    isR9421Implementated = Boolean.TrueString;
                }
            }

            if (null != isR9421Implementated)
            {
                bool implemented = Boolean.Parse(isR9421Implementated);
                bool isSatisfied = (response.NtTransData.Context.Length == 0);

                //
                // The following statement code will be run only when debugging.
                //
                Site.Log.Add(LogEntryKind.Debug,
                    @"Verify MS-SMB_R9421,Context.Length:{0}",
                    response.NtTransData.Context.Length);

                //
                // Verify MS-SMB requirement: MS-SMB_R9421.
                //
                Site.CaptureRequirementIfAreEqual<Boolean>(
                    implemented,
                    isSatisfied,
                    9421,
                    String.Format("[In FSCTL_SRV_REQUEST_RESUME_KEY Response]Context (variable): Since this feature is " +
                    "not used, this field SHOULD NOT<74> be included in the response. " +
                    "This requirement is {0}implemented", implemented ? "" : "not "));
            }
        }
        /// <summary>
        /// Create FSCTL_SRV_REQUEST_RESUME_KEY Response 
        /// </summary>
        /// <param name="connection">the connection identified the client</param>
        /// <param name = "resumeKey">
        /// 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>
        /// <returns>The SmbNtTransFsctlSrvRequestResumeKeyResponsePacket </returns>
        /// <exception cref="ArgumentNullException">connection must not be null</exception>
        public virtual SmbNtTransFsctlSrvRequestResumeKeyResponsePacket CreateFsctlSrvRequestResumeKeyResponse(
            SmbServerConnection connection, byte[] resumeKey)
        {
            if (connection == null)
            {
                throw new ArgumentNullException("connection");
            }

            SmbNtTransFsctlSrvRequestResumeKeyResponsePacket packet = new SmbNtTransFsctlSrvRequestResumeKeyResponsePacket();

            // get the request packet
            SmbPacket request = connection.GetRequestPacket(connection.MessageId);

            // create smb packet header
            packet.SmbHeader = CifsMessageUtils.CreateSmbHeader(
                SmbCommand.SMB_COM_NT_TRANSACT,
                connection.ProcessId, connection.MessageId, request.SmbHeader.Uid, request.SmbHeader.Tid,
                (SmbFlags)connection.Capability.Flag, (SmbFlags2)connection.Capability.Flags2);

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

            // reserved 3 bytes.
            smbParameters.Reserved1 = new byte[3];
            smbParameters.Setup = new ushort[0];

            smbParameters.WordCount = (byte)(CifsMessageUtils.GetSize<SMB_COM_NT_TRANSACT_SuccessResponse_SMB_Parameters>(
                smbParameters) / SmbCapability.NUM_BYTES_OF_WORD);

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

            // update trans2 data
            NT_TRANSACT_RESUME_KEY_Response_NT_Trans_Data ntTransData = packet.NtTransData;

            ntTransData.ResumeKey = resumeKey;
            ntTransData.ContextLength = 0;
            ntTransData.Context = new byte[0];

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

            packet.UpdateCountAndOffset();

            return packet;
        }
        private void verifyFsctlSrvRequestResumeKeyFunctionCode(
            SmbNtTransFsctlSrvRequestResumeKeyResponsePacket response)
        {
            //
            // The following statement code will be run only when debugging.
            //
            Site.Log.Add(LogEntryKind.Debug,
                @"Verify MS-SMB_R4988");

            //
            // Verify MS-SMB requirement: MS-SMB_R4988.
            //
            // Accordint to TD, the 24-bytes data generated by the SUT is saved in the field of ResumeKey.
            // ResumeKey is defined as an array of bytes, so the length of the array is the byte-length of ResumeKey.
            // And the latter half of the requirement is explaing the content of ResumeKey content and is informative.
            Site.CaptureRequirementIfAreEqual<int>(
                24,
                response.NtTransData.ResumeKey.Length,
                4988,
                @"[In Receiving an FSCTL_SRV_REQUEST_RESUME_KEY Function Code]The server MUST generate a 24-byte value
                that is used to uniquely identify the open of the file against which this operation is executed.");
        }
        /// <summary>
        /// create the nt transaction packet
        /// </summary>
        /// <param name="request">the request packet</param>
        /// <param name="smbHeader">the smb header of response packet</param>
        /// <param name="channel">the channel contains the packet bytes</param>
        /// <returns>the response packet</returns>
        private SmbPacket CreateNtTransactionResponsePacket(SmbPacket request, SmbHeader smbHeader, Channel channel)
        {
            SmbPacket smbPacket = null;

            if (smbHeader.Status == 0 && channel.Peek<byte>(0) == 0 && channel.Peek<ushort>(1) == 0)
            {
                return smbPacket;
            }

            SmbNtTransactRequestPacket ntTransactRequest = request as SmbNtTransactRequestPacket;
            if (ntTransactRequest == null)
            {
                return smbPacket;
            }

            // find regular packet
            switch ((uint)ntTransactRequest.SmbParameters.Function)
            {
                case (uint)NtTransSubCommand.NT_TRANSACT_RENAME:
                    smbPacket = new SmbNtTransRenameResponsePacket();
                    break;

                case (uint)NtTransSubCommand.NT_TRANSACT_CREATE:
                    smbPacket = new SmbNtTransactCreateResponsePacket();
                    break;

                case (uint)NtTransSubCommand.NT_TRANSACT_IOCTL:

                    NT_TRANSACT_IOCTL_SETUP setup =
                       CifsMessageUtils.ToStuct<NT_TRANSACT_IOCTL_SETUP>(
                       CifsMessageUtils.ToBytesArray<ushort>(ntTransactRequest.SmbParameters.Setup));

                    switch ((NtTransFunctionCode)setup.FunctionCode)
                    {
                        case NtTransFunctionCode.FSCTL_SRV_ENUMERATE_SNAPSHOTS:
                            smbPacket = new SmbNtTransFsctlSrvEnumerateSnapshotsResponsePacket();
                            break;

                        case NtTransFunctionCode.FSCTL_SRV_REQUEST_RESUME_KEY:
                            smbPacket = new SmbNtTransFsctlSrvRequestResumeKeyResponsePacket();
                            break;

                        case NtTransFunctionCode.FSCTL_SRV_COPYCHUNK:
                            smbPacket = new SmbNtTransFsctlSrvCopyChunkResponsePacket();
                            break;

                        default:
                            smbPacket = new SmbNtTransactIoctlResponsePacket();
                            break;
                    }

                    break;

                case (uint)SmbNtTransSubCommand.NT_TRANSACT_QUERY_QUOTA:
                    smbPacket = new SmbNtTransQueryQuotaResponsePacket();
                    break;

                case (uint)SmbNtTransSubCommand.NT_TRANSACT_SET_QUOTA:
                    smbPacket = new SmbNtTransSetQuotaResponsePacket();
                    break;

                default:
                    break;
            }

            return smbPacket;
        }
 /// <summary>
 /// Deep copy constructor.
 /// </summary>
 public SmbNtTransFsctlSrvRequestResumeKeyResponsePacket(
     SmbNtTransFsctlSrvRequestResumeKeyResponsePacket packet)
     : base(packet)
 {
 }
        /// <summary>
        /// create the nt transaction packet
        /// </summary>
        /// <param name="request">the request packet</param>
        /// <param name="smbHeader">the smb header of response packet</param>
        /// <param name="channel">the channel contains the packet bytes</param>
        /// <returns>the response packet</returns>
        private SmbPacket CreateNtTransactionResponsePacket(SmbPacket request, SmbHeader smbHeader, Channel channel)
        {
            SmbPacket smbPacket = null;

            if (smbHeader.Status == 0 && channel.Peek <byte>(0) == 0 && channel.Peek <ushort>(1) == 0)
            {
                return(smbPacket);
            }

            SmbNtTransactRequestPacket ntTransactRequest = request as SmbNtTransactRequestPacket;

            if (ntTransactRequest == null)
            {
                return(smbPacket);
            }

            // find regular packet
            switch ((uint)ntTransactRequest.SmbParameters.Function)
            {
            case (uint)NtTransSubCommand.NT_TRANSACT_RENAME:
                smbPacket = new SmbNtTransRenameResponsePacket();
                break;

            case (uint)NtTransSubCommand.NT_TRANSACT_CREATE:
                smbPacket = new SmbNtTransactCreateResponsePacket();
                break;

            case (uint)NtTransSubCommand.NT_TRANSACT_IOCTL:

                NT_TRANSACT_IOCTL_SETUP setup =
                    CifsMessageUtils.ToStuct <NT_TRANSACT_IOCTL_SETUP>(
                        CifsMessageUtils.ToBytesArray <ushort>(ntTransactRequest.SmbParameters.Setup));

                switch ((NtTransFunctionCode)setup.FunctionCode)
                {
                case NtTransFunctionCode.FSCTL_SRV_ENUMERATE_SNAPSHOTS:
                    smbPacket = new SmbNtTransFsctlSrvEnumerateSnapshotsResponsePacket();
                    break;

                case NtTransFunctionCode.FSCTL_SRV_REQUEST_RESUME_KEY:
                    smbPacket = new SmbNtTransFsctlSrvRequestResumeKeyResponsePacket();
                    break;

                case NtTransFunctionCode.FSCTL_SRV_COPYCHUNK:
                    smbPacket = new SmbNtTransFsctlSrvCopyChunkResponsePacket();
                    break;

                default:
                    smbPacket = new SmbNtTransactIoctlResponsePacket();
                    break;
                }

                break;

            case (uint)SmbNtTransSubCommand.NT_TRANSACT_QUERY_QUOTA:
                smbPacket = new SmbNtTransQueryQuotaResponsePacket();
                break;

            case (uint)SmbNtTransSubCommand.NT_TRANSACT_SET_QUOTA:
                smbPacket = new SmbNtTransSetQuotaResponsePacket();
                break;

            default:
                break;
            }

            return(smbPacket);
        }
 /// <summary>
 /// Deep copy constructor. 
 /// </summary>
 public SmbNtTransFsctlSrvRequestResumeKeyResponsePacket(
     SmbNtTransFsctlSrvRequestResumeKeyResponsePacket packet)
     : base(packet)
 {
 }