Ejemplo n.º 1
0
        /// <summary>
        /// Open a folder in the specified folder.
        /// If the folder exists, return the folder ID,
        /// If not, create the folder first, and then return the folder ID.
        /// </summary>
        /// <param name="folderName">Folder name value</param>
        /// <param name="folderType">The folder type: generic or search folder</param>
        /// <param name="parentFolderId">The parent folder ID</param>
        /// <param name="openedFolderHandle">folder handle</param>
        /// <returns>Return folder ID</returns>
        protected ulong OpenFolder(string folderName, FolderType folderType, ulong parentFolderId, out uint openedFolderHandle)
        {
            ulong folderId;

            #region Open a folder
            RopOpenFolderRequest openFolderRequest;
            RopOpenFolderResponse openFolderResponse;

            openFolderRequest.RopId = 0x02;
            openFolderRequest.LogonId = 0x0;
            openFolderRequest.InputHandleIndex = 0x0;
            openFolderRequest.OutputHandleIndex = 0x01;
            openFolderRequest.FolderId = parentFolderId;
            openFolderRequest.OpenModeFlags = 0x0; // Opening an existing folder

            this.oxcstorAdapter.DoRopCall(openFolderRequest, this.outObjHandle, ROPCommandType.Others, out this.outputBuffer);

            openFolderResponse = (RopOpenFolderResponse)this.outputBuffer.RopsList[0];
            Site.Assert.AreEqual<uint>(
                0x00000000,
                openFolderResponse.ReturnValue,
                "0 indicates the ROP succeeds, other value indicates error occurs.");
            openedFolderHandle = this.outputBuffer.ServerObjectHandleTable[openFolderRequest.OutputHandleIndex];

            RopHardDeleteMessagesAndSubfoldersRequest deleteSearchFolders = new RopHardDeleteMessagesAndSubfoldersRequest
            {
                RopId = (byte)RopId.RopHardDeleteMessagesAndSubfolders,
                InputHandleIndex = 0,
                LogonId = 0,
                WantDeleteAssociated = 1
            };

            this.oxcstorAdapter.DoRopCall(deleteSearchFolders, openedFolderHandle, ROPCommandType.Others, out this.outputBuffer);
            #endregion

            #region Create a folder
            string folderNameWithNull = folderName + "\0";
            RopCreateFolderRequest createFolderRequest;
            RopCreateFolderResponse createFolderResponse;
            createFolderRequest.RopId = 0x1C;
            createFolderRequest.LogonId = 0x0;
            createFolderRequest.InputHandleIndex = 0x0;
            createFolderRequest.OutputHandleIndex = 0x01;
            createFolderRequest.FolderType = (byte)folderType;
            createFolderRequest.UseUnicodeStrings = 0x0; // FALSE
            createFolderRequest.OpenExisting = 0xFF; // non-zero(TRUE)
            createFolderRequest.Reserved = 0x0; // FALSE
            createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(folderNameWithNull);
            createFolderRequest.Comment = createFolderRequest.DisplayName;
            this.oxcstorAdapter.DoRopCall(createFolderRequest, openedFolderHandle, ROPCommandType.Others, out this.outputBuffer);
            createFolderResponse = (RopCreateFolderResponse)this.outputBuffer.RopsList[0];
            Site.Assert.AreEqual<uint>(
                0x00000000,
                createFolderResponse.ReturnValue,
                "if ROP succeeds, the this.returnValue of its response is 0(success)");
            folderId = createFolderResponse.FolderId;
            #endregion

            return folderId;
        }
        /// <summary>
        /// Delete sub folders and messages
        /// </summary>
        /// <param name="serverId">A 32-bit signed integer represent the Identity of server.</param>
        private void HardDeleteMessageAndSubfolders(int serverId)
        {
            int logonHandleIndex, inboxFolderIndex;

            // Reconnect the server
            bool resultDisconnect = this.oxcropsClient[serverId].Disconnect();
            Site.Assert.IsTrue(resultDisconnect, "Disconnecting server" + serverId + "should be successful.");
            this.Connect(serverId, Microsoft.Protocols.TestSuites.Common.ConnectionType.PrivateMailboxServer);
            this.Logon(serverId, LogonFlags.Private, out logonHandleIndex, out inboxFolderIndex);
            List<uint> soh;
            RopOpenFolderResponse res = this.OpenFolder(serverId, (uint)this.logonHandleOut, this.inboxFolderId, out soh);
            uint rootPublicFolderHandle = soh[res.OutputHandleIndex];

            uint folderHandle = rootPublicFolderHandle;
            RopHardDeleteMessagesAndSubfoldersRequest hardDeleteMessagesAndSubfoldersRequest = new RopHardDeleteMessagesAndSubfoldersRequest
            {
                RopId = 0x92,
                LogonId = 0x00,
                InputHandleIndex = 0x00,
                WantAsynchronous = 0x00,
                WantDeleteAssociated = 0xFF
            };
            this.Process(serverId, hardDeleteMessagesAndSubfoldersRequest, folderHandle);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Overrides TestClassBase's TestCleanup()
        /// </summary>
        protected override void TestCleanup()
        {
            string transport = Common.GetConfigurationPropertyValue("TransportSeq", this.Site);
            if ((!this.transportByMAPIOrNot && (transport.ToLower() != "ncacn_ip_tcp")) 
                || (this.transportByMAPIOrNot && Common.IsRequirementEnabled(300000001, this.Site))
                || ((transport.ToLower() == "ncacn_ip_tcp") && Common.IsRequirementEnabled(1911, this.Site)))
            {
                switch (TestContext.TestName)
                {
                    case "MSOXCSTOR_S01_TC01_TestLogonToPrivateMailBox":
                    case "MSOXCSTOR_S01_TC10_TestOperationsOnReadWriteProperties":
                        PropertyTag propertyPidTagOutOfOfficeState;
                        TaggedPropertyValue pidTagOutOfOfficeState = new TaggedPropertyValue();

                        // According to the Open Specification MS-OXPROPS, PidTagOutOfOfficeState's id is 0x661D
                        const ushort PropertyIdForPidTagOutOfOfficeState = 0x661D;

                        propertyPidTagOutOfOfficeState.PropertyId = PropertyIdForPidTagOutOfOfficeState;

                        // According to [MS-OXPROPS], PidTagOutOfOfficeState's data type is 0x000B
                        propertyPidTagOutOfOfficeState.PropertyType = 0x000B;
                        pidTagOutOfOfficeState.PropertyTag = propertyPidTagOutOfOfficeState;
                        pidTagOutOfOfficeState.Value = new byte[1];
                        pidTagOutOfOfficeState.Value[0] = 0x00;

                        this.TrySetLogonProperty(pidTagOutOfOfficeState);
                        break;
                    case "MSOXCSTOR_S01_TC11_TestRopLogonErrorCodes":
                        if (!this.transportByMAPIOrNot)
                        {
                            this.oxcstorAdapter.DisconnectEx();

                            if (Common.IsRequirementEnabled(193, this.Site)
                                || Common.IsRequirementEnabled(1268001, this.Site))
                            {
                                string userForDisableMailbox = Common.GetConfigurationPropertyValue(ConstValues.UserForDisableMailbox, this.Site);
                                string essdn = this.sutControlAdapter.GetUserDN(this.server1Name, userForDisableMailbox);

                                // Enable the disabled mailbox
                                if (string.IsNullOrEmpty(essdn))
                                {
                                    string status = this.sutControlAdapter.EnableMailbox(userForDisableMailbox);
                                    if (status.Equals("success", StringComparison.OrdinalIgnoreCase))
                                    {
                                        int sleepSeconds = int.Parse(Common.GetConfigurationPropertyValue(ConstValues.SleepSecondsAfterEnableMailbox, this.Site));
                                        Thread.Sleep(sleepSeconds * 1000);
                                    }
                                    else
                                    {
                                        Site.Assert.Fail("The mailbox of {0} is not enabled. Error: {1}.", userForDisableMailbox, status);
                                    }
                                }
                            }
                        }

                        return;
                    case "MSOXCSTOR_S01_TC04_TestRopGetStoreState":
                        RopOpenFolderRequest openFolderRequest;
                        RopOpenFolderResponse openFolderResponse;

                        openFolderRequest.RopId = 0x02;
                        openFolderRequest.LogonId = 0x0;
                        openFolderRequest.InputHandleIndex = 0x0;
                        openFolderRequest.OutputHandleIndex = 0x01;
                        openFolderRequest.FolderId = this.logonResponse.FolderIds[4]; // Inbox folder
                        openFolderRequest.OpenModeFlags = 0x0; // opening an existing folder

                        this.oxcstorAdapter.DoRopCall(openFolderRequest, this.outObjHandle, ROPCommandType.Others, out this.outputBuffer);

                        openFolderResponse = (RopOpenFolderResponse)this.outputBuffer.RopsList[0];
                        Site.Assert.AreEqual<uint>(
                            0x00000000,
                            openFolderResponse.ReturnValue,
                            "0 indicates the ROP succeeds, other value indicates error occurs.");
                        uint openedFolderHandle = this.outputBuffer.ServerObjectHandleTable[openFolderRequest.OutputHandleIndex];

                        RopHardDeleteMessagesAndSubfoldersRequest deleteSubfoldersOfInboxRequest = new RopHardDeleteMessagesAndSubfoldersRequest
                        {
                            RopId = 0x92,
                            InputHandleIndex = 0x00,
                            WantAsynchronous = 0x00,
                            WantDeleteAssociated = 0xff
                        };
                        this.oxcstorAdapter.DoRopCall(deleteSubfoldersOfInboxRequest, openedFolderHandle, ROPCommandType.Others, out this.outputBuffer);

                        RopHardDeleteMessagesAndSubfoldersResponse deleteSubfoldersOfInboxResponse = (RopHardDeleteMessagesAndSubfoldersResponse)this.outputBuffer.RopsList[0];
                        Site.Assert.AreEqual<uint>(
                            0x00000000,
                            deleteSubfoldersOfInboxResponse.ReturnValue,
                            "0 indicates the ROP succeeds, other value indicates error occurs.");
                        break;
                    default:
                        break;
                }

            this.oxcstorAdapter.DisconnectEx();
            }
        }
        public void MSOXCFOLD_S05_TC02_MessageDeletePartialCompleteValidation()
        {
            this.CheckWhetherSupportTransport();
            this.Adapter.DoConnect(ConnectionType.PrivateMailboxServer);
            uint logonHandle = 0;
            uint pidTagMemberRights = 0;

            this.GenericFolderInitialization();

            #region Step 1. Add permission entry for the user configured by "CommonUser" on the inbox and the root folder.
            uint inboxHandle = 0;
            this.OpenFolder(this.LogonHandle, this.DefaultFolderIds[this.inboxIndex], ref inboxHandle);

            // Add folder visible permission for the inbox.
            pidTagMemberRights = (uint)PidTagMemberRightsEnum.FolderVisible | (uint)PidTagMemberRightsEnum.ReadAny;
            this.AddPermission(this.commonUserEssdn, pidTagMemberRights, inboxHandle);

            // Add folder visible permission for the root folder.
            pidTagMemberRights = (uint)PidTagMemberRightsEnum.FolderVisible | (uint)PidTagMemberRightsEnum.ReadAny | (uint)PidTagMemberRightsEnum.EditOwned | (uint)PidTagMemberRightsEnum.Create | (uint)PidTagMemberRightsEnum.CreateSubFolder | (uint)PidTagMemberRightsEnum.DeleteOwned;
            this.AddPermission(this.commonUserEssdn, pidTagMemberRights, this.RootFolderHandle);
            #endregion

            #region Step 2. Create message and subfolder in the root folder.
            ulong messageId = 0;
            uint messageHandle = 0;
            this.CreateSaveMessage(this.RootFolderHandle, this.RootFolderId, ref messageId, ref messageHandle);

            uint subfolderHandle = 0;
            ulong subfolderId = 0;
            this.CreateFolder(this.RootFolderHandle, Constants.Subfolder1, ref subfolderId, ref subfolderHandle);
            #endregion

            #region Step 3. Logon the user configured by "CommonUser".
            this.Adapter.DoDisconnect();
            this.Adapter.DoConnect(this.sutServer, ConnectionType.PrivateMailboxServer, this.commonUserEssdn, this.domain, this.commonUser, this.commonUserPassword);
            this.Logon(LogonFlags.Private, out logonHandle, (uint)OpenFlags.UsePerMDBReplipMapping);
            #endregion

            #region Step 4. The "CommonUser" opens the root folder.
            this.OpenFolder(logonHandle, this.DefaultFolderIds[this.inboxIndex], ref inboxHandle);

            ulong rootFolderId = this.GetSubfolderIDByName(this.DefaultFolderIds[this.inboxIndex], logonHandle, this.RootFolder);
            uint rootFolderHandle = 0;
            RopOpenFolderResponse openFolderResponse = this.OpenFolder(logonHandle, rootFolderId, ref rootFolderHandle);

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R46202
            Site.CaptureRequirementIfAreEqual<uint>(
                Constants.SuccessCode,
                openFolderResponse.ReturnValue,
                46202,
                @"[In Processing a RopOpenFolder ROP Request] If the folder with the specified ID actually exists and the client has sufficient access rights to view the folder, the RopOpenFolder ROP performs successfully.");

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R394.
            // MS-OXCFOLD_R462 was verified, MS-OXCFOLD_R462 can be verified directly.
            Site.CaptureRequirement(
                394,
                @"[In Opening a Folder] The client MUST have sufficient access rights to the folder for this operation to succeed.");

            ulong commonUserMessageId = 0;
            uint commonUserMessageHandle = 0;
            this.CreateSaveMessage(rootFolderHandle, rootFolderId, ref commonUserMessageId, ref commonUserMessageHandle);

            uint commonUserSubfolderHandle = 0;
            ulong commonUserSubfolderId = 0;
            this.CreateFolder(rootFolderHandle, Constants.Subfolder2, ref commonUserSubfolderId, ref commonUserSubfolderHandle);
            #endregion

            #region Step 5. The client calls RopDeleteMessages to delete the message created in step 2.

            ulong[] messageIds = new ulong[] { messageId, commonUserMessageId };
            RopDeleteMessagesRequest deleteMessagesRequest = new RopDeleteMessagesRequest();
            RopDeleteMessagesResponse deleteMessagesResponse = new RopDeleteMessagesResponse();
            deleteMessagesRequest.RopId = (byte)RopId.RopDeleteMessages;
            deleteMessagesRequest.LogonId = Constants.CommonLogonId;
            deleteMessagesRequest.InputHandleIndex = Constants.CommonInputHandleIndex;
            deleteMessagesRequest.WantAsynchronous = 0x00;

            // The server does not generate a non-read receipt for the deleted messages.
            deleteMessagesRequest.NotifyNonRead = 0x00;
            deleteMessagesRequest.MessageIdCount = (ushort)messageIds.Length;
            deleteMessagesRequest.MessageIds = messageIds;
            deleteMessagesResponse = this.Adapter.DeleteMessages(deleteMessagesRequest, rootFolderHandle, ref this.responseHandles);

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R991
            Site.CaptureRequirementIfAreNotEqual<byte>(
                0,
                deleteMessagesResponse.PartialCompletion,
                991,
                @"[In RopDeleteMessages ROP Response Buffer] PartialCompletion (1 byte): If the ROP [RopDeleteMessages] fails for a subset of targets, the value of this field is nonzero (TRUE).");

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1147
            Site.CaptureRequirementIfAreNotEqual<uint>(
                0,
                deleteMessagesResponse.PartialCompletion,
                1147,
                @"[In Processing a RopDeleteMessages ROP Request] If the server fails to delete any messages, it sets the PartialCompletion field of the RopDeleteMessages ROP response buffer to nonzero (TRUE), as specified in section 2.2.1.11.2.");
            #endregion

            #region Step 6. The client calls RopHardDeleteMessages to delete the message created in step 2.
            RopHardDeleteMessagesRequest hardDeleteMessagesRequest = new RopHardDeleteMessagesRequest
            {
                RopId = 0x91,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                WantAsynchronous = 0x00,
                NotifyNonRead = 0x00,
                MessageIdCount = (ushort)messageIds.Length,
                MessageIds = messageIds
            };
            RopHardDeleteMessagesResponse hardDeleteMessagesResponse = this.Adapter.HardDeleteMessages(hardDeleteMessagesRequest, rootFolderHandle, ref this.responseHandles);

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R997.
            Site.CaptureRequirementIfAreNotEqual<byte>(
                0,
                hardDeleteMessagesResponse.PartialCompletion,
                997,
                @"[In RopHardDeleteMessages ROP Response Buffer] If the ROP [RopHardDeleteMessages] fails for a subset of targets, the value of this field is nonzero (TRUE).");

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R115602
            Site.CaptureRequirementIfAreNotEqual<byte>(
                0,
                hardDeleteMessagesResponse.PartialCompletion,
                115602,
                @"[In Processing a RopHardDeleteMessages ROP Request] In the server behavior, if the server fails to delete any messages, it sets the PartialCompletion field of the RopDeleteMessages ROP response buffer to nonzero (TRUE), as specified in section 2.2.1.11.2.");
            #endregion

            #region Step 7. The client calls RopHardDeleteMessagesAndSubfolders to delete the message created in step 2.
            RopHardDeleteMessagesAndSubfoldersRequest hardDeleteMessagesAndSubfoldersRequest = new RopHardDeleteMessagesAndSubfoldersRequest
            {
                RopId = (byte)RopId.RopHardDeleteMessagesAndSubfolders,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                WantAsynchronous = 0x00,
                WantDeleteAssociated = 0xFF
            };
            RopHardDeleteMessagesAndSubfoldersResponse hardDeleteMessagesAndSubfoldersResponse = this.Adapter.HardDeleteMessagesAndSubfolders(hardDeleteMessagesAndSubfoldersRequest, rootFolderHandle, ref this.responseHandles);
            
            if (Common.IsRequirementEnabled(2721, this.Site))
            {
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R2721");

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R2721
                Site.CaptureRequirementIfAreNotEqual<byte>(
                    0,
                    hardDeleteMessagesAndSubfoldersResponse.PartialCompletion,
                    2721,
                    @"[In RopHardDeleteMessagesAndSubfolders ROP Response Buffer] PartialCompletion (1 byte): If the ROP [RopHardDeleteMessagesAndSubfolders] fails for a subset of targets, the value of this field is nonzero (TRUE).");

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

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R113803.
                Site.CaptureRequirement(
                    113803,
                    @"[In Processing a RopHardDeleteMessagesAndSubfolders ROP Request] In the server behavior, if the server fails to delete any message or subfolder, it sets the PartialCompletion field of the RopHardDeleteMessagesAndSubfolders ROP response buffer to nonzero (TRUE), as specified in section 2.2.1.10.2.");
            }
            #endregion

            #region Step 8. The client calls RopMoveCopyMessages to move the message from the root folder to the inbox.
            List<uint> handleList = new List<uint>
            {
                rootFolderHandle, inboxHandle
            };

            RopMoveCopyMessagesRequest moveCopyMessagesRequest = new RopMoveCopyMessagesRequest
            {
                RopId = (byte)RopId.RopMoveCopyMessages,
                LogonId = Constants.CommonLogonId,
                SourceHandleIndex = 0x00,
                DestHandleIndex = 0x01,
                MessageIdCount = (ushort)messageIds.Length,
                MessageIds = messageIds,
                WantAsynchronous = 0x00,
                WantCopy = 0xFF
            };

            // WantCopy is nonzero (TRUE) indicates this is a copy operation.
            RopMoveCopyMessagesResponse moveCopyMessagesResponse = this.Adapter.MoveCopyMessages(moveCopyMessagesRequest, handleList, ref this.responseHandles);

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

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R10163.
                Site.CaptureRequirementIfAreNotEqual<byte>(
                    0,
                    moveCopyMessagesResponse.PartialCompletion,
                    10163,
                    @"[In RopMoveCopyMessages ROP Response Buffer] PartialCompletion (1 byte): If the ROP fails for a subset of targets, the value of this field is nonzero (TRUE).");

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

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R586.
                // MS-OXCFOLD_R10163 is verified, MS-OXCFOLD_R586 can be verified directly.
                Site.CaptureRequirement(
                    586,
                    @"[In Processing a RopMoveCopyMessages ROP Request] If the server fails to move or copy any message, it sets the PartialCompletion field of the RopMoveCopyMessages ROP response buffer to nonzero (TRUE), as specified in section 2.2.1.6.2.");
            }
            #endregion
        }
        /// <summary>
        /// Revert the permissions list.
        /// </summary>
        public override void Reset()
        {
            this.Logon(this.User2);

            uint folderHandle = this.GetFolderObjectHandle(FolderTypeEnum.CommonFolderType);
            
            // Clean up the folder
            RopHardDeleteMessagesAndSubfoldersRequest deleteSubfoldersOfInboxRequest = new RopHardDeleteMessagesAndSubfoldersRequest
            {
                RopId = 0x92,
                InputHandleIndex = 0x00,
                WantAsynchronous = 0x00,
                WantDeleteAssociated = 0xff
            };
            this.DoRopCall(deleteSubfoldersOfInboxRequest, folderHandle, ref this.response, ref this.rawData);

            RopHardDeleteMessagesAndSubfoldersResponse deleteSubfoldersOfInboxResponse = (RopHardDeleteMessagesAndSubfoldersResponse)this.response;
            Site.Assert.AreEqual<uint>(0, deleteSubfoldersOfInboxResponse.ReturnValue, "0 indicates the ROP succeeds, other value indicates error occurs.");

            this.messageIdsCreatedByOther.Clear();
            this.ownedMessageIds.Clear();

            // Restore the permissions for the user configured by the "User1Name"
            for (int i = 0; i < this.originalPermissionsList.Count; i++)
            {
                if (this.originalPermissionsList[i].PidTagMemberName == this.User1)
                {
                    PermissionData[] revertPermissionData = new PermissionData[1];
                    PermissionData permission = new PermissionData
                    {
                        PermissionDataFlags = 0x01
                    };

                    PropertyValue[] propertyValues = new PropertyValue[2];
                    propertyValues[0] = this.CreateEntryIdProperty(this.originalPermissionsList[i].PidTagMemberName);
                    propertyValues[1] = this.CreateRightsProperty(this.originalPermissionsList[i].PidTagMemberRights);
                    permission.PropertyValueCount = (ushort)propertyValues.Length;
                    permission.PropertyValues = propertyValues;

                    revertPermissionData[0] = permission;
                    RequestBufferFlags requestBufferFlags = new RequestBufferFlags
                    {
                        IsReplaceRowsFlagSet = false
                    };

                    // Call RopModifyPermissions to revert the permissions list.
                    this.responseSOHs = this.DoRopCall(
                        this.CreateModifyPermissionsRequestBuffer(revertPermissionData, requestBufferFlags),
                        folderHandle,
                        ref this.response,
                        ref this.rawData);

                    RopModifyPermissionsResponse modifyPermissionsResponse = (RopModifyPermissionsResponse)this.response;
                    Site.Log.Add(LogEntryKind.Comment, "The return value for restore the permissions in Reset(): {0:X}", modifyPermissionsResponse.ReturnValue);
                    break;
                }
                else
                {
                    this.RemovePermission(FolderTypeEnum.CommonFolderType, this.User1, new RequestBufferFlags());
                }
            }

            this.ReleaseObject(folderHandle);
            base.Reset();
        }
        public void MSOXCFOLD_S04_TC08_RopHardDeleteMessagesAndSubfoldersInPublicFolder()
        {
            if (!Common.IsRequirementEnabled(98301002, this.Site))
            {
                this.NeedCleanup = false;
                Site.Assert.Inconclusive("The server does not support the RopHardDeleteMessagesAndSubfolders ROP for public folders.");
            }

            this.CheckWhetherSupportTransport();
            this.Logon();
            this.PublicFolderInitialization();

            #region Step 1. The client calls RopCreateFolder to create [MSOXCFOLDSubfolder1] under the root public folder.

            RopCreateFolderRequest createFolderRequest = new RopCreateFolderRequest();
            RopCreateFolderResponse createFolderResponse = new RopCreateFolderResponse();
            createFolderRequest.RopId = (byte)RopId.RopCreateFolder;
            createFolderRequest.LogonId = Constants.CommonLogonId;
            createFolderRequest.InputHandleIndex = Constants.CommonInputHandleIndex;
            createFolderRequest.OutputHandleIndex = Constants.CommonOutputHandleIndex;
            createFolderRequest.FolderType = (byte)FolderType.Genericfolder;
            createFolderRequest.UseUnicodeStrings = 0x0;
            createFolderRequest.OpenExisting = 0x01;
            createFolderRequest.Reserved = 0x0;
            createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(Constants.Subfolder1);
            createFolderRequest.Comment = Encoding.ASCII.GetBytes(Constants.Subfolder1);

            createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.publicRootFolderHandle, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(0, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully.");
            uint subfolderHandle1 = this.responseHandles[0][createFolderResponse.OutputHandleIndex];
            #endregion

            #region Step 2. The client calls RopCreateFolder to create [MSOXCFOLDSubfolder2] under [MSOXCFOLDSubfolder1].

            createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(Constants.Subfolder2);
            createFolderRequest.Comment = Encoding.ASCII.GetBytes(Constants.Subfolder2);

            createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, subfolderHandle1, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(0, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully.");
            #endregion

            #region Step 3. The client creates a message in [MSOXCFOLDSubfolder1].

            uint messageHandle = 0;
            ulong messageId = 0;
            this.CreateSaveMessage(this.publicRootFolderHandle, this.publicRootFolderId, ref messageId, ref messageHandle);

            #endregion

            #region Step 4. The client calls RopHardDeleteMessagesAndSubfolders applying to [MSOXCFOLDSubfolder1].

            object ropResponse = new object();
            RopHardDeleteMessagesAndSubfoldersRequest hardDeleteMessagesAndSubfoldersRequest = new RopHardDeleteMessagesAndSubfoldersRequest();
            RopHardDeleteMessagesAndSubfoldersResponse hardDeleteMessagesAndSubfoldersResponse;
            hardDeleteMessagesAndSubfoldersRequest.RopId = (byte)RopId.RopHardDeleteMessagesAndSubfolders;
            hardDeleteMessagesAndSubfoldersRequest.LogonId = Constants.CommonLogonId;
            hardDeleteMessagesAndSubfoldersRequest.InputHandleIndex = Constants.CommonInputHandleIndex;
            hardDeleteMessagesAndSubfoldersRequest.WantAsynchronous = 0x00;
            hardDeleteMessagesAndSubfoldersRequest.WantDeleteAssociated = 0xFF;

            this.Adapter.DoRopCall(hardDeleteMessagesAndSubfoldersRequest, subfolderHandle1, ref ropResponse, ref this.responseHandles);
            hardDeleteMessagesAndSubfoldersResponse = (RopHardDeleteMessagesAndSubfoldersResponse)ropResponse;

            Site.Assert.AreEqual<uint>(0, hardDeleteMessagesAndSubfoldersResponse.ReturnValue, "RopHardDeleteMessagesAndSubfolders ROP operation performs successfully.");
            Site.Assert.AreEqual<uint>(0, hardDeleteMessagesAndSubfoldersResponse.PartialCompletion, "If delete all subsets of targets succeeds, PartialCompletion of its response will be 0 (success)");

            #endregion

            #region Step 5. The client calls GetContentsTable to retrieve the contents table of [MSOXCFOLDSubfolder1].

            RopGetContentsTableRequest getContentsTableRequest = new RopGetContentsTableRequest
            {
                RopId = (byte)RopId.RopGetContentsTable,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                OutputHandleIndex = Constants.CommonOutputHandleIndex,
                TableFlags = (byte)FolderTableFlags.None
            };

            RopGetContentsTableResponse getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, subfolderHandle1, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!");

            #endregion

            #region Step 6. The client calls GetHierarchyTable to retrieve the hierarchy table of [MSOXCFOLDSubfolder1].

            RopGetHierarchyTableRequest getHierarchyTableRequest = new RopGetHierarchyTableRequest
            {
                RopId = (byte)RopId.RopGetHierarchyTable,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                OutputHandleIndex = Constants.CommonOutputHandleIndex,
                TableFlags = (byte)FolderTableFlags.None
            };

            RopGetHierarchyTableResponse getHierarchyTableResponse = this.Adapter.GetHierarchyTable(getHierarchyTableRequest, subfolderHandle1, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, getHierarchyTableResponse.ReturnValue, "RopGetHierarchyTable ROP operation performs successfully!");

            // Add the debug information.
            Site.Log.Add(
                LogEntryKind.Debug,
                "Verify MS-OXCFOLD_R98301002: The message count of the target folder after RopEmptyFolder is {0}, the subfolder count of the target folder after RopEmptyFolder is {1}",
                getContentsTableResponse.RowCount,
                getHierarchyTableResponse.RowCount);

            bool isVerifyR98301002 = getHierarchyTableResponse.RowCount == 0 && getContentsTableResponse.RowCount == 0;

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R98301002.
            Site.CaptureRequirementIfIsTrue(
                isVerifyR98301002,
                98301002,
                @"[In Appendix A: Product Behavior] Implementation does support the RopHardDeleteMessagesAndSubfolders ROP ([MS-OXCROPS] section 2.2.4.10) for public folders. (Microsoft Exchange Server 2007 and Microsoft Exchange Server 2010 follow this behavior.)");
            #endregion
        }
        public void MSOXCFOLD_S02_TC03_RopHardDeleteMessagesAndSubfoldersSuccess()
        {
            this.CheckWhetherSupportTransport();
            this.Adapter.DoConnect(ConnectionType.PrivateMailboxServer);
            this.GenericFolderInitialization();

            #region Step 1. Call RopCreateFolder to create [MSOXCFOLDSubfolder1] in the root folder.
            uint subfolderHandle1 = 0;
            ulong subfolderId1 = 0;
            this.CreateFolder(this.RootFolderHandle, Constants.Subfolder1, ref subfolderId1, ref subfolderHandle1);
            #endregion

            #region Step 2. Call RopCreateFolder to create [MS-OXCFOLDSubfolder3] in the [MSOXCFOLDSubfolder1].
            uint subfolderHandle3 = 0;
            ulong subfolderId3 = 0;
            this.CreateFolder(subfolderHandle1, Constants.Subfolder3, ref subfolderId3, ref subfolderHandle3);
            #endregion

            #region Step 3. Create message in [MSOXCFOLDSubfolder1].
            uint messageHandle = 0;
            ulong messageId = 0;
            this.CreateSaveMessage(subfolderHandle1, subfolderId1, ref messageId, ref messageHandle);
            #endregion

            #region Step 4. Call RopHardDeleteMessagesAndSubfolders applying to the [MSOXCFOLDSubfolder1] synchronously.
            RopHardDeleteMessagesAndSubfoldersRequest hardDeleteMessagesAndSubfoldersRequest = new RopHardDeleteMessagesAndSubfoldersRequest
            {
                RopId = (byte)RopId.RopHardDeleteMessagesAndSubfolders,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                WantAsynchronous = 0x00,
                WantDeleteAssociated = 0xFF
            };
            RopHardDeleteMessagesAndSubfoldersResponse hardDeleteMessagesAndSubfoldersResponse = this.Adapter.HardDeleteMessagesAndSubfolders(hardDeleteMessagesAndSubfoldersRequest, subfolderHandle1, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(0, hardDeleteMessagesAndSubfoldersResponse.ReturnValue, "If ROP succeeds, ReturnValue of its response will be 0 (success)");

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R261.
            Site.CaptureRequirementIfAreEqual<byte>(
                0,
                hardDeleteMessagesAndSubfoldersResponse.PartialCompletion,
                261,
                @"[In RopHardDeleteMessagesAndSubfolders ROP Response Buffer] PartialCompletion (1 byte): Otherwise [if the ROP successes for a subset of targets], the value [of PartialCompletion field] is zero (FALSE).");

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1135
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(RopHardDeleteMessagesAndSubfoldersResponse),
                hardDeleteMessagesAndSubfoldersResponse.GetType(),
                1135,
                @"[In Processing a RopHardDeleteMessagesAndSubfolders ROP Request] The server responds with a RopHardDeleteMessagesAndSubfolders ROP response buffer.");

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R98302.
            Site.CaptureRequirementIfAreEqual<uint>(
                Constants.SuccessCode,
                hardDeleteMessagesAndSubfoldersResponse.ReturnValue,
                98302,
                @"[In RopHardDeleteMessagesAndSubfolders ROP] This ROP [RopHardDeleteMessagesAndSubfolders] applies to [both public folders and] private mailboxes.");

            #region Verify MS-OXCFOLD_R251,MS-OXCFOLD_113801 and MS-OXCFOLD_R43202

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R251.
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(RopHardDeleteMessagesAndSubfoldersResponse),
                hardDeleteMessagesAndSubfoldersResponse.GetType(),
                251,
                @"[In RopHardDeleteMessagesAndSubfolders ROP Request Buffer] WantAsynchronous (1 byte): [A Boolean value that is] zero (FALSE) if the ROP is to be processed synchronously.");
 
            bool isTargetFolderSoftDeleted = this.IsFolderSoftDeleted(subfolderId1);
            bool isTargetFolderHardDeleted = this.IsFolderHardDeleted(subfolderId1);
            bool isTargetFolderExist = !isTargetFolderSoftDeleted && !isTargetFolderHardDeleted;

            // Add the debug information.
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R113801: The validation result of whether the target folder was removed is {0}.", isTargetFolderExist);

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R113801.
            // MS-OXCFOLD_R434 is verified, if the target folder of RopHardDeleteMessagesAndSubfolders is exist, MS-OXCFOLD_R113801 can be verified.
            Site.CaptureRequirementIfIsTrue(
                isTargetFolderExist,
                113801,
                @"[In Processing a RopHardDeleteMessagesAndSubfolders ROP Request] In the server behavior, the server hard deletes the folder's messages and subfolders but does not delete the folder itself.");

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R43202.
            // MS-OXCFOLD_R113801 is verified, MS-OXCFOLD_R113801 can be verified directly.
            Site.CaptureRequirement(
                43202,
                @"[In Deleting the Contents of a Folder] To delete all messages and subfolders from a folder without deleting the folder itself, the client sends [either a RopEmptyFolder ROP request ([MS-OXCROPS] section 2.2.4.9)] or a RopHardDeleteMessagesAndSubfolders ROP request ([MS-OXCROPS] section 2.2.4.10).");
            #endregion
            #endregion

            #region Step 5. Create [MSOXCFOLDSubfolder3] in [MSOXCFOLDSubfolder1].
            this.CreateFolder(subfolderHandle1, Constants.Subfolder3, ref subfolderId3, ref subfolderHandle3);
            #endregion

            #region Step 6. Create a FAI message in [MSOXCFOLDSubfolder1].
            uint faiMessageHandle = 0;
            ulong faiMessageId = 0;
            this.CreateSaveMessage(subfolderHandle1, subfolderId1, 0x01, ref faiMessageId, ref faiMessageHandle);
            #endregion

            #region Step 7. Create a normal message in [MSOXCFOLDSubfolder1].
            this.CreateSaveMessage(subfolderHandle1, subfolderId1, ref messageId, ref messageHandle);
            #endregion

            #region Step 8. Call RopHardDeleteMessagesAndSubfolders applying to the [MSOXCFOLDSubfolder1] synchronously, the FAI message are not to be included in the deletion.
            hardDeleteMessagesAndSubfoldersRequest = new RopHardDeleteMessagesAndSubfoldersRequest
            {
                RopId = (byte)RopId.RopHardDeleteMessagesAndSubfolders,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                WantAsynchronous = 0x00,
                WantDeleteAssociated = 0x00
            };

            // The field WantDeleteAssociated is zero (FALSE) indicates the FAI messages are not to be included in the deletion.
            hardDeleteMessagesAndSubfoldersResponse = this.Adapter.HardDeleteMessagesAndSubfolders(hardDeleteMessagesAndSubfoldersRequest, subfolderHandle1, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(
                0,
                hardDeleteMessagesAndSubfoldersResponse.ReturnValue,
                "If ROP succeeds, ReturnValue of its response will be 0 (success)");
            Site.Assert.AreEqual<byte>(
                0,
                hardDeleteMessagesAndSubfoldersResponse.PartialCompletion,
                "If delete succeeds, PartialCompletion of its response will be 0 (success)");

            bool isNormalMessageRemovedWithWantDeleteAssociated = this.IsMessageDeleted(messageId, subfolderId1);
            bool isSubfolderRemovedWithWantDeleteAssociated = this.IsFolderHardDeleted(subfolderId3);

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

            bool faiMessageDeleted = this.IsMessageDeleted(faiMessageId, subfolderId1);

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R257
            // If the FAI message is not deleted, MS-OXCFOLD_R257 can be verified.
            Site.CaptureRequirementIfIsFalse(
                faiMessageDeleted,
                257,
                @"[In RopHardDeleteMessagesAndSubfolders ROP Request Buffer] WantDeleteAssociated (1 byte): The value is zero (FALSE) otherwise [if the FAI messages are not to be included in the deletion].");
            #endregion

            #region Step 9. Create [MSOXCFOLDSubfolder3] in [MSOXCFOLDSubfolder1].
            this.CreateFolder(subfolderHandle1, Constants.Subfolder3, ref subfolderId3, ref subfolderHandle3);
            #endregion

            #region Step 10. Create a normal message in [MSOXCFOLDSubfolder1].
            this.CreateSaveMessage(subfolderHandle1, subfolderId1, ref messageId, ref messageHandle);
            #endregion

            #region Step 11. Call RopHardDeleteMessagesAndSubfolders applying to the [MSOXCFOLDSubfolder1] synchronously, the FAI message to be included in the deletion.
            hardDeleteMessagesAndSubfoldersRequest = new RopHardDeleteMessagesAndSubfoldersRequest
            {
                RopId = (byte)RopId.RopHardDeleteMessagesAndSubfolders,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                WantAsynchronous = 0x00,
                WantDeleteAssociated = 0xFF
            };
            hardDeleteMessagesAndSubfoldersResponse = this.Adapter.HardDeleteMessagesAndSubfolders(hardDeleteMessagesAndSubfoldersRequest, subfolderHandle1, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(0, hardDeleteMessagesAndSubfoldersResponse.ReturnValue, "If ROP succeeds, ReturnValue of its response will be 0 (success)");
            Site.Assert.AreEqual<uint>(0, hardDeleteMessagesAndSubfoldersResponse.PartialCompletion, "If delete all subsets of targets succeeds, PartialCompletion of its response will be 0 (success)");

            #region Verify MS-OXCFOLD_R256,MS-OXCFOLD_R113804 and MS-OXCFOLD_R113805.

            // If the FAI message is hard deleted, MS-OXCFOLD_R256 can be verified.
            bool isVerifiedR256 = this.IsMessageDeleted(faiMessageId, subfolderId1);

            // Add the debug information.
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R256: The validation result of whether the FAI message was deleted when the WantDeleteAssociated was set is {0}", isVerifiedR256);

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R256
            Site.CaptureRequirementIfIsTrue(
                isVerifiedR256,
                256,
                @"[In RopHardDeleteMessagesAndSubfolders ROP Request Buffer] WantDeleteAssociated (1 byte): A Boolean value that is nonzero (TRUE) if the FAI messages are to be included in the deletion.");

            bool isNormalMessageRemovedWithoutWantDeleteAssociated = this.IsMessageDeleted(messageId, subfolderId1);

            // Add the debug information.
            Site.Log.Add(
                LogEntryKind.Debug,
                @"Verify MS-OXCFOLD_R113804:
                The validation result of whether the normal message was deleted when the WantDeleteAssociated was not set is {0};
                The validation result of whether the normal message was deleted when the WantDeleteAssociated was set is {1}",
                isNormalMessageRemovedWithWantDeleteAssociated,
                isNormalMessageRemovedWithoutWantDeleteAssociated);

            // MS-OXCFOLD_R256 is verified and the FAI message is hard deleted, if normal message is hard deleted, MS-OXCFOLD_R113804 can be captured.
            Site.CaptureRequirementIfIsTrue(
                isNormalMessageRemovedWithWantDeleteAssociated && isNormalMessageRemovedWithoutWantDeleteAssociated,
                113804,
                "[In Processing a RopHardDeleteMessagesAndSubfolders ROP Request] In the server behavior, if the WantDeleteAssociated field of the RopHardDeleteMessagesAndSubfolders ROP request buffer is set to nonzero (TRUE), as specified in section 2.2.1.10.1, then the server removes all FAI messages in addition to the normal messages.");
  
            bool isSubfolderRemovedWithoutWantDeleteAssociated = this.IsFolderHardDeleted(subfolderId3);

            if (Common.IsRequirementEnabled(46201002, this.Site))
            {
                bool isVerifiedR113805 = isSubfolderRemovedWithoutWantDeleteAssociated && isSubfolderRemovedWithWantDeleteAssociated;

                // Add the debug information.
                Site.Log.Add(
                    LogEntryKind.Debug,
                    @"Verify MS-OXCFOLD_R113805:
                    The validation result of whether the subfolder was removed when the WantDeleteAssociated was not set is {0}
                    The validation result of whether the subfolder was removed when the WantDeleteAssociated was set is {1}",
                    isSubfolderRemovedWithoutWantDeleteAssociated,
                    isSubfolderRemovedWithWantDeleteAssociated);

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R113805
                Site.CaptureRequirementIfIsTrue(
                    isVerifiedR113805,
                    113805,
                    @"[In Processing a RopHardDeleteMessagesAndSubfolders ROP Request] In the server behavior, the server removes all subfolders regardless of the value of the WantDeleteAssociated field.");
            }
            #endregion
            #endregion
        }
        public void MSOXCFOLD_S02_TC10_RopHardDeleteMessagesAndSubfoldersFailure()
        {
            this.CheckWhetherSupportTransport();
            this.Adapter.DoConnect(ConnectionType.PrivateMailboxServer);
            this.GenericFolderInitialization();

            #region Step 1.	Call RopHardDeleteMessagesAndSubfolders using a logon handle rather than a folder handle.
            RopHardDeleteMessagesAndSubfoldersRequest hardDeleteMessagesAndSubfoldersRequest = new RopHardDeleteMessagesAndSubfoldersRequest
            {
                RopId = (byte)RopId.RopHardDeleteMessagesAndSubfolders,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                WantAsynchronous = 0x00,
                WantDeleteAssociated = 0xFF
            };

            // Using logon object handle to hard-delete messages and subfolders is purposed to get error code ecNotSupported [0x80040102].  
            RopHardDeleteMessagesAndSubfoldersResponse hardDeleteMessagesAndSubfoldersResponse = this.Adapter.HardDeleteMessagesAndSubfolders(hardDeleteMessagesAndSubfoldersRequest, this.LogonHandle, ref this.responseHandles);

            #region Verify MS-OXCFOLD_R630 and MS-OXCFOLD_R629.

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

            Site.CaptureRequirementIfAreEqual<uint>(
                0x80040102,
                hardDeleteMessagesAndSubfoldersResponse.ReturnValue,
                630,
                "[In Processing a RopHardDeleteMessagesAndSubfolders ROP Request] When the error code is ecNotSupported, it indicates that the object that this ROP [RopHardDeleteMessagesAndSubfolders ROP] was called on is not a Folder object.");

            // The MS-OXCFOLD_R630 captured error code [ecNotSupported] using a logon object handle, capture this requirement directly.
            Site.CaptureRequirement(
                629,
                @"[In Processing a RopHardDeleteMessagesAndSubfolders ROP Request]The value of error code ecNotSupported is 0x80040102.");

            #endregion
            #endregion
        }
        /// <summary>
        /// Hard deletes all messages and subfolders from a folder without deleting the folder itself.
        /// </summary>
        /// <param name="ropHardDeleteMessagesAndSubfoldersRequest">RopHardDeleteMessagesAndSubfoldersRequest object.</param>
        /// <param name="insideObjHandle">Server object handle in RopHardDeleteMessagesAndSubfolders.</param>
        /// <param name="responseSOHTable">Server objects handles in RopHardDeleteMessagesAndSubfoldersResponse.</param>
        /// <returns>RopHardDeleteMessagesAndSubfoldersResponse object.</returns>
        public RopHardDeleteMessagesAndSubfoldersResponse HardDeleteMessagesAndSubfolders(
            RopHardDeleteMessagesAndSubfoldersRequest ropHardDeleteMessagesAndSubfoldersRequest,
            uint insideObjHandle,
            ref List<List<uint>> responseSOHTable)
        {
            object temp = new object();
            this.ExcuteRopCall((ISerializable)ropHardDeleteMessagesAndSubfoldersRequest, insideObjHandle, ref temp, ref responseSOHTable, ref this.rawData);
            RopHardDeleteMessagesAndSubfoldersResponse ropHardDeleteMessagesAndSubfoldersResponse = (RopHardDeleteMessagesAndSubfoldersResponse)temp;

            #region Capture Code
            // The ReturnValue equal to 0x00000000 indicate ROP operation success
            if (0x00000000 == ropHardDeleteMessagesAndSubfoldersResponse.ReturnValue)
            {
                this.VerifyRopHardDeleteMessagesAndSubfolders(ropHardDeleteMessagesAndSubfoldersResponse);
            }
            #endregion

            return ropHardDeleteMessagesAndSubfoldersResponse;
        }
        /// <summary>
        /// Clean the Inbox folder in private mailbox.
        /// </summary>
        /// <param name="folderID">The specified folder's FID.</param>
        private void CleanFolder(ulong folderID)
        {
            RopOpenFolderRequest openFolderRequest = new RopOpenFolderRequest
            {
                RopId = (byte)RopId.RopOpenFolder,
                LogonId = CommonLogonId,
                InputHandleIndex = CommonInputHandleIndex,
                OutputHandleIndex = CommonOutputHandleIndex,
                FolderId = folderID,
                OpenModeFlags = 0x00
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openFolderRequest, this.insideObjHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            uint folderHandle = this.ResponseSOHs[0][((RopOpenFolderResponse)this.response).OutputHandleIndex];

            RopHardDeleteMessagesAndSubfoldersRequest hardDeleteMessagesAndSubfoldersRequest = new RopHardDeleteMessagesAndSubfoldersRequest()
            {
                RopId = (byte)RopId.RopHardDeleteMessagesAndSubfolders,
                LogonId = CommonLogonId,
                InputHandleIndex = CommonInputHandleIndex,
                WantAsynchronous = 0x00, // Synchronously
                WantDeleteAssociated = 0xFF // TRUE: delete all messages and subfolders
            };
            object temp = new object();
            this.MSOXCMSGAdapter.DoRopCall(hardDeleteMessagesAndSubfoldersRequest, folderHandle, ref temp, ref this.rawData, GetPropertiesFlags.None);
        }