public static void RopSeekStreamMethod(SeekStreamCondition condition, out bool isStreamExtended, out CPRPTErrorCode error) { Condition.IsTrue(isInitialized && isStreamOpenedSuccess); if (condition == SeekStreamCondition.MovedBeyondMaxStreamSize) { error = CPRPTErrorCode.StreamSeekError; isStreamExtended = false; ModelHelper.CaptureRequirement( 582, "[In Processing RopSeekStream] If the client requests the seek pointer be moved beyond 2^31 bytes, the server MUST return the StreamSeekError error code in the ReturnValue field of the ROP response buffer."); } else if (condition == SeekStreamCondition.MovedBeyondEndOfStream) { error = CPRPTErrorCode.None; isStreamExtended = true; ModelHelper.CaptureRequirement( 583, @"[In Processing RopSeekStream] If the client requests the seek pointer be moved beyond the end of the stream, the stream is extended, and zeros filled to the new seek location."); } else if (condition == SeekStreamCondition.OriginInvalid) { error = CPRPTErrorCode.StreamInvalidParam; isStreamExtended = false; } else { error = CPRPTErrorCode.None; isStreamExtended = false; } }
/// <summary> /// This method is used to set the seek pointer to a new location, which is relative to the beginning of the stream, the end of the stream, or the location of the current seek pointer. /// </summary> /// <param name="condition">Specifies particular scenario of RopSeekStream.</param> /// <param name="isStreamExtended">Indicates whether a stream object is extended and zero filled to the new seek location.</param> /// <param name="error">Returned error code.</param> public void RopSeekStreamMethod(SeekStreamCondition condition, out bool isStreamExtended, out CPRPTErrorCode error) { error = CPRPTErrorCode.None; isStreamExtended = false; RopGetStreamSizeResponse sizeRes = this.RopGetStreamSize(this.cprptCurrentHandle, true); uint size = sizeRes.StreamSize; // The origin value in RopSeekStreamMethod. byte origin = (byte)Origin.Beginning; // The offset value in RopSeekStreamMethod. long offset = 0; switch (condition) { case SeekStreamCondition.MovedBeyondMaxStreamSize: origin = (byte)Origin.Beginning; // The maximum value of unit is larger than 2^31 bytes. offset = uint.MaxValue; break; case SeekStreamCondition.MovedBeyondEndOfStream: origin = (byte)Origin.End; offset++; break; case SeekStreamCondition.Normal: break; case SeekStreamCondition.OriginInvalid: origin = (byte)Origin.Invalid; break; default: break; } RopSeekStreamResponse seekStreamResponse = this.RopSeekStream(this.cprptCurrentHandle, origin, offset, false); error = (CPRPTErrorCode)seekStreamResponse.ReturnValue; if (error != CPRPTErrorCode.StreamSeekError) { if (condition == SeekStreamCondition.MovedBeyondEndOfStream) { this.RopWriteStream(this.cprptCurrentHandle, WriteData, true); } sizeRes = this.RopGetStreamSize(this.cprptCurrentHandle, true); if (size < sizeRes.StreamSize) { isStreamExtended = true; } } this.VerifyRopSeekStream(seekStreamResponse, condition); }
/// <summary> /// Verify the RopSeekStream operation related requirements. /// </summary> /// <param name="ropSeekStreamResponse">The RopSeekStream response buffer structure.</param> /// <param name="seekStereamCondition">Specifies the particular scenario when performing RopSeekStream.</param> private void VerifyRopSeekStream(RopSeekStreamResponse ropSeekStreamResponse, SeekStreamCondition seekStereamCondition) { // Since the RopSeekStream ROP response was parsed successfully, MS-OXCPRPT_R57902 can be captured directly. Site.CaptureRequirement( 57902, @"[In Processing RopSeekStream] The server responds with a RopSeekStream ROP response buffer."); // CPRPTErrorCode.None indicates the operation is performed successfully. if (ropSeekStreamResponse.ReturnValue.Equals((uint)CPRPTErrorCode.None)) { // If this operation is performed successfully, that means this operation is valid on Stream objects. Site.CaptureRequirement( 33101, @"[In RopSeekStream ROP] This ROP is valid on Stream objects."); // Since the RopSeekStream ROP response is performed successfully, MS-OXCPRPT_R581 can be captured directly. Site.CaptureRequirement( 581, @"[In Processing RopSeekStream] The server modifies the location of the seek point associated with the Stream object according to the ROP request buffer. "); // Since the RopSeekStream ROP response is performed successfully, MS-OXCPRPT_R330 can be captured directly. Site.CaptureRequirement( 330, @"[In RopSeekStream ROP] RopSeekStream sets the seek pointer to a new location."); // The parser has ensured the field satisfied the format, otherwise the response cannot be received. Site.CaptureRequirement( 341, @"[In RopSeekStream ROP Response Buffer] NewPosition (8 bytes): An integer."); } if (seekStereamCondition == SeekStreamCondition.OriginInvalid) { if (Common.IsRequirementEnabled(903, this.Site)) { Site.CaptureRequirementIfAreEqual<uint>( (uint)CPRPTErrorCode.StreamInvalidParam, ropSeekStreamResponse.ReturnValue, 903, @"[In Processing RopSeekStream] Implementation does return error code ""0x80030057"" with name ""StreamInvalidParam"", when The value of the Origin field is invalid.(Microsoft Exchange Server 2007 and above follow this behavior)"); } } if (seekStereamCondition == SeekStreamCondition.MovedBeyondMaxStreamSize) { if (Common.IsRequirementEnabled(894, this.Site)) { Site.CaptureRequirementIfAreEqual<uint>( (uint)CPRPTErrorCode.StreamSeekError, ropSeekStreamResponse.ReturnValue, 894, @"[In Appendix A: Product Behavior] Implementation does return error code ""0x80030019"" with name ""StreamSeekError"", When Tried to seek to offset before the start or beyond the max stream size of 2^31.(Microsoft Exchange Server 2007 and above follow this behavior)"); } } }