A class indicates the Execute request type request body.
Inheritance: MailboxRequestBodyBase
        /// <summary>
        /// Send ROP request through MAPI over HTTP
        /// </summary>
        /// <param name="rgbIn">ROP request buffer.</param>
        /// <param name="pcbOut">The maximum size of the rgbOut buffer to place response in.</param>
        /// <param name="rawData">The response payload bytes.</param>
        /// <returns>0 indicates success, other values indicate failure. </returns>
        public uint Execute(byte[] rgbIn, uint pcbOut, out byte[] rawData)
        {
            uint ret = 0;

            ExecuteRequestBody executeBody = new ExecuteRequestBody();

            // Client requests server to not compress or XOR payload of rgbOut and rgbAuxOut.
            executeBody.Flags         = 0x00000003;
            executeBody.RopBufferSize = (uint)rgbIn.Length;
            executeBody.RopBuffer     = rgbIn;

            // Set the max size of the rgbAuxOut
            executeBody.MaxRopOut           = pcbOut; // 0x10008;
            executeBody.AuxiliaryBufferSize = 0;
            executeBody.AuxiliaryBuffer     = new byte[] { };

            HttpWebResponse response = SendMAPIHttpRequest(
                this.site,
                this.mailStoreUrl,
                this.userName,
                this.domain,
                this.userPassword,
                executeBody,
                "Execute",
                this.cookies);

            string responseCode = response.Headers["X-ResponseCode"];

            byte[] rawBuffer = ReadHttpResponse(response);
            response.GetResponseStream().Close();

            if (int.Parse(responseCode) == 0)
            {
                ChunkedResponse chunkedResponse = ChunkedResponse.ParseChunkedResponse(rawBuffer);

                ExecuteSuccessResponseBody responseSuccess = ExecuteSuccessResponseBody.Parse(chunkedResponse.ResponseBodyRawData);

                rawData = responseSuccess.RopBuffer;
                ret     = responseSuccess.ErrorCode;
            }
            else
            {
                rawData = null;
                this.site.Assert.Fail("MAPIHTTP call failed, the error code returned from server is: {0}", responseCode);
            }

            this.cookies = response.Cookies;
            return(ret);
        }
        /// <summary>
        /// Send ROP request through MAPI over HTTP
        /// </summary>
        /// <param name="rgbIn">ROP request buffer.</param>
        /// <param name="pcbOut">The maximum size of the rgbOut buffer to place response in.</param>
        /// <param name="rawData">The response payload bytes.</param>
        /// <returns>0 indicates success, other values indicate failure. </returns>
        public uint Execute(byte[] rgbIn, uint pcbOut, out byte[] rawData)
        {
            uint ret = 0;

            ExecuteRequestBody executeBody = new ExecuteRequestBody();

            // Client requests server to not compress or XOR payload of rgbOut and rgbAuxOut.
            executeBody.Flags = 0x00000003;
            executeBody.RopBufferSize = (uint)rgbIn.Length;
            executeBody.RopBuffer = rgbIn;

            // Set the max size of the rgbAuxOut
            executeBody.MaxRopOut = pcbOut; // 0x10008;
            executeBody.AuxiliaryBufferSize = 0;
            executeBody.AuxiliaryBuffer = new byte[] { };

            HttpWebResponse response = SendMAPIHttpRequest(
                this.site,
                this.mailStoreUrl,
                this.userName,
                this.domain,
                this.userPassword,
                executeBody,
                "Execute",
                this.cookies);

            string responseCode = response.Headers["X-ResponseCode"];

            byte[] rawBuffer = ReadHttpResponse(response);
            response.GetResponseStream().Close();

            if (int.Parse(responseCode) == 0)
            {
                ChunkedResponse chunkedResponse = ChunkedResponse.ParseChunkedResponse(rawBuffer);

                ExecuteSuccessResponseBody responseSuccess = ExecuteSuccessResponseBody.Parse(chunkedResponse.ResponseBodyRawData);

                rawData = responseSuccess.RopBuffer;
                ret = responseSuccess.ErrorCode;
            }
            else
            {
                rawData = null;
                this.site.Assert.Fail("MAPIHTTP call failed, the error code returned from server is: {0}", responseCode);
            }

            this.cookies = response.Cookies;
            return ret;
        }
        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
        }
        public void MSOXCMAPIHTTP_S01_TC05_SendInvalidRequestBody()
        {
            this.CheckMapiHttpIsSupported();
            WebHeaderCollection headers = new WebHeaderCollection();
            MailboxResponseBodyBase responseBody;

            #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 includes an invalid request body.
            WebHeaderCollection executeHeaders = AdapterHelper.InitializeHTTPHeader(RequestType.Execute, AdapterHelper.ClientInstance, AdapterHelper.Counter);

            byte[] ropBuffer = RopBufferHelper.BuildRequestBuffer(this.GetRopLogonRequest(), 0);

            // Construct an invalid request body that RopBuffer is null and the RopBufferSize is not zero.
            ExecuteRequestBody invalidRequestBody = new ExecuteRequestBody();
            invalidRequestBody.Flags = 0x00000003;
            invalidRequestBody.RopBufferSize = (uint)ropBuffer.Length;
            invalidRequestBody.RopBuffer = new byte[] { };
            invalidRequestBody.MaxRopOut = 0x10008;
            invalidRequestBody.AuxiliaryBufferSize = 0;
            invalidRequestBody.AuxiliaryBuffer = new byte[] { };

            List<string> metaTags = new List<string>();
            responseBody = this.SendExecuteRequest(invalidRequestBody, ref executeHeaders, out metaTags);
           
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R148");
        
            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R148
            this.Site.CaptureRequirementIfAreEqual<uint>(
                12,
                AdapterHelper.GetFinalResponseCode(executeHeaders["X-ResponseCode"]),
                148,
                @"[In X-ResponseCode Header Field] Invalid Request Body (12): The request body is invalid.");
            #endregion

            #region Send a Disconnect request to destroy the Session Context.
            this.Adapter.Disconnect(out responseBody);
            #endregion
        }
        /// <summary>
        /// Send an Execute request type that includes a ROP to server.
        /// </summary>
        /// <param name="requestBody">The Execute request body.</param>
        /// <param name="headers">The HTTP header in request and response.</param>
        /// <param name="metatags">The meta-tag in response.</param>
        /// <returns>Return an Execute successful response body.</returns>
        private MailboxResponseBodyBase SendExecuteRequest(ExecuteRequestBody requestBody, ref WebHeaderCollection headers, out List<string> metatags)
        {
            MailboxResponseBodyBase response;
            this.Adapter.Execute(requestBody, AdapterHelper.SessionContextCookies, ref headers, out response, out metatags);

            return response;
        }
        /// <summary>
        /// Initialize an Execute request Body.
        /// </summary>
        /// <param name="rop">The ROP which is included in RopBuffer field in Execute request Body.</param>
        /// <param name="insideObjectHandle">The server object handle in request.</param>
        /// <returns>The Execute request body.</returns>
        private ExecuteRequestBody InitializeExecuteRequestBody(ISerializable rop, uint insideObjectHandle)
        {
            byte[] ropBuffer = this.RopBufferHelper.BuildRequestBuffer(rop, insideObjectHandle);

            ExecuteRequestBody requestBody = new ExecuteRequestBody();

            // The Flags field is 0x00000003 meaning the server must not compress and not obfuscate the ROP response payload.
            requestBody.Flags = 0x00000003;
            requestBody.RopBufferSize = (uint)ropBuffer.Length;
            requestBody.RopBuffer = ropBuffer;

            // An unsigned integer that specifies the maximum size for the RopBuffer field of the Execute request type success response body.
            requestBody.MaxRopOut = 0x10008;
            requestBody.AuxiliaryBufferSize = 0;
            requestBody.AuxiliaryBuffer = new byte[] { };

            return requestBody;
        }
        /// <summary>
        /// This method is used by the client to send remote operation requests to the server with specified cookies.
        /// </summary>
        /// <param name="requestBody">The request body of the Execute request type.</param>
        /// <param name="cookies">Cookies used to identify the Session Context.</param>
        /// <param name="httpHeaders">The request and response header of the Execute request type.</param>
        /// <param name="responseBody">The response body of the Execute request type.</param>
        /// <param name="metatags">The meta tags in the response body buffer.</param>
        /// <returns>The status code of the Execute request type.</returns>
        public uint Execute(ExecuteRequestBody requestBody, CookieCollection cookies, ref WebHeaderCollection httpHeaders, out MailboxResponseBodyBase responseBody, out List<string> metatags)
        {
            responseBody = null;
            metatags = null;
            byte[] rawBuffer;

            // Send the execute HTTP request and get the response.
            HttpWebResponse response = this.SendMAPIHttpRequest(this.userName, this.password, requestBody, ServerEndpoint.MailboxServerEndpoint, cookies, httpHeaders, out rawBuffer);
            httpHeaders = response.Headers;
            uint responseCode = AdapterHelper.GetFinalResponseCode(response.Headers["X-ResponseCode"]);
             
            // Read the HTTP response buffer and parse the response to correct format.
            CommonResponse commonResponse = CommonResponse.ParseCommonResponse(rawBuffer);
            metatags = commonResponse.MetaTags;
            if (responseCode == 0)
            {
                Site.Assert.IsNotNull(commonResponse.ResponseBodyRawData, "The response body should contains data.");
                uint statusCode = BitConverter.ToUInt32(commonResponse.ResponseBodyRawData, 0);
                if (statusCode == 0)
                {
                    // Execute request type executed successfully when the StatusCode field equals zero.
                    ExecuteSuccessResponseBody responseSuccess = ExecuteSuccessResponseBody.Parse(commonResponse.ResponseBodyRawData);
                    responseBody = responseSuccess;

                    this.VerifyHTTPS(response);
                    this.VerifyExecuteSuccessResponseBody(responseSuccess);
                }

                this.VerifyHTTPHeaders(response.Headers);
                this.VerifyAuthentication(response);
                this.VerifyAutoDiscover(response.StatusCode, ServerEndpoint.MailboxServerEndpoint);
                this.VerifyAdditionalHeaders(commonResponse.AdditionalHeaders);
                this.VerifyRequestTypesForMailboxServerEndpoint(response.Headers, commonResponse);
                this.VerifyResponseMetaTags(commonResponse.MetaTags);
            }

            this.VerifyContentTypeHeader(response.Headers);
            this.VerifyRespondingToAllRequestTypeRequests(response, commonResponse, responseCode);
            response.GetResponseStream().Close();
            AdapterHelper.SessionContextCookies = response.Cookies;
            return responseCode;
        }