public static void TestNativeCallableValid()
    {
        /*
         * void TestNativeCallable()
         * {
         *         .locals init ([0] native int ptr)
         *         IL_0000:  nop
         *         IL_0002:  ldftn      int32 CallbackMethod(native int,native int)
         *
         *         IL_0012:  stloc.0
         *         IL_0013:  ldloc.0
         *         IL_0014:  ldsfld     native int [mscorlib]System.IntPtr::Zero
         *         IL_0019:  call       bool NativeMethods::EnumWindows(native int,
         *                                                                            native int)
         *         IL_001e:  pop
         *         IL_001f:  ret
         *   }
         */
        DynamicMethod testNativeCallable = new DynamicMethod("TestNativeCallable", null, null, typeof(Program).Module);
        ILGenerator   il = testNativeCallable.GetILGenerator();

        il.DeclareLocal(typeof(IntPtr));
        il.Emit(OpCodes.Nop);
        il.Emit(OpCodes.Ldftn, typeof(Program).GetMethod("CallbackMethod"));
        il.Emit(OpCodes.Stloc_0);
        il.Emit(OpCodes.Ldloc_0);
        il.Emit(OpCodes.Ldsfld, typeof(IntPtr).GetField("Zero"));
        il.Emit(OpCodes.Call, typeof(NativeMethods).GetMethod("EnumWindows"));
        il.Emit(OpCodes.Pop);
        il.Emit(OpCodes.Ret);
        NativeMethodInvoker testNativeMethod = (NativeMethodInvoker)testNativeCallable.CreateDelegate(typeof(NativeMethodInvoker));

        testNativeMethod();
    }
示例#2
0
        /// <summary>
        /// Call native method & process any exception
        /// </summary>
        /// <param name="nativeClient"></param>
        /// <param name="serviceCode"></param>
        /// <param name="opCode"></param>
        /// <param name="argObject"></param>
        /// <returns></returns>

        public NativeMethodTransportObject InvokeNativeMethod(
            INativeSession nativeClient,
            int serviceCodeInt,
            int opCodeInt,
            NativeMethodTransportObject transportObject)
        {
            NativeMethodInvokerInstance = new NativeMethodInvoker();

            NativeMethodTransportObject resultObject =
                NativeMethodInvokerInstance.InvokeNativeMethod(
                    nativeClient,
                    serviceCodeInt,
                    opCodeInt,
                    transportObject);

            return(resultObject);
        }
示例#3
0
        /// <summary>
        /// Call a service method and return result
        /// </summary>
        /// <param name="serviceCode"></param>
        /// <param name="subServiceCode"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>

        public NativeMethodTransportObject CallServiceMethod(
            ServiceCodes serviceCode,
            object subServiceCode,
            object parameters)
        {
            INativeSession nativeClient = CreateNativeSessionProxy();

            NativeMethodInvokerInstance = new NativeMethodInvoker();
            Services.Native.NativeMethodTransportObject resultObject =
                NativeMethodInvokerInstance.InvokeNativeMethod(
                    nativeClient,
                    (int)serviceCode,
                    (int)subServiceCode,
                    new NativeMethodTransportObject(parameters));
            ((IClientChannel)nativeClient).Close();
            return(resultObject);
        }
    public static void NegativeTest_ViaCalli()
    {
        Console.WriteLine($"{nameof(NegativeTest_ViaCalli)} function via calli instruction. The CLR _will_ crash.");

        /*
         * void TestUnmanagedCallersOnlyViaCalli()
         * {
         *      .locals init (native int V_0)
         *      IL_0000:  nop
         *      IL_0001:  ldftn      void CallbackViaCalli(int32)
         *      IL_0007:  stloc.0
         *
         *      IL_0008:  ldc.i4     1234
         *      IL_000d:  ldloc.0
         *      IL_000e:  calli      void(int32)
         *
         *      IL_0013:  nop
         *      IL_0014:  ret
         * }
         */
        DynamicMethod testUnmanagedCallersOnly = new DynamicMethod("TestUnmanagedCallersOnlyViaCalli", null, null, typeof(Program).Module);
        ILGenerator   il = testUnmanagedCallersOnly.GetILGenerator();

        il.DeclareLocal(typeof(IntPtr));
        il.Emit(OpCodes.Nop);

        // Get native function pointer of the callback
        il.Emit(OpCodes.Ldftn, typeof(Program).GetMethod(nameof(CallbackViaCalli)));
        il.Emit(OpCodes.Stloc_0);

        il.Emit(OpCodes.Ldc_I4, 1234);
        il.Emit(OpCodes.Ldloc_0);
        il.EmitCalli(OpCodes.Calli, CallingConventions.Standard, null, new Type[] { typeof(int) }, null);

        il.Emit(OpCodes.Nop);
        il.Emit(OpCodes.Ret);

        NativeMethodInvoker testNativeMethod = (NativeMethodInvoker)testUnmanagedCallersOnly.CreateDelegate(typeof(NativeMethodInvoker));

        // It is not possible to catch the resulting ExecutionEngineException exception.
        // To observe the crashing behavior set a breakpoint in the ReversePInvokeBadTransition() function
        // located in src/vm/dllimportcallback.cpp.
        testNativeMethod();
    }
    public static void NegativeTest_ViaLdftn()
    {
        /*
         * .locals init (native int V_0)
         * IL_0000:  nop
         * IL_0001:  ldftn      void ConsoleApplication1.Program::callback(int32)
         * IL_0007:  stloc.0
         * IL_0008:  ldc.i4.s   12
         * IL_000a:  ldloc.0
         * IL_000b:  calli      void(int32)
         * IL_0010:  nop
         * IL_0011:  ret
         */
        DynamicMethod testNativeCallable = new DynamicMethod("TestNativeCallableLdftn", null, null, typeof(Program).Module);
        ILGenerator   il = testNativeCallable.GetILGenerator();

        il.DeclareLocal(typeof(IntPtr));
        il.Emit(OpCodes.Nop);
        il.Emit(OpCodes.Ldftn, typeof(Program).GetMethod("LdftnCallback"));
        il.Emit(OpCodes.Stloc_0);
        il.Emit(OpCodes.Ldc_I4, 12);
        il.Emit(OpCodes.Ldloc_0);

        SignatureHelper sig = SignatureHelper.GetMethodSigHelper(typeof(Program).Module, null, new Type[] { typeof(int) });

        sig.AddArgument(typeof(int));

        // il.EmitCalli is not available  and the below is not correct
        il.Emit(OpCodes.Calli, sig);
        il.Emit(OpCodes.Nop);
        il.Emit(OpCodes.Ret);

        NativeMethodInvoker testNativeMethod = (NativeMethodInvoker)testNativeCallable.CreateDelegate(typeof(NativeMethodInvoker));

        testNativeMethod();
    }