Skip to content
Snippets Groups Projects
  1. Jan 31, 2023
    • Aaron Hill's avatar
      combase: Generate apartment OXID in rpcss · 1f3186d0
      Aaron Hill authored
      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:
      
      1. Call `IBackgroundCopyJob_SetNotify` interface on a BITS
         job. This causes us to create a proxy (in the other process
         hosting 'qmgr') for the `IBackgroundCopyCallback` pointer
         passed as a parameter.
      2. Trigger MTA apartment re-creation (in the process running the setup,
         *not* the process with the `IBackgroundCopyCallback` proxy)
         through `CoUninitialize` followed by `CoInitializeEx`.
      3. Call `IBackgroundCopyJob_SetNotify` on a newly created job,
         but with the same `IBackgroundCopyCallback` 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`.
      Verified
      1f3186d0
    • Aaron Hill's avatar
      ole32: Test that re-creating an apartment results in a new OXID · e190b654
      Aaron Hill authored
      Wine currently re-uses the original OXID when an apartment
      is re-created, so this is marked with `todo_wine` for now.
      Verified
      e190b654
  2. Jan 30, 2023
  3. Jan 27, 2023
Loading