/// <summary>
/// It calls native method EcDoRpcExt2 that sends remote operation (ROP) commands to the server with a Session Context Handle.
/// </summary>
/// <param name="pcxh">On input, the client MUST pass a valid Session Context Handle that was created by calling EcDoConnectEx.
/// The server uses the Session Context Handle to identify the Session Context to use for this call. On output, the server MUST return the same Session Context Handle on success.</param>
/// <param name="pulFlags">On input, this parameter contains flags that tell the server how to build the rgbOut parameter.</param>
/// <param name="rgbIn">This buffer contains the ROP request payload. </param>
/// <param name="ropRequestLength">This parameter contains the length of the ROP request payload passed in the rgbIn parameter.</param>
/// <param name="rgbOut">On success, this buffer contains the ROP response payload.</param>
/// <param name="pcbOut">On input, this parameter contains the maximum size of the rgbOut buffer.On output,
/// this parameter contains the size of the ROP response payload.</param>
/// <param name="rgbAuxIn"> This parameter contains an auxiliary payload buffer.</param>
/// <param name="auxInLength">On input, this parameter contains the length of the auxiliary payload buffer passed in the rgbAuxIn parameter.</param>
/// <param name="rgbAuxOut">On output, the server can return auxiliary payload data to the client.</param>
/// <param name="pcbAuxOut">On input, this parameter contains the maximum length of the rgbAuxOut buffer.
/// On output, this parameter contains the size of the data to be returned in the rgbAuxOut buffer.</param>
/// <param name="pulTransTime">On output, the server stores the number of milliseconds the call took to execute.</param>
/// <returns>If the method succeeds, the return value is 0. If the method fails, return RPC error code RPC exception code.</returns>
private uint RpcExt2(
ref IntPtr pcxh,
ref uint pulFlags,
byte[] rgbIn,
uint ropRequestLength,
out byte[] rgbOut,
ref uint pcbOut,
byte[] rgbAuxIn,
uint auxInLength,
out byte[] rgbAuxOut,
ref uint pcbAuxOut,
out uint pulTransTime)
{
this.site.Assert.AreNotEqual <IntPtr>(IntPtr.Zero, pcxh, "Session Context should not be empty.");
this.site.Assert.AreEqual <uint>(ropRequestLength, (uint)rgbIn.Length, "Passed in buffer rgbIn length should be equal to cbIn.");
this.site.Assert.AreEqual <uint>(auxInLength, (uint)rgbAuxIn.Length, "Passed in buffer rgbAuxIn length should be equal to cbAuxIn.");
IntPtr rgbInPtr = Marshal.AllocHGlobal(rgbIn.Length);
IntPtr rgbAuxInPtr = Marshal.AllocHGlobal(rgbAuxIn.Length);
try
{
Marshal.Copy(rgbIn, 0, rgbInPtr, rgbIn.Length);
Marshal.Copy(rgbAuxIn, 0, rgbAuxInPtr, rgbAuxIn.Length);
IntPtr rgbOutPtr = Marshal.AllocHGlobal((int)pcbOut);
IntPtr rgbAuxOutPtr = Marshal.AllocHGlobal((int)pcbAuxOut);
uint ret = NativeMethods.EcDoRpcExt2(
ref pcxh,
ref pulFlags,
rgbInPtr,
ropRequestLength,
rgbOutPtr,
ref pcbOut,
rgbAuxInPtr,
auxInLength,
rgbAuxOutPtr,
ref pcbAuxOut,
out pulTransTime);
rgbOut = new byte[(int)pcbOut];
Marshal.Copy(rgbOutPtr, rgbOut, 0, (int)pcbOut);
Marshal.FreeHGlobal(rgbOutPtr);
rgbAuxOut = new byte[(int)pcbAuxOut];
Marshal.Copy(rgbAuxOutPtr, rgbAuxOut, 0, (int)pcbAuxOut);
Marshal.FreeHGlobal(rgbAuxOutPtr);
if (ret != 0)
{
this.site.Log.Add(LogEntryKind.Comment, "EcDoRpcExt2 returns error code {0}. Refers to [MS-OXCDATA] section 2.4 for more information.", ret);
}
return(ret);
}
catch (SEHException e)
{
rgbOut = null;
rgbAuxOut = null;
pulTransTime = 0;
uint errorCode = RpcExceptionCode(e);
this.site.Log.Add(LogEntryKind.Comment, "EcDoRpcExt2 throws exception, system error code is {0}, the error message is: {1}", errorCode, (new Win32Exception((int)errorCode)).ToString());
return(errorCode);
}
finally
{
Marshal.FreeHGlobal(rgbInPtr);
Marshal.FreeHGlobal(rgbAuxInPtr);
}
}