[PATCH 5/6] ole32: Allow unmarshalling objects into an implicit MTA.

Zebediah Figura z.figura12 at gmail.com
Mon Apr 9 21:24:48 CDT 2018


On 09/04/18 21:15, Zebediah Figura wrote:
> Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
> ---
>  dlls/ole32/compobj.c         |   2 +-
>  dlls/ole32/compobj_private.h |   3 +-
>  dlls/ole32/marshal.c         |  32 ++++++++----
>  dlls/ole32/rpc.c             |  12 +++--
>  dlls/ole32/tests/marshal.c   | 114 +++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 148 insertions(+), 15 deletions(-)
> 

Repasting my earlier note here since I forgot to edit the patch:

----

This patch results in some good news and some bad news for bug 18070.

The good news is that we can unmarshal into literally any
thread—uninitialized, STA, or MTA—as long as there's an MTA somewhere
else in the process. This means we can use a COM proxy on any
thread. The bad news is that we can't change threading models
(i.e. initialize or uninitialize COM on a thread) while we're doing
this, or ole32 will throw up RPC_E_WRONG_THREAD when we try to make a
proxy call.

The symptoms of bug 18070 show that there has to exist an MTA in the
process, but that COM can't be initialized on the thread itself: "It
is up to the custom action to initialize COM to its liking." This fits
the MTA condition quite nicely, but then runs into the separate
problem that the custom action can change the threading model on us.

What this means is that we can't keep proxies around on the custom
action's thread and then just run all calls to MSI functions through
them, since they might go bad at any point. I see at least two
solutions to this:

(1) Keep the COM objects on a different thread (probably just the
thread that the MTA is initialized on). Then use a dedicated 'pipe'
thread to thunk callbacks to the MTA thread, whence they will then be
converted into proxy calls.

(2) Instead of keeping COM objects around during the entire custom
action, create and then release one generic 'server' object every time
an MSI function is called. This will, of course, work regardless of
what threading model the custom action's thread is actively using,
since it won't change during the course of the call.

(3) Along the same lines as (2), but potentially even simpler: use the
RPC APIs directly. That is, replace our
IWineMsiRemotePackage_GetProperty(...) with a simpler
remote_GetProperty(...) that does about the same thing, but without
the overhead of going through ole32. (And for all the work I did to
make ole32 work right! But it is for the best.)

I'm most inclined towards (3)—I think it'll be the solution with the
least overhead, and it won't take too much work to convert from what
we have.

Therefore: if anyone has any alternate preferences, reasons why one or
more of the above won't work, or general feedback, please speak now.
Alternatively, wait until I've done all the work to convert everything
to RPC server stubs, and then tell me why it all won't work ;-)



More information about the wine-devel mailing list