Nevermind, you answered my question, and thanks.
Now I'll try to implement this lite dispatch interface and we'll see what happens.
Basically I wasn't handling the unknowns myself.
Posted on 2003-07-17 09:34:28 by Homer
I'm defining my sink interface as follows:

LPTHIS typedef ptr
MyQueryInterface proto :LPTHIS,:DWORD,:DWORD
MyAddRef proto :LPTHIS
MyRelease proto :LPTHIS
MyGetTypeInfoCount proto :LPTHIS,:ptr DWORD
MyGetTypeInfo proto :LPTHIS,:dword, :LCID, :ptr ptr ITypeInfo
MyGetIDsOfNames proto :LPTHIS,:ptr IID,:ptr,:dword,:LCID,:ptr DISPID
MyInvoke_ proto :LPTHIS,:DISPID,:ptr IID,:LCID,:dword,:ptr DISPPARAMS,:ptr VARIANT,:ptr EXCEPINFO,:ptr DWORD

IMyDispatch STRUCT
IMyDispatch_QueryInterface dd ?
IMyDispatch_AddRef dd ?
IMyDispatch_Release dd ?
IMyDispatch_GetTypeInfoCount dd ?
IMyDispatch_GetTypeInfo dd ?
IMyDispatch_GetIDsOfNames dd ?
IMyDispatch_Invoke_ dd ?
IMyDispatch ENDS

MyDispatch IMyDispatch <offset MyQueryInterface, offset MyAddRef, \
offset MyRelease,offset MyGetTypeInfoCount, \
offset MyGetTypeInfo,offset MyGetIDsOfNames,offset MyInvoke_ >

does that look ok thus far?
Posted on 2003-07-18 02:33:22 by Homer
yes, no problem

you may look at include file There a IDispatch event sink interface is defined in macro DEFINE_EVENTHELPER, which may give you some clues.
Posted on 2003-07-18 03:15:52 by japheth
Ok good, I made progress, but unfortunately I've hit a wall.
When I call IConnectionPoint_Advise, my IUnknown_QueryInterface procedure is getting a request from the object for a pointer to the Events Interface (it's sending me the Events IID in the request), but my IDispatch_Invoke never gets hit. Yours does, I've just found your handy dandy events notifications window in ur comview tool :)
Strange, the "Cookie" handed back by the Advise method looks awfully like the interface pointer I hand back from QueryInterface too ... does Advise actually manipulate the vtable of the source interface in some way? If so, since this is an InProc server, do I have write access to do this myself?

Here's my Unknown_QueryInterface handler code - look ok ?
Only the first case ever gets triggered by this object it seems.

det dd ?
MyQueryInterface proc pThis:LPTHIS,pid:LPGUID, peepee:DWORD
mov esi,pid
mov edi,peepee
invoke CmpGUID,esi,addr IID_IYAcsEvents,16 ;This is it
.if eax==TRUE
lea eax,MyDispatch
mov det,eax
lea eax,det
mov dword ptr,eax
return S_OK
invoke CmpGUID,esi,addr IID_IUnknown,16
.if eax==TRUE
lea eax,MyDispatch
mov det,eax
lea eax,det
mov dword ptr,eax
return S_OK
invoke CmpGUID,esi,addr IID_Dispatch,16
.if eax==TRUE
lea eax,MyDispatch
mov det,eax
lea eax,det
mov dword ptr,eax
return S_OK
mov dword ptr,0
invoke MessageBox,0,CTXT("An unhandled Interface Request was received.."),CTXT("Weirdness?"),MB_OK
MyQueryInterface ENDP

Sidenote - I am not "locking" or "activating" this windowless object, I've been assuming that CoCreateInstance handles all that... safe assumption?
Thanks for your time.
Posted on 2003-07-18 23:26:12 by Homer
Hi EvilHomer2k,

your source looks not so good.

