Esempio n. 1
0
        /// <summary>
        /// Retrieve the RopNotify and RopPending response by sending an empty RPC request.
        /// </summary>
        /// <param name="expectGetNotification">A bool type indicating whether expect to get any notification.</param>
        /// <returns>The list of ROP response, empty if no response returned.</returns>
        public IList <IDeserializable> GetNotification(bool expectGetNotification)
        {
            IList <IDeserializable> notification;
            List <List <uint> >     responseSOHs;

            // If expectGetNotification is true, which means the notifications are expected. Do a loop to get notifications.
            // Otherwise, only get the notification once.
            if (expectGetNotification)
            {
                // The retry times to try getting notifications.
                int retryCount = int.Parse(Common.GetConfigurationPropertyValue("RetryCount", this.Site));
                int sleepTime  = int.Parse(Common.GetConfigurationPropertyValue("SleepTime", this.Site));
                do
                {
                    // Sleep some time to get pending notification and notification details,
                    // the sleep time is implementation-specific, which can be configured.
                    Thread.Sleep(sleepTime);

                    notification = this.Process(
                        null,
                        this.LogonHandle,
                        out responseSOHs);
                    retryCount--;
                }while (notification.Count == 0 && retryCount > 0);
                Site.Assert.AreNotEqual <int>(
                    0,
                    notification.Count,
                    "Failed to get the RopNotify and RopPending response.");
                foreach (IDeserializable rsp in notification)
                {
                    if (rsp is RopNotifyResponse)
                    {
                        RopNotifyResponse response = (RopNotifyResponse)rsp;
                        this.VerifyRopNotifyResponse(response);
                    }
                    else if (rsp is RopPendingResponse)
                    {
                        this.VerifyRopPendingResponse();
                    }

                    this.VerifyROPTransport();
                    this.VerifyMAPITransport();
                }
            }
            else
            {
                notification = this.Process(
                    null,
                    this.LogonHandle,
                    out responseSOHs);
            }

            return(notification);
        }
        /// <summary>
        /// Verify NotificationFlags of RopNotify response.
        /// </summary>
        /// <param name="ropNotifyResponse">The response of ropNotify</param>
        private void VerifyNotificationFlagsOfRopNotify(RopNotifyResponse ropNotifyResponse)
        {
            // FlagsBit.T is 0x1000. T bit is set in NotificationFlags.
            bool isTBitSet = (ropNotifyResponse.NotificationData.NotificationFlags & (ushort)FlagsBit.T) == (ushort)FlagsBit.T;
            if (isTBitSet)
            {
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R112");

                // Since the RopNotify response is de-serialized as this requirement's description, so if the T bit can get successfully, 
                // this requirement can be verified directly.
                Site.CaptureRequirement(
                    112,
                    @"[In NotificationData Structure] 0x1000: specify flag T.");

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R114");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R114
                this.Site.CaptureRequirementIfAreEqual<int>(
                    0x0010,
                    (int)ropNotifyResponse.NotificationData.NotificationType,
                    114,
                    @"[In NotificationData Structure] If this bit [0x1000] is set, the NotificationType MUST be 0x0010.");
            }

            // FlagsBit.U is 0x2000. U bit is set.
            bool isUBitSet = (ropNotifyResponse.NotificationData.NotificationFlags & (ushort)FlagsBit.U) == (ushort)FlagsBit.U;
            if (isUBitSet)
            {
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R115");

                // Since the RopNotify response is de-serialized as this requirement's description, so if the U bit can get successfully, 
                // this requirement can be verified directly.
                Site.CaptureRequirement(
                    115,
                    @"[In NotificationData Structure] 0x2000: specify flag U.");

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R117");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R117
                this.Site.CaptureRequirementIfAreEqual<int>(
                    0x0010,
                    (int)ropNotifyResponse.NotificationData.NotificationType,
                    117,
                    @"[In NotificationData Structure] If this bit [0x2000] is set, the NotificationType MUST be 0x0010.");
            }

            // FlagsBit.S is 0x4000. S bit is set.
            bool isSBitSet = (ropNotifyResponse.NotificationData.NotificationFlags & (ushort)FlagsBit.S) == (ushort)FlagsBit.S;
            if (isSBitSet)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R118");

                // Since the RopNotify response is de-serialized as this requirement's description, so if the S bit can get successfully, 
                // this requirement can be verified directly.
                Site.CaptureRequirement(
                    118,
                    @"[In NotificationData Structure] 0x4000: specify flag S.");

                int actualBitSet = ropNotifyResponse.NotificationData.NotificationFlags & (ushort)FlagsBit.M;

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R120");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R120
                this.Site.CaptureRequirementIfAreEqual<int>(
                    0x8000,
                    actualBitSet,
                    120,
                    @"[In NotificationData Structure] If this bit [0x4000] is set, bit 0x8000 MUST be set.");
            }

            // FlagsBit.M is 0x8000. M bit is set.
            bool isMBitSet = (ropNotifyResponse.NotificationData.NotificationFlags & (ushort)FlagsBit.M) == (ushort)FlagsBit.M;
            if (isMBitSet)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R121");

                // Since the RopNotify response is de-serialized as this requirement's description, so if the M bit can get successfully, 
                // this requirement can be verified directly.
                Site.CaptureRequirement(
                    121,
                    @"[In NotificationData Structure] 0x8000: specify flag M.");
            }

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R138");

            int notificationFlagsLength = Marshal.SizeOf(ropNotifyResponse.NotificationData.NotificationFlags) * 8;
            int notificationTypeLength = notificationFlagsLength - 4;

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R138
            // NotificationFlags (2 bytes) is a combination of NotificationType and flags (T bit,U bit,S bit,M bit), so the size of the NotificationType is the size of NotificationFlags subtract the four bit (T bit,U bit,S bit,M bit). 
            this.Site.CaptureRequirementIfAreEqual<int>(
                12,
                notificationTypeLength,
                138,
                @"[In NotificationData Structure] It [NotificationType] is 12 bits.");
        }
        /// <summary>
        /// Verify RopNotify response for other events(ObjectCreated,ObjectDeleted,ObjectModified,ObjectMoved,ObjectCopied,SearchResult)
        /// </summary>
        /// <param name="ropNotifyResponse">The response of ropNotify</param>
        private void VerifyRopNotifyForOtherEvents(RopNotifyResponse ropNotifyResponse)
        {
            if (ropNotifyResponse.NotificationData.FolderId != null)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R169");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R169
                this.Site.CaptureRequirementIfAreEqual<int>(
                    8,
                    Marshal.SizeOf(ropNotifyResponse.NotificationData.FolderId),
                    169,
                    @"[In NotificationData Structure] It [FolderId] is 8 bytes.");
            }

            if (ropNotifyResponse.NotificationData.MessageId != null)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R173");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R173
                this.Site.CaptureRequirementIfAreEqual<int>(
                    8,
                    Marshal.SizeOf(ropNotifyResponse.NotificationData.MessageId),
                    173,
                    @"[In NotificationData Structure] It [MessageId] is 8 bytes.");
            }

            bool isTotalMessageCountAvailable = (ropNotifyResponse.NotificationData.NotificationFlags & (ushort)FlagsBit.T) == (ushort)FlagsBit.T;

            if (isTotalMessageCountAvailable)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R205");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R205
                this.Site.CaptureRequirementIfAreEqual<int>(
                    4,
                    Marshal.SizeOf(ropNotifyResponse.NotificationData.TotalMessageCount),
                    205,
                    @"[In NotificationData Structure] It [TotalMessageCount]  is 4 bytes.");
            }

            bool isUnreadMessageCountAvailable = (ropNotifyResponse.NotificationData.NotificationFlags & (ushort)FlagsBit.U) == (ushort)FlagsBit.U;

            if (isUnreadMessageCountAvailable)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R209");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R209
                this.Site.CaptureRequirementIfAreEqual<int>(
                    4,
                    Marshal.SizeOf(ropNotifyResponse.NotificationData.UnreadMessageCount),
                    209,
                    @"[In NotificationData Structure] It [UnreadMessageCount]  is 4 bytes.");
            }

            if (ropNotifyResponse.NotificationData.ParentFolderId != null)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R177");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R177
                this.Site.CaptureRequirementIfAreEqual<int>(
                    8,
                    Marshal.SizeOf(ropNotifyResponse.NotificationData.ParentFolderId),
                    177,
                    @"[In NotificationData Structure] It [ParentFolderId]  is 8 bytes.");
            }

            // Refer to MS-OXCNOTIF section 2.2.1.4.1.1: OldFolderId is available only if the NotificationType value in the NotificationFlags field is 0x0020(ObjectMoved) or 0x0040(ObjectCopied).
            bool isOldFolderIdAvailable = ropNotifyResponse.NotificationData.NotificationType == NotificationType.ObjectMoved ||
                        ropNotifyResponse.NotificationData.NotificationType == NotificationType.ObjectCopied;

            if (isOldFolderIdAvailable)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R181");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R181
                this.Site.CaptureRequirementIfAreEqual<int>(
                    8,
                    Marshal.SizeOf(ropNotifyResponse.NotificationData.OldFolderId),
                    181,
                    @"[In NotificationData Structure] It [OldFolderId] is 8 bytes.");
            }

            // Refer to MS-OXCNOTIF section 2.2.1.4.1.1: OldMessageId is available only if the value of the NotificationType field in the NotificationFlags field is
            // 0x0020(ObjectMoved) or 0x0040(ObjectCopied) and bit 0x8000(M bit) is set in the NotificationFlags field.
            bool isOldMessageIdAvailable = (ropNotifyResponse.NotificationData.NotificationType == NotificationType.ObjectMoved ||
                ropNotifyResponse.NotificationData.NotificationType == NotificationType.ObjectCopied) &&
                (ropNotifyResponse.NotificationData.NotificationFlags & (ushort)FlagsBit.M) == (ushort)FlagsBit.M;
            if (isOldMessageIdAvailable)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R185");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R185
                this.Site.CaptureRequirementIfAreEqual<int>(
                    8,
                    Marshal.SizeOf(ropNotifyResponse.NotificationData.OldMessageId),
                    185,
                    @"[In NotificationData Structure] It [OldMessageId] is 8 bytes.");
            }

            // Refer to MS-OXCNOTIF section 2.2.1.4.1.1: OldParentFolderId is available only if the value of the NotificationType field in the NotificationFlags field is 0x0020(ObjectMoved) or 0x0040(ObjectCopied)
            // and bit 0x8000(M bit) is not set in the NotificationFlags field.
            bool isOldParentFolderIdAvailable = (ropNotifyResponse.NotificationData.NotificationType == NotificationType.ObjectMoved ||
                ropNotifyResponse.NotificationData.NotificationType == NotificationType.ObjectCopied) &&
                (ropNotifyResponse.NotificationData.NotificationFlags & (ushort)FlagsBit.M) != (ushort)FlagsBit.M;

            if (isOldParentFolderIdAvailable)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R189");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R189
                this.Site.CaptureRequirementIfAreEqual<int>(
                    8,
                    Marshal.SizeOf(ropNotifyResponse.NotificationData.OldParentFolderId),
                    189,
                    @"[In NotificationData Structure] It [OldParentFolderId] is 8 bytes.");
            }

            // Refer to MS-OXCNOTIF section 2.2.1.4.1.1: TagCount is available only if the value of the NotificationType field in the NotificationFlags field is 0x0004(ObjectCreated) or 0x0010(ObjectModified).
            bool isTagCountAvailable = ropNotifyResponse.NotificationData.NotificationType == NotificationType.ObjectCreated ||
                    ropNotifyResponse.NotificationData.NotificationType == NotificationType.ObjectModified;
            if (isTagCountAvailable)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R193");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R193
                this.Site.CaptureRequirementIfAreEqual<int>(
                    2,
                    Marshal.SizeOf(ropNotifyResponse.NotificationData.TagCount),
                    193,
                    @"[In NotificationData Structure] It [TagCount]  is 2 bytes.");
            }
        }
        /// <summary>
        /// Verify RopNotify response for NewMail events
        /// </summary>
        /// <param name="ropNotifyResponse">The response of ropNotify</param>
        private void VerifyRopNotifyForNewMail(RopNotifyResponse ropNotifyResponse)
        {
            if (ropNotifyResponse.NotificationData.NotificationType == NotificationType.NewMail)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R213");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R213
                this.Site.CaptureRequirementIfAreEqual<int>(
                    4,
                    Marshal.SizeOf(ropNotifyResponse.NotificationData.MessageFlags),
                    213,
                    @"[In NotificationData Structure] It [MessageFlags] is 4 bytes.");
            
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R217");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R217
                this.Site.CaptureRequirementIfAreEqual<int>(
                    1,
                    Marshal.SizeOf(ropNotifyResponse.NotificationData.UnicodeFlag),
                    217,
                    @"[In NotificationData Structure] It [UnicodeFlag]  is 1 byte.");
            }

            if (ropNotifyResponse.NotificationData.MessageClass != null)
            {
                if (ropNotifyResponse.NotificationData.UnicodeFlag == 0x00)
                {
                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R219");

                    // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R219
                    bool isVerifiedR219 = this.IsNullTerminatedASCIIStr(ropNotifyResponse.NotificationData.MessageClass);

                    this.Site.CaptureRequirementIfIsTrue(
                        isVerifiedR219,
                        219,
                        @"[In NotificationData Structure]  otherwise, [the value of UnicodeFlag is]FALSE (0x00) indicates the value of the MessageClass is in ASCII.");

                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R225");

                    // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R225
                    bool isVerifiedR225 = this.IsNullTerminatedASCIIStr(ropNotifyResponse.NotificationData.MessageClass);

                    this.Site.CaptureRequirementIfIsTrue(
                        isVerifiedR225,
                        225,
                        @"[In NotificationData Structure] The string [MessageClass] is in ASCII if UnicodeFlag is set to FALSE (0x00).");

                    // Add the debug information
                    Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R223");

                    // The requirements R225 have already verify the string type of MessageClass, 
                    // so capture it directly.
                    this.Site.CaptureRequirement(
                        223,
                        @"[In NotificationData Structure] MessageClass (variable): A null-terminated string containing the message class of the new mail.");
                }
            }
        }
        /// <summary>
        /// Verify RopNotify response for TableModified events.
        /// </summary>
        /// <param name="ropNotifyResponse">The response of ropNotify</param>
        private void VerifyRopNotifyForTableModified(RopNotifyResponse ropNotifyResponse)
        {
            if (ropNotifyResponse.NotificationData.NotificationType == NotificationType.TableModified)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R139");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R139
                this.Site.CaptureRequirementIfAreEqual<int>(
                    2,
                    Marshal.SizeOf(ropNotifyResponse.NotificationData.TableEventType),
                    139,
                    @"[In NotificationData Structure] It [TableEventType] is 2 bytes.");
            }

            // Refer to MS-OXCNOTIF section 2.2.1.4.1.1: TableRowFolderID is available only if the TableEventType field is available and is 0x0003(TableRowAdded), 0x0004(TableRowDeleted), or 0x0005(TableRowModified).
            bool isTableRowFolderIDAvailable = ropNotifyResponse.NotificationData.TableEventType == (ushort)EventTypeOfTable.TableRowAdded ||
                            ropNotifyResponse.NotificationData.TableEventType == (ushort)EventTypeOfTable.TableRowDeleted ||
                            ropNotifyResponse.NotificationData.TableEventType == (ushort)EventTypeOfTable.TableRowModified;
            if (isTableRowFolderIDAvailable)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R140");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R140
                this.Site.CaptureRequirementIfAreEqual<int>(
                    8,
                    Marshal.SizeOf(ropNotifyResponse.NotificationData.TableRowFolderID),
                    140,
                    @"[In NotificationData Structure] It [TableRowFolderID] is 8 bytes.");
            }

            // Refer to MS-OXCNOTIF section 2.2.1.4.1.1: TableRowMessageID is available only if bit 0x8000(M bit) is set in the NotificationFlags field and if the TableEventType field is available
            // and is 0x0003(TableRowAdded), 0x0004(TableRowDeleted), or 0x0005(TableRowModified).
            bool isTableRowMessageIDAvailable = (ropNotifyResponse.NotificationData.TableEventType == (ushort)EventTypeOfTable.TableRowAdded ||
                           ropNotifyResponse.NotificationData.TableEventType == (ushort)EventTypeOfTable.TableRowDeleted ||
                           ropNotifyResponse.NotificationData.TableEventType == (ushort)EventTypeOfTable.TableRowModified) &&
                           ((ropNotifyResponse.NotificationData.NotificationFlags & (ushort)FlagsBit.M) == (ushort)FlagsBit.M);

            if (isTableRowMessageIDAvailable)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R144");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R144
                this.Site.CaptureRequirementIfAreEqual<int>(
                    8,
                    Marshal.SizeOf(ropNotifyResponse.NotificationData.TableRowMessageID),
                    144,
                    @"[In NotificationData Structure] It [TableRowMessageID] is 8 bytes.");
            }

            // Refer to MS-OXCNOTIF section 2.2.1.4.1.1: TableRowInstance is available only if bit 0x8000(M bit) is set in the NotificationFlags field and if the TableEventType field is available
            // and is 0x0003(TableRowAdded), 0x0004(TableRowDeleted), or 0x0005(TableRowModified).
            bool isTableRowInstanceAvalible = (ropNotifyResponse.NotificationData.TableEventType == (ushort)EventTypeOfTable.TableRowAdded ||
                            ropNotifyResponse.NotificationData.TableEventType == (ushort)EventTypeOfTable.TableRowDeleted ||
                            ropNotifyResponse.NotificationData.TableEventType == (ushort)EventTypeOfTable.TableRowModified) &&
                            (ropNotifyResponse.NotificationData.NotificationFlags & (ushort)FlagsBit.M) == (ushort)FlagsBit.M;

            if (isTableRowInstanceAvalible)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R148");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R148
                this.Site.CaptureRequirementIfAreEqual<int>(
                    4,
                    Marshal.SizeOf(ropNotifyResponse.NotificationData.TableRowInstance),
                    148,
                    @"[In NotificationData Structure] It [TableRowInstance] is 4 bytes.");
            }

            if (ropNotifyResponse.NotificationData.InsertAfterTableRowFolderID != null)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R152");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R152
                this.Site.CaptureRequirementIfAreEqual<int>(
                    8,
                    Marshal.SizeOf(ropNotifyResponse.NotificationData.InsertAfterTableRowFolderID),
                    152,
                    @"[In NotificationData Structure] It [InsertAfterTableRowFolderID] is 8 bytes.");
            }

            // Refer to MS-OXCNOTIF section 2.2.1.4.1.1: InsertAfterTableRowID is available only if bit 0x8000(M bit) is set in the NotificationFlags field
            // and if the TableEventType field is available and is 0x0003(TableRowAdded)or 0x0005(TableRowModified).
            bool isInsertAfterTableRowIDAvailable = (ropNotifyResponse.NotificationData.TableEventType == (ushort)EventTypeOfTable.TableRowAdded ||
              ropNotifyResponse.NotificationData.TableEventType == (ushort)EventTypeOfTable.TableRowModified) &&
              (ropNotifyResponse.NotificationData.NotificationFlags & (ushort)FlagsBit.M) == (ushort)FlagsBit.M;

            if (isInsertAfterTableRowIDAvailable)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R156");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R156
                this.Site.CaptureRequirementIfAreEqual<int>(
                    8,
                    Marshal.SizeOf(ropNotifyResponse.NotificationData.InsertAfterTableRowID),
                    156,
                    @"[In NotificationData Structure] It [InsertAfterTableRowID] is 8 bytes.");
            }

            if (ropNotifyResponse.NotificationData.InsertAfterTableRowInstance != null)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R160");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R160
                this.Site.CaptureRequirementIfAreEqual<int>(
                    4,
                    Marshal.SizeOf(ropNotifyResponse.NotificationData.InsertAfterTableRowInstance),
                    160,
                    @"[In NotificationData Structure] It [InsertAfterTableRowInstance] is 4 bytes.");
            }

            // Refer to MS-OXCNOTIF section 2.2.1.4.1.1: TableRowDataSize is available only if the TableEventType field is available and is 0x0003(TableRowAdded)or 0x0005(TableRowModified).
            bool isTableRowDataSizeAvailable = ropNotifyResponse.NotificationData.TableEventType == (ushort)EventTypeOfTable.TableRowAdded ||
                          ropNotifyResponse.NotificationData.TableEventType == (ushort)EventTypeOfTable.TableRowModified;

            if (isTableRowDataSizeAvailable)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R162");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R162
                this.Site.CaptureRequirementIfAreEqual<int>(
                    2,
                    Marshal.SizeOf(ropNotifyResponse.NotificationData.TableRowDataSize),
                    162,
                    @"[In NotificationData Structure] It [TableRowDataSize] is 2 bytes.");
            }
        }
        /// <summary>
        /// This method is used to verify the TableModify of NotificationType. 
        /// </summary>
        /// <param name="notifyResponse">The notification response</param>
        private void VerifyTableModifyNotificationFlag(RopNotifyResponse notifyResponse)
        {
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R110");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R110
            this.Site.CaptureRequirementIfAreEqual<int>(
                0x0100,
                notifyResponse.NotificationData.NotificationFlags & 0x0fff,
                110,
                @"[In NotificationData Structure] [NotificationType value] 0x0100: The notification is for a TableModified event.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R18");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R18
            // Client can receive TableModified notification indicates that a table has been modified on the server.
            this.Site.CaptureRequirementIfAreEqual<int>(
                0x0100,
                notifyResponse.NotificationData.NotificationFlags & 0x0fff,
                18,
                @"[In Server Event Types] TableModified: A table has been modified on the server.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R40001");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R40001
            // If R110 and R18 been verified, R40001 will be verified.
            this.Site.CaptureRequirement(
                40001,
                @"[In RopRegisterNotification ROP Request Buffer] [NotificationTypes value] 0x0100: The server sends notifications to the client when TableModified events occur within the scope of interest.");
        }
        /// <summary>
        /// Verify NotificationFlags of RopNotify response.
        /// </summary>
        /// <param name="ropNotifyResponse">The response of ropNotify</param>
        private void VerifyNotificationFlagsOfRopNotify(RopNotifyResponse ropNotifyResponse)
        {
            // FlagsBit.T is 0x1000. T bit is set in NotificationFlags.
            bool isTBitSet = (ropNotifyResponse.NotificationFlags & (ushort)FlagsBit.T) == (ushort)FlagsBit.T;

            if (isTBitSet)
            {
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R112");

                // Since the RopNotify response is de-serialized as this requirement's description, so if the T bit can get successfully,
                // this requirement can be verified directly.
                Site.CaptureRequirement(
                    112,
                    @"[In RopNotify ROP Response Buffer] T (1 bit): Bitmask = 0x1000.");

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R114");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R114
                this.Site.CaptureRequirementIfAreEqual <int>(
                    0x0010,
                    (int)ropNotifyResponse.NotificationType,
                    114,
                    @"[In RopNotify ROP Response Buffer] If this bit [T] is set, NotificationType MUST be 0x0010.");
            }

            // FlagsBit.U is 0x2000. U bit is set.
            bool isUBitSet = (ropNotifyResponse.NotificationFlags & (ushort)FlagsBit.U) == (ushort)FlagsBit.U;

            if (isUBitSet)
            {
                // Since the RopNotify response is de-serialized as this requirement's description, so if the U bit can get successfully,
                // this requirement can be verified directly.
                Site.CaptureRequirement(
                    115,
                    @"[In RopNotify ROP Response Buffer] U (1 bit): Bitmask = 0x2000.");

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R117");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R117
                this.Site.CaptureRequirementIfAreEqual <int>(
                    0x0010,
                    (int)ropNotifyResponse.NotificationType,
                    117,
                    @"[In RopNotify ROP Response Buffer] If this bit [U] is set, NotificationType MUST be 0x0010.");
            }

            // FlagsBit.S is 0x4000. S bit is set.
            bool isSBitSet = (ropNotifyResponse.NotificationFlags & (ushort)FlagsBit.S) == (ushort)FlagsBit.S;

            if (isSBitSet)
            {
                // Since the RopNotify response is de-serialized as this requirement's description, so if the S bit can get successfully,
                // this requirement can be verified directly.
                Site.CaptureRequirement(
                    118,
                    @"[In RopNotify ROP Response Buffer] S (1 bit): Bitmask = 0x4000.");

                int actualBitSet = ropNotifyResponse.NotificationFlags & (ushort)FlagsBit.M;

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R120");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R120
                this.Site.CaptureRequirementIfAreEqual <int>(
                    0x8000,
                    actualBitSet,
                    120,
                    @"[In RopNotify ROP Response Buffer] If this bit [S] is set, bit 0x8000 MUST be set.");
            }

            // FlagsBit.M is 0x8000. M bit is set.
            bool isMBitSet = (ropNotifyResponse.NotificationFlags & (ushort)FlagsBit.M) == (ushort)FlagsBit.M;

            if (isMBitSet)
            {
                // Since the RopNotify response is de-serialized as this requirement's description, so if the M bit can get successfully,
                // this requirement can be verified directly.
                Site.CaptureRequirement(
                    121,
                    @"[In RopNotify ROP Response Buffer]M (1 bit): Bitmask = 0x8000.");
            }

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R138");

            int notificationFlagsLength = Marshal.SizeOf(ropNotifyResponse.NotificationFlags) * 8;
            int notificationTypeLength  = notificationFlagsLength - 4;

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R138
            // NotificationFlags (2 bytes) is a combination of NotificationType and flags (T bit,U bit,S bit,M bit), so the size of the NotificationType is the size of NotificationFlags subtract the four bit (T bit,U bit,S bit,M bit).
            this.Site.CaptureRequirementIfAreEqual <int>(
                12,
                notificationTypeLength,
                138,
                @"[In RopNotify ROP Response Buffer] It [NotificationType] is 12 bits.");
        }
        /// <summary>
        /// Verify RopNotify response for NewMail events
        /// </summary>
        /// <param name="ropNotifyResponse">The response of ropNotify</param>
        private void VerifyRopNotifyForNewMail(RopNotifyResponse ropNotifyResponse)
        {
            if (ropNotifyResponse.NotificationType == NotificationType.NewMail)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R213");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R213
                this.Site.CaptureRequirementIfAreEqual <int>(
                    4,
                    Marshal.SizeOf(ropNotifyResponse.MessageFlags),
                    213,
                    @"[In RopNotify ROP Response Buffer] It [MessageFlags] is 4 bytes.");

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R217");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R217
                this.Site.CaptureRequirementIfAreEqual <int>(
                    1,
                    Marshal.SizeOf(ropNotifyResponse.UnicodeFlag),
                    217,
                    @"[In RopNotify ROP Response Buffer] It [UnicodeFlag]  is 1 byte.");
            }

            if (ropNotifyResponse.MessageClass != null)
            {
                if (ropNotifyResponse.UnicodeFlag == 0x00)
                {
                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R219");

                    // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R219
                    bool isVerifiedR219 = this.IsNullTerminatedASCIIStr(ropNotifyResponse.MessageClass);

                    this.Site.CaptureRequirementIfIsTrue(
                        isVerifiedR219,
                        219,
                        @"[In RopNotify ROP Response Buffer] otherwise, [the value of UnicodeFlag is]FALSE (0x00) indicates the value of the MessageClass field is in ASCII.");

                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R225");

                    // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R225
                    bool isVerifiedR225 = this.IsNullTerminatedASCIIStr(ropNotifyResponse.MessageClass);

                    this.Site.CaptureRequirementIfIsTrue(
                        isVerifiedR225,
                        225,
                        @"[In RopNotify ROP Response Buffer] The string [MessageClass] is in ASCII if UnicodeFlag is set to FALSE (0x00).");

                    // Add the debug information
                    Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R223");

                    // The requirements R225 have already verify the string type of MessageClass,
                    // so capture it directly.
                    this.Site.CaptureRequirement(
                        223,
                        @"[In RopNotify ROP Response Buffer] MessageClass (variable): A null-terminated string containing the message class of the new mail.");
                }
            }
        }
        /// <summary>
        /// This method is used to verify RopNotify response elements for ObjectMoved event. 
        /// </summary>
        /// <param name="notifyResponse">The notification response</param>
        private void VerifyObjectMovedNotificationElements(RopNotifyResponse notifyResponse)
        {
            // The value 0x0020 of NotificationType means this notification is for ObjectMoved event, 
            // this method is called after notification for ObjectMoved to verify response elements.
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R18301");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R18301
            // The value 0x0020 of NotificationType means that notification is for a ObjectMoved event.
            // So if the OldFolderId in the response is not null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                notifyResponse.NotificationData.OldFolderId,
                18301,
                @"[In NotificationData Structure] This field [OldFolderId] is available if the NotificationType value in the NotificationFlags field is 0x0020.");

            if ((notifyResponse.NotificationData.NotificationFlags & (ushort)FlagsBit.M) != (ushort)FlagsBit.M)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R19101");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R19101
                this.Site.CaptureRequirementIfIsNotNull(
                    notifyResponse.NotificationData.OldParentFolderId,
                    19101,
                    @"[In NotificationData Structure] This field [OldParentFolderId] is available if the value of the NotificationType in the NotificationFlags field is 0x0020 and bit 0x8000 is not set in the NotificationFlags field.");
            }
        }
        /// <summary>
        /// This method is used to verify RopNotify response elements for ObjectModified event. 
        /// </summary>
        /// <param name="notifyResponse">The notification response</param>
        private void VerifyObjectModifiedNotificationElements(RopNotifyResponse notifyResponse)
        {
            // The value 0x0010 of NotificationType means this notification is for ObjectModified event, 
            // this method is called after notification for ObjectModified to verify response elements.
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R19502");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R19502
            // The value 0x0010 of NotificationType means that notification is for a ObjectModified event.
            // So if the TagCount in the response is not null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                notifyResponse.NotificationData.TagCount,
                19502,
                @"[In NotificationData Structure] This field [TagCount] is available if the value of the NotificationType in the NotificationFlags field is 0x0010.");
        }
        /// <summary>
        /// This method is used to verify RopNotify response elements for ObjectCreated event. 
        /// </summary>
        /// <param name="notifyResponse">The notification response</param>
        private void VerifyObjectCreatedNotificationElements(RopNotifyResponse notifyResponse)
        {
            // The value 0x0004 of NotificationType means this notification is for ObjectCreated event, 
            // this method is called after notification for ObjectCreated to verify response elements.
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R19501");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R19501
            // The value 0x0004 of NotificationType means that notification is for a ObjectCreated event.
            // So if the TagCount in the response is not null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                notifyResponse.NotificationData.TagCount,
                19501,
                @"[In NotificationData Structure] This field [TagCount] is available if the value of the NotificationType in the NotificationFlags field is 0x0004.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R21502");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R21502
            // The value 0x0004 of NotificationType means that notification is for a ObjectCreated event.
            // So if the MessageFlags in the response is null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNull(
                notifyResponse.NotificationData.MessageFlags,
                21502,
                @"[In NotificationData Structure] This field [MessageFlags] is not available if the value of the NotificationType in the NotificationFlags field is 0x0004. For details, see [MS-OXCMSG] section 2.2.1.6.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R22102");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R22102
            // The value 0x0004 of NotificationType means that notification is for a ObjectCreated event.
            // So if the UnicodeFlag in the response is null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNull(
                notifyResponse.NotificationData.UnicodeFlag,
                22102,
                @"[In NotificationData Structure] This field [UnicodeFlag] is not available if the value of the NotificationType field in the NotificationFlags field is 0x0004.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R22602");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R22602
            // The value 0x0004 of NotificationType means that notification is for a ObjectCreated event.
            // So if the MessageClass in the response is null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNull(
                notifyResponse.NotificationData.MessageClass,
                22602,
                @"[In NotificationData Structure] This field [MessageClass] is not available if the value of the NotificationType in the NotificationFlags field is 0x0004.");

            if ((notifyResponse.NotificationData.NotificationFlags & (ushort)FlagsBit.M) != (ushort)FlagsBit.M && (notifyResponse.NotificationData.NotificationFlags & (ushort)FlagsBit.S) != (ushort)FlagsBit.S)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R17901");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R17901
                this.Site.CaptureRequirementIfIsNotNull(
                    notifyResponse.NotificationData.ParentFolderId,
                    17901,
                    @"[In NotificationData Structure] This field [ParentFolderId] is available if the value of the NotificationType field is 0x0004, and it [RopNotify ROP] is sent for a message in a folder (both bit 0x4000 and bit 0x8000 are not set in the NotificationFlags field).");
            }
        }
        /// <summary>
        /// This method is used to verify RopNotify response elements for NewMail event. 
        /// </summary>
        /// <param name="notifyResponse">The notification response</param>
        private void VerifyNewMailNotificationElements(RopNotifyResponse notifyResponse)
        {
            // The value 0x0002 of NotificationType means this notification is for NewMail event, 
            // this method is called after notification for NewMail to verify response elements.
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R12402");

            bool isR12402Satisfied = false;

            if (notifyResponse.NotificationData.TableEventType == null)
            {
                isR12402Satisfied = true;
            }
            else
            {
                if (notifyResponse.NotificationData.TableEventType == (ushort)EventTypeOfTable.NONE)
                {
                    isR12402Satisfied = true;
                }
            }

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R12402
            // The value 0x0002 of NotificationType means that notification is for a NewMail event.
            // So if the TableEventType in the response is null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsTrue(
                isR12402Satisfied,
                12402,
                @"[In NotificationData Structure] This field [TableEventType] is not available if the NotificationType value in the NotificationFlags field is 0x0002.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R17103");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R17103
            // The value 0x0002 of NotificationType means that notification is for a NewMail event.
            // So if the FolderId in the response is not null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                notifyResponse.NotificationData.FolderId,
                17103,
                @"[In NotificationData Structure] This field [FolderId] is available if the NotificationType value in the NotificationFlags field is 0x0002.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R17905");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R17905
            // The value 0x0002 of NotificationType means that notification is for a NewMail event.
            // So if the ParentFolderId in the response is null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNull(
                notifyResponse.NotificationData.ParentFolderId,
                17905,
                @"[In NotificationData Structure] This field [ParentFolderId] is not available if the value of the NotificationType field is 0x0002.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R18303");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R18303
            // The value 0x0002 of NotificationType means that notification is for a NewMail event.
            // So if the OldFolderId in the response is null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNull(
                notifyResponse.NotificationData.OldFolderId,
                18303,
                @"[In NotificationData Structure] This field [OldFolderId] is not available if the NotificationType value in the NotificationFlags field is 0x0002.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R18703");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R18703
            // The value 0x0002 of NotificationType means that notification is for a NewMail event.
            // So if the OldMessageId in the response is null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNull(
                notifyResponse.NotificationData.OldMessageId,
                18703,
                @"[In NotificationData Structure] This field [OldMessageId] is not available if the value of the NotificationType in the NotificationFlags field is 0x0002.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R19103");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R19103
            // The value 0x0002 of NotificationType means that notification is for a NewMail event.
            // So if the OldParentFolderId in the response is null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNull(
                notifyResponse.NotificationData.OldParentFolderId,
                19103,
                @"[In NotificationData Structure] This field [OldParentFolderId] is not available if the value of the NotificationType in the NotificationFlags field is 0x0002.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R19503");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R19503
            // The value 0x0002 of NotificationType means that notification is for a NewMail event.
            // So if the TagCount in the response is null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNull(
                notifyResponse.NotificationData.TagCount,
                19503,
                @"[In NotificationData Structure] This field [TagCount] is not available if the value of the NotificationType in the NotificationFlags field is 0x0002.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R21501");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R21501
            // The value 0x0002 of NotificationType means that notification is for a NewMail event.
            // So if the MessageFlags in the response is not null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                notifyResponse.NotificationData.MessageFlags,
                21501,
                @"[In NotificationData Structure] This field [MessageFlags] is available if the value of the NotificationType in the NotificationFlags field is 0x0002. For details, see [MS-OXCMSG] section 2.2.1.6.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R22101");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R22101
            // The value 0x0002 of NotificationType means that notification is for a NewMail event.
            // So if the UnicodeFlag in the response is not null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                notifyResponse.NotificationData.UnicodeFlag,
                22101,
                @"[In NotificationData Structure] This field [UnicodeFlag] is available if the value of the NotificationType field in the NotificationFlags field is 0x0002.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R22601");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R22601
            // The value 0x0002 of NotificationType means that notification is for a NewMail event.
            // So if the MessageClass in the response is not null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                notifyResponse.NotificationData.MessageClass,
                22601,
                @"[In NotificationData Structure] This field [MessageClass] is available if the value of the NotificationType in the NotificationFlags field is 0x0002.");

            if ((notifyResponse.NotificationData.NotificationFlags & (ushort)FlagsBit.M) == (ushort)FlagsBit.M)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R17501");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R17501
                this.Site.CaptureRequirementIfIsNotNull(
                    notifyResponse.NotificationData.MessageId,
                    17501,
                    @"[In NotificationData Structure] This field [MessageId] is available if the NotificationType value in the NotificationFlags field is 0x0002, and bit 0x8000 is set in the NotificationFlags field.");
            }
        }
        /// <summary>
        /// This method is used to verify RopNotify response elements for TableRowModified event. 
        /// </summary>
        /// <param name="notifyResponse">The notification response</param>
        private void VerifyTableRowModifiedNotificationElements(RopNotifyResponse notifyResponse)
        {
            // The value 0x0005 of TableEventType means this notification is for TableRowModified event, 
            // this method is called after notification for TableRowModified to verify response elements.
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R14203");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R14203
            // TableEventType with value 0x0005 means the notification is for TableRowModified event, so if the TableRowFolderID is not null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                notifyResponse.NotificationData.TableRowFolderID,
                14203,
                @"[In NotificationData Structure] This field [TableRowFolderID] is available if the TableEventType field is available and is 0x0005.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R15402");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R15402
            // TableEventType with value 0x0005 means the notification is for TableRowModified event, so if the InsertAfterTableRowFolderID is not null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                notifyResponse.NotificationData.InsertAfterTableRowFolderID,
                15402,
                @"[In NotificationData Structure] This field [InsertAfterTableRowFolderID] is available, if the TableEventType field is available and is 0x0005.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R16402");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R16402
            // TableEventType with value 0x0005 means the notification is for TableRowModified event, so if the TableRowDataSize is not null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                notifyResponse.NotificationData.TableRowDataSize,
                16402,
                @"[In NotificationData Structure] This field [TableRowDataSize] is available only if the TableEventType field is available and is 0x0005.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R16702");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R16702
            // TableEventType with value 0x0005 means the notification is for TableRowModified event, so if the TableRowData is not null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                notifyResponse.NotificationData.TableRowData,
                16702,
                @"[In NotificationData Structure] This field [TableRowData] is available if the TableEventType field is available and is 0x0005.");

            // FlagsBit.M is 0x8000. If FlagsBit.M & NotificationFlags is itself, indicate that M bit is set. 
            if ((notifyResponse.NotificationData.NotificationFlags & (ushort)FlagsBit.M) == (ushort)FlagsBit.M)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R14603");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R14603
                // TableEventType with value 0x0005 means the notification is for TableRowModified event, so if the TableRowMessageID is not null, this requirement can be verified.
                this.Site.CaptureRequirementIfIsNotNull(
                    notifyResponse.NotificationData.TableRowMessageID,
                    14603,
                    @"[In NotificationData Structure] This field [TableRowMessageID] is available if bit 0x8000 is set in the NotificationFlags field and if the TableEventType field is available and is 0x0005.");

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R15003");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R15003
                // TableEventType with value 0x0005 means the notification is for TableRowModified event, so if the TableRowInstance is not null, this requirement can be verified.
                this.Site.CaptureRequirementIfIsNotNull(
                    notifyResponse.NotificationData.TableRowInstance,
                    15003,
                    @"[In NotificationData Structure] This field [TableRowInstance] is available if bit 0x8000 is set in the NotificationFlags field and if the TableEventType field is available and is 0x0005.");

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R15802");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R15802
                this.Site.CaptureRequirementIfIsNotNull(
                    notifyResponse.NotificationData.InsertAfterTableRowID,
                    15802,
                    @"[In NotificationData Structure] This field [InsertAfterTableRowID] is available if bit 0x8000 is set in the NotificationFlags field and if the TableEventType field is available and is 0x0005.");
            }
        }
        /// <summary>
        /// This method is used to verify RopNotify response elements for TableRowAdded event. 
        /// </summary>
        /// <param name="notifyResponse">The notification response</param>
        private void VerifyTableRowAddedNotificationElements(RopNotifyResponse notifyResponse)
        {
            // The value 0x0003 of TableEventType means this notification is for TableRowAdded event, 
            // this method is called after notification for TableRowAdded to verify response elements.
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R12401");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R12401
            // The value 0x0100 of NotificationType means that notification is for a TableModified event, cause TableRowAdded is one of the TableModified events.
            // So if the TableEventType in the response is not null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                notifyResponse.NotificationData.TableEventType,
                12401,
                @"[In NotificationData Structure] This field [TableEventType] is available if the NotificationType value in the NotificationFlags field is 0x0100.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R17101");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R17101
            // The value 0x0100 of NotificationType means that notification is for a TableModified event, cause TableRowAdded is one of the TableModified events.
            // So if the FolderId in the response is null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNull(
                notifyResponse.NotificationData.FolderId,
                17101,
                @"[In NotificationData Structure] This field [FolderId] is not available if the NotificationType value in the NotificationFlags field is 0x0100.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R17502");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R17502
            // The value 0x0100 of NotificationType means that notification is for a TableModified event, cause TableRowAdded is one of the TableModified events.
            // So if the MessageId in the response is null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNull(
                notifyResponse.NotificationData.MessageId,
                17502,
                @"[In NotificationData Structure] This field [MessageId] is not available if the NotificationType value in the NotificationFlags field is 0x0100.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R14201");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R14201
            // TableEventType with value 0x0003 means the notification is for TableRowAdded event, so if the TableRowFolderID is not null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                notifyResponse.NotificationData.TableRowFolderID,
                14201,
                @"[In NotificationData Structure] This field [TableRowFolderID] is available if the TableEventType field is available and is 0x0003.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R15401");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R15401
            // TableEventType with value 0x0003 means the notification is for TableRowAdded event, so if the InsertAfterTableRowFolderID is not null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                notifyResponse.NotificationData.InsertAfterTableRowFolderID,
                15401,
                @"[In NotificationData Structure] This field [InsertAfterTableRowFolderID] is available if the TableEventType field is available and is 0x0003.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R16401");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R16401
            // TableEventType with value 0x0003 means the notification is for TableRowAdded event, so if the TableRowDataSize is not null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                notifyResponse.NotificationData.TableRowDataSize,
                16401,
                @"[In NotificationData Structure] This field [TableRowDataSize] is available if the TableEventType field is available and is 0x0003.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R16701");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R16701
            // TableEventType with value 0x0003 means the notification is for TableRowAdded event, so if the TableRowData is not null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                notifyResponse.NotificationData.TableRowData,
                16701,
                @"[In NotificationData Structure] This field [TableRowData] is available if the TableEventType field is available and is 0x0003.");

            // FlagsBit.M is 0x8000. If FlagsBit.M & NotificationFlags is itself, indicate that M bit is set. 
            if ((notifyResponse.NotificationData.NotificationFlags & (ushort)FlagsBit.M) == (ushort)FlagsBit.M)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R14601");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R14601
                // TableEventType with value 0x0003 means the notification is for TableRowAdded event, so if the TableRowMessageID is not null, this requirement can be verified.
                this.Site.CaptureRequirementIfIsNotNull(
                    notifyResponse.NotificationData.TableRowMessageID,
                    14601,
                    @"[In NotificationData Structure] This field [TableRowMessageID] is available if bit 0x8000 is set in the NotificationFlags field and if the TableEventType field is available and is 0x0003.");

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R15001");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R15001
                // TableEventType with value 0x0003 means the notification is for TableRowAdded event, so if the TableRowInstance is not null, this requirement can be verified.
                this.Site.CaptureRequirementIfIsNotNull(
                    notifyResponse.NotificationData.TableRowInstance,
                    15001,
                    @"[In NotificationData Structure] This field [TableRowInstance] is available if bit 0x8000 is set in the NotificationFlags field and if the TableEventType field is available and is 0x0003.");

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R15801");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R15801
                this.Site.CaptureRequirementIfIsNotNull(
                    notifyResponse.NotificationData.InsertAfterTableRowID,
                    15801,
                    @"[In NotificationData Structure] This field [InsertAfterTableRowID] is available if bit 0x8000 is set in the NotificationFlags field and if the TableEventType field is available and is 0x0003.");
            }
        }
        /// <summary>
        /// This method is used to verify RopNotify response elements for TableChanged event. 
        /// </summary>
        /// <param name="notifyResponse">The notification response</param>
        private void VerifyTableChangedNotificationElements(RopNotifyResponse notifyResponse)
        {
            // The value 0x0001 of TableEventType means this notification is for TableChanged event, 
            // this method is called after notification for TableChanged to verify response elements.
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R14204");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R14204
            // TableEventType with value 0x0001 means the notification is for TableChanged event, so if the TableRowFolderID is null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNull(
                notifyResponse.NotificationData.TableRowFolderID,
                14204,
                @"[In NotificationData Structure] This field [TableRowFolderID] is not available if the TableEventType field is 0x0001.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R15403");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R15403
            // TableEventType with value 0x0001 means the notification is for TableChanged event, so if the InsertAfterTableRowFolderID is null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNull(
                notifyResponse.NotificationData.InsertAfterTableRowFolderID,
                15403,
                @"[In NotificationData Structure] This field [InsertAfterTableRowFolderID] is not available if the TableEventType field is 0x0001.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R15803");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R15803
            // TableEventType with value 0x0001 means the notification is for TableChanged event, so if the InsertAfterTableRowID is null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNull(
                notifyResponse.NotificationData.InsertAfterTableRowID,
                15803,
                @"[In NotificationData Structure] This field [InsertAfterTableRowID] is not available if the TableEventType field is 0x0001.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R16403");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R16403
            // TableEventType with value 0x0001 means the notification is for TableChanged event, so if the TableRowDataSize is null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNull(
                notifyResponse.NotificationData.TableRowDataSize,
                16403,
                @"[In NotificationData Structure] This field [TableRowDataSize] is not available if the TableEventType field is 0x0001.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R16703");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R16703
            // TableEventType with value 0x0001 means the notification is for TableChanged event, so if the TableRowData is null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNull(
                notifyResponse.NotificationData.TableRowData,
                16703,
                @"[In NotificationData Structure] This field [TableRowData] is not available  if the TableEventType field is 0x0001.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R14604");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R14604
            // TableEventType with value 0x0001 means the notification is for TableChanged event, so if the TableRowMessageID is null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNull(
                notifyResponse.NotificationData.TableRowMessageID,
                14604,
                @"[In NotificationData Structure] This field [TableRowMessageID] is not available if the TableEventType field is 0x0001.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R15004");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R15004
            // TableEventType with value 0x0001 means the notification is for TableChanged event, so if the TableRowInstance is null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNull(
                notifyResponse.NotificationData.TableRowInstance,
                15004,
                @"[In NotificationData Structure] This field [TableRowInstance] is not available if the TableEventType field is 0x0001.");
        }
