Corruption of string data in WM_COPYDATA

P

pedrito

I've got an app that takes a URL as an argument. If a second instance of my
application is started with a URL argument, instead of starting up, it sends
the URL to the first instance.

WM_COPYDATA seemed the best way to handle this, but my string appears to be
getting corrupted in transit.

The code for sending the string is as follows:

COPYDATA cd = new COPYDATA();
cd.dwData = 0;
cd.cbData = (uint) (_startupUrl.Length * 2);
cd.lpData = Marshal.StringToHGlobalUni(_startupUrl);
IntPtr lpPtr = Marshal.AllocHGlobal(Marshal.SizeOf(cd));

Marshal.StructureToPtr(cd, lpPtr, true);
SendMessage(process.MainWindowHandle, 0x004A, 0, lpPtr);
COPYDATA cd2 = (COPYDATA) Marshal.PtrToStructure(lpPtr, typeof(COPYDATA));
string strCheck = Marshal.PtrToStringUni(cd2.lpData);
Debug.WriteLine("Sent URL: " + strCheck);

Marshal.FreeHGlobal(lpPtr);


Now, the Debug.WriteLine shows that the string is correct at the time of
sending.

On the receiving end, my code is pretty much like the 2 lines before the
Debug.WriteLine. When I get the WM_COPYDATA message, the code is:

COPYDATA cd = (COPYDATA) Marshal.PtrToStructure(m.LParam, typeof(COPYDATA));
string url = Marshal.PtrToStringUni(cd.lpData);

At this point, however url generally has about 5 unicode characters appended
to it (I don't know what they are, they just show up as those empty box
characters).

Anyone have any idea what's going wrong here?

Thanks
 
M

Mattias Sjögren

Anyone have any idea what's going wrong here?

The PtrToStringUni method you're calling assumes that the string is
null terminated, but there's no guarantee that it is in this case.
Change it to

string url = Marshal.PtrToStringUni(cd.lpData, cd.cbData / 2);


Mattias
 
P

pedrito

Ah, super. Thanks so much.

Mattias Sjögren said:
The PtrToStringUni method you're calling assumes that the string is
null terminated, but there's no guarantee that it is in this case.
Change it to

string url = Marshal.PtrToStringUni(cd.lpData, cd.cbData / 2);


Mattias
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top