Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / December 2007

Tip: Looking for answers? Try searching our database.

Passing String to other Applications with SendMessage,...

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Kerem Gümrükcü - 03 Dec 2007 23:04 GMT
Hi,

i want to emulate a (synchronous) BroadCastSystemMessage
with EnumWindows and  SendMessage. I dont want to use
the BroadcastSystemMessage because it needs the SE_TCB_NAME
Privilege (you dont have this in normal). So i decided to use the
EnumWindows with SendMessage. What i try here is to pass a
WM_USER+1111 with LParam and WParam, pointing to strings.
But when i try to get the strings at the other end with
Marshal.PtrToStringAnsi,
the String itself is empty. I dont know what the mistake here is, so
a little code:

IntPtr ptrIPAddress = IntPtr.Zero;
IntPtr ptrGUID = IntPtr.Zero;

ptrIPAddress =
Marshal.AllocHGlobal(Encoding.ASCII.GetByteCount(this.textBoxGGIPAIPAddress.Text));
ptrGUID =
Marshal.AllocHGlobal(Encoding.ASCII.GetByteCount(this.guidApplicationGUID.ToString()));

ptrIPAddress = Marshal.StringToHGlobalAnsi(this.textBoxGGIPAIPAddress.Text);
ptrGUID = Marshal.StringToHGlobalAnsi(this.guidApplicationGUID.ToString());

//(IntPtr,uint, IntPtr,IntPtr)
SendMessage(hWnd, (uint)WindowsMessages.WM_USER + 1111, ptrGUID ,
ptrIPAddress );

Marshal.FreeHGlobal(ptrIPAddress);
Marshal.FreeHGlobal(ptrGUID);

At the other end i try this, but nothing is in there:

protected override void WndProc(ref Message m)
{
if (m.Msg == (uint) WindowsAPIClass.WindowsMessages.WM_USER + 1111)
{
String s = Marshal.PtrToStringAnsi(m.LParam);
MessageBox.Show(s);
}
base.WndProc(ref m);
}

How to do this? I cant use remoting or stuff like that, because
the message should be available for any application running on
the System,...it seems that the global memory isnt really global,...

Regards

Kerem

Signature

-----------------------
Beste Grüsse / Best regards / Votre bien devoue
Kerem Gümrükcü
Microsoft Live Space: http://kerem-g.spaces.live.com/
Latest Open-Source Projects: http://entwicklung.junetz.de
-----------------------
"This reply is provided as is, without warranty express or implied."

Michael C - 03 Dec 2007 23:16 GMT
> Hi,
>
[quoted text clipped - 8 lines]
> the String itself is empty. I dont know what the mistake here is, so
> a little code:

You can't pass a pointer cross process. Each application has it own
completely seperate memory space. What is a valid pointer for your app is
not a valid pointer for another. You should look at the WM_COPY_DATA message
as it will copy your string data cross-process and is quite easy to use.

Michael
Kerem Gümrükcü - 03 Dec 2007 23:29 GMT
Hi Michael,

yes i know this but I still tried to find a way. I know
the WM_COPYDATA but it would be great if
this would be possible with some sort of WM_USER.
But since processes are exclusive i think i have to
go the WM_COPYDATA way,...

Regards

Kerem
Signature

-----------------------
Beste Grüsse / Best regards / Votre bien devoue
Kerem Gümrükcü
Microsoft Live Space: http://kerem-g.spaces.live.com/
Latest Open-Source Projects: http://entwicklung.junetz.de
-----------------------
"This reply is provided as is, without warranty express or implied."

Serge Baltic - 04 Dec 2007 14:36 GMT
Hello,

> i want to emulate a (synchronous) BroadCastSystemMessage
> with EnumWindows and  SendMessage.

Seems like you're trying to enumate SendMessage(HWND_BROADCAST, …) instead.
Why not use it?

(H) Serg
Kerem Gümrükcü - 04 Dec 2007 16:10 GMT
Hi Serge,

