/// <summary>
        /// This ROP logs on to a private mailbox or public folder. 
        /// </summary>
        /// <param name="logonType">This type specifies ongoing action on the private mailbox or public folder.</param>
        /// <param name="logonResponse">The response of this ROP.</param>
        /// <param name="userDN">This string specifies which mailbox to log on to.</param>
        /// <param name="needVerify">Whether need to verify the response.</param>
        /// <returns>The handle of logon object.</returns>
        private uint RopLogon(LogonType logonType, out RopLogonResponse logonResponse, string userDN, bool needVerify)
        {
            this.rawDataValue = null;
            this.responseValue = null;
            this.responseSOHsValue = null;
            userDN += "\0";
            uint insideObjHandle = 0;

            RopLogonRequest logonRequest = new RopLogonRequest()
            {
                RopId = (byte)RopId.RopLogon,
                LogonId = LogonId,
                OutputHandleIndex = (byte)HandleIndex.FirstIndex,
                StoreState = (uint)StoreState.None,

                // Set parameters for public folder logon type.
                LogonFlags = logonType == LogonType.PublicFolder ? (byte)LogonFlags.PublicFolder : (byte)LogonFlags.Private,
                OpenFlags = logonType == LogonType.PublicFolder ? (uint)(OpenFlags.UsePerMDBReplipMapping | OpenFlags.Public) : (uint)OpenFlags.UsePerMDBReplipMapping,

                // Set EssdnSize to 0, which specifies the size of the ESSDN field.
                EssdnSize = logonType == LogonType.PublicFolder ? (ushort)0 : (ushort)Encoding.ASCII.GetByteCount(userDN),
                Essdn = logonType == LogonType.PublicFolder ? null : Encoding.ASCII.GetBytes(userDN),
            };

            this.responseSOHsValue = this.ProcessSingleRop(logonRequest, insideObjHandle, ref this.responseValue, ref this.rawDataValue, RopResponseType.SuccessResponse);
            logonResponse = (RopLogonResponse)this.responseValue;
            if (needVerify)
            {
                this.Site.Assert.AreEqual((uint)RopResponseType.SuccessResponse, logonResponse.ReturnValue, string.Format("Logon Failed! Error: 0x{0:X8}", logonResponse.ReturnValue));
            }

            return this.responseSOHsValue[0][logonResponse.OutputHandleIndex];
        }
        /// <summary>
        /// The user connects to the server and logons to the mailbox of the user configured by "AdminUserName" in ptfconfig.
        /// </summary>
        /// <param name="userName">The user to logon to the mailbox of the user configured by "AdminUserName" in ptfconfig</param>
        public void Logon(string userName)
        {
            bool isConnected;

            // If the user is already connected to the server, not connect again.
            // If the user is not connected to the server, connect it.
            if (!string.Equals(this.currentLogonUser, userName, StringComparison.OrdinalIgnoreCase))
            {
                // Disconnect the previous RPC connection.
                this.oxcropsClient.Disconnect();

                string userDN = string.Empty;
                string password = string.Empty;
                if (string.Equals(userName, this.User2, StringComparison.OrdinalIgnoreCase))
                {
                    userDN = this.AdminUserEssdn;
                    password = this.AdminUserPassword;
                }
                else if (string.Equals(userName, this.User1, StringComparison.OrdinalIgnoreCase))
                {
                    userDN = this.User1Essdn;
                    password = this.User1Password;
                }
                else
                {
                    this.currentLogonUser = null;
                    Site.Assert.Fail("The user {0} is not allowed to logon to the server. Check the user.", userName);
                }

                // The user logons to the User2's mailbox.
                isConnected = this.oxcropsClient.Connect(this.ServerName, ConnectionType.PrivateMailboxServer, userDN, this.Domain, userName, password);
                Site.Assert.IsTrue(isConnected, "True indicates connecting to server successfully.");
                this.ropLogonResponse = this.ROPLogon(LogonType.Mailbox, this.AdminUserEssdn, out this.inobjHandle);
                Site.Assert.AreEqual<uint>(UINT32SUCCESS, this.ropLogonResponse.ReturnValue, "0 indicates the user {0} logs on to the {1}'s mailbox successfully.", userName, this.User2);
                this.VerifyCredential(userName, password, this.ropLogonResponse.ReturnValue);
                this.currentLogonUser = userName;
            }
            else
            {
                Site.Log.Add(LogEntryKind.Comment, "The user {0} is already connected to the server.", userName);
            }
        }
        /// <summary>
        /// Logon to Public Folder.
        /// </summary>
        private void Logon()
        {
            bool returnStatus = this.Adapter.DoConnect(ConnectionType.PublicFolderServer);
            Site.Assert.IsTrue(returnStatus, "connection is successful");

            // Logon to Public Folder.
            this.logonResponse = this.Logon(LogonFlags.PublicFolder, out this.publicLogonHandle);
        }
        /// <summary>
        /// Verify RopLogon Success Response
        /// </summary>
        /// <param name="ropLogonResponse">The response of the RopLogon request</param>
        private void VerifyRopLogonSuccessResponse(RopLogonResponse ropLogonResponse)
        {
            byte logonFlags = ropLogonResponse.LogonFlags;

            // This bit is set for logon to a private mailbox and is not set for logon to public folders.
            if (logonFlags == (byte)LogonFlags.Private)
            {
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R121,LogonFlags:{0}", ropLogonResponse.LogonFlags);

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R121
                bool isVerifyR121 = ((ropLogonResponse.LogonFlags & 0x01) == (byte)LogonFlags.Private)
                                    || ((ropLogonResponse.LogonFlags & 0x02) == (byte)LogonFlags.Undercover)
                                    || ((ropLogonResponse.LogonFlags & 0x04) == (byte)LogonFlags.Ghosted);

                Site.CaptureRequirementIfIsTrue(
                    isVerifyR121,
                    121,
                    @"[In RopLogon ROP Redirect Response Buffer] LogonFlags (1 byte): The possible values[the value of Private is 0x01, the value of Undercover is 0x02, the value of Ghosted is 0x04] are specified in [MS-OXCSTOR] Section 2.2.1.1.2.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R43
                Site.CaptureRequirementIfAreEqual<Type>(
                    typeof(byte),
                    ropLogonResponse.RopId.GetType(),
                    43,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailboxes] RopId (1 byte): ): An unsigned integer .");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R45
                Site.CaptureRequirementIfAreEqual<byte>(
                    (byte)RopId.RopLogon,
                    ropLogonResponse.RopId,
                    45,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailboxes] RopId (1 byte): For this operation[RopLogon], this field[RopId (1 byte)] is set to 0xFE.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R46
                Site.CaptureRequirementIfAreEqual<Type>(
                    typeof(byte),
                    ropLogonResponse.OutputHandleIndex.GetType(),
                    46,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailboxes] OutputHandleIndex (1 byte): An unsigned integer.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R48
                Site.CaptureRequirementIfAreEqual<Type>(
                    typeof(uint),
                    ropLogonResponse.ReturnValue.GetType(),
                    48,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailboxes] ReturnValue (4 bytes): An unsigned integer.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R50
                Site.CaptureRequirementIfAreEqual<uint>(
                    SuccessReturnValue,
                    ropLogonResponse.ReturnValue,
                    50,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailboxes] ReturnValue (4 bytes): For this response[Success Response Buffer for Private Mailboxes], this field is set to 0x00000000.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R51
                Site.CaptureRequirementIfAreEqual<Type>(
                    typeof(byte),
                    ropLogonResponse.LogonFlags.GetType(),
                    51,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailboxes] LogonFlags (1 byte): ): A flags structure.");

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R70,LogonFlags:{0}", ropLogonResponse.LogonFlags);

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R70
                bool isVerifyR70 = ((ropLogonResponse.LogonFlags & (byte)LogonFlags.Private) == (byte)LogonFlags.Private)
                                   || ((ropLogonResponse.LogonFlags & (byte)LogonFlags.Undercover) == (byte)LogonFlags.Undercover)
                                   || ((ropLogonResponse.LogonFlags & (byte)LogonFlags.Ghosted) == (byte)LogonFlags.Ghosted);

                Site.CaptureRequirementIfIsTrue(
                    isVerifyR70,
                    70,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailboxes] LogonFlags (1 byte): The possible values[the value of Private is 0x01, the value of Undercover is 0x02 and the value of Ghosted is 0x04] are specified in [MS-OXCSTOR] Section2.2.1.1.3.");

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R53, the actual size of element in FolderIds is {0} and length of FolderIds is {1}", Marshal.SizeOf(ropLogonResponse.FolderIds[0]), ropLogonResponse.FolderIds.Length);

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R53
                // If size of element in FolderIds is 8 byte and the length of  FolderIds is 13, then verify this requirement
                bool isVerifyR53 = (Marshal.SizeOf(ropLogonResponse.FolderIds[0]) == 8) && (ropLogonResponse.FolderIds.Length == 13);

                Site.CaptureRequirementIfIsTrue(
                    isVerifyR53,
                    53,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailboxes] FolderIds (104 bytes): 13 64-bit identifiers.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R55
                Site.CaptureRequirementIfAreEqual<Type>(
                    typeof(byte),
                    ropLogonResponse.ResponseFlags.GetType(),
                    55,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailboxes] ResponseFlags (1 byte): A flags structure.");

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R71,ResponseFlags:{0}", ropLogonResponse.ResponseFlags);

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R71
                bool isVerifyR71 = ((ropLogonResponse.ResponseFlags & 0x01) == (byte)ResponseFlags.Reserved)
                                   || ((ropLogonResponse.ResponseFlags & 0x02) == (byte)ResponseFlags.OwnerRight)
                                   || ((ropLogonResponse.ResponseFlags & 0x04) == (byte)ResponseFlags.SendAsRight)
                                   || ((ropLogonResponse.ResponseFlags & 0x10) == (byte)ResponseFlags.OOF);

                Site.CaptureRequirementIfIsTrue(
                    isVerifyR71,
                    71,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailboxes] ResponseFlags (1 byte): The possible values[the value of Reserved is 0x01, the value of OwnerRight is 0x02, the value of SendAsRight is 0x04, the value of OOF is 0x10] are specified in [MS-OXCSTOR] Section 2.2.1.1.3.");

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R57
                bool isVerifyR57 = this.IsGUID(ropLogonResponse.MailboxGuid);

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R57, the actual type of MailboxGuid type is :{0}", ropLogonResponse.MailboxGuid.GetType().Name);
                Site.CaptureRequirementIfIsTrue(
                    isVerifyR57,
                    57,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailboxes] MailboxGuid (16 bytes): A GUID.");

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R59, the actual type of RepId is {0} and length of it is {1}", ropLogonResponse.ReplId.GetType().Name, ropLogonResponse.ReplId.Length);

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R59
                // The 16-bit is 2-element byte array. If the RepId is byte array and the length of it is 2, the R59 is verified
                bool isVerifyR59 = (ropLogonResponse.ReplId.GetType() == typeof(byte[])) &&
                                   (ropLogonResponse.ReplId.Length == 2);

                Site.CaptureRequirementIfIsTrue(
                    isVerifyR59,
                    59,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailboxes] ReplId (2 bytes): An identifier.");

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R61, the actual type of ReplGuid is:{0}", ropLogonResponse.ReplGuid.GetType().Name);
                
                // Verify MS-OXCROPS requirement: MS-OXCROPS_R61

                // Determine whether ReplGuid is GUID or not. 
                bool isVerifyR61 = this.IsGUID(ropLogonResponse.ReplGuid);

                Site.CaptureRequirementIfIsTrue(
                    isVerifyR61,
                    61,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailboxes] ReplGuid (16 bytes): ): A GUID.");

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R62, the actual type of ReplGuid is {0}", ropLogonResponse.ReplGuid.GetType().Name);

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R62

                // Determine whether ReplGuid is GUID or not. 
                // If ReplGuid is GUID, it indicates this field specifies the replica GUID.
                bool isVerifyR62 = this.IsGUID(ropLogonResponse.ReplGuid);

                Site.CaptureRequirementIfIsTrue(
                    isVerifyR62,
                    62,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailboxes] ReplGuid (16 bytes): This field specifies the replica GUID that is associated with the replica ID, which is specified in the ReplId field.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R63
                // This LogonTime structure is generated based on the IDL from MS-OXCROPS,
                // If this field is type of LogonTime, the requirement is verified.
                Site.CaptureRequirementIfAreEqual<Type>(
                    typeof(LogonTime),
                    ropLogonResponse.LogonTime.GetType(),
                    63,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailboxes] LogonTime (8 bytes): A LogonTime structure.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R65
                Site.CaptureRequirementIfAreEqual<Type>(
                    typeof(ulong),
                    ropLogonResponse.GwartTime.GetType(),
                    65,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailboxes] GwartTime (8 bytes): An unsigned integer.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R74
                Site.CaptureRequirementIfAreEqual<Type>(
                    typeof(uint),
                    ropLogonResponse.StoreState.GetType(),
                    74,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailboxes] StoreState (4 bytes): A flags structure.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R77
                Site.CaptureRequirementIfAreEqual<Type>(
                    typeof(byte),
                    ropLogonResponse.LogonTime.Seconds.GetType(),
                    77,
                    @"[In LogonTime Structure] Seconds (1 byte): An unsigned integer.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R79
                Site.CaptureRequirementIfAreEqual<Type>(
                    typeof(byte),
                    ropLogonResponse.LogonTime.Minutes.GetType(),
                    79,
                    @"[In LogonTime Structure] Minutes (1 byte): An unsigned integer.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R81
                Site.CaptureRequirementIfAreEqual<Type>(
                    typeof(byte),
                    ropLogonResponse.LogonTime.Hour.GetType(),
                    81,
                    @"[In LogonTime Structure] Hour (1 byte): An unsigned integer.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R83
                Site.CaptureRequirementIfAreEqual<Type>(
                    typeof(byte),
                    ropLogonResponse.LogonTime.DayOfWeek.GetType(),
                    83,
                    @"[In LogonTime Structure] DayOfWeek (1 byte): An enumeration.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R85
                Site.CaptureRequirementIfAreEqual<Type>(
                    typeof(byte),
                    ropLogonResponse.LogonTime.Day.GetType(),
                    85,
                    @"[In LogonTime Structure] Day (1 byte): An unsigned integer.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R87
                Site.CaptureRequirementIfAreEqual<Type>(
                    typeof(byte),
                    ropLogonResponse.LogonTime.Month.GetType(),
                    87,
                    @"[In LogonTime Structure] Month (1 byte): An unsigned integer.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R89
                Site.CaptureRequirementIfAreEqual<Type>(
                    typeof(ushort),
                    ropLogonResponse.LogonTime.Year.GetType(),
                    89,
                    @"[In LogonTime Structure] Year (2 bytes): An unsigned integer.");
            }
            else if (logonFlags == (byte)LogonFlags.PublicFolder)
            {
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R91");

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R91
                Site.CaptureRequirementIfAreEqual<Type>(
                    typeof(byte),
                    ropLogonResponse.RopId.GetType(),
                    91,
                    @"[In RopLogon ROP Success Response Buffer for Public Folders] RopId (1 byte): An unsigned integer.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R93
                Site.CaptureRequirementIfAreEqual<byte>(
                    (byte)RopId.RopLogon,
                    ropLogonResponse.RopId,
                    93,
                    @"[In RopLogon ROP Success Response Buffer for Public Folders] RopId (1 byte): For this operation[RopLogon], this field[RopId (1 byte)] is set to 0xFE.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R94
                Site.CaptureRequirementIfAreEqual<Type>(
                    typeof(byte),
                    ropLogonResponse.OutputHandleIndex.GetType(),
                    94,
                    @"[In RopLogon ROP Success Response Buffer for Public Folders] OutputHandleIndex (1 byte): An unsigned integer.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R96
                Site.CaptureRequirementIfAreEqual<Type>(
                    typeof(uint),
                    ropLogonResponse.ReturnValue.GetType(),
                    96,
                    @"[In RopLogon ROP Success Response Buffer for Public Folders] ReturnValue (4 bytes): An unsigned integer.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R98
                Site.CaptureRequirementIfAreEqual<uint>(
                    SuccessReturnValue,
                    ropLogonResponse.ReturnValue,
                    98,
                    @"[In RopLogon ROP Success Response Buffer for Public Folders] ReturnValue (4 bytes): For this response[Success Response Buffer for Public Folders], this field is set to 0x00000000.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R99
                Site.CaptureRequirementIfAreEqual<Type>(
                    typeof(byte),
                    ropLogonResponse.LogonFlags.GetType(),
                    99,
                    @"[In RopLogon ROP Success Response Buffer for Public Folders] LogonFlags (1 byte): A flags structure.");

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

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R100
                Site.CaptureRequirementIfAreEqual<byte>(
                    (byte)LogonFlags.PublicFolder,
                    ropLogonResponse.LogonFlags,
                    100,
                    @"[In RopLogon ROP Success Response Buffer for Public Folders] LogonFlags (1 byte): The possible values[the value of Public is 0x00] are specified in [MS-OXCSTOR]2.2.1.1.4.");

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R102, the actual type of FolderIds is {0} and length of array is {1}", ropLogonResponse.FolderIds.GetType().Name, ropLogonResponse.FolderIds.Length);

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R102
                // If the type of FolderIds is long[] or ulong[] and the length of array is 13, then verify this requirement
                bool isVerifyR102 = (ropLogonResponse.FolderIds.GetType() == typeof(long[]) ||
                                    ropLogonResponse.FolderIds.GetType() == typeof(ulong[])) &&
                                    (ropLogonResponse.FolderIds.Length == 13);

                Site.CaptureRequirementIfIsTrue(
                    isVerifyR102,
                    102,
                    @"[In RopLogon ROP Success Response Buffer for Public Folders] FolderIds (104 bytes): 13 64-bit identifiers.");

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R104, the actual type of ReqlId is {0} and length of it is {1}", ropLogonResponse.ReplId.GetType().Name, ropLogonResponse.ReplId.Length);

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R104
                bool isVerifyR104 = (ropLogonResponse.ReplId.GetType() == typeof(byte[])) &&
                                    (ropLogonResponse.ReplId.Length == 2);

                Site.CaptureRequirementIfIsTrue(
                    isVerifyR104,
                    104,
                    @"[In RopLogon ROP Success Response Buffer for Public Folders] ReplId (2 bytes): An identifier.");

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R106, the actual type of ReplGuid is :{0}", ropLogonResponse.ReplGuid.GetType().Name);

                // Verify MS-OXCROPS requirement: MS-OXCROPS_R106
                bool isVerifyR106 = this.IsGUID(ropLogonResponse.ReplGuid);

                Site.CaptureRequirementIfIsTrue(
                    isVerifyR106,
                    106,
                    @"[In RopLogon ROP Success Response Buffer for Public Folders] ReplGuid (16 bytes): A GUID that specifies the replica GUID associated with the replica ID that is specified in the ReplId field.");

                if (Common.IsRequirementEnabled(4720, this.Site))
                {
                    bool isVerifyR4720 = false;
                    for (int i = 0; i < ropLogonResponse.PerUserGuid.Length; i++)
                    {
                        bool verify = ropLogonResponse.PerUserGuid[i] != 0x00;

                        // If one byte of PerUserGuid is zero then break the iteration 
                        if (verify)
                        {
                            isVerifyR4720 = true;
                            break;
                        }
                    }

                    // Add the debug information
                    Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R4720, the actual value of PerUserGuid is {0}", BitConverter.ToString(ropLogonResponse.PerUserGuid));

                    // Verify MS-OXCROPS requirement: MS-OXCROPS_R4720
                    Site.CaptureRequirementIfIsTrue(
                        isVerifyR4720,
                        4720,
                        @"[In Appendix B: Product Behavior] Implementation does not set the PerUserGuid field to an empty GUID. (<5> Section 2.2.3.1.3: Exchange 2007 does not set the PerUserGuid field to an empty GUID.)");
                }

                if (Common.IsRequirementEnabled(214, this.Site))
                {
                    bool isVerifyR214 = true;
                    for (int i = 0; i < ropLogonResponse.PerUserGuid.Length; i++)
                    {
                        isVerifyR214 = isVerifyR214 & (ropLogonResponse.PerUserGuid[i] == 0x00);

                        // If one byte of PerUserGuid not zero then break the iteration 
                        if (!isVerifyR214)
                        {
                            break;
                        }
                    }

                    // Add the comment information for debugging
                    Site.Log.Add(LogEntryKind.Comment, "Verify MS-OXCROPS_R214,PerUserGuid:{0}", ropLogonResponse.PerUserGuid);

                    // Verify MS-OXCROPS requirement: 214
                    Site.CaptureRequirementIfIsTrue(
                        isVerifyR214,
                        214,
                        @"[In Appendix B: Product Behavior] PerUserGuid (16 bytes): Implementation does set this field to an empty GUID (all zeroes). (Microsoft Exchange Server 2010 and above follow this behavior.)");
                }               
            }
        }
        /// <summary>
        /// Log on mailbox with specified user.
        /// </summary>
        /// <param name="testUser">Identify the user to log on to the server.</param>
        public void LogonMailbox(TestUser testUser)
        {
            this.testUser = testUser;
            RopLogonResponse logonResponse = new RopLogonResponse();
            if (testUser == TestUser.TestUser1)
            {
                this.OxoruleAdapter.Connect(ConnectionType.PrivateMailboxServer, this.User1Name, this.User1ESSDN, this.User1Password);

                // Logon to private mailbox.
                this.LogonHandle = this.OxoruleAdapter.RopLogon(LogonType.Mailbox, this.User1ESSDN, out logonResponse);
            }
            else
            {
                this.OxoruleAdapter.Connect(ConnectionType.PrivateMailboxServer, this.User2Name, this.User2ESSDN, this.User2Password);

                // Logon to private mailbox.
                this.LogonHandle = this.OxoruleAdapter.RopLogon(LogonType.Mailbox, this.User2ESSDN, out logonResponse);
            }

            // Get the mailbox's GUID
            this.MailboxGUID = logonResponse.MailboxGuid;

            // Get folder ids.
            this.InboxFolderID = logonResponse.FolderIds[4];
            this.DAFFolderID = logonResponse.FolderIds[1];
            outBoxFolderID = logonResponse.FolderIds[5];
            sentItemsFolderID = logonResponse.FolderIds[6];

            // Open inbox and get inbox folder handle.
            RopOpenFolderResponse openInboxResponse = new RopOpenFolderResponse();
            this.InboxFolderHandle = this.OxoruleAdapter.RopOpenFolder(this.LogonHandle, this.InboxFolderID, out openInboxResponse);

            // Open DAF folder and get daf folder handle.
            RopOpenFolderResponse openDAFResponse = new RopOpenFolderResponse();
            this.DAFFolderHandle = this.OxoruleAdapter.RopOpenFolder(this.LogonHandle, this.DAFFolderID, out openDAFResponse);

            // Open outbox folder and get outbox folder handle.
            RopOpenFolderResponse openOutBoxResponse = new RopOpenFolderResponse();
            outBoxFolderHandle = this.OxoruleAdapter.RopOpenFolder(this.LogonHandle, outBoxFolderID, out openOutBoxResponse);

            // Open sent items folder and get sent items folder handle.
            RopOpenFolderResponse openSentItemsFolderResponse = new RopOpenFolderResponse();
            sentItemsFolderHandle = this.OxoruleAdapter.RopOpenFolder(this.LogonHandle, sentItemsFolderID, out openSentItemsFolderResponse);

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

            // Verify MS-OXORULE requirement: MS-OXORULE_R508.
            // If the DAF folder handle is not zero. It means the DAF has been created.
            Site.CaptureRequirementIfAreNotEqual<ulong>(
                0,
                this.DAFFolderHandle,
                508,
                @"[In Initialization] Prior to any client connecting to a mailbox, the server MUST ensure that the DAF has been created for that mailbox as specified in [MS-OXOSFLD] section 3.1.4.1.");
        }
Пример #6
0
        /// <summary>
        /// Get Folder Object Handle.
        /// </summary>
        /// <param name="logonResponse">The response of RopLogon</param>
        /// <returns>Return the folder object handle</returns>
        protected uint GetFolderObjectHandle(ref RopLogonResponse logonResponse)
        {
            // Step 1: Open a folder.
            #region Open folder

            RopOpenFolderRequest openFolderRequest;
            RopOpenFolderResponse openFolderResponse;

            openFolderRequest.RopId = (byte)RopId.RopOpenFolder;

            openFolderRequest.LogonId = LogonId;
            openFolderRequest.InputHandleIndex = InputHandleIndex0;
            openFolderRequest.OutputHandleIndex = OutputHandleIndex1;
            openFolderRequest.FolderId = logonResponse.FolderIds[4];
            openFolderRequest.OpenModeFlags = (byte)FolderOpenModeFlags.None;

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Step 1: Begin to send the RopOpenFolder request in GetFolderObjectHandle method.");

            // Send the RopOpenFolder request to open folder.
            this.responseSOHs = this.cropsAdapter.ProcessSingleRop(
                openFolderRequest,
                this.inputObjHandle,
                ref this.response,
                ref this.rawData,
                RopResponseType.SuccessResponse);
            openFolderResponse = (RopOpenFolderResponse)this.response;

            Site.Assert.AreEqual<uint>(
                TestSuiteBase.SuccessReturnValue,
                openFolderResponse.ReturnValue,
                "If ROP succeeds, the ReturnValue of its response is 0 (success0");

            uint openedFolderHandle = this.responseSOHs[0][openFolderResponse.OutputHandleIndex];

            #endregion

            // Step 2: Create subfolder.
            #region Create subfolder

            RopCreateFolderRequest createFolderRequest;
            RopCreateFolderResponse createFolderResponse;

            createFolderRequest.RopId = (byte)RopId.RopCreateFolder;
            createFolderRequest.LogonId = LogonId;
            createFolderRequest.InputHandleIndex = InputHandleIndex0;
            createFolderRequest.OutputHandleIndex = OutputHandleIndex1;
            createFolderRequest.FolderType = (byte)FolderType.Genericfolder;
            createFolderRequest.UseUnicodeStrings = Convert.ToByte(Zero);
            createFolderRequest.OpenExisting = NonZero;
            createFolderRequest.Reserved = Reserved;
            createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(DisplayNameAndCommentForNonSearchFolder + "\0");
            createFolderRequest.Comment = Encoding.ASCII.GetBytes(DisplayNameAndCommentForNonSearchFolder + "\0");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Step 2: Begin to send the RopCreateFolder request in GetFolderObjectHandle method.");

            // Send the RopCreateFolder request and verify the success response.
            this.responseSOHs = this.cropsAdapter.ProcessSingleRop(
                createFolderRequest,
                openedFolderHandle,
                ref this.response,
                ref this.rawData,
                RopResponseType.SuccessResponse);
            createFolderResponse = (RopCreateFolderResponse)this.response;
            Site.Assert.AreEqual<uint>(
                TestSuiteBase.SuccessReturnValue,
                createFolderResponse.ReturnValue,
                "If ROP succeeds, the ReturnValue of its response is 0 (success0");

            #endregion

            // Step 3: Get and return the handle of created folder.
            uint folderHandle = this.responseSOHs[0][createFolderResponse.OutputHandleIndex];
            return folderHandle;
        }
Пример #7
0
        /// <summary>
        /// Create message each one loop In InBox
        /// </summary>
        /// <param name="logonResponse">the logon response be used to create message</param>
        /// <param name="tableHandle">The tableHanlder of the new folder</param>
        /// <param name="count">The count of created messages</param>
        /// <param name="createMessageRequest">The ROP CreateMessageRequest</param>
        /// <param name="saveChangesMessageRequest">The ROP SaveChangesMessageRequest</param>
        /// <param name="releaseRequest">The ROP ReleaseRequest</param>
        protected void CreateSingleProcessEachLoop(ref RopLogonResponse logonResponse, out uint tableHandle, int count, RopCreateMessageRequest createMessageRequest, RopSaveChangesMessageRequest saveChangesMessageRequest, RopReleaseRequest releaseRequest)
        {
            RopCreateMessageResponse createMessageResponse = new RopCreateMessageResponse();
            RopSaveChangesMessageResponse saveChangesMessageResponse = new RopSaveChangesMessageResponse();
            #region Preparing the table: CreateFolder

            // Open a folder first
            RopOpenFolderRequest openFolderRequest;
            RopOpenFolderResponse openFolderResponse;

            openFolderRequest.RopId = (byte)RopId.RopOpenFolder;

            openFolderRequest.LogonId = TestSuiteBase.LogonId;
            openFolderRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0;
            openFolderRequest.OutputHandleIndex = TestSuiteBase.OutputHandleIndex1;
            openFolderRequest.FolderId = logonResponse.FolderIds[4];
            openFolderRequest.OpenModeFlags = (byte)FolderOpenModeFlags.None;

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Step 2: Begin to send the RopOpenFolder request.");

            this.responseSOHs = this.cropsAdapter.ProcessSingleRop(
                openFolderRequest,
                this.inputObjHandle,
                ref this.response,
                ref this.rawData,
                RopResponseType.SuccessResponse);
            openFolderResponse = (RopOpenFolderResponse)this.response;
            Site.Assert.AreEqual<uint>(
                TestSuiteBase.SuccessReturnValue,
                openFolderResponse.ReturnValue,
                "if ROP succeeds, the ReturnValue of its response is 0(success)");
            uint openedFolderHandle = this.responseSOHs[0][openFolderResponse.OutputHandleIndex];

            // Create a new subfolder in the opened folder
            // The new subfolder will be used as target folder
            RopCreateFolderRequest createFolderRequest;
            RopCreateFolderResponse createFolderResponse;

            createFolderRequest.RopId = (byte)RopId.RopCreateFolder;
            createFolderRequest.LogonId = TestSuiteBase.LogonId;
            createFolderRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0;
            createFolderRequest.OutputHandleIndex = TestSuiteBase.OutputHandleIndex1;
            createFolderRequest.FolderType = (byte)FolderType.Genericfolder;
            createFolderRequest.UseUnicodeStrings = Convert.ToByte(TestSuiteBase.Zero);
            createFolderRequest.OpenExisting = TestSuiteBase.NonZero;
            createFolderRequest.Reserved = TestSuiteBase.Reserved;
            createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(TestSuiteBase.DisplayNameAndCommentForNonSearchFolder + "\0");
            createFolderRequest.Comment = Encoding.ASCII.GetBytes(TestSuiteBase.DisplayNameAndCommentForNonSearchFolder + "\0");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Step 2: Begin to send the RopCreateFolder request.");

            this.responseSOHs = this.cropsAdapter.ProcessSingleRop(
                createFolderRequest,
                openedFolderHandle,
                ref this.response,
                ref this.rawData,
                RopResponseType.SuccessResponse);
            createFolderResponse = (RopCreateFolderResponse)this.response;
            Site.Assert.AreEqual<uint>(
                TestSuiteBase.SuccessReturnValue,
                createFolderResponse.ReturnValue,
                "if ROP succeeds, the ReturnValue of its response is 0(success)");
            uint targetFolderHandle = this.responseSOHs[0][openFolderResponse.OutputHandleIndex];
            tableHandle = this.GetContentsTableHandle(targetFolderHandle);
            ulong folderId = createFolderResponse.FolderId;

            #endregion

            #region Preparing the table: RopCreateAndSaveMessages

            int waitTime = int.Parse(Common.GetConfigurationPropertyValue("WaitTime", this.Site));
            int maxRetryCount = int.Parse(Common.GetConfigurationPropertyValue("RetryCount", this.Site));
            int retryCount;
            uint returnValue = 0;
            for (int i = 1; i < count; i++)
            {
                // If the RPC report error code reported by the following three ROP methods is 1726 (The remote procedure call failed), 
                // re-do the common steps of this case.
                if (returnValue == 1726)
                {
                    #region The common steps
                    // Add the debug information
                    Site.Log.Add(LogEntryKind.Debug, "If RPC error code is 1726, re-connect to server.");
                    this.cropsAdapter.RpcConnect(
                        Common.GetConfigurationPropertyValue("SutComputerName", this.Site),
                        ConnectionType.PrivateMailboxServer,
                        Common.GetConfigurationPropertyValue("UserEssdn", this.Site),
                        Common.GetConfigurationPropertyValue("Domain", this.Site),
                        Common.GetConfigurationPropertyValue("AdminUserName", this.Site),
                        Common.GetConfigurationPropertyValue("PassWord", this.Site));
                    logonResponse = this.Logon(LogonType.Mailbox, this.userDN, out this.inputObjHandle);

                    // Add the debug information
                    Site.Log.Add(LogEntryKind.Debug, "Step 2:Begin to send the RopOpenFolder request.");

                    this.responseSOHs = this.cropsAdapter.ProcessSingleRop(
                        openFolderRequest,
                        this.inputObjHandle,
                        ref this.response,
                        ref this.rawData,
                        RopResponseType.SuccessResponse);
                    openFolderResponse = (RopOpenFolderResponse)this.response;

                    Site.Assert.AreEqual<uint>(
                        TestSuiteBase.SuccessReturnValue,
                        openFolderResponse.ReturnValue,
                        "if ROP succeeds, the ReturnValue of its response is 0(success)");
                    openedFolderHandle = this.responseSOHs[0][openFolderResponse.OutputHandleIndex];

                    // Add the debug information
                    Site.Log.Add(LogEntryKind.Debug, "Step 2:Begin to send the RopCreateFolder request.");

                    this.responseSOHs = this.cropsAdapter.ProcessSingleRop(
                        createFolderRequest,
                        openedFolderHandle,
                        ref this.response,
                        ref this.rawData,
                        RopResponseType.SuccessResponse);
                    createFolderResponse = (RopCreateFolderResponse)this.response;
                    Site.Assert.AreEqual<uint>(
                        TestSuiteBase.SuccessReturnValue,
                        createFolderResponse.ReturnValue,
                        "if ROP succeeds, the ReturnValue of its response is 0(success)");
                    targetFolderHandle = this.responseSOHs[0][openFolderResponse.OutputHandleIndex];
                    tableHandle = this.GetContentsTableHandle(targetFolderHandle);
                    folderId = createFolderResponse.FolderId;
                    #endregion
                }

                #region Create message
                createMessageRequest.FolderId = folderId;

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Step 2:Begin to send the RopCreateMessage request:loop counter i={0}", i);
                retryCount = maxRetryCount;

                do
                {
                    // Send the RopCreateMessage to create message.
                    this.responseSOHs = this.cropsAdapter.ProcessSingleRopWithReturnValue(
                        createMessageRequest,
                        this.inputObjHandle,
                        ref this.response,
                        ref this.rawData,
                        RopResponseType.SuccessResponse,
                        out returnValue);
                    System.Threading.Thread.Sleep(waitTime);
                    retryCount--;
                }
                while (this.response is RopBackoffResponse && retryCount >= 0);

                Site.Assert.IsTrue(retryCount >= 0, "The case {0} failed since server is busy and always returns RopBackoff in the response, reduce your server load and try again.", this.TestContext.TestName);

                // If the error code is 1726, continue this loop.
                if (returnValue == 1726)
                {
                    continue;
                }

                createMessageResponse = (RopCreateMessageResponse)this.response;
                Site.Assert.AreEqual<uint>(
                    TestSuiteBase.SuccessReturnValue,
                    createMessageResponse.ReturnValue,
                "if ROP succeeds, the ReturnValue of its response is 0(success)");
                uint targetMessageHandle = this.responseSOHs[0][createMessageResponse.OutputHandleIndex];
                #endregion

                #region Save message
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Step 2:Begin to send the RopSaveChangesMessage request:loop counter i={0}", i);

                retryCount = maxRetryCount;

                // Do the loop when response is RopBackoffResponse or saveChangesMessageResponse is 0x80040401 (ecTimeout).
                do
                {
                    // Send the RopSaveChangesMessage request to save the created message.
                    this.responseSOHs = this.cropsAdapter.ProcessSingleRopWithReturnValue(
                        saveChangesMessageRequest,
                        targetMessageHandle,
                        ref this.response,
                        ref this.rawData,
                        RopResponseType.SuccessResponse,
                        out returnValue);

                    if (this.response is RopSaveChangesMessageResponse)
                    {
                        saveChangesMessageResponse = (RopSaveChangesMessageResponse)this.response;
                    }

                    System.Threading.Thread.Sleep(waitTime);
                    retryCount--;
                }
                while ((this.response is RopBackoffResponse || saveChangesMessageResponse.ReturnValue == 0x80040401) && retryCount >= 0);

                Site.Assert.IsTrue(retryCount >= 0, "The case {0} failed since server is busy and always returns RopBackoff in the response, reduce your server load and try again.", this.TestContext.TestName);

                // If the error code is 1726, continue this loop.
                if (returnValue == 1726)
                {
                    continue;
                }

                saveChangesMessageResponse = (RopSaveChangesMessageResponse)this.response;
                Site.Assert.AreEqual<uint>(
                    TestSuiteBase.SuccessReturnValue,
                    saveChangesMessageResponse.ReturnValue,
                "if ROP succeeds, the ReturnValue of its response is 0(success)");
                #endregion

                #region Release all resources
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Step 2:Begin to send the RopRelease request.");

                retryCount = maxRetryCount;

                do
                {
                    this.responseSOHs = this.cropsAdapter.ProcessSingleRopWithReturnValue(
                        releaseRequest,
                        targetMessageHandle,
                        ref this.response,
                        ref this.rawData,
                        RopResponseType.SuccessResponse,
                        out returnValue);
                    System.Threading.Thread.Sleep(waitTime);
                    retryCount--;
                }
                while (this.response is RopBackoffResponse && retryCount >= 0);

                Site.Assert.IsTrue(retryCount >= 0, "The case {0} failed since server is busy and always returns RopBackoff in the response, reduce your server load and try again.", this.TestContext.TestName);

                // If the error code is 1726, continue this loop.
                if (returnValue == 1726)
                {
                    continue;
                }
                #endregion
            }

            // If the error code 1726 occurs on the last time of the above "for" loop, re-do the common steps.
            if (returnValue == 1726)
            {
                #region The common steps
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "If RPC error code is 1726, re-connect to server.");
                this.cropsAdapter.RpcConnect(
                    Common.GetConfigurationPropertyValue("SutComputerName", this.Site),
                    ConnectionType.PrivateMailboxServer,
                    Common.GetConfigurationPropertyValue("UserEssdn", this.Site),
                    Common.GetConfigurationPropertyValue("Domain", this.Site),
                    Common.GetConfigurationPropertyValue("AdminUserName", this.Site),
                    Common.GetConfigurationPropertyValue("PassWord", this.Site));
                logonResponse = this.Logon(LogonType.Mailbox, this.userDN, out this.inputObjHandle);

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Step 2:Begin to send the RopOpenFolder request.");

                this.responseSOHs = this.cropsAdapter.ProcessSingleRop(
                    openFolderRequest,
                    this.inputObjHandle,
                    ref this.response,
                    ref this.rawData,
                    RopResponseType.SuccessResponse);
                openFolderResponse = (RopOpenFolderResponse)this.response;

                Site.Assert.AreEqual<uint>(
                    TestSuiteBase.SuccessReturnValue,
                    openFolderResponse.ReturnValue,
                    "if ROP succeeds, the ReturnValue of its response is 0(success)");
                openedFolderHandle = this.responseSOHs[0][openFolderResponse.OutputHandleIndex];

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Step 2:Begin to send the RopCreateFolder request.");

                this.responseSOHs = this.cropsAdapter.ProcessSingleRop(
                    createFolderRequest,
                    openedFolderHandle,
                    ref this.response,
                    ref this.rawData,
                    RopResponseType.SuccessResponse);
                createFolderResponse = (RopCreateFolderResponse)this.response;
                Site.Assert.AreEqual<uint>(
                    TestSuiteBase.SuccessReturnValue,
                    createFolderResponse.ReturnValue,
                    "if ROP succeeds, the ReturnValue of its response is 0(success)");
                targetFolderHandle = this.responseSOHs[0][openFolderResponse.OutputHandleIndex];
                tableHandle = this.GetContentsTableHandle(targetFolderHandle);
                folderId = createFolderResponse.FolderId;
                #endregion
            }

            #endregion
        }
        /// <summary>
        /// Verify the response by sending the ROP RopLogon for the public folders.
        /// </summary>
        /// <param name="request">The structure of ROP RopLogon request.</param>
        /// <param name="response">The structure of ROP ROPLogonForPublicFolder response.</param>
        private void VerifyRopLogonForPublicFolder(RopLogonRequest request, RopLogonResponse response)
        {
            // The returnValue is 0 to indicate that the response is successful.
            if (response.ReturnValue == 0)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R13");

                // Verify MS-OXCSTOR requirement: MS-OXCSTOR_R13
                this.Site.CaptureRequirementIfAreEqual<uint>(
                    0,
                    response.ReturnValue,
                    13,
                    @"[In RopLogon ROP] The RopLogon ROP ([MS-OXCROPS] section 2.2.3.1) establishes a logon session between the client and the server.");

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R146, LogonFlags:{0}", response.LogonFlags);

                // Verify MS-OXCSTOR requirement: MS-OXCSTOR_R146
                bool isVerifyR146 = ((LogonFlags)response.LogonFlags & ~(LogonFlags.Private | LogonFlags.PublicFolder | LogonFlags.Ghosted | LogonFlags.Undercover)) == 0;

                Site.CaptureRequirementIfIsTrue(
                    isVerifyR146,
                    146,
                    @"[In RopLogon ROP Success Response Buffer for Public Folders] LogonFlags: This field [LogonFlags] is composed of the Private, Undercover, and Ghosted flags.");

                #region Capture 1071
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R1071");

                // In the step2 logon a Public Folders.
                // Verify MS-OXCSTOR requirement: MS-OXCSTOR_R1071
                Site.CaptureRequirementIfAreEqual<byte>(
                    request.LogonFlags,
                    response.LogonFlags,
                    1071,
                    @"[In RopLogon ROP Success Response Buffer for Public Folders] LogonFlags: The server returns these flags [Private, Undercover, and Ghosted] unchanged from the LogonFlags field of the RopLogon request (section 2.2.1.1.1).");
                #endregion

                Guid perUserGuid = new Guid(response.PerUserGuid);

                if (Common.IsRequirementEnabled(1332, this.Site))
                {
                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R1332");

                    // Verify MS-OXCSTOR requirement: MS-OXCSTOR_R1332
                    this.Site.CaptureRequirementIfAreNotEqual<Guid>(
                        Guid.Empty,
                        perUserGuid,
                        1332,
                        @"[In Appendix A: Product Behavior] The implementation does not set the PerUserGuid field to an empty GUID. (<9> Section 2.2.1.1.4: Exchange 2007 does not set the PerUserGuid field to an empty GUID.)");
                }

                if (Common.IsRequirementEnabled(163, this.Site))
                {
                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R163");

                    // Verify MS-OXCSTOR requirement: MS-OXCSTOR_R163
                    this.Site.CaptureRequirementIfAreEqual<Guid>(
                        Guid.Empty,
                        perUserGuid,
                        163,
                        @"Implementation does set this field [PerUserGuid in RopLogon ROP Success Response Buffer for Public Folders] to an empty GUID (all zeroes). (Exchange 2003, Exchange 2010 and above follow this behavior.)");
                }

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

                // Verify MS-OXCSTOR requirement: MS-OXCSTOR_R3012
                // Check if the LogonFlag is set.
                bool isVerifyR3012 = (response.LogonFlags & (byte)LogonFlags.Private) == (byte)LogonFlags.Private;

                // The server returns the LogonFlags unchanged from the LogonFlag filed of the RopLogon request , So
                // if the response LgonFlag don't contain Private flag, it is not set in the request, then this requirement 
                // will be verified.
                Site.CaptureRequirementIfIsFalse(
                    isVerifyR3012,
                    3012,
                    @"[In RopLogon ROP Success Response Buffer for Public Folders] The success response buffer for public folders is sent only when the Private bit is not set in the LogonFlags field of the RopLogon request (section 2.2.1.1.1).");
            }
            else if (response.ReturnValue == 0x00000478)
            {
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R112");

                // Verify MS-OXCSTOR requirement: MS-OXCSTOR_R112
                bool isVerifyR112 = ((LogonFlags)response.LogonFlags & ~(LogonFlags.Private | LogonFlags.PublicFolder | LogonFlags.Ghosted | LogonFlags.Undercover)) == 0;

                Site.CaptureRequirementIfIsTrue(
                    isVerifyR112,
                    112,
                    @"[In RopLogon ROP Redirect Response Buffer] LogonFlags: This field contains the Private, Undercover, and Ghosted flags.");

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

                // Verify MS-OXCSTOR requirement: MS-OXCSTOR_R115
                bool isVerifyR115 = Common.IsNullTerminatedASCIIStr(response.ServerName);

                Site.CaptureRequirementIfIsTrue(
                    isVerifyR115,
                    115,
                    @"[In RopLogon ROP Redirect Response Buffer] ServerName: The string includes the terminating NULL character.");
            }
        }
        /// <summary>
        /// Clean up the test.
        /// </summary>
        protected override void TestCleanup()
        {
            if (this.isReceiveNewMail == true)
            {
                WebHeaderCollection headers = new WebHeaderCollection();
                MailboxResponseBodyBase response;

                #region Send a valid Connect request type to establish a Session Context with the server.
                ConnectSuccessResponseBody connectResponse = this.ConnectToServer(out headers);
                #endregion

                #region Send an Execute request that incluldes Logon ROP to server.
                WebHeaderCollection executeHeaders = AdapterHelper.InitializeHTTPHeader(RequestType.Execute, AdapterHelper.ClientInstance, AdapterHelper.Counter);

                ExecuteRequestBody requestBody = this.InitializeExecuteRequestBody(this.GetRopLogonRequest());
                List<string> metaTags = new List<string>();

                ExecuteSuccessResponseBody executeSuccessResponse = this.SendExecuteRequest(requestBody, ref executeHeaders, out metaTags) as ExecuteSuccessResponseBody;

                ulong folderId;
                RopLogonResponse logonResponse = new RopLogonResponse();
                uint logonHandle = this.ParseLogonResponse(executeSuccessResponse.RopBuffer, out folderId, out logonResponse);
                #endregion

                #region Send an Execute request to open inbox folder.
                RPC_HEADER_EXT[] rpcHeaderExts;
                byte[][] rops;
                uint[][] serverHandleObjectsTables;
                RopOpenFolderRequest openFolderRequest = this.OpenFolderRequest(logonResponse.FolderIds[4]);

                ExecuteRequestBody openFolderRequestBody = this.InitializeExecuteRequestBody(openFolderRequest, logonHandle);
                executeHeaders = AdapterHelper.InitializeHTTPHeader(RequestType.Execute, AdapterHelper.ClientInstance, AdapterHelper.Counter);
                executeSuccessResponse = this.SendExecuteRequest(openFolderRequestBody, ref executeHeaders, out metaTags) as ExecuteSuccessResponseBody;

                RopBufferHelper ropBufferHelper = new RopBufferHelper(Site);
                ropBufferHelper.ParseResponseBuffer(executeSuccessResponse.RopBuffer, out rpcHeaderExts, out rops, out serverHandleObjectsTables);
                RopOpenFolderResponse openFolderResponse = new RopOpenFolderResponse();
                openFolderResponse.Deserialize(rops[0], 0);
                 uint folderHandle = serverHandleObjectsTables[0][openFolderResponse.OutputHandleIndex];
                #endregion

                #region Send an Execute request type to hard delete messages in inbox folder.
                RopHardDeleteMessagesAndSubfoldersRequest hardDeleteRequest;
                hardDeleteRequest.RopId = (byte)RopId.RopHardDeleteMessagesAndSubfolders;
                hardDeleteRequest.LogonId = ConstValues.LogonId;

                // Set InputHandleIndex to 0x00, which specifies the location in the Server object handle table
                // where the handle for the input Server object is stored.
                hardDeleteRequest.InputHandleIndex = 0;
                hardDeleteRequest.WantAsynchronous = 0x00; // Synchronously
                hardDeleteRequest.WantDeleteAssociated = 0xFF; // TRUE: delete all messages and subfolders
                ExecuteRequestBody hardDeleteRequestBody = this.InitializeExecuteRequestBody(hardDeleteRequest, folderHandle);
                executeHeaders = AdapterHelper.InitializeHTTPHeader(RequestType.Execute, AdapterHelper.ClientInstance, AdapterHelper.Counter);
                executeSuccessResponse = this.SendExecuteRequest(hardDeleteRequestBody, ref executeHeaders, out metaTags) as ExecuteSuccessResponseBody;
                RopHardDeleteMessagesAndSubfoldersResponse hardDeleteMessagesAndSubfoldersResponse = new RopHardDeleteMessagesAndSubfoldersResponse();
                hardDeleteMessagesAndSubfoldersResponse.Deserialize(rops[0], 0);
                #endregion

                #region Send an Execute request to open sent items folder.
                openFolderRequest = this.OpenFolderRequest(logonResponse.FolderIds[6]);

                openFolderRequestBody = this.InitializeExecuteRequestBody(openFolderRequest, logonHandle);
                executeHeaders = AdapterHelper.InitializeHTTPHeader(RequestType.Execute, AdapterHelper.ClientInstance, AdapterHelper.Counter);
                executeSuccessResponse = this.SendExecuteRequest(openFolderRequestBody, ref executeHeaders, out metaTags) as ExecuteSuccessResponseBody;

                ropBufferHelper = new RopBufferHelper(Site);
                ropBufferHelper.ParseResponseBuffer(executeSuccessResponse.RopBuffer, out rpcHeaderExts, out rops, out serverHandleObjectsTables);
                openFolderResponse = new RopOpenFolderResponse();
                openFolderResponse.Deserialize(rops[0], 0);
                folderHandle = serverHandleObjectsTables[0][openFolderResponse.OutputHandleIndex];
                #endregion

                #region Send an Execute request type to hard delete messages in sent items folder.
                hardDeleteRequest.RopId = (byte)RopId.RopHardDeleteMessagesAndSubfolders;
                hardDeleteRequest.LogonId = ConstValues.LogonId;

                // Set InputHandleIndex to 0x00, which specifies the location in the Server object handle table
                // where the handle for the input Server object is stored.
                hardDeleteRequest.InputHandleIndex = 0;
                hardDeleteRequest.WantAsynchronous = 0x00; // Synchronously
                hardDeleteRequest.WantDeleteAssociated = 0xFF; // TRUE: delete all messages and subfolders
                hardDeleteRequestBody = this.InitializeExecuteRequestBody(hardDeleteRequest, folderHandle);
                executeHeaders = AdapterHelper.InitializeHTTPHeader(RequestType.Execute, AdapterHelper.ClientInstance, AdapterHelper.Counter);
                executeSuccessResponse = this.SendExecuteRequest(hardDeleteRequestBody, ref executeHeaders, out metaTags) as ExecuteSuccessResponseBody;
                hardDeleteMessagesAndSubfoldersResponse = new RopHardDeleteMessagesAndSubfoldersResponse();
                hardDeleteMessagesAndSubfoldersResponse.Deserialize(rops[0], 0);
                #endregion

                #region Send a Disconnect request to destroy the Session Context.
                this.Adapter.Disconnect(out response);
                #endregion

                this.isReceiveNewMail = false;
            }

            base.TestCleanup();
        }
Пример #10
0
        /// <summary>
        /// Notification initialize.
        /// </summary>
        protected void NotificationInitialize()
        {
            // Make the sender connection and log on to trigger the notification.
            this.isSenderContextConnected = this.cnotifAdapter.DoConnect(ConnectionType.PrivateMailboxServer);
            this.Site.Assert.IsTrue(this.isSenderContextConnected, "If is connected, the ReturnValue of its response is true(success)");
            this.logonRsp = this.cnotifAdapter.Logon();

            this.inboxFolderId = this.logonRsp.FolderIds[4];
            this.outboxFolderId = this.logonRsp.FolderIds[5];
            this.rpcContextForSend = this.cnotifAdapter.RPCContext;
            this.senderContextLogonHandle = this.cnotifAdapter.LogonHandle;

            uint inboxHandle;
            this.OpenFolder(this.inboxFolderId, out inboxHandle);

            uint newMessageHandle;
            uint newFolderHandle;

            // Create the a subfolder in Inbox folder.
            string folderName = Common.GenerateResourceName(Site, "NewSubFolder");
            RopCreateFolderResponse createFolderRsp = this.CreateFolder(inboxHandle, folderName, out newFolderHandle, FolderType.Genericfolder);
            this.newFolderId = createFolderRsp.FolderId;

            // Create the message which are used to trigger event.
            this.CreateMessage(this.inboxFolderId, out newMessageHandle);
            RopSaveChangesMessageResponse saveRsp = this.SaveMessage(newMessageHandle);
            this.triggerMessageId = saveRsp.MessageId;

            // Create the message which are used for locating.
            this.CreateMessage(this.inboxFolderId, out newMessageHandle);
            saveRsp = this.SaveMessage(newMessageHandle);
            this.locatingMessageId = saveRsp.MessageId;

            // Make the receiver connection and log on to register the notification.
            if (Common.GetConfigurationPropertyValue("TransportSeq", this.Site).ToLower() == "mapi_http")
            {
                this.cnotifAdapter.SwitchSessionContext();
            }

            this.isReceiverContextConnected = this.cnotifAdapter.DoConnect(ConnectionType.PrivateMailboxServer);
            this.Site.Assert.IsTrue(this.isReceiverContextConnected, "If is connected, the ReturnValue of its response is true(success)");
            this.rpcContextForReceive = this.cnotifAdapter.RPCContext;
            this.cnotifAdapter.Logon();
            this.receiverContextLogonHandle = this.cnotifAdapter.LogonHandle;
        }
        /// <summary>
        /// Verify the response by sending the ROP RopLogon for the private mailbox.
        /// </summary>
        /// <param name="request">The structure of ROP RopLogon request.</param>
        /// <param name="response">The structure of ROP RopLogon response.</param>
        private void VerifyRopLogonForPrivateMailbox(RopLogonRequest request, RopLogonResponse response)
        {
            if (response.ReturnValue == 0)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R13");

                // Verify MS-OXCSTOR requirement: MS-OXCSTOR_R13
                // If calling RopLogon ROP successfully, indicates the logon session is established.
                this.Site.CaptureRequirement(
                    13,
                    @"[In RopLogon ROP] The RopLogon ROP ([MS-OXCROPS] section 2.2.3.1) establishes a logon session between the client and the server.");

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

                // Verify MS-OXCSTOR requirement: MS-OXCSTOR_R106
                // If calling RopLogon ROP successfully, indicates the Essdn is right identifier to log on to mailbox.
                this.Site.CaptureRequirement(
                    106,
                    @"[In RopLogon ROP Request Buffer] Essdn: In the case of a private mailbox logon, this field contains an ASCII string that uniquely identifies a mailbox to log on to.");

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

                // Verify MS-OXCSTOR requirement: MS-OXCSTOR_R123
                this.Site.CaptureRequirementIfAreEqual<byte>(
                    0x01,
                    (byte)(response.ResponseFlags & (byte)0x01),
                    123,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailbox] [Response Flags] The description of flag Reserved: This bit [Reserved] MUST be set.");

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

                // Verify MS-OXCSTOR requirement: MS-OXCSTOR_R122
                // Check if the flag Reserved is 0x01. 
                Site.CaptureRequirementIfAreEqual<byte>(
                    0x01,
                    (byte)(response.ResponseFlags & (byte)0x01),
                    122,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailbox] [Response Flags] The value of flag Reserved: 0x01.");

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

                // Verify MS-OXCSTOR requirement: MS-OXCSTOR_R1062
                this.Site.CaptureRequirementIfAreEqual<byte>(
                    request.LogonFlags,
                    response.LogonFlags,
                    1062,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailbox] LogonFlags: The server returns these flags [Private, Undercover, and Ghostedflags] unchanged from the LogonFlags field of the RopLogon request (section 2.2.1.1.1).");

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

                // Verify MS-OXCSTOR requirement: MS-OXCSTOR_R118
                this.Site.CaptureRequirementIfAreEqual<byte>(
                    request.LogonFlags,
                    response.LogonFlags,
                    118,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailbox] LogonFlags: This field is composed of the Private, Undercover, and Ghosted flags.");

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

                // Verify MS-OXCSTOR requirement: MS-OXCSTOR_R117
                // The RopLogon ROP response structure for public folders is designated
                Site.CaptureRequirement(
                    117,
                    @"[In RopLogon ROP Success Response Buffer for Private Mailbox] The following field values [LogonFlags, FolderIds, Response Flags, ReplId, ReplGuid, Logon Time, GwartTime, StoreState] are included in the RopLogon response only when the Private bit is set in the LogonFlags field of the RopLogon request (section 2.2.1.1.1).");
            }
        }
Пример #12
0
        /// <summary>
        /// Get the FolderId of a created subFolder by opening a folder and creating a subfolder.
        /// </summary>
        /// <param name="logonResponse">Logon response</param>
        /// <returns>The created subfolder's ID</returns>
        protected ulong GetCreatedsubFolderId(ref RopLogonResponse logonResponse)
        {
            // Step 1: Open a folder.
            #region Open folder

            RopOpenFolderRequest openFolderRequest;
            RopOpenFolderResponse openFolderResponse;

            openFolderRequest.RopId = (byte)RopId.RopOpenFolder;

            openFolderRequest.LogonId = TestSuiteBase.LogonId;

            // Set InputHandleIndex to 0x0, which specifies the location in the Server object handle table where the handle for the input Server object is stored.
            openFolderRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0;

            // Set OutputHandleIndex to 0x01, which specifies the location in the Server object handle table where the handle for the output Server object will be stored.
            openFolderRequest.OutputHandleIndex = TestSuiteBase.OutputHandleIndex1;

            // Set FolderId to 5th folder, which is the FolderId of that will be opened.
            openFolderRequest.FolderId = logonResponse.FolderIds[4];

            openFolderRequest.OpenModeFlags = (byte)FolderOpenModeFlags.None;

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Step 1: Begin to send the RopOpenFolder request.");

            // Send the RopOpenFolder request to the server and verify the success response.
            this.responseSOHs = cropsAdapter.ProcessSingleRop(
                openFolderRequest,
                this.inputObjHandle,
                ref this.response,
                ref this.rawData,
                RopResponseType.SuccessResponse);
            openFolderResponse = (RopOpenFolderResponse)response;

            Site.Assert.AreEqual<uint>(
                TestSuiteBase.SuccessReturnValue,
                openFolderResponse.ReturnValue,
                "If ROP succeeds, the ReturnValue of its response is 0 (success)");

            // Get the folder handle, which will be used as input handle in RopCreateFolder.
            uint openedFolderHandle = this.responseSOHs[0][openFolderResponse.OutputHandleIndex];

            #endregion

            // Step 2:Create a subfolder under the opened folder
            #region Create subfolder

            RopCreateFolderRequest createFolderRequest;
            RopCreateFolderResponse createFolderResponse;

            createFolderRequest.RopId = (byte)RopId.RopCreateFolder;
            createFolderRequest.LogonId = TestSuiteBase.LogonId;

            // Set InputHandleIndex to 0x0, which specifies the location in the Server object handle table
            // where the handle for the input Server object is stored.
            createFolderRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0;

            // Set OutputHandleIndex to 0x01, which specifies the location in the Server object handle table
            // where the handle for the output Server object will be stored.
            createFolderRequest.OutputHandleIndex = TestSuiteBase.OutputHandleIndex1;

            createFolderRequest.FolderType = (byte)FolderType.Genericfolder;

            // Set UseUnicodeStrings to 0x0, which specifies the DisplayName and Comment are not specified in Unicode.
            createFolderRequest.UseUnicodeStrings = Convert.ToByte(TestSuiteBase.Zero);

            // Set OpenExisting to 0xFF, which means the folder being created will be opened when it is already existed.
            createFolderRequest.OpenExisting = TestSuiteBase.NonZero;

            // Set Reserved to 0x0, this field is reserved and MUST be set to 0.
            createFolderRequest.Reserved = TestSuiteBase.Reserved;

            // Set DisplayName, which specifies the name of the created folder.
            createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(TestSuiteBase.DisplayNameAndCommentForNonSearchFolder + "\0");

            // Set Comment, which specifies the folder comment that is associated with the created folder.
            createFolderRequest.Comment = Encoding.ASCII.GetBytes(TestSuiteBase.DisplayNameAndCommentForNonSearchFolder + "\0");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Step 2: Begin to send the RopCreateFolder request.");

            // Send the RopCreateFolder request to the server and verify the success response.
            this.responseSOHs = cropsAdapter.ProcessSingleRop(
                createFolderRequest,
                openedFolderHandle,
                ref this.response,
                ref this.rawData,
                RopResponseType.SuccessResponse);
            createFolderResponse = (RopCreateFolderResponse)response;

            Site.Assert.AreEqual<uint>(
                TestSuiteBase.SuccessReturnValue,
                createFolderResponse.ReturnValue,
                "If ROP succeeds, the ReturnValue of its response is 0 (success)");

            #endregion

            // Step 3:Get and return the folder id of created folder.
            ulong objectId = createFolderResponse.FolderId;
            return objectId;
        }
        /// <summary>
        /// Verify RopLogon Failure Response
        /// </summary>
        /// <param name="ropLogonResponse">The response of the RopLogon Request</param>
        private void VerifyRopLogonFailureResponse(RopLogonResponse ropLogonResponse)
        {
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R128");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R128
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(byte),
                ropLogonResponse.RopId.GetType(),
                128,
                @"[In RopLogon ROP Failure Response Buffer] RopId (1 byte): An unsigned integer.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R130
            Site.CaptureRequirementIfAreEqual<byte>(
                (byte)RopId.RopLogon,
                ropLogonResponse.RopId,
                130,
                @"[In RopLogon ROP Failure Response Buffer] RopId (1 byte): For this operation[RopLogon], this field[RopId (1 byte)] is set to 0xFE.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R131
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(byte),
                ropLogonResponse.OutputHandleIndex.GetType(),
                131,
                @"[In RopLogon ROP Failure Response Buffer] OutputHandleIndex (1 byte): An unsigned integer.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R133
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(uint),
                ropLogonResponse.ReturnValue.GetType(),
                133,
                @"[In RopLogon ROP Failure Response Buffer] ReturnValue (4 bytes): An unsigned integer.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R135,ReturnValue:{0}", ropLogonResponse.ReturnValue);

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R135
            bool isVerifyR135 = (ropLogonResponse.ReturnValue != SuccessReturnValue) &&
                                (ropLogonResponse.ReturnValue != WrongServer);

            Site.CaptureRequirementIfIsTrue(
                isVerifyR135,
                135,
                @"[In RopLogon ROP Failure Response Buffer] ReturnValue (4 bytes): For this response[Failure Response], this field is set to a value other than 0x00000000 or 0x00000478.");
        }
        /// <summary>
        /// Verify RopLogon Redirect Response
        /// </summary>
        /// <param name="ropLogonResponse">The response of the RopLogon Request</param>
        private void VerifyRopLogonRedirectResponse(RopLogonResponse ropLogonResponse)
        {
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R112");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R112
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(byte),
                ropLogonResponse.RopId.GetType(),
                112,
                @"[In RopLogon ROP Redirect Response Buffer] RopId (1 byte): An unsigned integer.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R114
            Site.CaptureRequirementIfAreEqual<byte>(
                (byte)RopId.RopLogon,
                ropLogonResponse.RopId,
                114,
                @"[In RopLogon ROP Redirect Response Buffer] RopId (1 byte): For this operation[RopLogon], this field[RopId (1 byte)] is set to 0xFE.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R115
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(byte),
                ropLogonResponse.OutputHandleIndex.GetType(),
                115,
                @"[In RopLogon ROP Redirect Response Buffer] OutputHandleIndex (1 byte): An unsigned integer.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R117
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(uint),
                ropLogonResponse.ReturnValue.GetType(),
                117,
                @"[In RopLogon ROP Redirect Response Buffer] ReturnValue (4 bytes): An unsigned integer.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R119
            Site.CaptureRequirementIfAreEqual<uint>(
                WrongServer,
                ropLogonResponse.ReturnValue,
                119,
                @"[In RopLogon ROP Redirect Response Buffer] ReturnValue (4 bytes): For this response[Redirect Response], this field is set to 0x00000478.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R120
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(byte),
                ropLogonResponse.LogonFlags.GetType(),
                120,
                @"[In RopLogon ROP Redirect Response Buffer] LogonFlags (1 byte): A flags structure.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R123
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(byte),
                ropLogonResponse.ServerNameSize.GetType(),
                123,
                @"[In RopLogon ROP Redirect Response Buffer] ServerNameSize (1 byte): An unsigned integer.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R125,ServerName:{0}", ropLogonResponse.ServerName);

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R125
            bool isVerifyR125 = this.IsNullTerminatedASCIIStr(ropLogonResponse.ServerName);

            Site.CaptureRequirementIfIsTrue(
                isVerifyR125,
                125,
                @"[In RopLogon ROP Redirect Response Buffer] ServerName (variable): A null-terminated ASCII string.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R126
            Site.CaptureRequirementIfAreEqual<int>(
                (int)ropLogonResponse.ServerNameSize,
                ropLogonResponse.ServerName.Length,
                126,
                @"[In RopLogon ROP Redirect Response Buffer] ServerName (variable): The number of characters (including the terminating null character) contained in this field is specified by the ServerNameSize field.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R124
            Site.CaptureRequirementIfAreEqual<int>(
                (int)ropLogonResponse.ServerNameSize,
                ropLogonResponse.ServerName.Length,
                124,
                @"[In RopLogon ROP Redirect Response Buffer] ServerNameSize (1 byte): This value specifies the length of the ServerName field.");
        }
Пример #15
0
        /// <summary>
        /// Compare the 2 RopLogonResponse objects. 
        /// </summary>
        /// <param name="res1">The first RopLogonResponse object</param>
        /// <param name="res2">The second RopLogonResponse object</param>
        /// <returns>True if equal; otherwise, false</returns>
        protected bool CompareLogonResponse(RopLogonResponse res1, RopLogonResponse res2)
        {
            bool logonResponsesAreSame = this.ByteArrayEquals(res1.MailboxGuid, res2.MailboxGuid) && (res1.OutputHandleIndex == res2.OutputHandleIndex) &&
                                this.ByteArrayEquals(res1.PerUserGuid, res2.PerUserGuid) && this.ByteArrayEquals(res1.ReplGuid, res2.ReplGuid) &&
                                this.ByteArrayEquals(res1.ReplId, res2.ReplId) && (res1.ResponseFlags == res2.ResponseFlags) && (res1.ReturnValue == res2.ReturnValue) && (res1.RopId == res2.RopId) &&
                                this.ByteArrayEquals(res1.ServerName, res2.ServerName) && (res1.ServerNameSize == res2.ServerNameSize) && (res1.StoreState == res2.StoreState);
            if (!logonResponsesAreSame)
            {
                return false;
            }

            const int FolderCounts = 13;

            // If the FolderID field is null.
            if ((null != res1.FolderIds) && (null != res2.FolderIds))
            {
                // Compare every FolderId in the FolderId array.
                for (int i = 0; i < FolderCounts; i++)
                {
                    if (res1.FolderIds[i] != res2.FolderIds[i])
                    {
                        return false;
                    }
                }
            }
            else if ((null == res1.FolderIds) & (null == res2.FolderIds))
            {
                return true;
            }
            else
            {
                return false;
            }

            return true;
        }
        /// <summary>
        /// Parse the logon response.
        /// </summary>
        /// <param name="logonRop">An array of bytes that constitute the ROP response payload.</param>
        /// <param name="logonFolderId">The folder ID which client logons on to it.</param>
        /// <param name="logonResponse">The logon response parsed from the ROP response payload.</param>
        /// <returns>The logon handle.</returns>
        private uint ParseLogonResponse(byte[] logonRop, out ulong logonFolderId, out RopLogonResponse logonResponse)
        {
            RPC_HEADER_EXT[] rpcHeaderExts;
            byte[][] rops;
            uint[][] serverHandleObjectsTables;

            RopBufferHelper.ParseResponseBuffer(logonRop, out rpcHeaderExts, out rops, out serverHandleObjectsTables);
            RopLogonResponse response = new RopLogonResponse();
            response.Deserialize(rops[0], 0);
            uint logonHandle = serverHandleObjectsTables[0][response.OutputHandleIndex];

            // The folder Id of inbox folder. 
            logonFolderId = response.FolderIds[4]; 
            logonResponse = response;

            return logonHandle;
        }
        /// <summary>
        /// Create a generic folder under the root folder.
        /// </summary>
        /// <param name="logonResponse">A logon response.</param>
        /// <returns>The object handle of the created folder.</returns>
        private uint CreateGenericFolderUnderRootFolder(ref RopLogonResponse logonResponse)
        {
            // Step 1: Open a folder.
            #region Open folder

            RopOpenFolderRequest openFolderRequest;
            RopOpenFolderResponse openFolderResponse;

            // Construct the RopOpenFolder request.
            openFolderRequest.RopId = (byte)RopId.RopOpenFolder;

            openFolderRequest.LogonId = TestSuiteBase.LogonId;
            openFolderRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0;
            openFolderRequest.OutputHandleIndex = TestSuiteBase.OutputHandleIndex1;
            openFolderRequest.FolderId = logonResponse.FolderIds[4];
            openFolderRequest.OpenModeFlags = (byte)FolderOpenModeFlags.None;

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Step 1: Begin to send the RopOpenFolder request in CreateGenericFolderUnderRootFolder method.");

            // Send the RopOpenFolder request to the server and verify the success response.
            this.responseSOHs = cropsAdapter.ProcessSingleRop(
                openFolderRequest,
                this.inputObjHandle,
                ref this.response,
                ref this.rawData,
                RopResponseType.SuccessResponse);
            openFolderResponse = (RopOpenFolderResponse)response;
            Site.Assert.AreEqual<uint>(
                TestSuiteBase.SuccessReturnValue,
                openFolderResponse.ReturnValue,
                "If ROP succeeds, the ReturnValue of its response is 0 (success)");

            // Get the handle of opened folder, which will be used as input handle in RopCreateFolder.
            uint openedFolderHandle = responseSOHs[0][openFolderResponse.OutputHandleIndex];

            #endregion

            // Step 2: Create a subfolder in opened folder.
            #region Create subfolder

            RopCreateFolderRequest createFolderRequest;
            RopCreateFolderResponse createFolderResponse;

            // Construct the RopCreateFolder request.
            createFolderRequest.RopId = (byte)RopId.RopCreateFolder;
            createFolderRequest.LogonId = TestSuiteBase.LogonId;
            createFolderRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0;
            createFolderRequest.OutputHandleIndex = TestSuiteBase.OutputHandleIndex1;
            createFolderRequest.FolderType = (byte)FolderType.Genericfolder;
            createFolderRequest.UseUnicodeStrings = Convert.ToByte(TestSuiteBase.Zero);
            createFolderRequest.OpenExisting = TestSuiteBase.NonZero;
            createFolderRequest.Reserved = TestSuiteBase.Reserved;
            createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(TestSuiteBase.DisplayNameAndCommentForNonSearchFolder + "\0");
            createFolderRequest.Comment = Encoding.ASCII.GetBytes(TestSuiteBase.DisplayNameAndCommentForNonSearchFolder + "\0");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Step 2: Begin to send the RopCreateFolder request in CreateGenericFolderUnderRootFolder method.");

            // Send the RopCreateFolder request to the server and verify the success response.
            this.responseSOHs = cropsAdapter.ProcessSingleRop(
                createFolderRequest,
                openedFolderHandle,
                ref this.response,
                ref this.rawData,
                RopResponseType.SuccessResponse);
            createFolderResponse = (RopCreateFolderResponse)response;
            Site.Assert.AreEqual<uint>(
                TestSuiteBase.SuccessReturnValue,
                createFolderResponse.ReturnValue,
                "If ROP succeeds, the ReturnValue of its response is 0 (success)");

            #endregion

            // Step 3: Get and return the handle of the created folder.
            uint targetFolderHandle = responseSOHs[0][createFolderResponse.OutputHandleIndex];
            return targetFolderHandle;
        }
        public void MSOXCMAPIHTTP_S01_TC08_ExecuteRequestType()
        {
            this.CheckMapiHttpIsSupported();
            WebHeaderCollection headers = new WebHeaderCollection();

            #region Send a valid Connect request type to establish a Session Context with the server.
            ConnectSuccessResponseBody connectResponse = this.ConnectToServer(out headers);
            Site.Assert.AreEqual<uint>(0, connectResponse.StatusCode, "The server should return a Status 0 in X-ResponseCode header if client connect to server succeeded.");
            #endregion

            #region Send an Execute request that includes Logon ROP to server.
            WebHeaderCollection executeHeaders = AdapterHelper.InitializeHTTPHeader(RequestType.Execute, AdapterHelper.ClientInstance, AdapterHelper.Counter);

            ExecuteRequestBody requestBody = this.InitializeExecuteRequestBody(this.GetRopLogonRequest());
            List<string> metaTags = new List<string>();
            ExecuteSuccessResponseBody executeSuccessResponse = this.SendExecuteRequest(requestBody, ref executeHeaders, out metaTags) as ExecuteSuccessResponseBody;

            #region Capture code
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R1134");

            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R1134
            // According to the Open Specification, the server must respond immediately to a request while the request is being queued and the initial response includes the PROCESSING meta-tag.
            // So MS-OXCMAPIHTTP_R1134 can be verified if the first meta-tag is PROCESSING.
            this.Site.CaptureRequirementIfAreEqual<string>(
                "PROCESSING",
                metaTags[0],
                1134,
                @"[In Response Meta-Tags] PROCESSING: The server has queued the request to be processed.");

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

            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R1136
            // According to the Open Specification, the final response must include the DONE meta-tag. And the response body is parsed according to the description of this requirement.
            // So if the last meta-tag is DONE and code can reach here, MS-OXCMAPIHTTP_R1136 can be verified.
            this.Site.CaptureRequirementIfAreEqual<string>(
                "DONE",
                metaTags[metaTags.Count - 1],
                1136,
                @"[In Response Meta-Tags] DONE: The server has completed the processing of the request and additional response headers and the response body follow the DONE meta-tag.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R1266. The header value of Transfer-Encoding is {0} and Content-Length is {1}.", executeHeaders["Transfer-Encoding"], executeHeaders["Content-Length"]);

            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R1266
            bool isVerifiedR1266 = string.IsNullOrEmpty(executeHeaders["Content-Length"]) && executeHeaders["Transfer-Encoding"].ToLower() == "chunked".ToLower();

            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR1266,
                2227,
                @"[In Responding to All Request Type Requests] If the server is using the ""chunked"" transfer coding, it MUST flush this to the client (being careful to make sure it disables any internal Nagle algorithms, as described in [RFC896], that might attempt to buffer response data).");

            // Add the debug information
            this.Site.Log.Add(
                LogEntryKind.Debug,
                "Verify MS-OXCMAPIHTTP_R1230. The first meta-Tag is {0}, the value of header Transfer-Encoding is {1}.",
                metaTags[0],
                executeHeaders["Transfer-Encoding"]);

            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R1230
            // Because the server will spend some time to process the Logon request. So the entire response is not readily available.
            // The first meta tag is not "DONE" indicates the server is processing the request and not done.
            bool isVerifiedR1230 = metaTags[0] != "DONE" && executeHeaders["Transfer-Encoding"].ToLower() == "chunked".ToLower();

            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR1230,
                1230,
                @"[In Responding to All Request Type Requests] If the entire response is not readily available, the server MUST use the Transfer-Encoding header, as specified in section 2.2.3.2.5, with a value of ""chunked"".");
            
            // R1230 ensures that the "chunked" transfer encoding is used and server can return data to the client while the request is still being processed.
            this.Site.CaptureRequirement(
                1174,
                @"[In Handling a Chunked Response] By using ""chunked"" transfer encoding, the server is able to return data to the client while the request is still being processed.");

            // R1230 ensures that the "chunked" transfer encoding is used and a positive connection between the server and client is established.
            this.Site.CaptureRequirement(
                1173,
                @"[In Handling a Chunked Response] To facilitate a positive connection between the server and client, the server uses the Transfer-Encoding header, as specified in section 2.2.3.2.5, with ""chunked"" transfer encoding, as specified in [RFC2616].");

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

            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R1244
            // The X-ResponseCode header is parsed after the DONE meta-tag, and Execute request type response body is parsed after the header X-ResponseCode. 
            // So if the last meta-tag is DONE and code can reach here, this requirement can be verified.
            this.Site.CaptureRequirementIfAreEqual<string>(
                metaTags[metaTags.Count - 1],
                "DONE",
                1244,
                @"[In Responding to All Request Type Requests] After the server finishes processing the request it finishes with the DONE meta-tag, as specified in section 2.2.7; followed by any additional response headers.");

            #endregion
            #endregion

            #region Send an Execute request to open one folder to check the logon operation succeeds.
            RPC_HEADER_EXT[] rpcHeaderExts;
            byte[][] rops;
            uint[][] serverHandleObjectsTables;

            RopBufferHelper ropBufferHelper = new RopBufferHelper(Site);
            ropBufferHelper.ParseResponseBuffer(executeSuccessResponse.RopBuffer, out rpcHeaderExts, out rops, out serverHandleObjectsTables);
            RopLogonResponse logonResponse = new RopLogonResponse();
            logonResponse.Deserialize(rops[0], 0);
            uint logonHandle = serverHandleObjectsTables[0][logonResponse.OutputHandleIndex];

            RopOpenFolderRequest openFolderRequest = this.OpenFolderRequest(logonResponse.FolderIds[4]);

            ExecuteRequestBody openFolderRequestBody = this.InitializeExecuteRequestBody(openFolderRequest, logonHandle);
            executeHeaders = AdapterHelper.InitializeHTTPHeader(RequestType.Execute, AdapterHelper.ClientInstance, AdapterHelper.Counter);
            executeSuccessResponse = this.SendExecuteRequest(openFolderRequestBody, ref executeHeaders, out metaTags) as ExecuteSuccessResponseBody;

            Site.Assert.AreEqual<uint>((uint)0, executeSuccessResponse.StatusCode, "Execute method should succeed.");
            ropBufferHelper.ParseResponseBuffer(executeSuccessResponse.RopBuffer, out rpcHeaderExts, out rops, out serverHandleObjectsTables);
            RopOpenFolderResponse openFolderResponse = new RopOpenFolderResponse();
            openFolderResponse.Deserialize(rops[0], 0);

            // Add the debug information
            this.Site.Log.Add(
                LogEntryKind.Debug,
                "Verify MS-OXCMAPIHTTP_R226. The error code of Execute request type is {0}, the return value of RopOpenFolder is {1}.",
                executeSuccessResponse.ErrorCode,
                openFolderResponse.ReturnValue);

            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R226
            // If the return value of RopOpenFolder is 0, it indicates that the Logon handle is valid, so the Execute request type can be used to send the remote operation requests.
            bool isVerifiedR226 = executeSuccessResponse.ErrorCode == 0 && openFolderResponse.ReturnValue == 0;

            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR226,
                226,
                @"[In Execute Request Type] The Execute request type is used by the client to send remote operation requests to the server.");
            #endregion

            #region Send a Disconnect request to destroy the Session Context.
            MailboxResponseBodyBase response;
            this.Adapter.Disconnect(out response);
            #endregion
        }
Пример #19
0
        /// <summary>
        /// Create Vast Messages In InBox
        /// </summary>
        /// <param name="logonResponse">the logon response be used to create message</param>
        /// <param name="tableHandle">The tableHanlder of the new folder</param>
        /// <param name="count">The count of created messages</param>
        /// <param name="createMessageRequest">The ROP CreateMessageRequest</param>
        /// <param name="saveChangesMessageRequest">The ROP SaveChangesMessageRequest</param>
        /// <param name="releaseRequest">The ROP ReleaseRequest</param>
        protected void CreateVastMessages(ref RopLogonResponse logonResponse, out uint tableHandle, int count, RopCreateMessageRequest createMessageRequest, RopSaveChangesMessageRequest saveChangesMessageRequest, RopReleaseRequest releaseRequest)
        {
            RopCreateMessageResponse createMessageResponse;
            RopSaveChangesMessageResponse saveChangesMessageResponse;
            #region Preparing the table: CreateFolder

            // Open a folder first
            RopOpenFolderRequest openFolderRequest;
            RopOpenFolderResponse openFolderResponse;

            openFolderRequest.RopId = (byte)RopId.RopOpenFolder;

            openFolderRequest.LogonId = TestSuiteBase.LogonId;
            openFolderRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0;
            openFolderRequest.OutputHandleIndex = TestSuiteBase.OutputHandleIndex1;
            openFolderRequest.FolderId = logonResponse.FolderIds[4];
            openFolderRequest.OpenModeFlags = (byte)FolderOpenModeFlags.None;

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Step 2: Begin to send the RopOpenFolder request.");

            this.responseSOHs = this.cropsAdapter.ProcessSingleRop(
                openFolderRequest,
                this.inputObjHandle,
                ref this.response,
                ref this.rawData,
                RopResponseType.SuccessResponse);
            openFolderResponse = (RopOpenFolderResponse)this.response;
            Site.Assert.AreEqual<uint>(
                TestSuiteBase.SuccessReturnValue,
                openFolderResponse.ReturnValue,
                "if ROP succeeds, the ReturnValue of its response is 0(success)");
            uint openedFolderHandle = this.responseSOHs[0][openFolderResponse.OutputHandleIndex];

            // Create a new subfolder in the opened folder
            // The new subfolder will be used as target folder
            RopCreateFolderRequest createFolderRequest;
            RopCreateFolderResponse createFolderResponse;

            createFolderRequest.RopId = (byte)RopId.RopCreateFolder;
            createFolderRequest.LogonId = TestSuiteBase.LogonId;
            createFolderRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0;
            createFolderRequest.OutputHandleIndex = TestSuiteBase.OutputHandleIndex1;
            createFolderRequest.FolderType = (byte)FolderType.Genericfolder;
            createFolderRequest.UseUnicodeStrings = Convert.ToByte(TestSuiteBase.Zero);
            createFolderRequest.OpenExisting = TestSuiteBase.NonZero;
            createFolderRequest.Reserved = TestSuiteBase.Reserved;
            createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(TestSuiteBase.DisplayNameAndCommentForNonSearchFolder + "\0");
            createFolderRequest.Comment = Encoding.ASCII.GetBytes(TestSuiteBase.DisplayNameAndCommentForNonSearchFolder + "\0");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Step 2: Begin to send the RopCreateFolder request.");

            this.responseSOHs = this.cropsAdapter.ProcessSingleRop(
                createFolderRequest,
                openedFolderHandle,
                ref this.response,
                ref this.rawData,
                RopResponseType.SuccessResponse);
            createFolderResponse = (RopCreateFolderResponse)this.response;
            Site.Assert.AreEqual<uint>(
                TestSuiteBase.SuccessReturnValue,
                createFolderResponse.ReturnValue,
                "if ROP succeeds, the ReturnValue of its response is 0(success)");
            uint targetFolderHandle = this.responseSOHs[0][openFolderResponse.OutputHandleIndex];
            tableHandle = this.GetContentsTableHandle(targetFolderHandle);
            ulong folderId = createFolderResponse.FolderId;

            #endregion

            int waitTime = int.Parse(Common.GetConfigurationPropertyValue("WaitTime", this.Site));
            int maxRetryCount = int.Parse(Common.GetConfigurationPropertyValue("RetryCount", this.Site));
            int retryCount;
            bool needRetry = false;
            uint returnValue = 0;
            int loopcount = 50;
            List<ISerializable> multipleRopRequests = new List<ISerializable>();
            List<IDeserializable> multipleRopResponses = new List<IDeserializable>();
            List<uint> multipleInputObjects = new List<uint>();
            List<uint> multipleOutputObjects = new List<uint>();

            for (int i = 0; i < count; i++)
            {
                // If the RPC report error code reported by the following three ROP methods is 1726 (The remote procedure call failed), 
                // re-do the common steps of this case.
                if (returnValue == 1726)
                {
                    // Step 1: Create a message.
                    #region Create message
                    // Add the debug information
                    Site.Log.Add(LogEntryKind.Debug, "If RPC error code is 1726, re-connect to server.");
                    this.cropsAdapter.RpcConnect(
                        Common.GetConfigurationPropertyValue("SutComputerName", this.Site),
                        ConnectionType.PrivateMailboxServer,
                        Common.GetConfigurationPropertyValue("UserEssdn", this.Site),
                        Common.GetConfigurationPropertyValue("Domain", this.Site),
                        Common.GetConfigurationPropertyValue("AdminUserName", this.Site),
                        Common.GetConfigurationPropertyValue("PassWord", this.Site));
                    logonResponse = this.Logon(LogonType.Mailbox, this.userDN, out this.inputObjHandle);
                    #endregion

                    // Add the debug information
                    Site.Log.Add(LogEntryKind.Debug, "Step 2:Begin to send the RopOpenFolder request.");

                    this.responseSOHs = this.cropsAdapter.ProcessSingleRop(
                        openFolderRequest,
                        this.inputObjHandle,
                        ref this.response,
                        ref this.rawData,
                        RopResponseType.SuccessResponse);
                    openFolderResponse = (RopOpenFolderResponse)this.response;

                    Site.Assert.AreEqual<uint>(
                        TestSuiteBase.SuccessReturnValue,
                        openFolderResponse.ReturnValue,
                        "if ROP succeeds, the ReturnValue of its response is 0(success)");
                    openedFolderHandle = this.responseSOHs[0][openFolderResponse.OutputHandleIndex];

                    // Add the debug information
                    Site.Log.Add(LogEntryKind.Debug, "Step 2:Begin to send the RopCreateFolder request.");

                    this.responseSOHs = this.cropsAdapter.ProcessSingleRop(
                        createFolderRequest,
                        openedFolderHandle,
                        ref this.response,
                        ref this.rawData,
                        RopResponseType.SuccessResponse);
                    createFolderResponse = (RopCreateFolderResponse)this.response;
                    Site.Assert.AreEqual<uint>(
                        TestSuiteBase.SuccessReturnValue,
                        createFolderResponse.ReturnValue,
                        "if ROP succeeds, the ReturnValue of its response is 0(success)");
                    targetFolderHandle = this.responseSOHs[0][openFolderResponse.OutputHandleIndex];
                    tableHandle = this.GetContentsTableHandle(targetFolderHandle);
                    folderId = createFolderResponse.FolderId;
                }

                // Step 1: Create a message.
                #region Create message

                createMessageRequest.FolderId = logonResponse.FolderIds[4];

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Step 1:Begin to send the RopCreateMessage request in CreateVastMessages method.");

                retryCount = maxRetryCount;
                do
                {
                    multipleRopRequests.Clear();
                    multipleRopResponses.Clear();
                    multipleOutputObjects.Clear();
                    multipleInputObjects.Clear();

                    // Send multiple RopCreateMessage to create messages.
                    for (int t = 0; t < loopcount; t++)
                    {
                        createMessageRequest.FolderId = folderId;
                        createMessageRequest.InputHandleIndex = 0;
                        createMessageRequest.OutputHandleIndex = Convert.ToByte(t + 1);
                        multipleRopRequests.Add(createMessageRequest);
                        if (t == 0)
                        {
                            multipleInputObjects.Add(this.inputObjHandle);
                        }
                        else
                        {
                            multipleInputObjects.Add(TestSuiteBase.DefaultFolderHandle);
                        }
                    }

                    // An additional default handle is needed since the output handle index is from 1 to t+1 in the above loop, and the last one is not added in the above loop.
                    multipleInputObjects.Add(TestSuiteBase.DefaultFolderHandle);

                    this.responseSOHs = this.cropsAdapter.ProcessMutipleRops(
                      multipleRopRequests,
                      multipleInputObjects,
                      ref multipleRopResponses,
                      ref this.rawData,
                      RopResponseType.SuccessResponse);

                    for (int t = 0; t < multipleRopResponses.Count; t++)
                    {
                        if (multipleRopResponses[t] is RopBackoffResponse)
                        {
                            needRetry = true;
                            break;
                        }
                    }

                    System.Threading.Thread.Sleep(waitTime);
                    retryCount--;
                }
                while (needRetry && retryCount >= 0);

                Site.Assert.IsTrue(retryCount >= 0, "The case {0} failed since server is busy, reduce your server load and try again.", this.TestContext.TestName);

                // If the error code is 1726, continue this loop.
                if (returnValue == 1726)
                {
                    continue;
                }

                for (int t = 0; t < multipleRopResponses.Count; t++)
                {
                    if (multipleRopResponses[t] is RopCreateMessageResponse)
                    {
                        createMessageResponse = (RopCreateMessageResponse)multipleRopResponses[t];
                        Site.Assert.AreEqual<uint>(
                            TestSuiteBase.SuccessReturnValue,
                            createMessageResponse.ReturnValue,
                            "if ROP succeeds, the ReturnValue of its response is 0(success)");
                        uint targetMessageHandle = this.responseSOHs[0][createMessageResponse.OutputHandleIndex];
                        multipleOutputObjects.Add(targetMessageHandle);
                    }
                }
                #endregion

                // Step 2: Save the created message.
                #region Save message

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Step 2:Begin to send the RopSaveChangesMessage request in CreateVastMessages method.");

                needRetry = false;
                retryCount = maxRetryCount;

                do
                {
                    multipleRopRequests.Clear();
                    multipleRopResponses.Clear();

                    // Send multiple RopSaveChangesMessage requests to save the created messages.
                    for (int t = 0; t < loopcount; t++)
                    {
                        saveChangesMessageRequest.InputHandleIndex = Convert.ToByte(t);
                        multipleRopRequests.Add(saveChangesMessageRequest);
                    }

                    this.responseSOHs = this.cropsAdapter.ProcessMutipleRops(
                     multipleRopRequests,
                     multipleOutputObjects,
                     ref multipleRopResponses,
                     ref this.rawData,
                     RopResponseType.SuccessResponse);

                    for (int t = 0; t < multipleRopResponses.Count; t++)
                    {
                        if (multipleRopResponses[t] is RopSaveChangesMessageResponse)
                        {
                            saveChangesMessageResponse = (RopSaveChangesMessageResponse)multipleRopResponses[t];
                            if (saveChangesMessageResponse.ReturnValue == 0x80040401)
                            {
                                needRetry = true;
                                break;
                            }
                        }
                        else if (this.response is RopBackoffResponse)
                        {
                            needRetry = false;
                            break;
                        }
                    }

                    System.Threading.Thread.Sleep(waitTime);
                    retryCount--;
                }
                while (this.response is RopBackoffResponse && retryCount >= 0);

                Site.Assert.IsTrue(retryCount >= 0, "The case {0} failed since server is busy, reduce your server load and try again.", this.TestContext.TestName);

                // If the error code is 1726, continue this loop.
                if (returnValue == 1726)
                {
                    continue;
                }

                for (int t = 0; t < multipleRopResponses.Count; t++)
                {
                    if (multipleRopResponses[t] is RopSaveChangesMessageResponse)
                    {
                        saveChangesMessageResponse = (RopSaveChangesMessageResponse)multipleRopResponses[t];
                        Site.Assert.AreEqual<uint>(
                            TestSuiteBase.SuccessReturnValue,
                            saveChangesMessageResponse.ReturnValue,
                        "if ROP succeeds, the ReturnValue of its response is 0(success)");
                    }
                }

                #endregion

                // Step 3: Send the RopRelease request to release all resources associated with a Server object.
                #region Release all resources

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Step 2:Begin to send the RopRelease request in CreateVastMessages method.");
                needRetry = false;
                retryCount = maxRetryCount;

                do
                {
                    multipleRopRequests.Clear();
                    multipleRopResponses.Clear();
                    for (int t = 0; t < loopcount; t++)
                    {
                        releaseRequest.InputHandleIndex = Convert.ToByte(t);
                        multipleRopRequests.Add(releaseRequest);
                    }

                    this.responseSOHs = this.cropsAdapter.ProcessMutipleRops(
                     multipleRopRequests,
                     multipleOutputObjects,
                     ref multipleRopResponses,
                     ref this.rawData,
                     RopResponseType.SuccessResponse);

                    if (multipleRopResponses.Count != 0)
                    {
                        for (int t = 0; t < multipleRopResponses.Count; t++)
                        {
                            if (multipleRopResponses[t] is RopBackoffResponse)
                            {
                                needRetry = true;
                                break;
                            }
                        }
                    }

                    System.Threading.Thread.Sleep(waitTime);
                    retryCount--;
                }
                while (needRetry && retryCount >= 0);

                Site.Assert.IsTrue(retryCount >= 0, "The case {0} failed since server is busy, reduce your server load and try again.", this.TestContext.TestName);

                // If the error code is 1726, continue this loop.
                if (returnValue == 1726)
                {
                    continue;
                }
                #endregion
            }

            // If the error code 1726 occurs on the last time of the above "for" loop, re-do the common steps.
            if (returnValue == 1726)
            {
                #region The common steps
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "If RPC error code is 1726, re-connect to server.");
                this.cropsAdapter.RpcConnect(
                    Common.GetConfigurationPropertyValue("SutComputerName", this.Site),
                    ConnectionType.PrivateMailboxServer,
                    Common.GetConfigurationPropertyValue("UserEssdn", this.Site),
                    Common.GetConfigurationPropertyValue("Domain", this.Site),
                    Common.GetConfigurationPropertyValue("AdminUserName", this.Site),
                    Common.GetConfigurationPropertyValue("PassWord", this.Site));
                logonResponse = this.Logon(LogonType.Mailbox, this.userDN, out this.inputObjHandle);
                #endregion
            }
        }
        public void MSOXCMAPIHTTP_S01_TC09_NotificationWaitWithPendingEvent()
        {
            this.CheckMapiHttpIsSupported();
            WebHeaderCollection headers = new WebHeaderCollection();

            #region Send a valid Connect request type to establish a Session Context with the server.
            ConnectSuccessResponseBody connectResponse = this.ConnectToServer(out headers);
            Site.Assert.AreEqual<uint>(0, connectResponse.StatusCode, "The server should return a Status 0 in X-ResponseCode header if client connect to server succeeded.");
            #endregion

            #region Send an Execute request that includes Logon ROP to server.
            WebHeaderCollection executeHeaders = AdapterHelper.InitializeHTTPHeader(RequestType.Execute, AdapterHelper.ClientInstance, AdapterHelper.Counter);

            ExecuteRequestBody requestBody = this.InitializeExecuteRequestBody(this.GetRopLogonRequest());
            List<string> metaTags = new List<string>();

            ExecuteSuccessResponseBody executeSuccessResponse = this.SendExecuteRequest(requestBody, ref executeHeaders, out metaTags) as ExecuteSuccessResponseBody;

            ulong folderId;
            RopLogonResponse logonResponse = new RopLogonResponse();
            uint logonHandle = this.ParseLogonResponse(executeSuccessResponse.RopBuffer, out folderId, out logonResponse);
            Site.Assert.AreEqual<uint>(0, logonResponse.ReturnValue, "Client logon to the server should be succeed and 0 is expected to be returned for the RopLogon. The returned value is {0}.", logonResponse.ReturnValue);

            #endregion

            #region Call RopRegisterNotification to register an event on server.
            executeHeaders = AdapterHelper.InitializeHTTPHeader(RequestType.Execute, AdapterHelper.ClientInstance, AdapterHelper.Counter);
            requestBody = this.InitializeExecuteRequestBody(this.RegisterNotificationRequest(folderId));
            metaTags = new List<string>();

            executeSuccessResponse = this.SendExecuteRequest(requestBody, ref executeHeaders, out metaTags) as ExecuteSuccessResponseBody;
            Site.Assert.AreEqual<uint>((uint)0, executeSuccessResponse.StatusCode, "Execute method should succeed.");
            #endregion

            #region Send a new mail to trigger the event.
            bool isSendSuccess = this.SUTControlAdapter.SendMailItem();
            this.Site.Assert.IsTrue(isSendSuccess, "Send a mail should successfully.");
            this.isReceiveNewMail = isSendSuccess;
            #endregion

            #region Call NotificationWait Request Type to get the pending event.
            NotificationWaitRequestBody notificationWaitRequestBody = this.NotificationWaitRequest();
            WebHeaderCollection notificationWaitWebHeaderCollection = AdapterHelper.InitializeHTTPHeader(RequestType.NotificationWait, AdapterHelper.ClientInstance, AdapterHelper.Counter);
            MailboxResponseBodyBase responseBody;
            Dictionary<string, string> addtionalHeaders = new Dictionary<string, string>();

            uint result = this.Adapter.NotificationWait(notificationWaitRequestBody, ref notificationWaitWebHeaderCollection, out responseBody, out metaTags, out addtionalHeaders);

            NotificationWaitSuccessResponseBody notificationWaitResponseBody = new NotificationWaitSuccessResponseBody();
            notificationWaitResponseBody = (NotificationWaitSuccessResponseBody)responseBody;
            Site.Assert.AreEqual<uint>((uint)0, notificationWaitResponseBody.StatusCode, "NotificationWait method should succeed and 0 is expected to be returned. The returned value is {0}.", notificationWaitResponseBody.StatusCode);

            #region Capture code
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R1371");

            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R1371
            // A pending event is registered in step 3 and triggered in step 4, so MS-OXCMAPIHTTP_R1371 can be verified if the value of EventPending flag is 0x00000001.
            this.Site.CaptureRequirementIfAreEqual<uint>(
                0x00000001,
                notificationWaitResponseBody.EventPending,
                1371,
                @"[In NotificationWait Request Type Success Response Body] [EventPending] The value 0x00000001 indicates that an event is pending.");

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

            // The pending event is registered and triggered in the above steps, so MS-OXCMAPIHTTP_R1258 can be verified if code can reach here.
            this.Site.CaptureRequirement(
                1258,
                @"[In Responding to a NotificationWait Request Type Request] This response [NotificationWait request type response] is not sent until the current server event completes.");

            #endregion
            #endregion

            #region Call Execute Request Type with no ROP in rgbIn to get the notify information.
            executeHeaders = AdapterHelper.InitializeHTTPHeader(RequestType.Execute, AdapterHelper.ClientInstance, AdapterHelper.Counter);
            byte[] ropBuffer = this.RopBufferHelper.BuildRequestBufferWithoutRop();
            metaTags = new List<string>();

            requestBody = new ExecuteRequestBody();
            requestBody.Flags = 0x00000003;
            requestBody.RopBufferSize = (uint)ropBuffer.Length;
            requestBody.RopBuffer = ropBuffer;
            requestBody.MaxRopOut = 0x10008;
            requestBody.AuxiliaryBufferSize = 0;
            requestBody.AuxiliaryBuffer = new byte[] { };

            executeSuccessResponse = this.SendExecuteRequest(requestBody, ref executeHeaders, out metaTags) as ExecuteSuccessResponseBody;
            Site.Assert.AreEqual<uint>((uint)0, executeSuccessResponse.StatusCode, "Execute method should succeed.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R318");
        
            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R318
            // No ROP is included in the request, so if the RopBuffer in the response is not null, it indicates that the event details are included in the Execute request type response buffer.
            this.Site.CaptureRequirementIfIsNotNull(
                executeSuccessResponse.RopBuffer,
                318,
                @"[In NotificationWait Request Type Success Response Body] [EventPending] The server will return the event details in the Execute request type response body.");
            #endregion

            #region Send a Disconnect request to destroy the Session Context.
            MailboxResponseBodyBase response;
            this.Adapter.Disconnect(out response);
            #endregion
        }
Пример #21
0
        /// <summary>
        /// Prepare the ROP request for RopCreateMessage, RopSaveChangesMessage and RopRelease.
        /// </summary>
        /// <param name="logonResponse">The response of RopLogon.</param>
        /// <param name="createMessageRequest">The request of RopCreateMessage.</param>
        /// <param name="saveChangesMessageRequest">The request of RopSaveChangesMessage.</param>
        /// <param name="releaseRequest">The request of RopRelease.</param>
        protected void PrepareRops(RopLogonResponse logonResponse, ref RopCreateMessageRequest createMessageRequest, ref RopSaveChangesMessageRequest saveChangesMessageRequest, ref RopReleaseRequest releaseRequest)
        {
            #region prepare rops for createmessage, savemessage and release
            createMessageRequest.RopId = (byte)RopId.RopCreateMessage;
            createMessageRequest.LogonId = TestSuiteBase.LogonId;
            createMessageRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0;
            createMessageRequest.OutputHandleIndex = TestSuiteBase.OutputHandleIndex1;

            // Set CodePageId to 0x0FFF, which specified the code page of Logon object will be used.
            createMessageRequest.CodePageId = TestSuiteBase.CodePageId;

            createMessageRequest.FolderId = logonResponse.FolderIds[4];
            createMessageRequest.AssociatedFlag = Convert.ToByte(TestSuiteBase.Zero);

            // Save message 
            saveChangesMessageRequest.RopId = (byte)RopId.RopSaveChangesMessage;
            saveChangesMessageRequest.LogonId = TestSuiteBase.LogonId;
            saveChangesMessageRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0;
            saveChangesMessageRequest.ResponseHandleIndex = TestSuiteBase.ResponseHandleIndex1;
            saveChangesMessageRequest.SaveFlags = (byte)SaveFlags.ForceSave;

            releaseRequest.RopId = (byte)RopId.RopRelease;
            releaseRequest.LogonId = TestSuiteBase.LogonId;
            releaseRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0;
            #endregion        
        }
        /// <summary>
        /// This ROP logs on to a mailbox or public folder. 
        /// </summary>
        /// <param name="logonType">This Type specifies ongoing action on the mailbox or public folder.</param>
        /// <param name="userESSDN">A string that identifies the user to log on to the server.</param>
        /// <param name="logonResponse">Response of this ROP.</param>
        /// <returns>Handle of logon object.</returns>
        public uint RopLogon(LogonType logonType, string userESSDN, out RopLogonResponse logonResponse)
        {
            this.rawData = null;
            this.response = null;
            this.responseSOHs = null;

            RopLogonRequest logonRequest;
            uint objHandle1 = 0;

            byte[] rawData1 = null;
            object response1 = null;
            List<List<uint>> responseSOHs1 = null;
            logonRequest.RopId = 0xFE;
            logonRequest.LogonId = 0x0;
            logonRequest.OutputHandleIndex = 0x0;

            logonRequest.StoreState = 0;

            if (LogonType.PublicFolder == logonType)
            {
                // Logon to public folders
                logonRequest.LogonFlags = 0x00;

                // Logon to public folders
                logonRequest.OpenFlags = 0x01000002;
                logonRequest.EssdnSize = 0;
                logonRequest.Essdn = null;
            }
            else
            {
                // Logon to a private mailbox
                logonRequest.LogonFlags = 0x01;

                // USE_PER_MDB_REPLID_MAPPING flag.
                logonRequest.OpenFlags = 0x01000000;
                if (userESSDN + "\0" == this.user1ESSDN)
                {
                    logonRequest.EssdnSize = (ushort)Encoding.ASCII.GetByteCount(this.user1ESSDN);
                    logonRequest.Essdn = Encoding.ASCII.GetBytes(this.user1ESSDN);
                }
                else
                {
                    logonRequest.EssdnSize = (ushort)Encoding.ASCII.GetByteCount(this.user2ESSDN);
                    logonRequest.Essdn = Encoding.ASCII.GetBytes(this.user2ESSDN);
                }
            }

            responseSOHs1 = this.DoRPCCall(logonRequest, objHandle1, ref response1, ref rawData1);
            logonResponse = (RopLogonResponse)response1;
            this.mailboxGUID = logonResponse.MailboxGuid;
            uint handle = responseSOHs1[0][logonResponse.OutputHandleIndex];
            return handle;
        }