News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Interesting alternate use for an API

Started by donkey, December 12, 2010, 02:03:35 PM

Previous topic - Next topic

donkey

If you register a message in Windows you give it some text and Windows will return a message number, you use RegisterWindowMessage for this function. Thing is there is no matching function to reverse the API, that is there is no function (AFAIK) that takes the number and returns the text. Well, not quite, it seems the GetClipboardFormatName performs it quite nicely. Try this:

invoke RegisterWindowMessage,"ThisTest"
invoke GetClipboardFormatName,eax,offset MessageName,256


MessageName will contain the text "ThisTest"

Could be used to send short text strings between applications.

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

dedndave

i wonder if you set the right flag bit, it is available from FormatMessage

Magnum

I got this far with the snippet.


.DATA

Info   db    "I swear it wasn't me, it was Bernie!!",0

.DATA?

MessageName db  ?


.CODE

%Date       db " &@Date" ; Compile date

start:

invoke RegisterWindowMessage,addr Info
invoke GetClipboardFormatName,eax,offset MessageName,256

Have a great day,
                         Andy

dedndave

QuoteI got this far with the snippet.

and ????? - lol

let me play with FormatMessage.....

it looks like this function was intended to be used for Find/Replace operations
it should be retievable with GetMessage

but, i am hard-headed - i still want to see if FormatMessage can access it   :P

Magnum

Looking for a use for it.

Maybe instead of the hotkey code, this can be used.

Have a great day,
                         Andy

dedndave

doesn't sound very convenient in that context
the program that posts the message would have to have focus to recognize a keystroke

donkey

Quote from: Magnum on December 12, 2010, 08:35:24 PM
Looking for a use for it.

Maybe instead of the hotkey code, this can be used.



One use I have for it is for one-shot interprocess communication. For example Help2Viewer can only run in a single instance, if it finds another instance it will send a WM_COPYDATA message with the command line and the running process will complete the operation while the new one shuts down. The command line can be sent as a registered message and the application can extract the text. Since I would be wary about polluting the system with registered messages I would probably only use it during shutdown of an application since the messages and their data are discarded once the process terminates. I plan on using it in a symbols program I never seem to get around to finishing, when an application receives a registered message the tool will display its string.

I really doubt that FormatMessage will get the text string here but its worth a try.

By the way Magnum, you have to allow enough room in the buffer you pass to GetClipboardFormatName to hold the entire string, obviously allocating 1 byte to hold a string that is 38 bytes long (with terminator) and telling it the buffer size is 256 bytes is not going to work well...

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

dedndave

can't you do that with SendMessage/GetMessage ???

Magnum

O.K.

I thought too much was alright, didn't want a buffer overflow.

Have a great day,
                         Andy

donkey

Quote from: Magnum on December 12, 2010, 10:05:26 PM
O.K.

I thought too much was alright, didn't want a buffer overflow.

You didn't have too much space in the buffer, you only have a 1 byte buffer in the code above, that is not enough space to hold the string, it will definitely overflow. Try to use this instead:

MessageName db  256 DUP (?)
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

jj2007

Nice discovery, Edgar!

include \masm32\include\masm32rt.inc

.data?
MessageName dd 2048 dup(?)

.code
TheString   db "A test string designed for 'InterProcessCommunication' aka IPC;", 13, 10, "it works also with special characters, and you can insert CrLf easily.",13, 10,\
   "The string can be a little bit longer, but it should not exceed 256 characters,", 13, 10, "apparently. Beyond 256, it will choke", 0

start:   invoke SetLastError, 0
   print "Testing RegisterWindowMessage with a "
   print str$(sizeof TheString), " byte string:", 13, 10
   invoke RegisterWindowMessage, offset TheString
   push eax
   print LastError$(), 13,10
   pop eax
   invoke GetClipboardFormatName,eax,offset MessageName, sizeof MessageName
   print LastError$(), 13,10
   print offset MessageName
   exit
end start

donkey

Quote from: dedndave on December 12, 2010, 09:48:48 PM
can't you do that with SendMessage/GetMessage ???

Not in most cases, you would need a way to marshal the data in order to transfer strings. Messages in Windows pass strings as pointers, the pointer from one process is meaningless to all other processes since they run in separate address spaces. The WM_COPYDATA message will marshal data for you but I was thinking this is much easier to set up for quick one-shot strings.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Antariy

System have some strict limits for number of possible registered messages. In usual usage this is enough, but if program will register thousands of messages per second, this will overflowed after a couple of seconds. Is not it?

donkey

Quote from: Antariy on December 12, 2010, 11:25:39 PM
System have some strict limits for number of possible registered messages. In usual usage this is enough, but if program will register thousands of messages per second, this will overflowed after a couple of seconds. Is not it?


Hi Antariy,

That's why I added this caveat:

QuoteSince I would be wary about polluting the system with registered messages I would probably only use it during shutdown of an application since the messages and their data are discarded once the process terminates

If you have to pass thousands of strings you should be using other methods anyway, this would be a pretty lame way to do it. For any sizable amount of data custom marshalling (eg allocating buffers across process boundaries using VirtualAllocEx), shared data in a dll or memory mapped files would be better solutions. As with everything, the method has to fit the needs.

It is a good point to stress though so newbies don't run out and start trying to transfer War and Peace from one app to another using registered messages  :wink

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Antariy

Quote from: donkey on December 12, 2010, 11:35:02 PM
Quote from: Antariy on December 12, 2010, 11:25:39 PM
System have some strict limits for number of possible registered messages. In usual usage this is enough, but if program will register thousands of messages per second, this will overflowed after a couple of seconds. Is not it?


Hi Antariy,

That's why I added this caveat:

QuoteSince I would be wary about polluting the system with registered messages I would probably only use it during shutdown of an application since the messages and their data are discarded once the process terminates

If you have to pass thousands of strings you should be using other methods anyway, this would be a pretty lame way to do it. For any sizable amount of data custom marshalling (eg allocating buffers across process boundaries using VirtualAllocEx), shared data in a dll or memory mapped files would be better solutions. As with everything, the method has to fit the needs.

No, when application was ended, registered messages was *not* deleted. They stay registered until system reboot. Try to get a string from GetClipboardFormatName for an atom which you get earlyer in other running, and you will see.

Of course, as IPC this method is not good, shared memory a lot better and faster.
But I have not seen reversing of message name by its atom in back, this nice trick you invent :thumbu



Alex