>Seems like you're trying to enumate SendMessage(HWND_BROADCAST, .) instead.
>Why not use it?

i need a synchronous way in sending the message. I also could use
PostMessage but it does place the message into the messageQ and
returns in the same moment. Send Message does not (if you use it
with every window handle obtained from EnumWindows and not
with HWND_BROADCAST,)...

Thanks anyway,...

Regards

Kerem

Signature

-----------------------
Beste Grüsse / Best regards / Votre bien devoue
Kerem Gümrükcü
Microsoft Live Space: http://kerem-g.spaces.live.com/
Latest Open-Source Projects: http://entwicklung.junetz.de
-----------------------
"This reply is provided as is, without warranty express or implied."

Mattias Sjögren - 04 Dec 2007 19:51 GMT
>ptrIPAddress =
>Marshal.AllocHGlobal(Encoding.ASCII.GetByteCount(this.textBoxGGIPAIPAddress.Text));
[quoted text clipped - 3 lines]
>ptrIPAddress = Marshal.StringToHGlobalAnsi(this.textBoxGGIPAIPAddress.Text);
>ptrGUID = Marshal.StringToHGlobalAnsi(this.guidApplicationGUID.ToString());

By overwriting the pointers you're leaking the memory you first
allocated with AllocHGlobal. Those calls seem completely unnecessary.

>How to do this? I cant use remoting or stuff like that, because
>the message should be available for any application running on
>the System,...it seems that the global memory isnt really global,...

If you want real global memory you should look at memory mapped files.
But it may be easier to use WM_COPYDATA as Michael suggested.

Mattias

Signature

