/// <summary>
        /// This method is used to ensure that any changes made to a Stream object are persisted in storage for a Folder object. 
        /// </summary>
        /// <param name="openFlag">Indicates the OpenModeFlags when stream is opened.</param>
        /// <param name="isPropertyValueChanged">Indicates whether property value is changed.</param>
        public void RopCommitStreamMethod(OpenModeFlags openFlag, out bool isPropertyValueChanged)
        {
            isPropertyValueChanged = false;
            RopCommitStreamResponse commitStreamResponse = this.RopCommitStream(this.cprptCurrentHandle, false);

            // Message and attachment object can only be changed after saving.
            this.RopSaveChangesAttachment(cprptAttachmentHandle[0], true);
            this.RopSaveChangesMessage(cprptMessageHandle[0], true);

            this.VerifyRopCommitStream(commitStreamResponse);

            if (commitStreamResponse.ReturnValue == (uint)CPRPTErrorCode.None)
            {
                // Check whether it is changed in DB.
                string objKey = string.Empty;
                switch (this.cprptCurrentType)
                {
                    case ServerObjectType.Message:
                        if (this.cprptCurrentObj == ObjectToOperate.FirstObject)
                        {
                            objKey = "Message1";
                        }
                        else
                        {
                            objKey = "Message2";
                        }

                        break;
                    case ServerObjectType.Folder:
                        if (this.cprptCurrentObj == ObjectToOperate.FirstObject)
                        {
                            objKey = "Folder1";
                        }
                        else
                        {
                            objKey = "Folder2";
                        }

                        break;
                    case ServerObjectType.Attachment:
                        if (this.cprptCurrentObj == ObjectToOperate.FirstObject)
                        {
                            objKey = "Attachment1";
                        }
                        else
                        {
                            objKey = "Attachment2";
                        }

                        break;
                    default:
                        break;
                }

                bool isPropertyFound;
                byte[] propertyValueAfterWriteStream = this.Session2ReadStream(objKey, this.tagPropertyValuesToVerification[objKey].PropertyTag, out isPropertyFound);
                isPropertyValueChanged = !Common.CompareByteArray(propertyValueAfterWriteStream, this.tagPropertyValuesToVerification[objKey].Value);
            }
        }
        /// <summary>
        /// Parse the RopOpenStreamRequest structure.
        /// </summary>
        /// <param name="s">An stream containing RopOpenStreamRequest structure.</param>
        public override void Parse(Stream s)
        {
            base.Parse(s);

            this.RopId = (RopIdType)ReadByte();
            this.LogonId = ReadByte();
            this.InputHandleIndex = ReadByte();
            this.OutputHandleIndex = ReadByte();
            this.PropertyTag = new PropertyTag();
            this.PropertyTag.Parse(s);
            this.OpenModeFlags = (OpenModeFlags)ReadByte();
        }
        /// <summary>
        /// This method is used to open a property as a Stream object, enabling the client to perform various streaming operations on the property. 
        /// </summary>
        /// <param name="obj">Specifies which object will be operated.</param>
        /// <param name="openFlag">Specifies OpenModeFlags for [RopOpenStream].</param>
        /// <param name="isPropertyTagExist">Indicates whether request property exist.</param>
        /// <param name="isStreamSizeEqualToStream">Indicates whether StreamSize in response is 
        /// the same with the current number of BYTES in the stream.</param>
        /// <param name="error">If the property tag does not exist for the object and "Create" 
        /// is not specified in OpenModeFlags, NotFound error should be returned.</param>
        public void RopOpenStreamMethod(ObjectToOperate obj, OpenModeFlags openFlag, bool isPropertyTagExist, out bool isStreamSizeEqualToStream, out CPRPTErrorCode error)
        {
            #region Initialize properties and parameter
            error = CPRPTErrorCode.None;
            isStreamSizeEqualToStream = false;
            TaggedPropertyValue propertyTag = this.GetTaggedPropertyTag(obj);

            uint handle = 0;
            switch (this.cprptCurrentType)
            {
                case ServerObjectType.Folder:
                    handle = cprptFolderHandle[(int)obj];

                    // For folder object, open PTagRulesData property
                    propertyTag = this.GetTaggedPropertyTag(ObjectToOperate.ThirdObject);
                    break;
                case ServerObjectType.Message:
                    handle = cprptMessageHandle[(int)obj];
                    break;
                case ServerObjectType.Attachment:
                    handle = cprptAttachmentHandle[(int)obj];
                    break;
                default:
                    Site.Assert.Fail("Invalid server object type {0} for RopOpenStream method.", this.cprptCurrentType);
                    break;
            }

            byte openModeFlags = ConstValues.OpenModeFlagsReadOnly;
            switch (openFlag)
            {
                case OpenModeFlags.ReadOnly:
                    openModeFlags = ConstValues.OpenModeFlagsReadOnly;
                    break;
                case OpenModeFlags.ReadWrite:
                    openModeFlags = ConstValues.OpenModeFlagsReadWrite;
                    break;
                case OpenModeFlags.Create:
                    openModeFlags = ConstValues.OpenModeFlagsCreate;
                    break;
                case OpenModeFlags.BestAccess:
                    openModeFlags = ConstValues.OpenModeFlagsBestAccess;
                    break;
                default:
                    this.Site.Assert.Fail("Invalid OpenModeFlags enum value {0}.", openFlag);
                    break;
            }

            if (isPropertyTagExist)
            {
                #region Get original stream value of current property tag
                string objKey;
                switch (this.cprptCurrentType)
                {
                    case ServerObjectType.Folder:
                        if (obj == ObjectToOperate.FirstObject)
                        {
                            objKey = "Folder1";
                        }
                        else
                        {
                            objKey = "Folder2";
                        }

                        break;
                    case ServerObjectType.Message:
                        if (obj == ObjectToOperate.FirstObject)
                        {
                            objKey = "Message1";
                        }
                        else
                        {
                            objKey = "Message2";
                        }

                        break;
                    case ServerObjectType.Attachment:
                        if (obj == ObjectToOperate.FirstObject)
                        {
                            objKey = "Attachment1";
                        }
                        else
                        {
                            objKey = "Attachment2";
                        }

                        break;
                    default:
                        objKey = string.Empty;
                        break;
                }

                bool isPropertyFound;
                byte[] originalStreamValue = this.Session2ReadStream(objKey, propertyTag.PropertyTag, out isPropertyFound);

                // Store the value for further verification
                TaggedPropertyValue tagPropertyValue = new TaggedPropertyValue
                {
                    PropertyTag = propertyTag.PropertyTag,
                    Value = originalStreamValue
                };

                if (this.tagPropertyValuesToVerification.ContainsKey(objKey))
                {
                    this.tagPropertyValuesToVerification[objKey] = tagPropertyValue;
                }
                else
                {
                    this.tagPropertyValuesToVerification.Add(objKey, tagPropertyValue);
                }
                #endregion
            }
            else
            {
                propertyTag.PropertyTag.PropertyId = NewCreatePropertyID;
                propertyTag.PropertyTag.PropertyType = (ushort)PropertyTypeName.PtypBinary;
            }

            error = CPRPTErrorCode.None;
            isStreamSizeEqualToStream = false;
            #endregion

            RopOpenStreamResponse openStreamResponse;
            uint openHandle = this.RopOpenStream(handle, out openStreamResponse, propertyTag.PropertyTag, openModeFlags, false);

            this.VerifyRopOpenStream(openStreamResponse, this.cprptCurrentType, isPropertyTagExist, openFlag);

            #region Verify error, isStreamSizeEqualToStream and set handle
            if (openFlag != OpenModeFlags.Create && isPropertyTagExist == false && openStreamResponse.ReturnValue == (uint)CPRPTErrorCode.NotFound)
            {
                error = CPRPTErrorCode.NotFound;
            }
            else if (openStreamResponse.ReturnValue == (uint)CPRPTErrorCode.None)
            {
                error = CPRPTErrorCode.None;
                uint streamSize = openStreamResponse.StreamSize;
                switch (obj)
                {
                    case ObjectToOperate.FirstObject:
                        this.cprptCurrentHandle = this.cprptFirstHandle = openHandle;
                        break;
                    case ObjectToOperate.SecondObject:
                        this.cprptSecondHandle = openHandle;
                        break;
                    default:
                        break;
                }

                RopSeekStreamResponse res = this.RopSeekStream(openHandle, (byte)Origin.End, ConstValues.RopSeekStreamOffsetZero, false);
                if (res.ReturnValue == (uint)CPRPTErrorCode.None)
                {
                    if (streamSize == res.NewPosition)
                    {
                        isStreamSizeEqualToStream = true;
                    }
                }
            }
            #endregion
        }
        /// <summary>
        /// This method is used to write the stream of bytes into a Stream object. 
        /// </summary>
        /// <param name="openFlag">Specifies the OpenModeFlags of the stream.</param>
        /// <param name="isExceedMax">Indicates whether the write will exceed the maximum stream size.</param>
        /// <param name="error"> Specifies the ErrorCode when WriteStream failed:STG_E_ACCESSDENIED
        /// 0x80030005 Write access is denied.When stream is opened with ReadOnly flag.</param>
        public void RopWriteStreamMethod(OpenModeFlags openFlag, bool isExceedMax, out CPRPTErrorCode error)
        {
            TaggedPropertyValue[] tagPtyValues = new TaggedPropertyValue[1];
            if (this.cprptCurrentType == ServerObjectType.Folder)
            {
                tagPtyValues[0] = this.GetTaggedPropertyTag(ObjectToOperate.ThirdObject);
            }
            else
            {
                tagPtyValues[0] = this.GetTaggedPropertyTag(this.cprptCurrentObj);
            }

            PropertyTag[] ptyTags;
            ptyTags = new PropertyTag[1];
            ptyTags[0] = tagPtyValues[0].PropertyTag;

            uint objHandle = 0;
            switch (this.cprptCurrentObj)
            {
                case ObjectToOperate.FirstObject:
                    objHandle = this.cprptFirstObjectHandle;
                    break;
                case ObjectToOperate.SecondObject:
                    objHandle = this.cprptSecondObjectHandle;
                    break;
                default:
                    break;
            }

            RopGetPropertiesSpecificResponse getPropertiesSpecificResponse = this.RopGetPropertiesSpecific(objHandle, 0, 0, ptyTags);
            bool canBeRetrieval = false;
            bool isChangInDB = true;
            bool forErrorCode = false;
            if (isExceedMax)
            {
                this.RopSeekStream(this.cprptCurrentHandle, (byte)Origin.Beginning, int.MaxValue, true);
            }

            RopSeekStreamResponse seekStreamResponse1 = this.RopSeekStream(this.cprptCurrentHandle, (byte)Origin.Current, 0, true);
            RopWriteStreamResponse writeStreamResponse = this.RopWriteStream(this.cprptCurrentHandle, WriteData, false);
            RopSeekStreamResponse seekStreamResponse2 = this.RopSeekStream(this.cprptCurrentHandle, (byte)Origin.Current, 0, true);
            bool isWriteSizeElemetRight = false;
            if (seekStreamResponse2.NewPosition - seekStreamResponse1.NewPosition == writeStreamResponse.WrittenSize)
            {
                isWriteSizeElemetRight = true;
            }

            if (writeStreamResponse.ReturnValue.Equals((uint)CPRPTErrorCode.None))
            {
                this.RopSeekStream(this.cprptCurrentHandle, (byte)Origin.Current, (long)(0 - WriteData.Length), true);
                RopReadStreamResponse readStreamResponse = this.RopReadStream(this.cprptCurrentHandle, (ushort)WriteData.Length, 0x70000000, false);
                if (WriteData == Encoding.ASCII.GetString(readStreamResponse.Data))
                {
                    canBeRetrieval = true;
                }

                RopGetPropertiesSpecificResponse getPropertiesSpecificResponse1 = this.RopGetPropertiesSpecific(objHandle, 0, 0, ptyTags);
                if (Common.CompareByteArray(getPropertiesSpecificResponse.RowData.PropertyValues[0].Value, getPropertiesSpecificResponse1.RowData.PropertyValues[0].Value))
                {
                    isChangInDB = false;
                }
            }
            else
            {
                forErrorCode = true;
            }

            this.VerifyRopWriteStream(writeStreamResponse, openFlag, WriteData, canBeRetrieval, isChangInDB, forErrorCode, isWriteSizeElemetRight);

            error = (CPRPTErrorCode)writeStreamResponse.ReturnValue;
        }
