Bug 324335 (MONO81659) - [Vista] Win32 Interop Issue
Summary: [Vista] Win32 Interop Issue
Status: RESOLVED FIXED
Alias: MONO81659
Product: Mono: Runtime
Classification: Mono
Component: interop (show other bugs)
Version: 1.1
Hardware: Other Other
: P3 - Medium : Normal
Target Milestone: ---
Assignee: Mono Bugs
QA Contact: Mono Bugs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-05-17 20:00 UTC by Jonathan Pobst
Modified: 2008-12-23 16:30 UTC (History)
3 users (show)

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Wiest 2007-09-15 20:39:01 UTC


---- Reported by monkey@jpobst.com 2007-05-17 13:00:47 MST ----

Description of Problem:
The attached code generally fails on SetClipboardData, causing problems for
MWF on Windows.  It does not fail on MS.Net 2.0 runtime.  My best guess is
an interop bug.

using System;
using System.Runtime.InteropServices;

public class HelloWorld
{
	static public void Main ()
	{
		//int CF_TEXT = 1;
		int CF_UNICODETEXT = 13;
		
		Console.WriteLine ("open succeeded: {0}", OpenClipboard (IntPtr.Zero));
		Console.WriteLine ("empty succeeded: {0}", EmptyClipboard ());

		IntPtr hmem = Marshal.StringToHGlobalUni ("test");

		Console.WriteLine ("hmem: {0}", hmem.ToString ());
		Console.WriteLine ("set succeeded: {0} ({1})", SetClipboardData
((uint)CF_UNICODETEXT, hmem) != IntPtr.Zero, GetLastError ());
		Console.WriteLine ("close succeeded: {0}", CloseClipboard ());
	}
	
	[DllImport ("user32.dll")]
	private extern static IntPtr SetClipboardData (uint format, IntPtr handle);
	[DllImport ("user32.dll")]
	private extern static bool OpenClipboard (IntPtr hwnd);
	[DllImport ("user32.dll")]
	private extern static bool CloseClipboard ();
	[DllImport ("user32.dll")]
	private extern static bool EmptyClipboard ();
	[DllImport ("kernel32.dll")]
	private extern static uint GetLastError ();
}

Actual Results (win/mono 1.2.4, 1.1 and 2.0 profile):
open succeeded: True
empty succeeded: True
hmem: 19459576
set succeeded: False (0)
close succeeded: True

Expected Results (.net 2.0):
open succeeded: True
empty succeeded: True
hmem: 2142512
set succeeded: True (0)
close succeeded: True



---- Additional Comments From sebastien@ximian.com 2007-05-17 13:24:22 MST ----

The sample does work with my old Mono 1.2.2.1 under Windows XP.

C:\Temp>mono --version
Mono JIT compiler version 1.2.2.1, (C) 2002-2006 Novell, Inc and
Contributors. www.mono-project.com
        TLS:           normal
        GC:            Included Boehm (with typed GC)
        SIGSEGV:       normal
        Disabled:      none

C:\Temp>mono 81659.exe
open succeeded: True
empty succeeded: True
hmem: 12492568
set succeeded: True (0)
close succeeded: True

Note that to ensure GetLastError is meaningful you should use:
   [DllImport ("user32.dll", SetLastError=true)]
and
   Marshal.GetLastWin32Error ()

Maybe it wouldn't be 0 ?




---- Additional Comments From gert.driesen@pandora.be 2007-05-17 13:34:35 MST ----

Works fine with SVN head on Windows XP too. Haven't checked on Vista 
though.



---- Additional Comments From monkey@jpobst.com 2007-05-17 15:03:31 MST ----

My VMWare Workstation beta expired last week.  I'll try to test on
WinXP when I can to see if I can reproduce it there.

Thanks for the tips on GetLastError, unfortunately it still returns 0.
 MSDN says it should have an error for me, but it doesn't seem to.



---- Additional Comments From vargaz@gmail.com 2007-05-19 11:34:13 MST ----

Try the managed GetLastWin32Error method:

http://blogs.msdn.com/adam_nathan/archive/2003/04/25/56643.aspx




---- Additional Comments From monkey@jpobst.com 2007-05-19 13:02:35 MST ----

Yep, that's what Sebastien suggested above.  Unfortunately, it returns 0.

"Some sort of w32 error occurred: 0"



---- Additional Comments From monkey@jpobst.com 2007-06-06 10:14:52 MST ----

This works correctly on Windows XP.  Updating summary to reflect this
is a Vista-only issue.



---- Additional Comments From joncham@gmail.com 2007-07-19 21:35:44 MST ----

I doubt this is the issue (and can't test without Vista), but you
could try setting the STAThread attribute on the Main in the test
program. Again, I doubt this is it, since I'm pretty sure we call
OleInitialize to correctly set up an STA in MWF.


Unknown bug field "cf_op_sys_details" encountered while moving bug
   <cf_op_sys_details>Vista (32bit)</cf_op_sys_details>
Unknown operating system unknown. Setting to default OS "Other".

Comment 1 Jonathan Pobst 2008-12-22 19:17:18 UTC
*** Bug 457110 has been marked as a duplicate of this bug. ***
Comment 2 Kornél Pál 2008-12-22 21:26:50 UTC
This works for me on Vista. If this is still failing for you please use Marshal.GetLastWin32Error() instead of GetLastError() and let us know the error value.
Comment 3 Andy Hume 2008-12-23 14:01:57 UTC
Does anyone know whether the original fault as seen in MWF itself is still present?  Was it that the setting clipboard data failed on Vista?  As this seems to be the same issue as fixed by bug 414446.  The SetClipboardData argument is a memory __handle__ and not a pointer.  The sample shows the wrong usage (AllocHGlobal returns a pointer!), which is as was fixed in MWF.



IIUC the sample output shows that the different behaviours is a fluke(?) of the memory allocation in StringToHGlobalUni!  Windows no longer has a memory handle table, so the handle/pointer value actually encodes which type it is [1].  In the test results above showing the pointers in hex is illuminating, see the last nibble.

Fails:
"hmem: 19459576" = 0x0128EDF8

Works:
"hmem:  2142512" = 0x0020B130

So in the first case Windows tries to dereference a handle, but in the second just uses it directly as a pointer.

[1] See the blogs posts around the following.  The commenter here describes the internals: <http://blogs.msdn.com/oldnewthing/archive/2004/11/09/254441.aspx#254644>
Comment 4 Jonathan Pobst 2008-12-23 16:30:27 UTC
Yes, both this and the original issue of using the clipboard crashing vista seem to be fixed.  Thanks!