http://bugzilla.novell.com/show_bug.cgi?id=565143
http://bugzilla.novell.com/show_bug.cgi?id=565143#c0 Summary: calli incorectly marshals byte[] Classification: Mono Product: Mono: Runtime Version: 2.6.x Platform: x86 OS/Version: Windows 7 Status: NEW Severity: Normal Priority: P5 - None Component: interop AssignedTo: [email protected] ReportedBy: [email protected] QAContact: [email protected] Found By: --- Blocker: --- Created an attachment (id=332921) --> (http://bugzilla.novell.com/attachment.cgi?id=332921) Repro User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; MS-RTC LM 8; MALC) calli instruction doesn't correctly marshal parameters of type byte[]. It should marhsal the array as a pointer to its first element. Instead it passes a wrong pointer so the array length is rewritten if the buffer is written to. The below code works if it injects instructions: il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Ldelema, typeof(byte)); after each byte[] array parameter load. --- code --- using System; using System.ComponentModel; using System.Reflection; using System.Reflection.Emit; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; namespace IronRuby.StandardLibrary.Win32API { public class Win32API { delegate int F(IntPtr a, int b, int c, int d, int e, byte[] f); public static void Main() { DynamicMethod calli = EmitCalliStub(); var f = (F)calli.CreateDelegate(typeof(F)); IntPtr ftn = GetFunction("shell32", "SHGetFolderPath"); byte[] path = new byte[1000]; f(ftn, 0, 0x0023, 0, 1, path); Console.WriteLine(path.Length); } [DllImport("kernel32.dll")] private static extern IntPtr LoadLibrary(string lpFileName); [DllImport("kernel32.dll")] private static extern IntPtr GetProcAddress(IntPtr module, string lpProcName); private static IntPtr GetFunction(string/*!*/ libraryName, string/*!*/ functionName) { IntPtr library = LoadLibrary(libraryName); if (library == IntPtr.Zero) { throw new Win32Exception(); } string procName = functionName; IntPtr function = GetProcAddress(library, procName); if (function == IntPtr.Zero) { function = GetProcAddress(library, procName + "A"); if (library == IntPtr.Zero) { throw new Win32Exception(); } } return function; } private static DynamicMethod/*!*/ EmitCalliStub() { var returnType = typeof(int); var parameterTypes = new Type[1 + 5]; // target function ptr: parameterTypes = new[] { typeof(IntPtr), typeof(int), typeof(int), typeof(int), typeof(int), typeof(byte[]) }; DynamicMethod dm = new DynamicMethod("calli", returnType, parameterTypes, DynamicModule); var il = dm.GetILGenerator(); var signature = SignatureHelper.GetMethodSigHelper(CallingConvention.Winapi, returnType); // calli args: for (int i = 1; i < parameterTypes.Length; i++) { il.Emit(OpCodes.Ldarg, i); signature.AddArgument(parameterTypes[i]); } il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Calli, signature); il.Emit(OpCodes.Ret); return dm; } private static ModuleBuilder _dynamicModule; private static ModuleBuilder DynamicModule { get { if (_dynamicModule == null) { var attributes = new[] { new CustomAttributeBuilder(typeof(UnverifiableCodeAttribute).GetConstructor(Type.EmptyTypes), new object[0]), new CustomAttributeBuilder(typeof(PermissionSetAttribute).GetConstructor(new Type[] { typeof(SecurityAction) }), new object[]{ SecurityAction.Demand }, new PropertyInfo[] { typeof(PermissionSetAttribute).GetProperty("Unrestricted") }, new object[] { true } ) }; string name = "DynamicAssembly"; var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(name), AssemblyBuilderAccess.Run, attributes); assembly.DefineVersionInfoResource(); _dynamicModule = assembly.DefineDynamicModule(name); } return _dynamicModule; } } } } Reproducible: Always Steps to Reproduce: 1. compile and run the above code or run the attached .exe Actual Results: 24948 (or some other random number != 1000) Expected Results: 1000 -- Configure bugmail: http://bugzilla.novell.com/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are the QA contact for the bug. You are the assignee for the bug. _______________________________________________ mono-bugs maillist - [email protected] http://lists.ximian.com/mailman/listinfo/mono-bugs
