- 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:
Robert Shearman 2005-02-15 15:44:25 +00:00 committed by Alexandre Julliard
parent a830bf55ca
commit 552cc7d5b3
4 changed files with 42 additions and 66 deletions

View File

@ -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) */

View File

@ -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);
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);

View File

@ -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);

View File

@ -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));