Before I start, sorry for the long email, but if I'm going to make our app work within the 3 weeks I have left, I'm going to have to learn about COM pretty quickly :/
Reading through the patch, I have a few questions.
Firstly, how much of the code in this patch is already duplicated in the WineHQ tree? I see a oleproxy.c file, from Marcus (C) 2002, which you removed from the build, but your patch is in parts (C) 2001. Does that mean that the patch removes code that actually it shouldn't when applied to WineHQ?
I don't understand this code:
+static void RpcChannel_push_request(RpcRequest *req) +{ + req->next = NULL; + req->ret = RPC_S_CALL_IN_PROGRESS; /* ? */ + EnterCriticalSection(&creq_cs); + if (creq_tail) creq_tail->next = req; + else { + creq_head = req; + creq_tail = req; + } + LeaveCriticalSection(&creq_cs); +}
If this is a double-ended queue, like it looks, then shouldn't the middle line read:
if (creq_tail) { creq_tail->next = req; creq_tail = req; } else .....
I can't see where creq_tail is moved otherwise. If you push two requests one after the other, it looks like the previous req would "fall off" the queue.
I don't understand why StubMan_Invoke only appears able to marshal IRemUnknown - I've been reading chapter 5 of "Essential COM" as well as MSDN and it would seem it should be able to marshal any interface? Is that just time pressures?
I don't understand what COM_CreateIIf does. Creates an imported interface?
In CoMarshalInterThreadInterfaceInStream(), there is this code:
+#ifdef FAKE_INTERTHREAD + hr = IStream_Write(*ppStm, &pUnk, sizeof(pUnk), NULL); + if (SUCCEEDED(hr)) IUnknown_AddRef(pUnk); + TRACE("<= %p\n", pUnk); +#else + hr = CoMarshalInterface(*ppStm, riid, pUnk, MSHCTX_INPROC, 0, MSHLFLAGS_NORMAL); +#endif
Was that just for development, or are there still times when fake interthread marshalling is needed?
In the builtin Proxy/Stub section, for IClassFactory, there is this code:
+#if 0 +/* we need to create an IDL compiler for Wine that can generate + * most of these automatically */
Followed by a section of unused code. Was this written before you decided to use MIDL? Is this code in the auto-generated dcom marshalling code? (I didn't read all of the auto-genned stuf)
In your typelib marshaller, there is this code:
+ case VT_VOID: /* <= InstallShield hack */ + { + LPVOID pv = *(LPVOID*)args; + const IID *piid; + if (pType->vt == VT_DISPATCH) piid = &IID_IDispatch; else + if (pType->vt == VT_UNKNOWN) piid = &IID_IUnknown; else + { + pv = (LPVOID)args; + piid = is_iid; + } + TRACE(" marshaling INTERFACE %p %s\n", pv, debugstr_guid(piid)); + hr = CoMarshalInterface(pStm, piid, pv, CLSCTX_LOCAL_SERVER, NULL, MSHLFLAGS_NORMAL); + } + break;
but in Marcus', it is just this:
case VT_VOID: if (debugout) MESSAGE("<void>"); return S_OK;
What is supposed to happen when marshalling a void param like this?
+static HRESULT WINAPI PSOAStub_Invoke(LPRPCSTUBBUFFER iface, + PRPCOLEMESSAGE pMsg, + LPRPCCHANNELBUFFER pChannel)
This function looks a lot like WineHQs ITypeInfo::Invoke. Is there any relation?
+static LPVOID OA_BuildProxyVtbl(LPTYPEINFO pInfo, int *pfs, int rec)
Likewise, this function would seem to be similar but not the same as some code in WineHQ (they both give warnings if you don't have stdole32.tlb). Same? Different?
Thanks for any insight you can give to me on these questions. Finally, I am wondering whether anything would break if I simply merged in (to my local tree) the duplicated code. As I mentioned previously, time is a big problem here, and I can't use Microsofts own implementation for whatever reason. I don't care about cleanliness.
thanks -mike