1. your proc modifies esi and edi. like in win32 api these (and ebx) should be save before
2. when your QUeryInterface gets called, you have already supplied an object to the server (with
IConnectionPoint::Advise. Parameter pThis should point to that object. But now in QueryInterface you are about to return totally different addressesm which is bad, and that in a global variable, which is even worse.
3. If a QueryInterface is successful, you should logically call IUnknown::AddRef, that is increment an internal object reference pointer.


Although I have already mentioned to look at for a sample here are the steps to make a minimal event sink
1. create object: allocate 8 bytes from heap, mov address of vtable in first dword, set second dword to 1 (is object reference pointer).
2. supply this address to IConnectionPoint::Advise
3. In QueryInterface do: compare your interface IIDs, if found one, get pThis and increment second dword. return pThis as interface, not a global var. save registers!
Posted on 2003-07-19 01:47:27 by japheth
Ok I'll clean up my dirty code .. is it really necessary to allocate the object on the heap? The calling process has loaded and attached all the support dlls like ole32, and inproc servers share the process space of their client when the client is local, yes? What I mean is that just defining the interface in the data segment of the calling client is somehow not a good idea ?? I know COM is a set of rules and this constitutes a breach, but I'm always curious where the boundaries lay.
Regardless, I'll implement my interface in heap memory and preserve my registers like I should and we'll see if it makes the difference :)
Posted on 2003-07-19 11:42:31 by Homer
Hi EvilHomer2k

is it really necessary to allocate the object on the heap?

No, of course not. The rule you should comply is that addresses of interfaces your client returns to the server remain constant. So if you are sure you need only one instance of your sink, define it in global memory. And if you dont require any resources which should be freed on termination, you may even omit the reference counter.
Posted on 2003-07-19 16:51:31 by japheth
I correctly preserve registers in MyQueryInterface.
I don't implement the object in heap memory.
I don't implement the internal counter for the object.
I use dummy procedures for AddRef and Release.
All I did was define pvtbl at vtbl-4
It's working :)

I'm joyously writing casecode for the various dispids that hit MyInvoke procedure :)

Thankyou for your continual support - I think I popped my cherry :)
I'll tidy everything up, work on the gui a little, then I'll post it all here for the benefit of all. I've come to the conclusion that this stuff is where we're all going in the next decade, and I'm glad to learn how to apply my lowlevel approach to higher code objects.
Posted on 2003-07-19 22:43:01 by Homer
Congratulations, EvilHomer2k :alright:

I'm looking forward to the great app you will supply soon ;)

Posted on 2003-07-20 01:35:14 by japheth
The object does implement security against my client.
Furthermore it breaches the COM contract in many, many ways.

The project folder is online...please let me know if any files are missing.

I managed to ascertain so far that the object manipulates its own vtbl and typelib at runtime, and it has some unlisted functions in the dll which are initialisation functions, and that the entire object is meant to be instanced by a higher object, which I am now examining more closely. This higher object contains a dummy interface with a whole set of bad pointers, whose values are correctly set by a callback in the lower object (actually a seh triggered by a bad float).
Very strange, very interesting :)

This might all be sounding a little like RE, which it is, but the intent is not commercial nor malicious, the intent is to learn - of course :)

I won't use this space to comment on the nature of the beast , except to mention that I'm more curious than ever :)
Posted on 2003-07-23 03:17:58 by Homer
I just looked at this directory. Surely it is better to zip these files and attach them to your post. I assume that the server binary is needed as well (or is it a "standard" com object?)
Posted on 2003-07-23 05:19:09 by japheth
It's Yahoo! Inc. 's interface to Lerner and Hauspie TruSpeech Codec...
this is basically an implementation of RFC1889 - the RTP protocol.
Technically I'm not in breach of either their TOS or any copyright law including wipo and dmca, and I'm not breaching the etiquette of the board.
I won't discuss the internal workings of this commercial atl object, but I will release source as appropriate in the spirit of education and open source.

This object is installed during installation of either yahoo messenger or by using their java-based applet. The applet itself requires no formal authoritative or legal waiver or disclaimer, although TOS are binding for accounts.
Nonetheless, the property is not mine, I appreciate the legal rights of its owners regardless, and have no commercial interest in this project.
Posted on 2003-07-24 09:00:02 by Homer
I vote for the one-way valve, since it could make a big difference in the usefulness of the helmet. As for

the danger part, I have no problem with the danger involved, as I also have done some fool things in my

life. I understand there's a chance this could end your life, but if I were there, I'd want to try the damn

thing too.
Posted on 2010-07-08 21:17:46 by Dreamza
Posted on 2010-07-09 01:19:57 by Homer