- Remove cruft left over from previous RPC backend implementation in
the apartment structure. - Don't pass an IPID by value for proxy_manager_create_ifproxy. - Disable more of RPC_UnregisterInterface to prevent the RPC runtime using freed memory. - Rename various external RPC backend functions so that they all have the same "RPC_" prefix. - Reduce the timeout of the function that connects to a local server to 30s, like native.
This commit is contained in:
parent
a830bf55ca
commit
552cc7d5b3
|
@ -245,8 +245,6 @@ static APARTMENT *apartment_construct(DWORD model)
|
|||
apt->oxid = ((OXID)GetCurrentProcessId() << 32) | 0xcafe;
|
||||
}
|
||||
|
||||
apt->shutdown_event = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
TRACE("Created apartment on OXID %s\n", wine_dbgstr_longlong(apt->oxid));
|
||||
|
||||
/* the locking here is not currently needed for the MTA case, but it
|
||||
|
@ -350,8 +348,6 @@ DWORD COM_ApartmentRelease(struct apartment *apt)
|
|||
if (apt->filter) IUnknown_Release(apt->filter);
|
||||
|
||||
DeleteCriticalSection(&apt->cs);
|
||||
SetEvent(apt->shutdown_event);
|
||||
CloseHandle(apt->shutdown_event);
|
||||
CloseHandle(apt->thread);
|
||||
HeapFree(GetProcessHeap(), 0, apt);
|
||||
}
|
||||
|
@ -1630,7 +1626,7 @@ HRESULT WINAPI CoGetClassObject(
|
|||
/* Next try out of process */
|
||||
if (CLSCTX_LOCAL_SERVER & dwClsContext)
|
||||
{
|
||||
return create_marshalled_proxy(rclsid,iid,ppv);
|
||||
return RPC_GetLocalClassObject(rclsid,iid,ppv);
|
||||
}
|
||||
|
||||
/* Finally try remote: this requires networked DCOM (a lot of work) */
|
||||
|
|
|
@ -130,11 +130,10 @@ struct apartment
|
|||
struct list proxies; /* imported objects (CS cs) */
|
||||
struct list stubmgrs; /* stub managers for exported objects (CS cs) */
|
||||
BOOL remunk_exported; /* has the IRemUnknown interface for this apartment been created yet? (CS cs) */
|
||||
LONG remoting_started; /* has the RPC system been started for this apartment? (LOCK) */
|
||||
|
||||
/* FIXME: These should all be removed long term as they leak information that should be encapsulated */
|
||||
/* FIXME: OID's should be given out by RPCSS */
|
||||
OID oidc; /* object ID counter, starts at 1, zero is invalid OID (CS cs) */
|
||||
DWORD listenertid; /* id of apartment_listener_thread */
|
||||
HANDLE shutdown_event; /* event used to tell the client_dispatch_thread to shut down */
|
||||
};
|
||||
|
||||
/* this is what is stored in TEB->ReservedForOle */
|
||||
|
@ -146,37 +145,23 @@ struct oletls
|
|||
DWORD inits; /* number of times CoInitializeEx called */
|
||||
};
|
||||
|
||||
|
||||
/* Global Interface Table Functions */
|
||||
|
||||
extern void* StdGlobalInterfaceTable_Construct(void);
|
||||
extern void StdGlobalInterfaceTable_Destroy(void* self);
|
||||
extern HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv);
|
||||
extern void* StdGlobalInterfaceTableInstance;
|
||||
|
||||
/* FIXME: these shouldn't be needed, except for 16-bit functions */
|
||||
extern HRESULT WINE_StringFromCLSID(const CLSID *id,LPSTR idstr);
|
||||
HRESULT WINAPI __CLSIDFromStringA(LPCSTR idstr, CLSID *id);
|
||||
|
||||
extern HRESULT create_marshalled_proxy(REFCLSID rclsid, REFIID iid, LPVOID *ppv);
|
||||
|
||||
extern void* StdGlobalInterfaceTableInstance;
|
||||
|
||||
/* Standard Marshalling definitions */
|
||||
typedef struct _wine_marshal_id {
|
||||
OXID oxid; /* id of apartment */
|
||||
OID oid; /* id of stub manager */
|
||||
IPID ipid; /* id of interface pointer */
|
||||
} wine_marshal_id;
|
||||
|
||||
inline static BOOL
|
||||
MARSHAL_Compare_Mids(wine_marshal_id *mid1,wine_marshal_id *mid2) {
|
||||
return
|
||||
(mid1->oxid == mid2->oxid) &&
|
||||
(mid1->oid == mid2->oid) &&
|
||||
IsEqualGUID(&(mid1->ipid),&(mid2->ipid))
|
||||
;
|
||||
}
|
||||
|
||||
HRESULT MARSHAL_Disconnect_Proxies(APARTMENT *apt);
|
||||
HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv);
|
||||
|
||||
/* Stub Manager */
|
||||
|
||||
ULONG stub_manager_int_addref(struct stub_manager *This);
|
||||
ULONG stub_manager_int_release(struct stub_manager *This);
|
||||
struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object);
|
||||
|
@ -193,15 +178,15 @@ HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub
|
|||
IRpcStubBuffer *ipid_to_apt_and_stubbuffer(const IPID *ipid, APARTMENT **stub_apt);
|
||||
HRESULT start_apartment_remote_unknown(void);
|
||||
|
||||
IRpcStubBuffer *mid_to_stubbuffer(wine_marshal_id *mid);
|
||||
/* RPC Backend */
|
||||
|
||||
void start_apartment_listener_thread(void);
|
||||
|
||||
HRESULT PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **pipebuf);
|
||||
void RPC_StartRemoting(struct apartment *apt);
|
||||
HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, IRpcChannelBuffer **pipebuf);
|
||||
HRESULT RPC_ExecuteCall(RPCOLEMESSAGE *msg, IRpcStubBuffer *stub);
|
||||
HRESULT RPC_RegisterInterface(REFIID riid);
|
||||
void RPC_UnregisterInterface(REFIID riid);
|
||||
void RPC_StartLocalServer(REFCLSID clsid, IStream *stream);
|
||||
void RPC_UnregisterInterface(REFIID riid);
|
||||
void RPC_StartLocalServer(REFCLSID clsid, IStream *stream);
|
||||
HRESULT RPC_GetLocalClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv);
|
||||
|
||||
/* This function initialize the Running Object Table */
|
||||
HRESULT WINAPI RunningObjectTableImpl_Initialize(void);
|
||||
|
@ -212,7 +197,9 @@ HRESULT WINAPI RunningObjectTableImpl_UnInitialize(void);
|
|||
/* This function decomposes a String path to a String Table containing all the elements ("\" or "subDirectory" or "Directory" or "FileName") of the path */
|
||||
int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable);
|
||||
|
||||
/* compobj.c */
|
||||
|
||||
/* Apartment Functions */
|
||||
|
||||
APARTMENT *COM_ApartmentFromOXID(OXID oxid, BOOL ref);
|
||||
APARTMENT *COM_ApartmentFromTID(DWORD tid);
|
||||
DWORD COM_ApartmentAddRef(struct apartment *apt);
|
||||
|
|
|
@ -476,7 +476,7 @@ static HRESULT proxy_manager_query_local_interface(struct proxy_manager * This,
|
|||
}
|
||||
|
||||
static HRESULT proxy_manager_create_ifproxy(
|
||||
struct proxy_manager * This, IPID ipid, REFIID riid, ULONG cPublicRefs,
|
||||
struct proxy_manager * This, const IPID *ipid, REFIID riid, ULONG cPublicRefs,
|
||||
struct ifproxy ** iif_out)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
@ -487,7 +487,7 @@ static HRESULT proxy_manager_create_ifproxy(
|
|||
list_init(&ifproxy->entry);
|
||||
|
||||
ifproxy->parent = This;
|
||||
ifproxy->ipid = ipid;
|
||||
ifproxy->ipid = *ipid;
|
||||
ifproxy->iid = *riid;
|
||||
ifproxy->refs = cPublicRefs;
|
||||
ifproxy->proxy = NULL;
|
||||
|
@ -535,7 +535,7 @@ static HRESULT proxy_manager_create_ifproxy(
|
|||
|
||||
*iif_out = ifproxy;
|
||||
TRACE("ifproxy %p created for IPID %s, interface %s with %lu public refs\n",
|
||||
ifproxy, debugstr_guid(&ipid), debugstr_guid(riid), cPublicRefs);
|
||||
ifproxy, debugstr_guid(ipid), debugstr_guid(riid), cPublicRefs);
|
||||
}
|
||||
else
|
||||
ifproxy_destroy(ifproxy);
|
||||
|
@ -795,8 +795,8 @@ StdMarshalImpl_MarshalInterface(
|
|||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
|
||||
start_apartment_listener_thread(); /* just to be sure we have one running. */
|
||||
start_apartment_remote_unknown();
|
||||
/* make sure this apartment can be reached from other threads / processes */
|
||||
RPC_StartRemoting(apt);
|
||||
|
||||
hres = IUnknown_QueryInterface((LPUNKNOWN)pv, riid, (LPVOID*)&pUnk);
|
||||
if (hres != S_OK)
|
||||
|
@ -843,13 +843,8 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFI
|
|||
if (!find_proxy_manager(apt, stdobjref->oxid, stdobjref->oid, &proxy_manager))
|
||||
{
|
||||
IRpcChannelBuffer *chanbuf;
|
||||
wine_marshal_id mid;
|
||||
|
||||
mid.oxid = stdobjref->oxid;
|
||||
mid.oid = stdobjref->oid;
|
||||
mid.ipid = stdobjref->ipid;
|
||||
|
||||
hr = PIPE_GetNewPipeBuf(&mid,&chanbuf);
|
||||
hr = RPC_CreateClientChannel(&stdobjref->oxid, &stdobjref->ipid, &chanbuf);
|
||||
if (hr == S_OK)
|
||||
hr = proxy_manager_construct(apt, stdobjref->flags,
|
||||
stdobjref->oxid, stdobjref->oid,
|
||||
|
@ -863,7 +858,7 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFI
|
|||
struct ifproxy * ifproxy;
|
||||
hr = proxy_manager_find_ifproxy(proxy_manager, riid, &ifproxy);
|
||||
if (hr == E_NOINTERFACE)
|
||||
hr = proxy_manager_create_ifproxy(proxy_manager, stdobjref->ipid,
|
||||
hr = proxy_manager_create_ifproxy(proxy_manager, &stdobjref->ipid,
|
||||
riid, stdobjref->cPublicRefs,
|
||||
&ifproxy);
|
||||
|
||||
|
|
|
@ -280,8 +280,7 @@ static const IRpcChannelBufferVtbl ServerRpcChannelBufferVtbl =
|
|||
};
|
||||
|
||||
/* returns a channel buffer for proxies */
|
||||
/* FIXME: needs renaming and mid removing */
|
||||
HRESULT PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **chan)
|
||||
HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, IRpcChannelBuffer **chan)
|
||||
{
|
||||
ClientRpcChannelBuffer *This;
|
||||
WCHAR endpoint[200];
|
||||
|
@ -290,7 +289,7 @@ HRESULT PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **chan)
|
|||
LPWSTR string_binding;
|
||||
|
||||
/* connect to the apartment listener thread */
|
||||
get_rpc_endpoint(endpoint, &mid->oxid);
|
||||
get_rpc_endpoint(endpoint, oxid);
|
||||
|
||||
TRACE("proxy pipe: connecting to endpoint: %s\n", debugstr_w(endpoint));
|
||||
|
||||
|
@ -308,7 +307,8 @@ HRESULT PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **chan)
|
|||
|
||||
if (status == RPC_S_OK)
|
||||
{
|
||||
status = RpcBindingSetObject(bind, &mid->ipid);
|
||||
IPID ipid2 = *ipid; /* why can't RpcBindingSetObject take a const? */
|
||||
status = RpcBindingSetObject(bind, &ipid2);
|
||||
if (status != RPC_S_OK)
|
||||
RpcBindingFree(&bind);
|
||||
}
|
||||
|
@ -459,9 +459,9 @@ void RPC_UnregisterInterface(REFIID riid)
|
|||
#if 0 /* this is a stub in builtin and spams the console with FIXME's */
|
||||
IID iid = *riid; /* RpcServerUnregisterIf doesn't take const IID */
|
||||
RpcServerUnregisterIf((RPC_IF_HANDLE)&rif->If, &iid, 0);
|
||||
#endif
|
||||
list_remove(&rif->entry);
|
||||
HeapFree(GetProcessHeap(), 0, rif);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -469,12 +469,11 @@ void RPC_UnregisterInterface(REFIID riid)
|
|||
LeaveCriticalSection(&csRegIf);
|
||||
}
|
||||
|
||||
/* FIXME: needs renaming */
|
||||
void start_apartment_listener_thread()
|
||||
/* make the apartment reachable by other threads and processes and create the
|
||||
* IRemUnknown object */
|
||||
void RPC_StartRemoting(struct apartment *apt)
|
||||
{
|
||||
APARTMENT *apt = COM_CurrentApt(); /* FIXME: pass as parameter */
|
||||
|
||||
if (!apt->listenertid)
|
||||
if (!InterlockedExchange(&apt->remoting_started, TRUE))
|
||||
{
|
||||
WCHAR endpoint[200];
|
||||
RPC_STATUS status;
|
||||
|
@ -488,13 +487,14 @@ void start_apartment_listener_thread()
|
|||
NULL);
|
||||
if (status != RPC_S_OK)
|
||||
ERR("Couldn't register endpoint %s\n", debugstr_w(endpoint));
|
||||
apt->listenertid = TRUE; /* FIXME: don't abuse this field and use remunk_exported, by moving remunk exporting into this function */
|
||||
|
||||
/* FIXME: move remote unknown exporting into this function */
|
||||
}
|
||||
start_apartment_remote_unknown();
|
||||
}
|
||||
|
||||
|
||||
static HRESULT
|
||||
create_server(REFCLSID rclsid)
|
||||
static HRESULT create_server(REFCLSID rclsid)
|
||||
{
|
||||
static const WCHAR embedding[] = { ' ', '-','E','m','b','e','d','d','i','n','g',0 };
|
||||
HKEY key;
|
||||
|
@ -548,8 +548,7 @@ create_server(REFCLSID rclsid)
|
|||
/*
|
||||
* start_local_service() - start a service given its name and parameters
|
||||
*/
|
||||
static DWORD
|
||||
start_local_service(LPCWSTR name, DWORD num, LPWSTR *params)
|
||||
static DWORD start_local_service(LPCWSTR name, DWORD num, LPWSTR *params)
|
||||
{
|
||||
SC_HANDLE handle, hsvc;
|
||||
DWORD r = ERROR_FUNCTION_FAILED;
|
||||
|
@ -586,8 +585,7 @@ start_local_service(LPCWSTR name, DWORD num, LPWSTR *params)
|
|||
*
|
||||
* Note: Local Services are not supported under Windows 9x
|
||||
*/
|
||||
static HRESULT
|
||||
create_local_service(REFCLSID rclsid)
|
||||
static HRESULT create_local_service(REFCLSID rclsid)
|
||||
{
|
||||
HRESULT hres = REGDB_E_READREGDB;
|
||||
WCHAR buf[40], keyname[50];
|
||||
|
@ -655,7 +653,7 @@ create_local_service(REFCLSID rclsid)
|
|||
#define PIPEPREF "\\\\.\\pipe\\"
|
||||
|
||||
/* FIXME: should call to rpcss instead */
|
||||
HRESULT create_marshalled_proxy(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
|
||||
HRESULT RPC_GetLocalClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
|
||||
{
|
||||
HRESULT hres;
|
||||
HANDLE hPipe;
|
||||
|
@ -667,7 +665,7 @@ HRESULT create_marshalled_proxy(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
|
|||
ULARGE_INTEGER newpos;
|
||||
int tries = 0;
|
||||
|
||||
static const int MAXTRIES = 10000;
|
||||
static const int MAXTRIES = 30; /* 30 seconds */
|
||||
|
||||
TRACE("rclsid=%s, iid=%s\n", debugstr_guid(rclsid), debugstr_guid(iid));
|
||||
|
||||
|
|
Loading…
Reference in New Issue