/// <summary>
/// Send ROP request to the server.
/// </summary>
/// <param name="requestROPs">ROP request objects.</param>
/// <param name="requestSOHTable">ROP request server object handle table.</param>
/// <param name="responseROPs">ROP response objects.</param>
/// <param name="responseSOHTable">ROP response server object handle table.</param>
/// <param name="rgbRopOut">The response payload bytes.</param>
/// <param name="pcbOut">The maximum size of the rgbOut buffer to place Response in.</param>
/// <param name="mailBoxUserName">Autodiscover find the mailbox according to this username.</param>
/// <returns>0 indicates success, other values indicate failure. </returns>
public uint RopCall(
List <ISerializable> requestROPs,
List <uint> requestSOHTable,
ref List <IDeserializable> responseROPs,
ref List <List <uint> > responseSOHTable,
ref byte[] rgbRopOut,
uint pcbOut,
string mailBoxUserName = null)
{
// Log the rop requests
if (requestROPs != null)
{
foreach (ISerializable requestROP in requestROPs)
{
byte[] ropData = requestROP.Serialize();
this.site.Log.Add(LogEntryKind.Comment, "Request: {0}", requestROP.GetType().Name);
this.site.Log.Add(LogEntryKind.Comment, Common.FormatBinaryDate(ropData));
}
}
// Construct request buffer
byte[] rgbIn = this.BuildRequestBuffer(requestROPs, requestSOHTable);
uint ret = 0;
switch (this.MapiContext.TransportSequence.ToLower())
{
case "mapi_http":
ret = this.mapiHttpAdapter.Execute(rgbIn, pcbOut, out rgbRopOut);
break;
case "ncacn_ip_tcp":
case "ncacn_http":
ret = this.rpcAdapter.RpcExt2(ref this.cxh, rgbIn, out rgbRopOut, ref pcbOut);
break;
default:
this.site.Assert.Fail("TransportSeq \"{0}\" is not supported by the test suite.");
break;
}
RPC_HEADER_EXT[] rpcHeaderExts;
byte[][] rops;
uint[][] serverHandleObjectsTables;
if (ret == OxcRpcErrorCode.ECNone)
{
this.ParseResponseBuffer(rgbRopOut, out rpcHeaderExts, out rops, out serverHandleObjectsTables);
// Deserialize rops
if (rops != null)
{
foreach (byte[] rop in rops)
{
List <IDeserializable> ropResponses = new List <IDeserializable>();
RopDeserializer.Deserialize(rop, ref ropResponses);
foreach (IDeserializable ropResponse in ropResponses)
{
responseROPs.Add(ropResponse);
Type type = ropResponse.GetType();
this.site.Log.Add(LogEntryKind.Comment, "Response: {0}", type.Name);
}
this.site.Log.Add(LogEntryKind.Comment, Common.FormatBinaryDate(rop));
}
}
// Deserialize serverHandleObjectsTables
if (serverHandleObjectsTables != null)
{
foreach (uint[] serverHandleObjectsTable in serverHandleObjectsTables)
{
List <uint> serverHandleObjectList = new List <uint>();
foreach (uint serverHandleObject in serverHandleObjectsTable)
{
serverHandleObjectList.Add(serverHandleObject);
}
responseSOHTable.Add(serverHandleObjectList);
}
}
// The return value 0x478 means that the client needs to reconnect server with server name in response
if (this.MapiContext.AutoRedirect && rops.Length > 0 && rops[0][0] == 0xfe && ((RopLogonResponse)responseROPs[0]).ReturnValue == 0x478)
{
// Reconnect server with returned server name
string serverName = Encoding.ASCII.GetString(((RopLogonResponse)responseROPs[0]).ServerName);
serverName = serverName.Substring(serverName.LastIndexOf("=") + 1);
responseROPs.Clear();
responseSOHTable.Clear();
bool disconnectReturnValue = this.Disconnect();
this.site.Assert.IsTrue(disconnectReturnValue, "Disconnect should be successful here.");
string rpcProxyOptions = null;
if (string.Compare(this.MapiContext.TransportSequence, "ncacn_http", true) == 0)
{
rpcProxyOptions = "RpcProxy=" + this.originalServerName + "." + this.domainName;
bool connectionReturnValue = this.RpcConnect(serverName, this.userDN, this.domainName, this.userName, this.userPassword, rpcProxyOptions);
this.site.Assert.IsTrue(connectionReturnValue, "RpcConnect_Internal should be successful here.");
}
else if (string.Compare(this.MapiContext.TransportSequence, "mapi_http", true) == 0)
{
if (mailBoxUserName == null)
{
mailBoxUserName = Common.GetConfigurationPropertyValue("AdminUserName", this.site);
if (mailBoxUserName == null || mailBoxUserName == "")
{
this.site.Assert.Fail(@"There must be ""AdminUserName"" configure item in the ptfconfig file.");
}
}
string requestURL = Common.GetConfigurationPropertyValue("AutoDiscoverUrlFormat", this.site);
requestURL = Regex.Replace(requestURL, @"\[ServerName\]", this.originalServerName, RegexOptions.IgnoreCase);
AutoDiscoverProperties autoDiscoverProperties = AutoDiscover.GetAutoDiscoverProperties(this.site, this.originalServerName, mailBoxUserName, this.domainName, requestURL, this.MapiContext.TransportSequence.ToLower());
this.privateMailboxServer = autoDiscoverProperties.PrivateMailboxServer;
this.privateMailboxProxyServer = autoDiscoverProperties.PrivateMailboxProxy;
this.publicFolderServer = autoDiscoverProperties.PublicMailboxServer;
this.publicFolderProxyServer = autoDiscoverProperties.PublicMailboxProxy;
this.privateMailStoreUrl = autoDiscoverProperties.PrivateMailStoreUrl;
this.publicFolderUrl = autoDiscoverProperties.PublicMailStoreUrl;
bool connectionReturnValue = this.MapiConnect(this.privateMailStoreUrl, this.userDN, this.domainName, this.userName, this.userPassword);
this.site.Assert.IsTrue(connectionReturnValue, "RpcConnect_Internal should be successful here.");
}
ret = this.RopCall(
requestROPs,
requestSOHTable,
ref responseROPs,
ref responseSOHTable,
ref rgbRopOut,
0x10008);
}
}
return(ret);
}