From 67620bcac9a1b6bf0b79fd25998ee8574f71c86f Mon Sep 17 00:00:00 2001 From: Vitek Karas Date: Fri, 20 Apr 2018 20:22:13 -0700 Subject: [PATCH] Add better coverage for Marshal.GetDelegateForFunctionPointer (#15339) Also fixes the test Main to correctly collect result codes from all 3 subtests. --- .../GetDelForFcnPtr_Negative_Catchable.cs | 81 +++++++++++++++++++++- .../GetFcnPtrForDel_Negative_Catchable.cs | 20 ++++-- 2 files changed, 91 insertions(+), 10 deletions(-) diff --git a/tests/src/Interop/MarshalAPI/FunctionPointer/GetDelForFcnPtr_Negative_Catchable.cs b/tests/src/Interop/MarshalAPI/FunctionPointer/GetDelForFcnPtr_Negative_Catchable.cs index 9fddac1..f649c61 100644 --- a/tests/src/Interop/MarshalAPI/FunctionPointer/GetDelForFcnPtr_Negative_Catchable.cs +++ b/tests/src/Interop/MarshalAPI/FunctionPointer/GetDelForFcnPtr_Negative_Catchable.cs @@ -54,7 +54,7 @@ public partial class FunctionPtr } catch (ArgumentException e) { - Console.WriteLine("Fail - passing a null type received the right exception type, wrong message, message was '{0}'", e.Message); + Console.WriteLine("Pass - passing a null type received the right exception type, wrong message, message was '{0}'", e.Message); } catch (Exception e) { @@ -71,7 +71,7 @@ public partial class FunctionPtr } catch (ArgumentException e) { - Console.WriteLine("Faile - threw the right exception passing a non-delegate type, but a wrong message, message was '{0}'", e.Message); + Console.WriteLine("Pass - threw the right exception passing a non-delegate type, but a wrong message, message was '{0}'", e.Message); } catch (Exception e) { @@ -80,6 +80,81 @@ public partial class FunctionPtr Console.WriteLine(e); } + // Delegate -> FcnPtr -> Delegate + try + { + VoidDelegate del = (VoidDelegate)Marshal.GetDelegateForFunctionPointer(fcnptr, typeof(VoidDelegate)); + if (del.Target != md.Target) + { + retVal = 0; + Console.WriteLine("Failure - the Target of the funcptr->delegate should be equal to the original method."); + Console.WriteLine(del.Target); + } + + if (del.Method != md.Method) + { + retVal = 0; + Console.WriteLine("Failure - The Method of the funcptr->delegate should be equal to the MethodInfo of the original method."); + Console.WriteLine(del.Method); + } + + // Try to call it + del(); + + Console.WriteLine("Pass - got a delegate for the function pointer."); + } + catch (Exception e) + { + retVal = 0; + Console.WriteLine("Failure - received exception while converting funcptr to delegate."); + Console.WriteLine(e); + } + + // Native FcnPtr -> Delegate + IntPtr pNativeMemory = IntPtr.Zero; + try + { + // Allocate a piece of native memory which in no way resembles valid function entry point. + // CLR will read the first couple of bytes and try to match it to known patterns. We need something + // which doesn't look like a reverse pinvoke thunk. + pNativeMemory = Marshal.AllocCoTaskMem(64); + Marshal.WriteInt32(pNativeMemory, 0); + Marshal.WriteInt32(pNativeMemory + 4, 0); + + VoidDelegate del = (VoidDelegate)Marshal.GetDelegateForFunctionPointer(pNativeMemory, typeof(VoidDelegate)); + if (del.Target != null) + { + retVal = 0; + Console.WriteLine("Failure - the Target of the funcptr->delegate should be null since we provided native funcptr."); + Console.WriteLine(del.Target); + } + + if (del.Method.Name != "Invoke") + { + retVal = 0; + Console.WriteLine("Failure - The Method of the native funcptr->delegate should be the Invoke method."); + Console.WriteLine(del.Method); + } + + // Don't try to call it - it's a random address. + + Console.WriteLine("Pass - got a delegate for the function pointer."); + } + catch (Exception e) + { + retVal = 0; + Console.WriteLine("Failure - received exception while converting funcptr to delegate."); + Console.WriteLine(e); + } + finally + { + if (pNativeMemory != IntPtr.Zero) + { + Marshal.FreeCoTaskMem(pNativeMemory); + } + } + + Console.WriteLine(retVal == 100 ? "Done - PASSED" : "Done - FAILED"); return retVal; } @@ -89,4 +164,4 @@ public partial class FunctionPtr Console.WriteLine("Simple method to get a delegate for"); } } -#pragma warning restore 618 \ No newline at end of file +#pragma warning restore 618 diff --git a/tests/src/Interop/MarshalAPI/FunctionPointer/GetFcnPtrForDel_Negative_Catchable.cs b/tests/src/Interop/MarshalAPI/FunctionPointer/GetFcnPtrForDel_Negative_Catchable.cs index e4b5c2d..01fc898 100644 --- a/tests/src/Interop/MarshalAPI/FunctionPointer/GetFcnPtrForDel_Negative_Catchable.cs +++ b/tests/src/Interop/MarshalAPI/FunctionPointer/GetFcnPtrForDel_Negative_Catchable.cs @@ -13,16 +13,16 @@ public partial class FunctionPtr public static int Main() { - RunGetFncSecTest(); + int retVal1 = RunGetFncSecTest(); - int retVal = 100; + int retVal2 = 100; VoidDelegate md = new VoidDelegate(FunctionPtr.Method); Console.WriteLine("\r\nTesting Marshal.GetFunctionPointerForDelegate()."); try { Marshal.GetFunctionPointerForDelegate(null); - retVal = 0; + retVal2 = 0; Console.WriteLine("Failure - did not receive an exception while passing null as the delegate"); } catch (ArgumentNullException e) @@ -31,13 +31,19 @@ public partial class FunctionPtr } catch (Exception e) { - retVal = 0; + retVal2 = 0; Console.WriteLine("Failure - receive an incorrect exception while passing null as the delegate"); Console.WriteLine(e); } - RunGetDelForFcnPtrTest(); - return retVal; + + int retVal3 = RunGetDelForFcnPtrTest(); + + if (retVal1 != 100) + return retVal1; + if (retVal2 != 100) + return retVal2; + return retVal3; } } -#pragma warning restore 618 \ No newline at end of file +#pragma warning restore 618 -- 2.7.4