combase: Generate apartment OXID in rpcss
Currently, apartment OXIDs are generated using the process ID
(and the thread ID for a single threaded-apartment). This means
that if an apartment is destroyed and re-created (using
CoUninitialize
followed by CoInitializeEx
), the newly created
apartment will end up with the same OXID as the old apartment.
However, testing shows that Windows will generate a new OXID
when an apartment is created in the above manner. This patch
uses rpcss
to generate a new OXID. The current process id is combined
with an incrementing counter stored in rpcss. This ensures that
re-creating an apartment will not re-use an OXID.
Additionally, this fixes an issue that caused the .NET 4.8 installer to become stuck during the downloading stage under Wine. The installer appears to perform the following actions:
- Call
IBackgroundCopyJob_SetNotify
interface on a BITS job. This causes us to create a proxy (in the other process hosting 'qmgr') for theIBackgroundCopyCallback
pointer passed as a parameter. - Trigger MTA apartment re-creation (in the process running the setup,
not the process with the
IBackgroundCopyCallback
proxy) throughCoUninitialize
followed byCoInitializeEx
. - Call
IBackgroundCopyJob_SetNotify
on a newly created job, but with the sameIBackgroundCopyCallback
pointer parameter.
When we deserialize the pointer passed to
IBackgroundCopyJob_SetNotify
, we will end up re-using the same
proxy_manager
that we created for the previous IBackgroundCopyCallback
.
This is due to the fact that the OIDs happen to match (due to the fact that
the .NET 4.8 setup appears to perform actions in the same order between
the old and new apartments), and the apartment OXIDs match as explained above.
above. As a result, we will use the old IPID when we send RPC packets
using this proxy_manager
. However, the new and old IPIDs will never match,
since their generation process includes RtlGenRandom
. This will cause a fault
packet to be generated on the listening side of the RPC connection.
By avoiding re-using OXIDs across re-created apartments,
we ensure that the proxy side will never incorrectly re-use a stale proxy_manager
.