MS OLE questions

Mike Hearn m.hearn at signal.qinetiq.com
Mon Jul 14 10:55:32 CDT 2003


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

-- 
Mike Hearn <m.hearn at signal.qinetiq.com>
QinetiQ - Malvern Technology Center




More information about the wine-devel mailing list