It's possible for a proxy to be released during the middle of an Invoke.
A specific scenario where this happened was a single-shot event sink
which, upon receiving the event it was waiting for, would immediately
call DispEventUnadvise. This removed the proxy pointing to that sink
from the connection point's list of subscribers and released it.
For such cases all state used to complete the Invoke must be owned by
the __proxy_frame kept on the stack; after calling NdrProxySendReceive
(which pumps STA messages and permits reentrancy), anything inside
*This could be use-after-free. MIDL_STUB_MESSAGE already had its own
IRPCChannelBuffer *pRpcChannelBuffer, but lacked its own refcount.
When this does crash, the exception is caught by RpcTryFinally, but
still leads to leaks since NdrProxyFreeBuffer wasn't able to call
IRPCChannelBuffer::FreeBuffer. To fix this, StdProxy_GetChannel() now
calls AddRef() when setting __proxy_frame::_StubMsg::pRpcChannelBuffer
and NdrProxyFreeBuffer() calls the corresponding Release().
--
v3: rpcrt4: Add a refcount owned by MIDL_STUB_MESSAGE.
rpcrt4/tests: Add tests for lifetime of IRpcChannelBuffer.
https://gitlab.winehq.org/wine/wine/-/merge_requests/957