public void MSOXCSTOR_S02_TC05_TestRopGetOwningServers()
{
this.CheckTransportIsSupported();
string publicFolderName = Common.GenerateResourceName(Site, "PublicFolder");
#region step1: Connect to server1
this.returnStatus = this.oxcstorAdapter.ConnectEx(ConnectionType.PublicFolderServer);
Site.Assert.IsTrue(this.returnStatus, "Connection is successful");
#endregion
#region step2: Call RopLogon ROP to log on public folders
// Set Public USE_PER_MDB_REPLID_MAPPING IGNORE_HOME_MDB flags
this.logonRequestForPublicFolder.OpenFlags = 0x01000202;
this.oxcstorAdapter.DoRopCall(this.logonRequestForPublicFolder, this.insideObjHandle, ROPCommandType.RopLogonPublicFolder, out this.outputBuffer);
this.outObjHandle = this.outputBuffer.ServerObjectHandleTable[0];
this.logonResponse = (RopLogonResponse)this.outputBuffer.RopsList[0];
Site.Assert.AreEqual<uint>(0, this.logonResponse.ReturnValue, "0 indicates the ROP succeeds, other value indicates error occurs.");
#endregion
#region step3: Open a public folder
RopOpenFolderRequest openFolderRequest;
RopOpenFolderResponse openFolderResponse;
openFolderRequest.RopId = 0x02;
openFolderRequest.LogonId = 0x0;
openFolderRequest.InputHandleIndex = 0x0;
openFolderRequest.OutputHandleIndex = 0x01;
// Root folder
openFolderRequest.FolderId = this.logonResponse.FolderIds[1];
// Opening an existing folder
openFolderRequest.OpenModeFlags = 0x0;
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];
#endregion
#region step4: Create a public folder
string publicFolder = publicFolderName;
string ghostPublicFolder = publicFolder + "\0";
RopCreateFolderRequest createFolderRequest;
RopCreateFolderResponse createFolderResponse;
createFolderRequest.RopId = 0x1C;
createFolderRequest.LogonId = 0x0;
createFolderRequest.InputHandleIndex = 0x0;
createFolderRequest.OutputHandleIndex = 0x01;
createFolderRequest.FolderType = 0x01; // Generic folder
createFolderRequest.UseUnicodeStrings = 0x0; // FALSE
createFolderRequest.OpenExisting = 0xFF; // non-zero(TRUE)
createFolderRequest.Reserved = 0x0; // FALSE
createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(ghostPublicFolder);
createFolderRequest.Comment = Encoding.ASCII.GetBytes(ghostPublicFolder);
this.oxcstorAdapter.DoRopCall(createFolderRequest, openedFolderHandle, ROPCommandType.Others, out this.outputBuffer);
createFolderResponse = (RopCreateFolderResponse)this.outputBuffer.RopsList[0];
ulong folderId = createFolderResponse.FolderId;
Site.Assert.AreEqual<uint>(
0x00000000,
createFolderResponse.ReturnValue,
"0 indicates the ROP succeeds, other value indicates error occurs.");
#endregion
#region step5: Call RopGetOwningServers ROP request with the existed public folder
this.getOwningServersRequest.FolderId = folderId;
this.oxcstorAdapter.DoRopCall(this.getOwningServersRequest, this.outObjHandle, ROPCommandType.RopGetOwningServers, out this.outputBuffer);
this.getOwningServersResponse = (RopGetOwningServersResponse)this.outputBuffer.RopsList[0];
Site.Assert.AreEqual<uint>(
0,
this.getOwningServersResponse.ReturnValue,
"0 indicates the ROP succeeds, other value indicates error occurs.");
#endregion
#region Capture
if (Common.IsRequirementEnabled(3490001, this.Site))
{
// Add the debug information
Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R3490001");
Site.CaptureRequirementIfAreEqual<uint>(
0,
this.getOwningServersResponse.ReturnValue,
3490001,
@"[In Appendix A: Product Behavior] Implementation does issue this operation [RopGetOwningServers] against a public folders logon. (Exchange 2013 follows this behavior.)");
}
// Add the debug information
Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R915");
Site.Assert.AreNotEqual<int>(0, this.getOwningServersResponse.OwningServersCount, "Check if the number of the OwningServers field is not 0");
// Verify MS-OXCSTOR requirement: MS-OXCSTOR_R915
Site.CaptureRequirementIfIsNotNull(
this.getOwningServersResponse.OwningServers,
915,
"[In Receiving a RopGetOwningServers ROP Request] The list contents of server identifiers constitute the value in the OwningServers field.");
if (Common.IsRequirementEnabled(1266002, this.Site))
{
RopLogonRequest logonRequestForPublicFolderUseResponseESSDN;
logonRequestForPublicFolderUseResponseESSDN = this.logonRequestForPublicFolder;
logonRequestForPublicFolderUseResponseESSDN.EssdnSize = (ushort)this.getOwningServersResponse.OwningServers[0].Length;
logonRequestForPublicFolderUseResponseESSDN.Essdn = System.Text.Encoding.ASCII.GetBytes(this.getOwningServersResponse.OwningServers[0]);
RopOutputBuffer ropBufUseEssdn;
this.oxcstorAdapter.DoRopCall(logonRequestForPublicFolderUseResponseESSDN, this.insideObjHandle, ROPCommandType.RopLogonPublicFolder, out ropBufUseEssdn);
RopLogonResponse logonResponseUseEssdn = (RopLogonResponse)ropBufUseEssdn.RopsList[0];
this.outObjHandle = this.outputBuffer.ServerObjectHandleTable[0];
// Use the ESSDN from the logonResponse ServerName field to Logon a public folder, if the logonResponseUserEssdn
// return value is 0 it indicates the ESSDN from the GetOwningServer response is a valid ESSDN for the client to connect to.
// Add the debug information
Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R1266002");
Site.CaptureRequirementIfAreEqual<uint>(
0,
logonResponseUseEssdn.ReturnValue,
1266002,
@"[In Appendix A: Product Behavior] In the case of a public folder logon, this field [Essdn] contains an ASCII string that uniquely identifies the server that contains the public folder mailbox to log on to. (Exchange 2013 follows this behavior)");
// Add the debug information
Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R370");
Site.CaptureRequirementIfAreEqual<uint>(
0,
logonResponseUseEssdn.ReturnValue,
370,
@"[In RopGetOwningServers ROP Success Response Buffer] OwningServers: Each string is the ESSDN of a public folder database that hosts an active replica of the content of the folder.");
// Add the debug information
this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R1061");
// Verify MS-OXCSTOR requirement: MS-OXCSTOR_R1061
this.Site.CaptureRequirementIfAreEqual<byte>(
logonRequestForPublicFolderUseResponseESSDN.LogonFlags,
logonResponseUseEssdn.LogonFlags,
1061,
@"[In RopLogon ROP Redirect Response Buffer] LogonFlags: The server returns these flags unchanged from the LogonFlags field of the RopLogon request (section 2.2.1.1.1).");
}
// Add the debug information
Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R914");
// Verify MS-OXCSTOR requirement: MS-OXCSTOR_914
Site.CaptureRequirementIfAreEqual<int>(
this.getOwningServersResponse.OwningServersCount,
this.getOwningServersResponse.OwningServers.Length,
914,
@"[In Receiving a RopGetOwningServers ROP Request] The current total list length constitutes the OwningServersCount value returned in the response.");
// Add the debug information
Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R390");
// Verify MS-OXCSTOR requirement: MS-OXCSTOR_R390
// The error code ecNone indicates the operation is implemented successfully, so if the ReturnValue
// is 0, MS-OXCSTOR_R390 is verified with valid FID.
Site.CaptureRequirementIfAreEqual<uint>(
0,
this.getOwningServersResponse.ReturnValue,
390,
@"[In Receiving a RopGetOwningServers ROP Request] The error code ecNone: Its value is 0x00000000.");
// Add the debug information
Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R391");
// Verify MS-OXCSTOR requirement: MS-OXCSTOR_R391
Site.CaptureRequirementIfAreEqual<uint>(
0,
this.getOwningServersResponse.ReturnValue,
391,
@"[In Receiving a RopGetOwningServers ROP Request] The error code ecNone: Success.");
// Add the debug information
Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R916");
// Verify MS-OXCSTOR requirement: MS-OXCSTOR_R916
// Check if the returned server's identifier moniker map into userDN's string
string expectedMoniker = this.userDN.Remove(this.userDN.IndexOf("/cn="));
bool isVerifiedR916 = this.getOwningServersResponse.OwningServers[0].ToUpper().Contains(expectedMoniker.ToUpper());
Site.CaptureRequirementIfIsTrue(
isVerifiedR916,
916,
@"[In Receiving a RopGetOwningServers ROP Request] The server MUST map whatever identifier moniker for each server it has into an ESSDN string to return to the client.");
#endregion
#region step6: RopGetOwningServers ROP
this.oxcstorAdapter.DoRopCall(this.getOwningServersRequest, this.outObjHandle, ROPCommandType.RopGetOwningServers, out this.outputBuffer);
RopGetOwningServersResponse getOwningServersResponse1;
getOwningServersResponse1 = (RopGetOwningServersResponse)this.outputBuffer.RopsList[0];
Site.Assert.AreEqual<uint>(
0,
getOwningServersResponse1.ReturnValue,
"0 indicates the ROP succeeds, other value indicates error occurs.");
#endregion
#region step7: RopGetOwningServers ROP with invalid FID
// Set an invalid FID
this.getOwningServersRequest.FolderId = 0x1;
this.oxcstorAdapter.DoRopCall(this.getOwningServersRequest, this.outObjHandle, ROPCommandType.RopGetOwningServers, out this.outputBuffer);
this.getOwningServersResponse = (RopGetOwningServersResponse)this.outputBuffer.RopsList[0];
#endregion
#region Capture
// Add the debug information
Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R1232");
// Verify MS-OXCSTOR requirement: MS-OXCSTOR_R1232
Site.CaptureRequirementIfAreEqual<uint>(
0x8004010F,
this.getOwningServersResponse.ReturnValue,
1232,
@"[In Receiving a RopGetOwningServers ROP Request] If the public folder specified by the FolderId field cannot be found in the public folder database, the server MUST fail the operation with 0x8004010F (ecNotFound) in the ReturnValue field.");
// Add the debug information
Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R394");
// Verify MS-OXCSTOR requirement: MS-OXCSTOR_R394
Site.CaptureRequirementIfAreEqual<uint>(
0x8004010F,
this.getOwningServersResponse.ReturnValue,
394,
@"[In Receiving a RopGetOwningServers ROP Request] The error code ecNotFound: Its value is 0x8004010F.");
// Add the debug information
Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCSTOR_R395");
// Verify MS-OXCSTOR requirement: MS-OXCSTOR_R395
Site.CaptureRequirementIfAreEqual<uint>(
0x8004010F,
this.getOwningServersResponse.ReturnValue,
395,
@"[In Receiving a RopGetOwningServers ROP Request] The error code ecNotFound: The FID could not be found in the public folder database.");
#endregion
#region step8: Softly delete the folder
// Log on to the public folder.
this.oxcstorAdapter.DoRopCall(this.logonRequestForPublicFolder, this.insideObjHandle, ROPCommandType.RopLogonPublicFolder, out this.outputBuffer);
this.logonResponse = (RopLogonResponse)this.outputBuffer.RopsList[0];
Site.Assert.AreEqual<uint>(0, this.logonResponse.ReturnValue, "0 indicates the ROP succeeds, other value indicates error occurs.");
this.outObjHandle = this.outputBuffer.ServerObjectHandleTable[0];
openFolderRequest.FolderId = this.logonResponse.FolderIds[1];
openFolderRequest.InputHandleIndex = 0x00;
openFolderRequest.OutputHandleIndex = 0x01;
// Opening an existing folder
openFolderRequest.OpenModeFlags = 0x0;
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];
// Get the folder Id.
this.oxcstorAdapter.DoRopCall(createFolderRequest, openedFolderHandle, ROPCommandType.Others, out this.outputBuffer);
createFolderResponse = (RopCreateFolderResponse)this.outputBuffer.RopsList[0];
folderId = createFolderResponse.FolderId;
Site.Assert.AreEqual<uint>(
0x00000000,
createFolderResponse.ReturnValue,
"0 indicates the ROP succeeds, other value indicates error occurs.");
RopDeleteFolderRequest deleteFolderRequest;
deleteFolderRequest.RopId = 0x1D;
deleteFolderRequest.LogonId = 0x00;
deleteFolderRequest.InputHandleIndex = 0x00;
// The folder and all of the Message objects in the folder are deleted.
deleteFolderRequest.DeleteFolderFlags = 0x01;
// Folder to be deleted
deleteFolderRequest.FolderId = folderId;
this.oxcstorAdapter.DoRopCall(deleteFolderRequest, openedFolderHandle, ROPCommandType.Others, out this.outputBuffer);
RopDeleteFolderResponse deleteFolderResponse = (RopDeleteFolderResponse)this.outputBuffer.RopsList[0];
Site.Assert.AreEqual<uint>(
0x00000000,
deleteFolderResponse.ReturnValue,
"0 indicates the ROP succeeds, other value indicates error occurs.");
#endregion
}