Exemplo n.º 5
0
        public static void RopOpenStreamMethod(
            ObjectToOperate objectToOperate,
            OpenModeFlags openFlag,
            bool isPropertyTagExist,
            out bool isStreamSizeEqualToStream,
            out CPRPTErrorCode error)
        {
            Condition.IsTrue(isInitialized);
            Condition.IsTrue(globalObj != ServerObjectType.Logon);

            // openFlag and error is designed for negative test case.
            error = CPRPTErrorCode.None;
            isStreamSizeEqualToStream = false;
            isStreamWriteSuccess = false;
            isStreamOpenedSuccess = true;

            streamOpenFlag = openFlag;
            ModelHelper.CaptureRequirement(
                885,
                @"[In Processing RopOpenStream] The server MUST open the stream in the mode indicated by the OpenModeFlags field as specified by the table in section 2.2.14.1.");

            if (isPropertyTagExist)
            {
                isStreamSizeEqualToStream = true;
            }
            else if (openFlag == OpenModeFlags.ReadOnly && isPropertyTagExist == false)
            {
                error = CPRPTErrorCode.NotFound;
                isStreamOpenedSuccess = false;
            }
        }
Exemplo n.º 6
0
        public static void RopCommitStreamMethod(OpenModeFlags openFlag, out bool isPropertyValueChanged)
        {
            Condition.IsTrue(isInitialized && isStreamOpenedSuccess);
            Condition.IsTrue(globalObj != ServerObjectType.Logon);
            Condition.IsTrue(streamOpenFlag == openFlag);
            if (isStreamWriteSuccess)
            {
                isPropertyValueChanged = true;
                ModelHelper.CaptureRequirement(
                    305,
                    @"[In RopCommitStream ROP] The RopCommitStream ROP ([MS-OXCROPS] section 2.2.9.4) ensures that any changes made to a Stream object are persisted in storage.");

                if (globalObj == ServerObjectType.Folder)
                {
                    ModelHelper.CaptureRequirement(
                       56405,
                       @"[In Processing RopWriteStream] For a Folder object, the value is persisted when the RopCommitStream ROP ([MS-OXCROPS] section 2.2.9.4) is issued on the Stream object or the Stream object is closed with a RopRelease ROP ([MS-OXCROPS] section 2.2.15.3).");
                }
            }
            else
            {
                isPropertyValueChanged = false;
            }

            isCommitStreamSuccess = true;
        }
