ole: Pass a channel into IRpcStubBuffer::Invoke.
Create a server channel and store this in the ifstub. Rename ipid_to_apt_and_stubbuffer to ipid_get_dispatch_params and make the function return an HRESULT. Return the channel for the ifstub in ipid_get_dispatch_params.
This commit is contained in:
parent
8e5b36147d
commit
a02cb3ebd6
|
@ -72,6 +72,7 @@ struct ifstub
|
|||
IPID ipid; /* RO */
|
||||
IUnknown *iface; /* RO */
|
||||
MSHLFLAGS flags; /* so we can enforce process-local marshalling rules (RO) */
|
||||
IRpcChannelBuffer*chan; /* channel passed to IRpcStubBuffer::Invoke (RO) */
|
||||
};
|
||||
|
||||
|
||||
|
@ -188,7 +189,7 @@ BOOL stub_manager_notify_unmarshal(struct stub_manager *m, const IPID *ipid);
|
|||
BOOL stub_manager_is_table_marshaled(struct stub_manager *m, const IPID *ipid);
|
||||
void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const IPID *ipid);
|
||||
HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub_manager **stubmgr_ret);
|
||||
IRpcStubBuffer *ipid_to_apt_and_stubbuffer(const IPID *ipid, APARTMENT **stub_apt);
|
||||
HRESULT ipid_get_dispatch_params(const IPID *ipid, APARTMENT **stub_apt, IRpcStubBuffer **stub, IRpcChannelBuffer **chan);
|
||||
HRESULT start_apartment_remote_unknown(void);
|
||||
|
||||
HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *obj, MSHLFLAGS mshlflags);
|
||||
|
@ -199,6 +200,7 @@ struct dispatch_params;
|
|||
|
||||
void RPC_StartRemoting(struct apartment *apt);
|
||||
HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, IRpcChannelBuffer **pipebuf);
|
||||
HRESULT RPC_CreateServerChannel(IRpcChannelBuffer **chan);
|
||||
void RPC_ExecuteCall(struct dispatch_params *params);
|
||||
HRESULT RPC_RegisterInterface(REFIID riid);
|
||||
void RPC_UnregisterInterface(REFIID riid);
|
||||
|
|
|
@ -227,7 +227,6 @@ static HRESULT WINAPI RpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER iface, RPC
|
|||
DWORD index;
|
||||
struct dispatch_params *params;
|
||||
DWORD tid;
|
||||
IRpcStubBuffer *stub;
|
||||
APARTMENT *apt;
|
||||
IPID ipid;
|
||||
|
||||
|
@ -248,11 +247,9 @@ static HRESULT WINAPI RpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER iface, RPC
|
|||
* from DllMain */
|
||||
|
||||
RpcBindingInqObject(msg->Handle, &ipid);
|
||||
stub = ipid_to_apt_and_stubbuffer(&ipid, &apt);
|
||||
if (apt && (apt->model & COINIT_APARTMENTTHREADED))
|
||||
hr = ipid_get_dispatch_params(&ipid, &apt, ¶ms->stub, ¶ms->chan);
|
||||
if ((hr == S_OK) && (apt->model & COINIT_APARTMENTTHREADED))
|
||||
{
|
||||
params->stub = stub;
|
||||
params->chan = NULL; /* FIXME: pass server channel */
|
||||
params->handle = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
|
||||
TRACE("Calling apartment thread 0x%08lx...\n", apt->tid);
|
||||
|
@ -261,7 +258,15 @@ static HRESULT WINAPI RpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER iface, RPC
|
|||
}
|
||||
else
|
||||
{
|
||||
if (stub) IRpcStubBuffer_Release(stub);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
/* otherwise, we go via RPC runtime so the stub and channel aren't
|
||||
* needed here */
|
||||
IRpcStubBuffer_Release(params->stub);
|
||||
params->stub = NULL;
|
||||
IRpcChannelBuffer_Release(params->chan);
|
||||
params->chan = NULL;
|
||||
}
|
||||
|
||||
/* we use a separate thread here because we need to be able to
|
||||
* pump the message loop in the application thread: if we do not,
|
||||
|
@ -275,6 +280,8 @@ static HRESULT WINAPI RpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER iface, RPC
|
|||
ERR("Could not create RpcSendReceive thread, error %lx\n", GetLastError());
|
||||
hr = E_UNEXPECTED;
|
||||
}
|
||||
else
|
||||
hr = S_OK;
|
||||
}
|
||||
if (apt) apartment_release(apt);
|
||||
|
||||
|
@ -459,35 +466,35 @@ void RPC_ExecuteCall(struct dispatch_params *params)
|
|||
}
|
||||
__ENDTRY
|
||||
IRpcStubBuffer_Release(params->stub);
|
||||
IRpcChannelBuffer_Release(params->chan);
|
||||
if (params->handle) SetEvent(params->handle);
|
||||
}
|
||||
|
||||
static void __RPC_STUB dispatch_rpc(RPC_MESSAGE *msg)
|
||||
{
|
||||
struct dispatch_params *params;
|
||||
IRpcStubBuffer *stub;
|
||||
APARTMENT *apt;
|
||||
IPID ipid;
|
||||
APARTMENT *apt;
|
||||
IPID ipid;
|
||||
HRESULT hr;
|
||||
|
||||
RpcBindingInqObject(msg->Handle, &ipid);
|
||||
|
||||
TRACE("ipid = %s, iMethod = %d\n", debugstr_guid(&ipid), msg->ProcNum);
|
||||
|
||||
params = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*params));
|
||||
params = HeapAlloc(GetProcessHeap(), 0, sizeof(*params));
|
||||
if (!params) return RpcRaiseException(E_OUTOFMEMORY);
|
||||
|
||||
stub = ipid_to_apt_and_stubbuffer(&ipid, &apt);
|
||||
if (!apt || !stub)
|
||||
hr = ipid_get_dispatch_params(&ipid, &apt, ¶ms->stub, ¶ms->chan);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
if (apt) apartment_release(apt);
|
||||
ERR("no apartment found for ipid %s\n", debugstr_guid(&ipid));
|
||||
return RpcRaiseException(RPC_E_DISCONNECTED);
|
||||
return RpcRaiseException(hr);
|
||||
}
|
||||
|
||||
params->msg = (RPCOLEMESSAGE *)msg;
|
||||
params->stub = stub;
|
||||
params->chan = NULL; /* FIXME: pass server channel */
|
||||
params->status = RPC_S_OK;
|
||||
params->hr = S_OK;
|
||||
params->handle = NULL;
|
||||
|
||||
/* Note: this is the important difference between STAs and MTAs - we
|
||||
* always execute RPCs to STAs in the thread that originally created the
|
||||
|
|
|
@ -365,29 +365,38 @@ HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
/* gets the apartment and IRpcStubBuffer from an object. the caller must
|
||||
* release the references to both objects */
|
||||
IRpcStubBuffer *ipid_to_apt_and_stubbuffer(const IPID *ipid, APARTMENT **stub_apt)
|
||||
/* gets the apartment, stub and channel of an object. the caller must
|
||||
* release the references to all objects if the function returned success,
|
||||
* otherwise no references are returned. */
|
||||
HRESULT ipid_get_dispatch_params(const IPID *ipid, APARTMENT **stub_apt,
|
||||
IRpcStubBuffer **stub, IRpcChannelBuffer **chan)
|
||||
{
|
||||
IRpcStubBuffer *ret = NULL;
|
||||
struct stub_manager *stubmgr;
|
||||
struct ifstub *ifstub;
|
||||
APARTMENT *apt;
|
||||
HRESULT hr;
|
||||
|
||||
*stub_apt = NULL;
|
||||
|
||||
hr = ipid_to_stub_manager(ipid, stub_apt, &stubmgr);
|
||||
if (hr != S_OK) return NULL;
|
||||
hr = ipid_to_stub_manager(ipid, &apt, &stubmgr);
|
||||
if (hr != S_OK) return RPC_E_DISCONNECTED;
|
||||
|
||||
ifstub = stub_manager_ipid_to_ifstub(stubmgr, ipid);
|
||||
if (ifstub)
|
||||
ret = ifstub->stubbuffer;
|
||||
{
|
||||
*stub = ifstub->stubbuffer;
|
||||
IRpcStubBuffer_AddRef(*stub);
|
||||
*chan = ifstub->chan;
|
||||
IRpcChannelBuffer_AddRef(*chan);
|
||||
*stub_apt = apt;
|
||||
|
||||
if (ret) IRpcStubBuffer_AddRef(ret);
|
||||
|
||||
stub_manager_int_release(stubmgr);
|
||||
|
||||
return ret;
|
||||
stub_manager_int_release(stubmgr);
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
stub_manager_int_release(stubmgr);
|
||||
apartment_release(apt);
|
||||
return RPC_E_DISCONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
/* generates an ipid in the following format (similar to native version):
|
||||
|
@ -417,6 +426,7 @@ static inline HRESULT generate_ipid(struct stub_manager *m, IPID *ipid)
|
|||
struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid, MSHLFLAGS flags)
|
||||
{
|
||||
struct ifstub *stub;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("oid=%s, stubbuffer=%p, iptr=%p, iid=%s\n",
|
||||
wine_dbgstr_longlong(m->oid), sb, iptr, debugstr_guid(iid));
|
||||
|
@ -424,6 +434,13 @@ struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *s
|
|||
stub = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct ifstub));
|
||||
if (!stub) return NULL;
|
||||
|
||||
hr = RPC_CreateServerChannel(&stub->chan);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, stub);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stub->stubbuffer = sb;
|
||||
if (sb) IRpcStubBuffer_AddRef(sb);
|
||||
|
||||
|
@ -468,9 +485,10 @@ static void stub_manager_delete_ifstub(struct stub_manager *m, struct ifstub *if
|
|||
list_remove(&ifstub->entry);
|
||||
|
||||
RPC_UnregisterInterface(&ifstub->iid);
|
||||
|
||||
|
||||
if (ifstub->stubbuffer) IUnknown_Release(ifstub->stubbuffer);
|
||||
IUnknown_Release(ifstub->iface);
|
||||
IRpcChannelBuffer_Release(ifstub->chan);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, ifstub);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue