/// <summary> /// Initialize a RpceStubEncoder. /// </summary> /// <param name="runtimeTargetPlatform">Runtime platform, x86 or amd64.</param> /// <param name="typeFormatString">Type format string generated by MIDL.</param> /// <param name="exprEvalRoutines">ExprEvalRoutines generated by MIDL if exists.</param> /// <exception cref="ArgumentNullException"> /// Thrown when typeFormatString is null. /// </exception> /// <exception cref="InvalidOperationException"> /// Thrown when runtimeTargetPlatform doesn't match current platform at runtime. /// </exception> public RpceStubEncoder( RpceStubTargetPlatform runtimeTargetPlatform, byte[] typeFormatString, RpceStubExprEval[] exprEvalRoutines) : base(runtimeTargetPlatform, typeFormatString, exprEvalRoutines) { int status; IntPtr bindingString; status = NativeMethods.RpcStringBindingCompose( null, "ncalrpc", null, localRpcEndpoint, null, out bindingString); if (status != NativeMethods.RPC_S_OK) { throw new InvalidOperationException( string.Format("RpcStringBindingCompose failed with error code {0}.", status)); } status = NativeMethods.RpcBindingFromStringBinding(bindingString, out localRpcHandle); if (status != NativeMethods.RPC_S_OK) { throw new InvalidOperationException( string.Format("RpcBindingFromStringBinding failed with error code {0}.", status)); } status = NativeMethods.RpcStringFree(ref bindingString); if (status != NativeMethods.RPC_S_OK) { throw new InvalidOperationException( string.Format("RpcStringFree failed with error code {0}.", status)); } }
/// <summary> /// constructor. /// </summary> /// <param name="runtimeTargetPlatform">Runtime platform, x86 or amd64.</param> /// <param name="typeFormatString">Type format string generated by MIDL.</param> /// <param name="exprEvalRoutines">ExprEvalRoutines generated by MIDL if exists.</param> /// <exception cref="ArgumentNullException"> /// Thrown when typeFormatString is null. /// </exception> /// <exception cref="InvalidOperationException"> /// Thrown when runtimeTargetPlatform doesn't match current platform at runtime. /// </exception> protected RpceStub( RpceStubTargetPlatform runtimeTargetPlatform, byte[] typeFormatString, RpceStubExprEval[] exprEvalRoutines) { if (typeFormatString == null) { throw new ArgumentNullException("typeFormatString"); } if ((IntPtr.Size == sizeof(Int32) && (runtimeTargetPlatform & RpceStubTargetPlatform.X86) != RpceStubTargetPlatform.X86) || (IntPtr.Size == sizeof(Int64) && (runtimeTargetPlatform & RpceStubTargetPlatform.Amd64) != RpceStubTargetPlatform.Amd64)) { throw new InvalidOperationException("Invalid target platform."); } allocatedMemoryList = new List<IntPtr>(); #region RPC_CLIENT_INTERFACE rpcClientInterface NativeMethods.RPC_CLIENT_INTERFACE rpcClientInterface = new NativeMethods.RPC_CLIENT_INTERFACE(); rpcClientInterface.Length = (uint)Marshal.SizeOf(typeof(NativeMethods.RPC_CLIENT_INTERFACE)); rpcClientInterface.InterfaceId.SyntaxGUID = RpceStubEncoder.RPCE_BIND_ONLY_SERVER.IF_ID; rpcClientInterface.InterfaceId.SyntaxVersion.MajorVersion = RpceStubEncoder.RPCE_BIND_ONLY_SERVER.IF_VERS_MAJOR; rpcClientInterface.InterfaceId.SyntaxVersion.MinorVersion = RpceStubEncoder.RPCE_BIND_ONLY_SERVER.IF_VERS_MINOR; rpcClientInterface.TransferSyntax.SyntaxGUID = RpceUtility.NDR_INTERFACE_UUID; rpcClientInterface.TransferSyntax.SyntaxVersion.MajorVersion = RpceUtility.NDR_INTERFACE_MAJOR_VERSION; rpcClientInterface.TransferSyntax.SyntaxVersion.MinorVersion = RpceUtility.NDR_INTERFACE_MINOR_VERSION; rpcClientInterface.DispatchTable = IntPtr.Zero; rpcClientInterface.RpcProtseqEndpointCount = 0; rpcClientInterface.RpcProtseqEndpoint = IntPtr.Zero; rpcClientInterface.Reserved = 0; rpcClientInterface.InterpreterInfo = IntPtr.Zero; rpcClientInterface.Flags = 0x00000000; #endregion #region MIDL_STUB_DESC stubDesc stubDesc = new NativeMethods.MIDL_STUB_DESC(); stubDesc.RpcInterfaceInformation = Marshal.AllocHGlobal(Marshal.SizeOf(rpcClientInterface)); Marshal.StructureToPtr(rpcClientInterface, stubDesc.RpcInterfaceInformation, false); stubDesc.pfnAllocate = new NativeMethods.PfnAllocate(MIDL_user_allocate); stubDesc.pfnFree = new NativeMethods.PfnFree(MIDL_user_free); stubDesc.apfnNdrRundownRoutines = IntPtr.Zero; stubDesc.aGenericBindingRoutinePairs = IntPtr.Zero; if (exprEvalRoutines == null || exprEvalRoutines.Length == 0) { stubDesc.apfnExprEval = IntPtr.Zero; } else { exprEvalList = new List<NativeMethods.EXPR_EVAL>(exprEvalRoutines.Length); stubDesc.apfnExprEval = Marshal.AllocHGlobal(IntPtr.Size * exprEvalRoutines.Length); for (int i = 0; i < exprEvalRoutines.Length; i++) { RpceStubExprEvalCallback callback = new RpceStubExprEvalCallback(this, exprEvalRoutines[i]); NativeMethods.EXPR_EVAL exprEval = new NativeMethods.EXPR_EVAL(callback.EXPR_EVAL); IntPtr funcPtr = Marshal.GetFunctionPointerForDelegate(exprEval); Marshal.WriteIntPtr(stubDesc.apfnExprEval, IntPtr.Size * i, funcPtr); //http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.getfunctionpointerfordelegate.aspx //Caller must manually keep the delegate from being collected by // the garbage collector from managed code. exprEvalList.Add(exprEval); } } stubDesc.aXmitQuintuple = IntPtr.Zero; stubDesc.pFormatTypes = Marshal.AllocHGlobal(typeFormatString.Length); Marshal.Copy(typeFormatString, 0, stubDesc.pFormatTypes, typeFormatString.Length); stubDesc.fCheckBounds = 0; /* -error bounds_check flag : "midl /error none" */ stubDesc.Version = 0x50000; /* Ndr library version */ stubDesc.pMallocFreeStruct = IntPtr.Zero; stubDesc.MIDLVersion = 0x70001e6; /* MIDL Version 7.0.486 */ stubDesc.CommFaultOffsets = IntPtr.Zero; stubDesc.aUserMarshalQuadruple = IntPtr.Zero; stubDesc.NotifyRoutineTable = IntPtr.Zero; /* notify & notify_flag routine table */ stubDesc.mFlags = 0x1; /* MIDL flag */ stubDesc.CsRoutineTables = IntPtr.Zero; /* cs routines */ stubDesc.ProxyServerInfo = IntPtr.Zero; /* proxy/server native */ stubDesc.pExprInfo = IntPtr.Zero; /* Reserved5 */ #endregion }
/// <summary> /// Initialize a RpceStubExprEvalCallback. /// </summary> /// <param name="stub">RpceStub which contain the EXPR_EVAL.</param> /// <param name="exprEvalRoutine">A EXPR_EVAL.</param> internal RpceStubExprEvalCallback(RpceStub stub, RpceStubExprEval exprEvalRoutine) { RpceStub = stub; exprEval = exprEvalRoutine; }
/// <summary> /// Encode parameter list to byte array in one method call. /// </summary> /// <param name="runtimeTargetPlatform">Runtime platform, x86 or amd64.</param> /// <param name="typeFormatString">Type format string generated by MIDL.</param> /// <param name="exprEvalRoutines">ExprEvalRoutines generated by MIDL if exists.</param> /// <param name="procFormatString">Proc format string generated by MIDL.</param> /// <param name="procFormatStringOffset">Offset of the procedure in procFormatString.</param> /// <param name="isClient">Is client side.</param> /// <param name="parameters">Parameters.</param> /// <returns>The byte array contains encoded parameters.</returns> /// <exception cref="ArgumentNullException"> /// Thrown when typeFormatString is null. /// </exception> /// <exception cref="InvalidOperationException"> /// Thrown when runtimeTargetPlatform doesn't match current platform at runtime. /// </exception> public static byte[] ToBytes( RpceStubTargetPlatform runtimeTargetPlatform, byte[] typeFormatString, RpceStubExprEval[] exprEvalRoutines, byte[] procFormatString, int procFormatStringOffset, bool isClient, params Int3264[] parameters) { using (RpceStubEncoder encoder = new RpceStubEncoder( runtimeTargetPlatform, typeFormatString, exprEvalRoutines)) { encoder.NdrClientInitializeNew(); encoder.NdrParametersBufferSize(procFormatString, procFormatStringOffset, isClient, parameters); encoder.NdrGetBuffer(); encoder.NdrParametersMarshall(procFormatString, procFormatStringOffset, isClient, parameters); return encoder.ToBytes(); } }