Esempio n. 16
0
        /// <summary>
        /// Verify RopNotify response.
        /// </summary>
        /// <param name="ropNotifyResponse">The response of ropNotify</param>
        private void VerifyRopNotifyResponse(RopNotifyResponse ropNotifyResponse)
        {
            if (Common.GetConfigurationPropertyValue("TransportSeq", this.Site).ToLower() == "mapi_http")
            {
                if (Common.IsRequirementEnabled(498, this.Site))
                {
                    // Add the debug information
                    Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R498");

                    // When the client receive asynchronous MAPI notification in the response through test suites by using
                    // underlying networking protocols, this method will be invoked, and this requirement will be verified directly.
                    Site.CaptureRequirement(
                        498,
                        @"[In Appendix A: Product Behavior] This ROP [RopNotify] MUST appear in the Execute request type success response body. (Exchange 2013 SP1 and above follow this behavior.)");
                }
            }

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R240");
        
            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R240
            // If server response a RopNotify, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                ropNotifyResponse,
                240,
                @"[In Sending Notification Details] The server sends notification details to the client by sending the RopNotify ROP response (section 2.2.1.4.1).");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R89");

            // If RopNotify is returned in the response buffer through the test suite, 
            // this method will be invoked, and this requirement will be verified directly.
            Site.CaptureRequirement(
                89,
                @"[In RopNotify ROP] This ROP [RopNotify] MUST appear in response buffers of the EcDoRpcExt2 method, as specified in [MS-OXCRPC] section 3.1.4.2.");

            if (Common.IsRequirementEnabled(346, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R346: the response type is {0}", ropNotifyResponse.GetType().Name);

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R346
                this.Site.CaptureRequirementIfAreEqual<string>(
                    "RopNotifyResponse",
                    ropNotifyResponse.GetType().Name,
                    346,
                    @"[In Appendix A: Product Behavior] Implementation does send a RopNotify ROP response (section 2.2.1.4.1) to the client for each pending notification on the session context that is associated with the client. (Exchange 2007 and above follow this behavior.)");
            }

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R136");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R136
            Site.CaptureRequirementIfAreEqual<int>(
                4,
                Marshal.SizeOf(ropNotifyResponse.NotificationHandle),
                136,
                @"[In RopNotify ROP Response Buffer] It [NotificationHandle] is 4 bytes.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R137");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R137
            Site.CaptureRequirementIfAreEqual<int>(
                2,
                Marshal.SizeOf(ropNotifyResponse.NotificationData.NotificationFlags),
                137,
                @"[In NotificationData Structure] It [NotificationFlags] is 2 bytes.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R97002");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R97002
            Site.CaptureRequirementIfIsInstanceOfType(
                ropNotifyResponse.LogonId,
                typeof(byte),
                97002,
                @"[In RopNotify ROP Response Buffer] [LogonId ] is 1 byte.");

            // Verify NotificationFlags of RopNotify response
            this.VerifyNotificationFlagsOfRopNotify(ropNotifyResponse);

            // Verify RopNotify response for NewMail events
            this.VerifyRopNotifyForNewMail(ropNotifyResponse);

            // Verify RopNotify response for TableModified events
            this.VerifyRopNotifyForTableModified(ropNotifyResponse);

            // Verify RopNotify response for other events(ObjectCreated, ObjectDeleted, ObjectModified, ObjectMoved, ObjectCopied and SearchResult)
            this.VerifyRopNotifyForOtherEvents(ropNotifyResponse);
        }
        /// <summary>
        /// Verify RopNotify response for TableModified events.
        /// </summary>
        /// <param name="ropNotifyResponse">The response of ropNotify</param>
        private void VerifyRopNotifyForTableModified(RopNotifyResponse ropNotifyResponse)
        {
            if (ropNotifyResponse.NotificationType == NotificationType.TableModified)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R139");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R139
                this.Site.CaptureRequirementIfAreEqual <int>(
                    2,
                    Marshal.SizeOf(ropNotifyResponse.TableEventType),
                    139,
                    @"[In RopNotify ROP Response Buffer] It [TableEventType] is 2 bytes.");
            }

            // Refer to MS-OXCNOTIF section 2.2.1.4.1.1: TableRowFolderID is available only if the TableEventType field is available and is 0x0003(TableRowAdded), 0x0004(TableRowDeleted), or 0x0005(TableRowModified).
            bool isTableRowFolderIDAvailable = ropNotifyResponse.TableEventType == (ushort)EventTypeOfTable.TableRowAdded ||
                                               ropNotifyResponse.TableEventType == (ushort)EventTypeOfTable.TableRowDeleted ||
                                               ropNotifyResponse.TableEventType == (ushort)EventTypeOfTable.TableRowModified;

            if (isTableRowFolderIDAvailable)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R140");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R140
                this.Site.CaptureRequirementIfAreEqual <int>(
                    8,
                    Marshal.SizeOf(ropNotifyResponse.TableRowFolderID),
                    140,
                    @"[In RopNotify ROP Response Buffer] It [TableRowFolderID] is 8 bytes.");
            }

            // Refer to MS-OXCNOTIF section 2.2.1.4.1.1: TableRowMessageID is available only if bit 0x8000(M bit) is set in the NotificationFlags field and if the TableEventType field is available
            // and is 0x0003(TableRowAdded), 0x0004(TableRowDeleted), or 0x0005(TableRowModified).
            bool isTableRowMessageIDAvailable = (ropNotifyResponse.TableEventType == (ushort)EventTypeOfTable.TableRowAdded ||
                                                 ropNotifyResponse.TableEventType == (ushort)EventTypeOfTable.TableRowDeleted ||
                                                 ropNotifyResponse.TableEventType == (ushort)EventTypeOfTable.TableRowModified) &&
                                                ((ropNotifyResponse.NotificationFlags & (ushort)FlagsBit.M) == (ushort)FlagsBit.M);

            if (isTableRowMessageIDAvailable)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R144");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R144
                this.Site.CaptureRequirementIfAreEqual <int>(
                    8,
                    Marshal.SizeOf(ropNotifyResponse.TableRowMessageID),
                    144,
                    @"[In RopNotify ROP Response Buffer] It [TableRowMessageID] is 8 bytes.");
            }

            // Refer to MS-OXCNOTIF section 2.2.1.4.1.1: TableRowInstance is available only if bit 0x8000(M bit) is set in the NotificationFlags field and if the TableEventType field is available
            // and is 0x0003(TableRowAdded), 0x0004(TableRowDeleted), or 0x0005(TableRowModified).
            bool isTableRowInstanceAvalible = (ropNotifyResponse.TableEventType == (ushort)EventTypeOfTable.TableRowAdded ||
                                               ropNotifyResponse.TableEventType == (ushort)EventTypeOfTable.TableRowDeleted ||
                                               ropNotifyResponse.TableEventType == (ushort)EventTypeOfTable.TableRowModified) &&
                                              (ropNotifyResponse.NotificationFlags & (ushort)FlagsBit.M) == (ushort)FlagsBit.M;

            if (isTableRowInstanceAvalible)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R148");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R148
                this.Site.CaptureRequirementIfAreEqual <int>(
                    4,
                    Marshal.SizeOf(ropNotifyResponse.TableRowInstance),
                    148,
                    @"[In RopNotify ROP Response Buffer] It [TableRowInstance] is 4 bytes.");
            }

            if (ropNotifyResponse.InsertAfterTableRowFolderID != null)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R152");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R152
                this.Site.CaptureRequirementIfAreEqual <int>(
                    8,
                    Marshal.SizeOf(ropNotifyResponse.InsertAfterTableRowFolderID),
                    152,
                    @"[In RopNotify ROP Response Buffer] It [InsertAfterTableRowFolderID] is 8 bytes.");
            }

            // Refer to MS-OXCNOTIF section 2.2.1.4.1.1: InsertAfterTableRowID is available only if bit 0x8000(M bit) is set in the NotificationFlags field
            // and if the TableEventType field is available and is 0x0003(TableRowAdded)or 0x0005(TableRowModified).
            bool isInsertAfterTableRowIDAvailable = (ropNotifyResponse.TableEventType == (ushort)EventTypeOfTable.TableRowAdded ||
                                                     ropNotifyResponse.TableEventType == (ushort)EventTypeOfTable.TableRowModified) &&
                                                    (ropNotifyResponse.NotificationFlags & (ushort)FlagsBit.M) == (ushort)FlagsBit.M;

            if (isInsertAfterTableRowIDAvailable)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R156");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R156
                this.Site.CaptureRequirementIfAreEqual <int>(
                    8,
                    Marshal.SizeOf(ropNotifyResponse.InsertAfterTableRowID),
                    156,
                    @"[In RopNotify ROP Response Buffer] It [InsertAfterTableRowID] is 8 bytes.");
            }

            if (ropNotifyResponse.InsertAfterTableRowInstance != null)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R160");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R160
                this.Site.CaptureRequirementIfAreEqual <int>(
                    4,
                    Marshal.SizeOf(ropNotifyResponse.InsertAfterTableRowInstance),
                    160,
                    @"[In RopNotify ROP Response Buffer] It [InsertAfterTableRowInstance] is 4 bytes.");
            }

            // Refer to MS-OXCNOTIF section 2.2.1.4.1.1: TableRowDataSize is available only if the TableEventType field is available and is 0x0003(TableRowAdded)or 0x0005(TableRowModified).
            bool isTableRowDataSizeAvailable = ropNotifyResponse.TableEventType == (ushort)EventTypeOfTable.TableRowAdded ||
                                               ropNotifyResponse.TableEventType == (ushort)EventTypeOfTable.TableRowModified;

            if (isTableRowDataSizeAvailable)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R162");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R162
                this.Site.CaptureRequirementIfAreEqual <int>(
                    2,
                    Marshal.SizeOf(ropNotifyResponse.TableRowDataSize),
                    162,
                    @"[In RopNotify ROP Response Buffer] It [TableRowDataSize] is 2 bytes.");
            }
        }
        /// <summary>
        /// This method is used to verify RopNotify response elements for ObjectCopied event. 
        /// </summary>
        /// <param name="notifyResponse">The notification response</param>
        private void VerifyObjectCopiedNotificationElements(RopNotifyResponse notifyResponse)
        {
            // The value 0x0040 of NotificationType means this notification is for ObjectCopied event, 
            // this method is called after notification for ObjectCopied to verify response elements.
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R18302");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R18302
            // The value 0x0040 of NotificationType means that notification is for a ObjectCopied event.
            // So if the OldFolderId in the response is not null, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                notifyResponse.NotificationData.OldFolderId,
                18302,
                @"[In NotificationData Structure] This field [OldFolderId] is available if the NotificationType value in the NotificationFlags field is 0x0040.");

            if ((notifyResponse.NotificationData.NotificationFlags & (ushort)FlagsBit.M) == (ushort)FlagsBit.M)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R18702");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R18702
                this.Site.CaptureRequirementIfIsNotNull(
                    notifyResponse.NotificationData.OldMessageId,
                    18702,
                    @"[In NotificationData Structure] This field [OldMessageId] is available if the value of the NotificationType in the NotificationFlags field is 0x0040 and bit 0x8000 is set in the NotificationFlags field.");
            }

            if ((notifyResponse.NotificationData.NotificationFlags & (ushort)FlagsBit.T) != (ushort)FlagsBit.T)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R20702");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R20702
                this.Site.CaptureRequirementIfIsNull(
                    notifyResponse.NotificationData.TotalMessageCount,
                    20702,
                    @"[In NotificationData Structure] This field [TotalMessageCount] is not available if bit 0x1000 is not set in the NotificationFlags field.");
            }

            if ((notifyResponse.NotificationData.NotificationFlags & (ushort)FlagsBit.U) != (ushort)FlagsBit.U)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R21102");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R21102
                this.Site.CaptureRequirementIfIsNull(
                    notifyResponse.NotificationData.UnreadMessageCount,
                    21102,
                    @"[In NotificationData Structure] This field [UnreadMessageCount] is not available if bit 0x2000 is not set in the NotificationFlags field.");
            }
        }
        /// <summary>
        /// Verify RopNotify response for other events(ObjectCreated,ObjectDeleted,ObjectModified,ObjectMoved,ObjectCopied,SearchResult)
        /// </summary>
        /// <param name="ropNotifyResponse">The response of ropNotify</param>
        private void VerifyRopNotifyForOtherEvents(RopNotifyResponse ropNotifyResponse)
        {
            if (ropNotifyResponse.FolderId != null)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R169");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R169
                this.Site.CaptureRequirementIfAreEqual <int>(
                    8,
                    Marshal.SizeOf(ropNotifyResponse.FolderId),
                    169,
                    @"[In RopNotify ROP Response Buffer] It [FolderId] is 8 bytes.");
            }

            if (ropNotifyResponse.MessageId != null)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R173");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R173
                this.Site.CaptureRequirementIfAreEqual <int>(
                    8,
                    Marshal.SizeOf(ropNotifyResponse.MessageId),
                    173,
                    @"[In RopNotify ROP Response Buffer] It [MessageId] is 8 bytes.");
            }

            bool isTotalMessageCountAvailable = (ropNotifyResponse.NotificationFlags & (ushort)FlagsBit.T) == (ushort)FlagsBit.T;

            if (isTotalMessageCountAvailable)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R205");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R205
                this.Site.CaptureRequirementIfAreEqual <int>(
                    4,
                    Marshal.SizeOf(ropNotifyResponse.TotalMessageCount),
                    205,
                    @"[In RopNotify ROP Response Buffer] It [TotalMessageCount]  is 4 bytes.");
            }

            bool isUnreadMessageCountAvailable = (ropNotifyResponse.NotificationFlags & (ushort)FlagsBit.U) == (ushort)FlagsBit.U;

            if (isUnreadMessageCountAvailable)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R209");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R209
                this.Site.CaptureRequirementIfAreEqual <int>(
                    4,
                    Marshal.SizeOf(ropNotifyResponse.UnreadMessageCount),
                    209,
                    @"[In RopNotify ROP Response Buffer] It [UnreadMessageCount]  is 4 bytes.");
            }

            if (ropNotifyResponse.ParentFolderId != null)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R177");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R177
                this.Site.CaptureRequirementIfAreEqual <int>(
                    8,
                    Marshal.SizeOf(ropNotifyResponse.ParentFolderId),
                    177,
                    @"[In RopNotify ROP Response Buffer] It [ParentFolderId]  is 8 bytes.");
            }

            // Refer to MS-OXCNOTIF section 2.2.1.4.1.1: OldFolderId is available only if the NotificationType value in the NotificationFlags field is 0x0020(ObjectMoved) or 0x0040(ObjectCopied).
            bool isOldFolderIdAvailable = ropNotifyResponse.NotificationType == NotificationType.ObjectMoved ||
                                          ropNotifyResponse.NotificationType == NotificationType.ObjectCopied;

            if (isOldFolderIdAvailable)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R181");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R181
                this.Site.CaptureRequirementIfAreEqual <int>(
                    8,
                    Marshal.SizeOf(ropNotifyResponse.OldFolderId),
                    181,
                    @"[In RopNotify ROP Response Buffer] It [OldFolderId] is 8 bytes.");
            }

            // Refer to MS-OXCNOTIF section 2.2.1.4.1.1: OldMessageId is available only if the value of the NotificationType field in the NotificationFlags field is
            // 0x0020(ObjectMoved) or 0x0040(ObjectCopied) and bit 0x8000(M bit) is set in the NotificationFlags field.
            bool isOldMessageIdAvailable = (ropNotifyResponse.NotificationType == NotificationType.ObjectMoved ||
                                            ropNotifyResponse.NotificationType == NotificationType.ObjectCopied) &&
                                           (ropNotifyResponse.NotificationFlags & (ushort)FlagsBit.M) == (ushort)FlagsBit.M;

            if (isOldMessageIdAvailable)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R185");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R185
                this.Site.CaptureRequirementIfAreEqual <int>(
                    8,
                    Marshal.SizeOf(ropNotifyResponse.OldMessageId),
                    185,
                    @"[In RopNotify ROP Response Buffer] It [OldMessageId] is 8 bytes.");
            }

            // Refer to MS-OXCNOTIF section 2.2.1.4.1.1: OldParentFolderId is available only if the value of the NotificationType field in the NotificationFlags field is 0x0020(ObjectMoved) or 0x0040(ObjectCopied)
            // and bit 0x8000(M bit) is not set in the NotificationFlags field.
            bool isOldParentFolderIdAvailable = (ropNotifyResponse.NotificationType == NotificationType.ObjectMoved ||
                                                 ropNotifyResponse.NotificationType == NotificationType.ObjectCopied) &&
                                                (ropNotifyResponse.NotificationFlags & (ushort)FlagsBit.M) != (ushort)FlagsBit.M;

            if (isOldParentFolderIdAvailable)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R189");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R189
                this.Site.CaptureRequirementIfAreEqual <int>(
                    8,
                    Marshal.SizeOf(ropNotifyResponse.OldParentFolderId),
                    189,
                    @"[In RopNotify ROP Response Buffer] It [OldParentFolderId] is 8 bytes.");
            }

            // Refer to MS-OXCNOTIF section 2.2.1.4.1.1: TagCount is available only if the value of the NotificationType field in the NotificationFlags field is 0x0004(ObjectCreated) or 0x0010(ObjectModified).
            bool isTagCountAvailable = ropNotifyResponse.NotificationType == NotificationType.ObjectCreated ||
                                       ropNotifyResponse.NotificationType == NotificationType.ObjectModified;

            if (isTagCountAvailable)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R193");

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R193
                this.Site.CaptureRequirementIfAreEqual <int>(
                    2,
                    Marshal.SizeOf(ropNotifyResponse.TagCount),
                    193,
                    @"[In RopNotify ROP Response Buffer] It [TagCount]  is 2 bytes.");
            }
        }
        /// <summary>
        /// Verify RopNotify Response
        /// </summary>
        /// <param name="ropNotifyResponse">The response of RopNotify request</param>
        private void VerifyRopNotifyResponse(RopNotifyResponse ropNotifyResponse)
        {
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R4423");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R4423
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(byte),
                ropNotifyResponse.RopId.GetType(),
                4423,
                @"[In RopNotify ROP Response Buffer] RopId (1 byte): An unsigned integer.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R4425");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R4425
            Site.CaptureRequirementIfAreEqual<byte>(
                (byte)RopId.RopNotify,
                ropNotifyResponse.RopId,
                4425,
                @"[In RopNotify ROP Response Buffer, RopId (1 byte):] For this operation[RopNotify] this field is set to 0x2A.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R4426");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R4426
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(uint),
                ropNotifyResponse.NotificationHandle.GetType(),
                4426,
                @"[In RopNotify ROP Response Buffer]NotificationHandle (4 bytes): A Server object handle.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R4428");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R4428
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(byte),
                ropNotifyResponse.LogonId.GetType(),
                4428,
                @"[In RopNotify ROP Response Buffer] LogonId (1 byte): An unsigned integer.");
        }
        /// <summary>
        /// Verify RopNotify response.
        /// </summary>
        /// <param name="ropNotifyResponse">The response of ropNotify</param>
        private void VerifyRopNotifyResponse(RopNotifyResponse ropNotifyResponse)
        {
            if (Common.GetConfigurationPropertyValue("TransportSeq", this.Site).ToLower() == "mapi_http")
            {
                if (Common.IsRequirementEnabled(498, this.Site))
                {
                    // Add the debug information
                    Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R498");

                    // When the client receive asynchronous MAPI notification in the response through test suites by using
                    // underlying networking protocols, this method will be invoked, and this requirement will be verified directly.
                    Site.CaptureRequirement(
                        498,
                        @"[In Appendix A: Product Behavior] This ROP [RopNotify] MUST appear in the Execute request type success response body. (Exchange 2013 SP1 follows this behavior.)");
                }
            }

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R240");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R240
            // If server response a RopNotify, this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                ropNotifyResponse,
                240,
                @"[In Sending Notification Details] The server sends notification details to the client by sending the RopNotify ROP response (section 2.2.1.4.1).");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R89");

            // If RopNotify is returned in the response buffer through the test suite,
            // this method will be invoked, and this requirement will be verified directly.
            Site.CaptureRequirement(
                89,
                @"[In RopNotify ROP] This ROP [RopNotify] MUST appear in response buffers of the EcDoRpcExt2 method, as specified in [MS-OXCRPC] section 3.1.4.2.");

            if (Common.IsRequirementEnabled(346, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R346: the response type is {0}", ropNotifyResponse.GetType().Name);

                // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R346
                this.Site.CaptureRequirementIfAreEqual <string>(
                    "RopNotifyResponse",
                    ropNotifyResponse.GetType().Name,
                    346,
                    @"[In Appendix A: Product Behavior] Implementation does send a RopNotify ROP response (section 2.2.1.4.1) to the client for each pending notification on the session context that is associated with the client. (Exchange 2007 and above follow this behavior.)");
            }

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R136");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R136
            Site.CaptureRequirementIfAreEqual <int>(
                4,
                Marshal.SizeOf(ropNotifyResponse.NotificationHandle),
                136,
                @"[In RopNotify ROP Response Buffer] It [NotificationHandle] is 4 bytes.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCNOTIF_R137");

            // Verify MS-OXCNOTIF requirement: MS-OXCNOTIF_R137
            Site.CaptureRequirementIfAreEqual <int>(
                2,
                Marshal.SizeOf(ropNotifyResponse.NotificationFlags),
                137,
                @"[In RopNotify ROP Response Buffer] It [NotificationFlags] is 2 bytes.");

            // Verify NotificationFlags of RopNotify response
            this.VerifyNotificationFlagsOfRopNotify(ropNotifyResponse);

            // Verify RopNotify response for NewMail events
            this.VerifyRopNotifyForNewMail(ropNotifyResponse);

            // Verify RopNotify response for TableModified events
            this.VerifyRopNotifyForTableModified(ropNotifyResponse);

            // Verify RopNotify response for other events(ObjectCreated, ObjectDeleted, ObjectModified, ObjectMoved, ObjectCopied and SearchResult)
            this.VerifyRopNotifyForOtherEvents(ropNotifyResponse);
        }
        /// <summary>
        /// Get notification detail from server.
        /// </summary>
        /// <returns>Notify ROP response.</returns>
        public RopNotifyResponse NotificationProcess()
        {
            List<IDeserializable> responseRops = new List<IDeserializable>();
            RopNotifyResponse notifyResponse = new RopNotifyResponse();
            uint ret = this.oxcropsClient.RopCall(null, null, ref responseRops, ref this.responseSOHs, ref this.rawData, 0x10008);
            Site.Assert.AreEqual<uint>(OxcRpcErrorCode.ECNone, ret, "ROP call should be successful here, the error code is: {0}", ret);

            foreach (IDeserializable response in responseRops)
            {
                string responseName = response.GetType().Name;
                if (responseName == Constants.NameOfRopNotifyResponse)
                {
                    notifyResponse = (RopNotifyResponse)response;
                    break;
                }
            }

            return notifyResponse;
        }