/// <summary> /// Get LongTermIdFromId /// </summary> /// <param name="folderID">The folder ID</param> /// <returns>Return LongTermId</returns> protected LongTermId GetLongTermIdFromId(ulong folderID) { this.longTermIdFromIdRequest.ObjectId = folderID; this.oxcstorAdapter.DoRopCall(this.longTermIdFromIdRequest, this.outObjHandle, ROPCommandType.RopLongTermIdFromId, out this.outputBuffer); this.longTermIdFromIdResponse = (RopLongTermIdFromIdResponse)this.outputBuffer.RopsList[0]; Site.Assert.AreEqual<uint>( 0, this.longTermIdFromIdResponse.ReturnValue, "If ROP succeeds, the this.returnValue of its response is 0 (success)"); return this.longTermIdFromIdResponse.LongTermId; }
/// <summary> /// Get longTermId bytes. /// </summary> /// <param name="serverId">The server ID</param> /// <param name="objectId">The id need to be converted</param> /// <returns>The converted longTermId from id.</returns> private byte[] GetLongTermIdByte(int serverId, ulong objectId) { RopLongTermIdFromIdRequest ropLongTermIdFromIdRequest = new RopLongTermIdFromIdRequest(); RopLongTermIdFromIdResponse ropLongTermIdFromIdResponse = new RopLongTermIdFromIdResponse(); // Construct the RopLongTermIdFromId request. ropLongTermIdFromIdRequest.RopId = 0x43; ropLongTermIdFromIdRequest.LogonId = 0x00; ropLongTermIdFromIdRequest.InputHandleIndex = 0x00; ropLongTermIdFromIdRequest.ObjectId = objectId; // Send the RopLongTermIdFromId request to convert the short-term ID into a long-term ID. ropLongTermIdFromIdResponse = (RopLongTermIdFromIdResponse)this.Process(serverId, ropLongTermIdFromIdRequest, this.logonHandleOut); byte[] longTermByte = new byte[ropLongTermIdFromIdResponse.LongTermId.DatabaseGuid.Length + ropLongTermIdFromIdResponse.LongTermId.GlobalCounter.Length]; Array.Copy(ropLongTermIdFromIdResponse.LongTermId.DatabaseGuid, 0, longTermByte, 0, ropLongTermIdFromIdResponse.LongTermId.DatabaseGuid.Length); Array.Copy(ropLongTermIdFromIdResponse.LongTermId.GlobalCounter, 0, longTermByte, ropLongTermIdFromIdResponse.LongTermId.DatabaseGuid.Length, ropLongTermIdFromIdResponse.LongTermId.GlobalCounter.Length); return longTermByte; }
/// <summary> /// Verify the response by sending the ROP RopLongTermIdFromId /// </summary> /// <param name="request">The structure of ROP RopLongTermIdFromId request.</param> /// <param name="response">The structure of ROP RopLongTermIdFromId response.</param> private void VerifyRopLongTermIdFromId(RopLongTermIdFromIdRequest request, RopLongTermIdFromIdResponse response) { if (response.ReturnValue == 0) { ulong globalCounter = 0; for (int i = 0; i < 6; i++) { globalCounter += (ulong)(((ulong)response.LongTermId.GlobalCounter[i]) << (i * 8)); } globalCounter = globalCounter << 16; // The last 2 bytes of the Folder ID or Message ID are not fixed. ulong maskedObjectId = request.ObjectId & ~(ulong)0xFFFF; // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R69742"); // If the response can be parsed successfully and the return value is success, indicates the ROP's functionality is consistent with its description. // The returned LongTermID is associated with the given a Folder ID or Message ID. this.Site.CaptureRequirementIfAreEqual<ulong>( maskedObjectId, globalCounter, 69742, @"[In RopLongTermIdFromId ROP] The RopLongTermIdFromId ROP ([MS-OXCROPS] section 2.2.3.8) is used to obtain a LongTermID structure, as specified in [MS-OXCDATA] section 2.2.1.3.1, given a Folder ID structure or Message ID structure, as specified in [MS-OXCDATA] section 2.2.1.1 or section 2.2.1.2. "); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R440"); // Verify MS-OXCSTOR requirement: MS-OXCSTOR_R440 // If the high 48 bits in ObjectId and GlobalCounter are same, indicates the LongTermId related to the requested REPLID is valid in the REPLID and REPLGUID to-and-from mapping table. Site.CaptureRequirementIfAreEqual<ulong>( maskedObjectId, globalCounter, 440, @"[In RopLongTermIdFromId ROP Request Buffer] ObjectId: The 16-bit REPLID portion of the Folder ID or Message ID MUST be a valid entry in the REPLID and REPLGUID to-and-from mapping table."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R442"); // The LongTermId field is verified in the RopLongTermIdFromIdResponse structure. // If the LongTermId field is parsed successfully, this requirement can be captured directly. Site.CaptureRequirementIfIsNotNull( response.LongTermId, 442, @"[In RopLongTermIdFromId ROP Success Response Buffer] LongTermId: Contains the LongTermID structure, as specified in [MS-OXCDATA] section 2.2.1.3.1."); // The longTermId is null indicates its invalid object ID. if (response.LongTermId.DatabaseGuid != null) { // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R1244"); // Verify MS-OXCSTOR requirement: MS-OXCSTOR_R1244 // The underlying structure for LongTermId is parsed as structure as REPLGUID(128-bit) with the specified sequence, if GlobalCounter is associated with the given short-term ID,this requirement can be verified. Site.CaptureRequirementIfAreEqual<ulong>( maskedObjectId, globalCounter, 1244, @"[In Receiving a RopLongTermIdFromId ROP Request] The LongTermID consists of the 128-bit REPLGUID, followed by the 48-bit global counter portion of the given Folder ID or Message ID, followed by 16 bits of padding set to 0x0000."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCDATA_R2188"); // Verify MS-OXCDATA requirement: MS-OXCDATA_R2188 // The LongTermID is a GID, which is verified in "MS-OXCDATA", so here only need to verify the length of Pad field. bool isVerifyR2188 = response.LongTermId.Size() == 24; Site.CaptureRequirementIfIsTrue( isVerifyR2188, "MS-OXCDATA", 2188, @"[In LongTermID Structure] A LongTermID structure is a Global Identifier structure, as specified in section 2.2.1.3, plus a 2-byte Pad field that has the value 0x0000."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCDATA_R2189"); // The longtermID consists of DatabaseGuid, GlobalCounter and Padding, so its length is the sum of the three. int longTermIdLength = response.LongTermId.DatabaseGuid.Length + response.LongTermId.GlobalCounter.Length + 2; // +response.LongTermId.Padding.Length; // Verify MS-OXCDATA requirement: MS-OXCDATA_R2189 Site.CaptureRequirementIfAreEqual<int?>( 24, longTermIdLength, "MS-OXCDATA", 2189, @"[In LongTermID Structure] The total length of the LongTermID structure is 24 bytes."); } } }
/// <summary> /// Verify RopLongTermIdFromId Failure Response /// </summary> /// <param name="ropLongTermIdFromIdResponse">The failure response of RopLongTermIdFromId request</param> /// <param name="inputHandleIndex">The field of InputHandleIndex in RopLongTermIdFromId request</param> private void VerifyRopLongTermIdFromIdFailureResponse(RopLongTermIdFromIdResponse ropLongTermIdFromIdResponse, byte inputHandleIndex) { // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R351"); // Verify MS-OXCROPS requirement: MS-OXCROPS_R351 Site.CaptureRequirementIfAreEqual<Type>( typeof(byte), ropLongTermIdFromIdResponse.RopId.GetType(), 351, @"[In RopLongTermIdFromId ROP Failure Response Buffer] RopId (1 byte): An unsigned integer."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R353"); // Verify MS-OXCROPS requirement: MS-OXCROPS_R353 Site.CaptureRequirementIfAreEqual<byte>( (byte)RopId.RopLongTermIdFromId, ropLongTermIdFromIdResponse.RopId, 353, @"[In RopLongTermIdFromId ROP Failure Response Buffer] RopId (1 byte): For this operation[RopLongTermIdFromId], this field[RopId (1 byte)] is set to 0x43."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R354"); // Verify MS-OXCROPS requirement: MS-OXCROPS_R354 Site.CaptureRequirementIfAreEqual<Type>( typeof(byte), ropLongTermIdFromIdResponse.InputHandleIndex.GetType(), 354, @"[In RopLongTermIdFromId ROP Failure Response Buffer] InputHandleIndex (1 byte): An unsigned integer."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R355"); // Verify MS-OXCROPS requirement: MS-OXCROPS_R355 Site.CaptureRequirementIfAreEqual<byte>( inputHandleIndex, ropLongTermIdFromIdResponse.InputHandleIndex, 355, @"[In RopLongTermIdFromId ROP Failure Response Buffer] InputHandleIndex (1 byte): This index MUST be set to the value specified in the InputHandleIndex field in the request."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R356"); // Verify MS-OXCROPS requirement: MS-OXCROPS_R356 Site.CaptureRequirementIfAreEqual<Type>( typeof(uint), ropLongTermIdFromIdResponse.ReturnValue.GetType(), 356, @"[In RopLongTermIdFromId ROP Failure Response Buffer] ReturnValue (4 bytes):An unsigned integer."); // Refer to MS-OXCROPS: For some ROPs, Exchange 2003 and Exchange 2007 use different methods to resolve the Server object and, // therefore, do not fail the ROP if the index is invalid. if (Common.IsRequirementEnabled(4713, this.Site)) { // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R4713"); // Verify MS-OXCROPS requirement: MS-OXCROPS_R4713 Site.CaptureRequirementIfAreEqual<uint>( SuccessReturnValue, ropLongTermIdFromIdResponse.ReturnValue, 4713, @"[In Appendix B: Product Behavior] For some ROPs, Implementation does use different methods to resolve the Server object and, therefore, do not fail the ROP if the index is invalid. (<23> Section 3.2.5.1: For some ROPs, Exchange 2007 use different methods to resolve the Server object and, therefore, do not fail the ROP if the index is invalid.)"); } else { // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R358"); // Verify MS-OXCROPS requirement: MS-OXCROPS_R358 Site.CaptureRequirementIfAreNotEqual<uint>( SuccessReturnValue, ropLongTermIdFromIdResponse.ReturnValue, 358, @"[In RopLongTermIdFromId ROP Failure Response Buffer] ReturnValue (4 bytes): For this response[Failure Response], this field[ReturnValue (4 bytes)] is set to a value other than 0x00000000."); } }
/// <summary> /// Verify RopLongTermIdFromId Success Response /// </summary> /// <param name="ropLongTermIdFromIdResponse">The success response of RopLongTermIdFromId request</param> /// <param name="inputHandleIndex">The field of InputHandleIndex in RopLongTermIdFromId request</param> private void VerifyRopLongTermIdFromIdSuccessResponse(RopLongTermIdFromIdResponse ropLongTermIdFromIdResponse, byte inputHandleIndex) { // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R340"); // Verify MS-OXCROPS requirement: MS-OXCROPS_R340 Site.CaptureRequirementIfAreEqual<Type>( typeof(byte), ropLongTermIdFromIdResponse.RopId.GetType(), 340, @"[In RopLongTermIdFromId ROP Success Response Buffer] RopId (1 byte): An unsigned integer ."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R342"); // Verify MS-OXCROPS requirement: MS-OXCROPS_R342 Site.CaptureRequirementIfAreEqual<byte>( (byte)RopId.RopLongTermIdFromId, ropLongTermIdFromIdResponse.RopId, 342, @"[In RopLongTermIdFromId ROP Success Response Buffer] RopId (1 byte): For this operation[RopLongTermIdFromId], this field[RopId (1 byte)] is set to 0x43."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R343"); // Verify MS-OXCROPS requirement: MS-OXCROPS_R343 Site.CaptureRequirementIfAreEqual<Type>( typeof(byte), ropLongTermIdFromIdResponse.InputHandleIndex.GetType(), 343, @"[In RopLongTermIdFromId ROP Success Response Buffer] InputHandleIndex (1 byte): An unsigned integer."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R344"); // Verify MS-OXCROPS requirement: MS-OXCROPS_R344 Site.CaptureRequirementIfAreEqual<byte>( inputHandleIndex, ropLongTermIdFromIdResponse.InputHandleIndex, 344, @"[In RopLongTermIdFromId ROP Success Response Buffer] InputHandleIndex (1 byte): This index MUST be set to the value of the InputHandleIndex field in the request. "); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R345"); // Verify MS-OXCROPS requirement: MS-OXCROPS_R345 Site.CaptureRequirementIfAreEqual<Type>( typeof(uint), ropLongTermIdFromIdResponse.ReturnValue.GetType(), 345, @"[In RopLongTermIdFromId ROP Success Response Buffer] ReturnValue (4 bytes): An unsigned integer."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R347"); // Verify MS-OXCROPS requirement: MS-OXCROPS_R347 Site.CaptureRequirementIfAreEqual<uint>( SuccessReturnValue, ropLongTermIdFromIdResponse.ReturnValue, 347, @"[In RopLongTermIdFromId ROP Success Response Buffer] ReturnValue (4 bytes): For this response[Success Response], this field[ReturnValue (4 bytes)] is set to 0x00000000."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R348"); // Verify MS-OXCROPS requirement: MS-OXCROPS_R348 Site.CaptureRequirementIfAreEqual<Type>( typeof(LongTermId), ropLongTermIdFromIdResponse.LongTermId.GetType(), 348, @"[In RopLongTermIdFromId ROP Success Response Buffer] LongTermId (24 bytes): A LongTermID structure."); }
/// <summary> /// Get LongTermId from object id. /// </summary> /// <param name="objHandle">object handle.</param> /// <param name="objId">Object id value.</param> /// <returns>ROP response.</returns> public RopLongTermIdFromIdResponse GetLongTermId(uint objHandle, ulong objId) { RopLongTermIdFromIdRequest longTermIdFromIdRequest = new RopLongTermIdFromIdRequest(); RopLongTermIdFromIdResponse longTermIdFromIdResponse = new RopLongTermIdFromIdResponse(); longTermIdFromIdRequest.InputHandleIndex = 0x00; longTermIdFromIdRequest.LogonId = 0x00; longTermIdFromIdRequest.RopId = 0x43; longTermIdFromIdRequest.ObjectId = objId; this.responseSOHs = this.DoRPCCall(longTermIdFromIdRequest, objHandle, ref this.response, ref this.rawData); longTermIdFromIdResponse = (RopLongTermIdFromIdResponse)this.response; return longTermIdFromIdResponse; }