Mattias Sjögren [C# MVP]  mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Kerem Gümrükcü - 04 Dec 2007 20:14 GMT
Hi Mattias,

>By overwriting the pointers you're leaking the memory you first
>allocated with AllocHGlobal. Those calls seem completely unnecessary.

Yes, this was the call from a earlier try, i removed it....

>If you want real global memory you should look at memory mapped files.
>But it may be easier to use WM_COPYDATA as Michael suggested.

Memory mapped files are in my case and also the approach of global
available data not that secure since want to make the thing more secure.
I use encrypted data that must be transfered,...

Thanks for the reply,...

Regards

Kerem

Signature

-----------------------
Beste Grüsse / Best regards / Votre bien devoue
Kerem Gümrükcü
Microsoft Live Space: http://kerem-g.spaces.live.com/
Latest Open-Source Projects: http://entwicklung.junetz.de
-----------------------
"This reply is provided as is, without warranty express or implied."

Mattias Sjögren - 04 Dec 2007 21:53 GMT
>Memory mapped files are in my case and also the approach of global
>available data not that secure since want to make the thing more secure.
>I use encrypted data that must be transfered,...

Sorry I'm not following. Memory mapped files seems lie a much more
secure solution in that case, since you can specify a security
descriptor for the file mapping and have complete control over who can
read and write from it.

Compare that to broadcasting data with window messages where any
message recipient gets to read the data.

Whether or not the data is encrypted is irrelevant to your
communication mechanism.

Mattias

Signature

Mattias Sjögren [C# MVP]  mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Kerem Gümrükcü - 05 Dec 2007 04:04 GMT
Hi Mattias,

i solved it another way, but my problem is passing
the data between two windows does not work. I get
garbage at the other end when passing the data with
the WM_COPYDATA Message.

Here is Code:

//structure to pass
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct APP_IP_GUID_INFORMATION
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string ApplicationGUID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string IPAddress;
}

[StructLayout(LayoutKind.Sequential)]
public struct CopyDataStruct
{
public int dwData;
public int cbData;
public IntPtr pData;
}

IntPtr ptrAIGI = IntPtr.Zero;
IntPtr ptrCDS = IntPtr.Zero;
IntPtr hWnd = IntPtr.Zero;

GGIPAWin32APIClass.APP_IP_GUID_INFORMATION aigi;
aigi.ApplicationGUID = this.guidApplicationGUID.ToString();
aigi.IPAddress = this.textBoxGGIPAIPAddress.Text;

ptrAIGI =
Marshal.AllocHGlobal(Marshal.SizeOf(typeof(GGIPAWin32APIClass.APP_IP_GUID_INFORMATION)));
Marshal.StructureToPtr(aigi, ptrAIGI, false);

GGIPAWin32APIClass.CopyDataStruct cds;
cds.dwData = this.Handle.ToInt32();
cds.cbData =
Marshal.SizeOf(typeof(GGIPAWin32APIClass.APP_IP_GUID_INFORMATION));
cds.pData = ptrAIGI;

ptrCDS =
Marshal.AllocHGlobal(Marshal.SizeOf(typeof(GGIPAWin32APIClass.CopyDataStruct)));
Marshal.StructureToPtr(cds, ptrCDS, false);

/*...........*/

hWnd = new IntPtr(Convert.ToInt32(ClienthWnd.Key.ToString()));
HandleRef hWndRef = new HandleRef(this,hWnd);
GGIPAWin32APIClass.SendMessage(hWndRef,
(uint)GGIPAWin32APIClass.WindowsMessages.WM_COPYDATA, this.Handle, ptrCDS)

/*...........*/

Marshal.FreeHGlobal(ptrAIGI);
Marshal.FreeHGlobal(ptrCDS);

The dwData and cbData at the other end are ok, but the pointer to the data
is garbage,...why.
Any idea? All pinvoke-functions and data is ASCII or ANSI,...

Thanks in advance,...

Regards

Kerem

Signature

-----------------------
Beste Grüsse / Best regards / Votre bien devoue
Kerem Gümrükcü
Microsoft Live Space: http://kerem-g.spaces.live.com/
Latest Open-Source Projects: http://entwicklung.junetz.de
-----------------------
"This reply is provided as is, without warranty express or implied."

Michael C - 05 Dec 2007 05:11 GMT
> The dwData and cbData at the other end are ok, but the pointer to the data
> is garbage,...why.
> Any idea? All pinvoke-functions and data is ASCII or ANSI,...

The pointer is garbage or what it points to is garbage? Are you sure you're
creating the data correctly? Try sending a byte array with a few arbitrary
values in it first. Also try using the rtlMoveMemory api to copy your data
to a byte array into your app as a test (ie not through SendMessage).

Michael
Kerem Gümrükcü - 05 Dec 2007 05:22 GMT
Hi Michael,

when i send the Data with WM_COPYDATA, the receiving
application has the right cbData and dwData values send from
my application, but pData is nothing else than random application.
I dont know whether the mistake lies on the sender or the receiver
side, but i think the mistake is on the sender side. I debugged my
reciver applications CopyDataStruct with VC++ (receiver is a
native app) and also a mannaged app. Bott apps pData is useless.
Dont as me why! Except the cbData and dwData nothing males sense.

Any ideas. Do i marshal the data the right way? Are my pinvoke
signatures ok?

Data should be TCHAR lpIPAddress[128] and
TCHAR lpApplicationGUID[128] at the other end...
But its something like "@/!29d)383Rgen%2%4"ß?0".
Pointing to "i dont know" data,...

Regards

Kerem

Signature

-----------------------
Beste Grüsse / Best regards / Votre bien devoue
Kerem Gümrükcü
Microsoft Live Space: http://kerem-g.spaces.live.com/
Latest Open-Source Projects: http://entwicklung.junetz.de
-----------------------
"This reply is provided as is, without warranty express or implied."

Michael C - 05 Dec 2007 05:51 GMT
> Hi Michael,
>
[quoted text clipped - 6 lines]
> native app) and also a mannaged app. Bott apps pData is useless.
> Dont as me why! Except the cbData and dwData nothing males sense.