Exemplo n.º 7
0
        public static void RopWriteStreamMethod(OpenModeFlags openFlag, bool isExceedMax, out CPRPTErrorCode error)
        {
            Condition.IsTrue(isInitialized && isStreamOpenedSuccess);
            Condition.IsTrue(openFlag == streamOpenFlag);
            Condition.IsTrue(globalObj != ServerObjectType.Logon);
            Condition.IfThen(isExceedMax, openFlag == OpenModeFlags.ReadWrite);

            error = CPRPTErrorCode.None;
            isStreamWriteSuccess = true;
            if (streamOpenFlag == OpenModeFlags.ReadWrite)
            {
                ModelHelper.CaptureRequirement(
                       269,
                       @"[In RopOpenStream ROP Request Buffer] OpenModeFlags: ReadWrite: Open the stream for read/write access.");
            }

            if (streamOpenFlag == OpenModeFlags.ReadOnly)
            {
                error = CPRPTErrorCode.STG_E_ACCESSDENIED;
                isStreamWriteSuccess = false;
                ModelHelper.CaptureRequirement(
                    267,
                    @"[In RopOpenStream ROP Request Buffer] OpenModeFlags: ReadOnly: Open the stream for read-only access.");
            }

            if (isExceedMax)
            {
                // For ExchangeServer 2007, StreamSizeError error code returned.
                if (requirementContainer[86706])
                {
                    error = CPRPTErrorCode.StreamSizeError;
                    ModelHelper.CaptureRequirement(
                        86706,
                        @"[In Appendix A: Product Behavior] Implementation does return the StreamSizeError error code. (<12> Section 3.2.5.13: Exchange 2003 and Exchange 2007 return the StreamSizeError error code if they write less than the amount requested.)");
                }

                // For Exchange 2010, toobig error code returned.
                if (requirementContainer[55707])
                {
                    error = CPRPTErrorCode.ecTooBig;
                    ModelHelper.CaptureRequirement(
                        55707,
                        @"[In Processing RopWriteStream] Implementation does  return the TooBig error code if it writes less than the amount requested.(Microsoft Exchange Server 2010 and above follow this behavior)");
                }

                if (requirementContainer[90102])
                {
                    error = CPRPTErrorCode.ecTooBig;
                    ModelHelper.CaptureRequirement(
                        90102,
                        @"[In Processing RopWriteStream] Implementation does return error code ""0x80040305"" with name ""TooBig"", when the write will exceed the maximum stream size.(Microsoft Exchange Server 2007 and above follow this behavior)");
                }

                isStreamWriteSuccess = false;
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Verify the RopWriteStream operation related requirements.
        /// </summary>
        /// <param name="ropWriteStreamResponse">The RopWriteStream response buffer structure.</param>
        /// <param name="openModeFlags">Specifies OpenModeFlags in RopOpenStream.</param>
        /// <param name="writeData">The data to be written to the stream.</param>
        /// <param name="canBeRetrieval">Indicates if the property is immediately available for retrieval by a ROP that uses the same object handle.</param>
        /// <param name="isChangedInDB">Indicates if the value is changed in database or not.</param>
        /// <param name="forErrorCode">Indicates if expecting to fail this operation</param>
        /// <param name="isWriteSizeElementRight">Indicates if the written size is right or not.</param>
        private void VerifyRopWriteStream(RopWriteStreamResponse ropWriteStreamResponse, OpenModeFlags openModeFlags, string writeData, bool canBeRetrieval, bool isChangedInDB, bool forErrorCode, bool isWriteSizeElementRight)
        {
            if (!forErrorCode)
            {
                // Since the RopWriteStream ROP response was parsed successfully, MS-OXCPRPT_R55703 can be captured directly.
                Site.CaptureRequirement(
                55703,
                @"[In Processing RopWriteStream] The server responds with a RopWriteStream ROP response buffer.");

                Site.CaptureRequirementIfIsTrue(
                    canBeRetrieval,
                    56401,
                    @"[In Processing RopWriteStream]After a RopWriteStream ROP request buffer is processed, the new value of the property MUST be immediately available for retrieval by a ROP that uses the same object handle. ");

                if (Common.IsRequirementEnabled(56402, this.Site))
                {
                    Site.CaptureRequirementIfIsFalse(
                        isChangedInDB,
                        56402,
                        @"[In Processing RopWriteStream]However, the new value of the property is not persisted to the database. ");
                }

                Site.CaptureRequirementIfAreEqual<int>(
                    writeData.Length,
                    (int)ropWriteStreamResponse.WrittenSize,
                    297,
                    @"[In RopWriteStream ROP] The RopWriteStream ROP ([MS-OXCROPS] section 2.2.9.3) writes the stream of bytes into a Stream object.");

                Site.CaptureRequirementIfAreEqual<int>(
                   writeData.Length,
                   (int)ropWriteStreamResponse.WrittenSize,
                   303,
                   @"[In RopWriteStream ROP Request Buffer] Data (variable): An array of bytes that constitute the data to be written to the stream.");

                // CPRPTErrorCode.None indicates the operation is performed successfully.
                if (ropWriteStreamResponse.ReturnValue.Equals((uint)CPRPTErrorCode.None))
                {
                    // If this operation is performed successfully, that means this operation is valid on Stream objects.
                    Site.CaptureRequirement(
                        29801,
                        @"[In RopWriteStream ROP] This operation is valid on Stream objects. ");

                    // The parser has ensured the field satisfied the format, otherwise the response cannot be received.
                    Site.CaptureRequirement(
                       304,
                       @"[In RopWriteStream ROP Response Buffer] WrittenSize (2 bytes): An integer.");

                    Site.CaptureRequirementIfIsTrue(
                        isWriteSizeElementRight,
                        30401,
                        @"[In RopWriteStream ROP Response Buffer] WrittenSize: An integer that specifies the number of bytes actually written to the stream.");
                }
            }
            else
            {
                // This mode is to test error code returned from server
                if (openModeFlags == OpenModeFlags.ReadOnly)
                {
                    if (Common.IsRequirementEnabled(901, this.Site))
                    {
                        Site.CaptureRequirementIfAreEqual<uint>(
                            (uint)CPRPTErrorCode.STG_E_ACCESSDENIED,
                            ropWriteStreamResponse.ReturnValue,
                            901,
                            @"[In Processing RopWriteStream] Implementation does return error code ""0x80030005"" with name ""StreamAccessDenied"", when Write access is denied.(Microsoft Exchange Server 2007 and above follow this behavior)");
                    }
                }
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Verify the RopOpenStream operation related requirements.
        /// </summary>
        /// <param name="ropOpenStreamResponse">The RopOpenStream response buffer structure.</param>
        /// <param name="objectType">Indicates which object type the RopOpenStream operation is acting on.</param>
        /// <param name="isPropertyTagExist">A boolean value indicates if the property tag exist for the object or not.</param>
        /// <param name="openFlag">Specifies OpenModeFlags for RopOpenStream.</param>
        private void VerifyRopOpenStream(RopOpenStreamResponse ropOpenStreamResponse, ServerObjectType objectType, bool isPropertyTagExist, OpenModeFlags openFlag)
        {
            if (!isPropertyTagExist && openFlag != OpenModeFlags.Create)
            {
                // Error code NotFound value is 0x8004010F
                bool isR891Satisfied = ropOpenStreamResponse.ReturnValue == 0x8004010F;
                if (isR891Satisfied)
                {
                    // The parser has ensured the field satisfied the format, otherwise the response cannot be received.
                    Site.CaptureRequirement(
                        "MS-OXCDATA",
                        2055,
                        @"[In Additional Error Codes] The numeric value (hex) for error code NotFound is 0x8004010F, %x0F.01.04.80.");
                }

                if (Common.IsRequirementEnabled(891, this.Site))
                {
                    // Verify MS-OXCPRPT requirement: MS-OXCPRPT_R891
                    Site.CaptureRequirementIfIsTrue(
                        isR891Satisfied,
                        891,
                        @"[In Processing RopOpenStream] Implementation does return error ""0x8004010F"" with name ""NotFound"", when The property tag does not exist for the object, and it cannot be created because the Create bit was not specified in OpenModeFlags field.(Microsoft Exchange Server 2007 and above follow this behavior)");
                }
            }
            else
            {
                // Since the RopOpenStream ROP response was parsed successfully, MS-OXCPRPT_R537 can be captured directly.
                Site.CaptureRequirement(
                    537,
                    @"[In Processing RopOpenStream] The server responds with a RopOpenStream ROP response buffer.");

                // If this operation is performed successfully, that means this operation opens a property as a Stream object.
                Site.CaptureRequirement(
                    251,
                    @"[In RopOpenStream ROP] The RopOpenStream ROP ([MS-OXCROPS] section 2.2.9.1) opens a property as a Stream object.");
                if (ropOpenStreamResponse.ReturnValue.Equals((uint)CPRPTErrorCode.None))
                {
                    if (objectType == ServerObjectType.Message)
                    {
                        // If the object type this operation acting on is Message object and this operation is performed successfully, then the following requirement can be captured.
                        Site.CaptureRequirement(
                            25301,
                            @"[In RopOpenStream ROP] This operation [RopOpenStream ROP] is valid on Message objects.");
                    }

                    if (objectType == ServerObjectType.Folder)
                    {
                        // If the object type this operation acting on is Folder object and this operation is performed successfully, then the following requirement can be captured.
                        Site.CaptureRequirement(
                            25302,
                            @"[In RopOpenStream ROP] This operation [RopOpenStream ROP] is valid on Folder objects.");
                    }

                    if (objectType == ServerObjectType.Attachment)
                    {
                        // If the object type this operation acting on is Attachment object and this operation is performed successfully, then the following requirement can be captured.
                        Site.CaptureRequirement(
                            25303,
                            @"[In RopOpenStream ROP] This operation [RopOpenStream ROP] is valid on Attachment objects.");
                    }

                    // If the OpenStream operation succeeds, it means the StreamSize filed has been set by server internally with the current number of BYTES in the stream.
                    // So this requirement can be verified directly. 
                    Site.CaptureRequirement(
                        276,
                        @"[In RopOpenStream ROP Response Buffer]StreamSize (4 bytes).");

                    // If the OpenStream operation succeeds, it means the StreamSize filed has been set by server internally with the current number of BYTES in the stream.
                    // So this requirement can be verified directly. 
                    Site.CaptureRequirement(
                       27601,
                       @"[In RopOpenStream ROP Response Buffer]StreamSize: An integer that specifies the number of bytes in the opened stream. ");
                }
            }
        }