c++ - Why is my TB_INSERTBUTTON message causing comctl32 to throw? -
i'm trying add additional button toolbar in internet explorer.
i assumed implementation straight forward, , using code:
tbbutton buttontoadd; zeromemory( &buttontoadd, sizeof( tbbutton ) ); buttontoadd.ibitmap = 1; buttontoadd.idcommand = 1; buttontoadd.fsstate = tbstate_enabled; buttontoadd.fsstyle = btns_button|btns_autosize; lresult insertbuttonresult = sendmessage( hwndtoolbar, tb_insertbutton, 0, (lparam)&buttontoadd );
when message sent, internet explorer crash 90% of time (10% of time, broken button on toolbar) following exception:
unhandled exception @ 0x000007fefb97ddfa (comctl32.dll) in iexplore.exe: 0xc000041d: unhandled exception encountered during user callback.
given results aren't consistent, assumed sort of memory layout issue. tried send tb_insertbuttona
instead (my application defaults tb_insertbuttonw
), has no effect on issue.
i tried both 32 , 64 builds of application, both have same result.
i took @ callstack of iexplore.exe
, looks this:
comctl32.dll!ctoolbar::tbinputstruct(struct _tbbuttondata *,struct _tbbutton const *) unknown comctl32.dll!ctoolbar::tbinsertbuttons(unsigned int,unsigned int,struct _tbbutton *,int) unknown comctl32.dll!ctoolbar::toolbarwndproc(struct hwnd__ *,unsigned int,unsigned __int64,__int64) unknown comctl32.dll!ctoolbar::s_toolbarwndproc(struct hwnd__ *,unsigned int,unsigned __int64,__int64) unknown user32.dll!usercallwinproccheckwow() unknown user32.dll!dispatchclientmessage() unknown user32.dll!__fndword() unknown ntdll.dll!kiusercallbackdispatchercontinue() unknown user32.dll!ntuserpeekmessage() unknown user32.dll!peekmessagew() unknown ...
i found interesting, because i'm assuming method @ top copies data input structure internal structure , goes wrong. what's wrong input data structure?
the source code available on github at: https://github.com/oliversalzburg/ie-button
it failing because sending message contains pointer across process boundary. note fact pass address:
lresult insertbuttonresult = sendmessage(hwndtoolbar, tb_insertbutton, 0, (lparam)&buttontoadd);
that final parameter address in processes address space. recipient different process , address pass has no meaning in address space of other process.
some messages, instance wm_settext
, have payloads marshalled other process system. tb_insertbutton
not fall category. 1 of rules of tb_insertbutton
pointer pass has meaning in process owns recipient window.
you can resolve using virtualalloc
, writeprocessmemory
, etc. allocate , write memory in other process.
be warned difficult task right. in particular matters whether or not 2 processes have same bitness. layout of struct differs between 32 , 64 bit. easiest way make sure send right layout compile process same bitness target process.
by far easiest way inside target process. if write plugin not have deal of these issues , able use officially supported apis extension.
as raymond says, attempting rather dangerous , heed advice.
Comments
Post a Comment