Delegated proxies pass the IID of the parent interface to NdrProxyGetBuffer(). However, this interface was never registered with ole32 on the server side, so calls to delegated methods will return RPC_S_UNKNOWN_IF. Therefore we have ole32 ignore the passed-in parameter and use the real proxy ID.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45673 Signed-off-by: Zebediah Figura z.figura12@gmail.com --- It's not clear to me that this is the correct way to solve bug 45673. If this seems to be the wrong approach; I'd really appreciate some help on determining what the right approach is.
dlls/ole32/compobj_private.h | 2 +- dlls/ole32/marshal.c | 2 +- dlls/ole32/rpc.c | 6 ++++-- dlls/rpcrt4/tests/cstub.c | 2 -- 4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h index 212d328..1e564a3 100644 --- a/dlls/ole32/compobj_private.h +++ b/dlls/ole32/compobj_private.h @@ -210,7 +210,7 @@ struct dispatch_params;
void RPC_StartRemoting(struct apartment *apt) DECLSPEC_HIDDEN; HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, - const OXID_INFO *oxid_info, + const OXID_INFO *oxid_info, const IID *iid, DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan, APARTMENT *apt) DECLSPEC_HIDDEN; HRESULT RPC_CreateServerChannel(DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan) DECLSPEC_HIDDEN; diff --git a/dlls/ole32/marshal.c b/dlls/ole32/marshal.c index 7c0f541..6bfd47e 100644 --- a/dlls/ole32/marshal.c +++ b/dlls/ole32/marshal.c @@ -1290,7 +1290,7 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, { IRpcChannelBuffer *chanbuf; hr = RPC_CreateClientChannel(&stdobjref->oxid, &stdobjref->ipid, - &proxy_manager->oxid_info, + &proxy_manager->oxid_info, riid, proxy_manager->dest_context, proxy_manager->dest_context_data, &chanbuf, apt); diff --git a/dlls/ole32/rpc.c b/dlls/ole32/rpc.c index 9aa945b..bd4611d 100644 --- a/dlls/ole32/rpc.c +++ b/dlls/ole32/rpc.c @@ -109,6 +109,7 @@ typedef struct OXID oxid; /* apartment in which the channel is valid */ DWORD server_pid; /* id of server process */ HANDLE event; /* cached event handle */ + IID iid; /* IID of the proxy this belongs to */ } ClientRpcChannelBuffer;
struct dispatch_params @@ -650,7 +651,7 @@ static HRESULT WINAPI ClientRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface,
cif->Length = sizeof(RPC_CLIENT_INTERFACE); /* RPC interface ID = COM interface ID */ - cif->InterfaceId.SyntaxGUID = *riid; + cif->InterfaceId.SyntaxGUID = This->iid; /* COM objects always have a version of 0.0 */ cif->InterfaceId.SyntaxVersion.MajorVersion = 0; cif->InterfaceId.SyntaxVersion.MinorVersion = 0; @@ -1096,7 +1097,7 @@ static const IRpcChannelBufferVtbl ServerRpcChannelBufferVtbl =
/* returns a channel buffer for proxies */ HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, - const OXID_INFO *oxid_info, + const OXID_INFO *oxid_info, const IID *iid, DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan, APARTMENT *apt) { @@ -1155,6 +1156,7 @@ HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, apartment_getoxid(apt, &This->oxid); This->server_pid = oxid_info->dwPid; This->event = NULL; + This->iid = *iid;
*chan = &This->super.IRpcChannelBuffer_iface;
diff --git a/dlls/rpcrt4/tests/cstub.c b/dlls/rpcrt4/tests/cstub.c index 22d4569..6b99e82 100644 --- a/dlls/rpcrt4/tests/cstub.c +++ b/dlls/rpcrt4/tests/cstub.c @@ -1403,10 +1403,8 @@ static void test_delegated_methods(void) ok(ret == 9, "got %d\n", ret);
hr = ITest1_GetClassID(test_obj, &clsid); -todo_wine { ok(hr == S_OK, "got %#x\n", hr); ok(IsEqualGUID(&clsid, &CLSID_test1), "got %s\n", wine_dbgstr_guid(&clsid)); -}
ITest1_Release(test_obj);