How do you know it's your pointer that is rubbish? The pointer will be
changed from one app to the other. It's possible that the data is incorrect
*before* it is sent and the SendMessage is working correctly. Check this
first using the 2 suggestion in my previous post.

Michael
Kerem Gümrükcü - 05 Dec 2007 06:23 GMT
Hi Michael,

i am desperately looking for a Memory Window
in my VStudio 2005 Standard Edition. Did i miss
something or do i dont have one there? I dont want
to debug it the native way or use some external
debugger to have a in-depth look into the pointers
memory address. I have a symbol file and i can use
some external debugger like Smidgeonsofts PEDebugger
or some other *.pdb able debugger.

But this is not the point here. When i do a MessageBox
on the Structs Members "IPAddress" and "ApplicationGUID"
i get valid Strings displayed. Maybe something is corrupted after
Marshal.StructToPtr,...i cant see the memory pointers address,
thats the point...

Regards

Kerem

Signature

-----------------------
Beste Grüsse / Best regards / Votre bien devoue
Kerem Gümrükcü
Microsoft Live Space: http://kerem-g.spaces.live.com/
Latest Open-Source Projects: http://entwicklung.junetz.de
-----------------------
"This reply is provided as is, without warranty express or implied."

Michael C - 05 Dec 2007 06:38 GMT
> Hi Michael,
>
> i am desperately looking for a Memory Window
> in my VStudio 2005 Standard Edition. Did i miss
> something or do i dont have one there?

Try Ctrl + Alt + M and then push 1. Otherwise it should be on a menu
somewhere.

> I dont want
> to debug it the native way or use some external
> debugger to have a in-depth look into the pointers
> memory address. I have a symbol file and i can use
> some external debugger like Smidgeonsofts PEDebugger
> or some other *.pdb able debugger.

My suggestion was to just copy the data to a byte array and have a look at
what's in the byte array. If that has what you expect then you are half way
there. Although looking at the memory window is probably easier.

The other idea is to create a small amount of arbitrary data (again, use a
byte array) and see if that gets copied across ok.

Michael
Kerem Gümrükcü - 05 Dec 2007 15:37 GMT
Hi Michael,

i was missing the Memory window and the command
you suggested didnt work. So i did a raw debugging with
ollydbg and a raw disassembly of the memory and looked
at the memory pointing from the CopyDataStruct.
Everything was fine, but i made a wrong calculation at the
other end receiving the WM_COPYDATA. The size and
the offset to the data was wrong, so it was clear the i
pointed at random process data. Problem solved,..everybody
is happy!

And now i found this, but too late...(sigh)

http://msdn2.microsoft.com/en-us/library/s3aw423e(VS.80).aspx
http://msdn2.microsoft.com/en-us/library/9k643651(VS.80).aspx

Will be usefull the next time!
Visual Studio: Every Day a new experience,...

Thank you very much,...

Regards

Kerem

Signature

-----------------------
Beste Grüsse / Best regards / Votre bien devoue
Kerem Gümrükcü
Microsoft Live Space: http://kerem-g.spaces.live.com/
Latest Open-Source Projects: http://entwicklung.junetz.de
-----------------------
"This reply is provided as is, without warranty express or implied."

Serge Baltic - 04 Dec 2007 22:41 GMT
Hello,

> How to do this? I cant use remoting or stuff like that, because the
> message should be available for any application running on the
> System,...

What do you mean by “available for any application” — is that about not every
application being managed?

There're lots of things intended for communication in the Windows NT OS,
still I've made practical use of COM only. That should work equally good
for both managed and unmanaged. Putting an object into the Running Objects
Table makes it possible to place calls on it from other processes, handling
the string marshalling issues automatically for you.

If all you need to transmit are strings, you could take a look at DDE also.
That's perfectly suited for the case “broadcast a string message to a number
of listeners”, and could be implemented in .NET. For instance, that's the
way how Shell opens the second document in the existing application, like
a new link in IE, a new document in Word, and so on.

(H) Serge

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.