Commit 552cc7d5 authored by Robert Shearman's avatar Robert Shearman Committed by Alexandre Julliard

- 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.
parent a830bf55
...@@ -245,8 +245,6 @@ static APARTMENT *apartment_construct(DWORD model) ...@@ -245,8 +245,6 @@ static APARTMENT *apartment_construct(DWORD model)
apt->oxid = ((OXID)GetCurrentProcessId() << 32) | 0xcafe; 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)); 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 /* the locking here is not currently needed for the MTA case, but it
...@@ -350,8 +348,6 @@ DWORD COM_ApartmentRelease(struct apartment *apt) ...@@ -350,8 +348,6 @@ DWORD COM_ApartmentRelease(struct apartment *apt)
if (apt->filter) IUnknown_Release(apt->filter); if (apt->filter) IUnknown_Release(apt->filter);
DeleteCriticalSection(&apt->cs); DeleteCriticalSection(&apt->cs);
SetEvent(apt->shutdown_event);
CloseHandle(apt->shutdown_event);
CloseHandle(apt->thread); CloseHandle(apt->thread);
HeapFree(GetProcessHeap(), 0, apt); HeapFree(GetProcessHeap(), 0, apt);
} }
...@@ -1630,7 +1626,7 @@ HRESULT WINAPI CoGetClassObject( ...@@ -1630,7 +1626,7 @@ HRESULT WINAPI CoGetClassObject(
/* Next try out of process */ /* Next try out of process */
if (CLSCTX_LOCAL_SERVER & dwClsContext) 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) */ /* Finally try remote: this requires networked DCOM (a lot of work) */
......
...@@ -130,11 +130,10 @@ struct apartment ...@@ -130,11 +130,10 @@ struct apartment
struct list proxies; /* imported objects (CS cs) */ struct list proxies; /* imported objects (CS cs) */
struct list stubmgrs; /* stub managers for exported 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) */ 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) */ 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 */ /* this is what is stored in TEB->ReservedForOle */
...@@ -146,37 +145,23 @@ struct oletls ...@@ -146,37 +145,23 @@ struct oletls
DWORD inits; /* number of times CoInitializeEx called */ DWORD inits; /* number of times CoInitializeEx called */
}; };
/* Global Interface Table Functions */
extern void* StdGlobalInterfaceTable_Construct(void); extern void* StdGlobalInterfaceTable_Construct(void);
extern void StdGlobalInterfaceTable_Destroy(void* self); extern void StdGlobalInterfaceTable_Destroy(void* self);
extern HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv); extern HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv);
extern void* StdGlobalInterfaceTableInstance;
/* FIXME: these shouldn't be needed, except for 16-bit functions */ /* FIXME: these shouldn't be needed, except for 16-bit functions */
extern HRESULT WINE_StringFromCLSID(const CLSID *id,LPSTR idstr); extern HRESULT WINE_StringFromCLSID(const CLSID *id,LPSTR idstr);
HRESULT WINAPI __CLSIDFromStringA(LPCSTR idstr, CLSID *id); 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_Disconnect_Proxies(APARTMENT *apt);
HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv); HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv);
/* Stub Manager */
ULONG stub_manager_int_addref(struct stub_manager *This); ULONG stub_manager_int_addref(struct stub_manager *This);
ULONG stub_manager_int_release(struct stub_manager *This); ULONG stub_manager_int_release(struct stub_manager *This);
struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object); 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 ...@@ -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); IRpcStubBuffer *ipid_to_apt_and_stubbuffer(const IPID *ipid, APARTMENT **stub_apt);
HRESULT start_apartment_remote_unknown(void); HRESULT start_apartment_remote_unknown(void);
IRpcStubBuffer *mid_to_stubbuffer(wine_marshal_id *mid); /* RPC Backend */
void start_apartment_listener_thread(void); void RPC_StartRemoting(struct apartment *apt);
HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, IRpcChannelBuffer **pipebuf);
HRESULT PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **pipebuf);
HRESULT RPC_ExecuteCall(RPCOLEMESSAGE *msg, IRpcStubBuffer *stub); HRESULT RPC_ExecuteCall(RPCOLEMESSAGE *msg, IRpcStubBuffer *stub);
HRESULT RPC_RegisterInterface(REFIID riid); HRESULT RPC_RegisterInterface(REFIID riid);
void RPC_UnregisterInterface(REFIID riid); void RPC_UnregisterInterface(REFIID riid);
void RPC_StartLocalServer(REFCLSID clsid, IStream *stream); void RPC_StartLocalServer(REFCLSID clsid, IStream *stream);
HRESULT RPC_GetLocalClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv);
/* This function initialize the Running Object Table */ /* This function initialize the Running Object Table */
HRESULT WINAPI RunningObjectTableImpl_Initialize(void); HRESULT WINAPI RunningObjectTableImpl_Initialize(void);
...@@ -212,7 +197,9 @@ HRESULT WINAPI RunningObjectTableImpl_UnInitialize(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 */ /* 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); int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable);
/* compobj.c */
/* Apartment Functions */
APARTMENT *COM_ApartmentFromOXID(OXID oxid, BOOL ref); APARTMENT *COM_ApartmentFromOXID(OXID oxid, BOOL ref);
APARTMENT *COM_ApartmentFromTID(DWORD tid); APARTMENT *COM_ApartmentFromTID(DWORD tid);
DWORD COM_ApartmentAddRef(struct apartment *apt); DWORD COM_ApartmentAddRef(struct apartment *apt);
......
...@@ -476,7 +476,7 @@ static HRESULT proxy_manager_query_local_interface(struct proxy_manager * This, ...@@ -476,7 +476,7 @@ static HRESULT proxy_manager_query_local_interface(struct proxy_manager * This,
} }
static HRESULT proxy_manager_create_ifproxy( 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) struct ifproxy ** iif_out)
{ {
HRESULT hr; HRESULT hr;
...@@ -487,7 +487,7 @@ static HRESULT proxy_manager_create_ifproxy( ...@@ -487,7 +487,7 @@ static HRESULT proxy_manager_create_ifproxy(
list_init(&ifproxy->entry); list_init(&ifproxy->entry);
ifproxy->parent = This; ifproxy->parent = This;
ifproxy->ipid = ipid; ifproxy->ipid = *ipid;
ifproxy->iid = *riid; ifproxy->iid = *riid;
ifproxy->refs = cPublicRefs; ifproxy->refs = cPublicRefs;
ifproxy->proxy = NULL; ifproxy->proxy = NULL;
...@@ -535,7 +535,7 @@ static HRESULT proxy_manager_create_ifproxy( ...@@ -535,7 +535,7 @@ static HRESULT proxy_manager_create_ifproxy(
*iif_out = ifproxy; *iif_out = ifproxy;
TRACE("ifproxy %p created for IPID %s, interface %s with %lu public refs\n", 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 else
ifproxy_destroy(ifproxy); ifproxy_destroy(ifproxy);
...@@ -795,8 +795,8 @@ StdMarshalImpl_MarshalInterface( ...@@ -795,8 +795,8 @@ StdMarshalImpl_MarshalInterface(
return CO_E_NOTINITIALIZED; return CO_E_NOTINITIALIZED;
} }
start_apartment_listener_thread(); /* just to be sure we have one running. */ /* make sure this apartment can be reached from other threads / processes */
start_apartment_remote_unknown(); RPC_StartRemoting(apt);
hres = IUnknown_QueryInterface((LPUNKNOWN)pv, riid, (LPVOID*)&pUnk); hres = IUnknown_QueryInterface((LPUNKNOWN)pv, riid, (LPVOID*)&pUnk);
if (hres != S_OK) if (hres != S_OK)
...@@ -843,13 +843,8 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFI ...@@ -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)) if (!find_proxy_manager(apt, stdobjref->oxid, stdobjref->oid, &proxy_manager))
{ {
IRpcChannelBuffer *chanbuf; IRpcChannelBuffer *chanbuf;
wine_marshal_id mid;
mid.oxid = stdobjref->oxid; hr = RPC_CreateClientChannel(&stdobjref->oxid, &stdobjref->ipid, &chanbuf);
mid.oid = stdobjref->oid;
mid.ipid = stdobjref->ipid;
hr = PIPE_GetNewPipeBuf(&mid,&chanbuf);
if (hr == S_OK) if (hr == S_OK)
hr = proxy_manager_construct(apt, stdobjref->flags, hr = proxy_manager_construct(apt, stdobjref->flags,
stdobjref->oxid, stdobjref->oid, stdobjref->oxid, stdobjref->oid,
...@@ -863,7 +858,7 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFI ...@@ -863,7 +858,7 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFI
struct ifproxy * ifproxy; struct ifproxy * ifproxy;
hr = proxy_manager_find_ifproxy(proxy_manager, riid, &ifproxy); hr = proxy_manager_find_ifproxy(proxy_manager, riid, &ifproxy);
if (hr == E_NOINTERFACE) 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, riid, stdobjref->cPublicRefs,
&ifproxy); &ifproxy);
......
...@@ -280,8 +280,7 @@ static const IRpcChannelBufferVtbl ServerRpcChannelBufferVtbl = ...@@ -280,8 +280,7 @@ static const IRpcChannelBufferVtbl ServerRpcChannelBufferVtbl =
}; };
/* returns a channel buffer for proxies */ /* returns a channel buffer for proxies */
/* FIXME: needs renaming and mid removing */ HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, IRpcChannelBuffer **chan)
HRESULT PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **chan)
{ {
ClientRpcChannelBuffer *This; ClientRpcChannelBuffer *This;
WCHAR endpoint[200]; WCHAR endpoint[200];
...@@ -290,7 +289,7 @@ HRESULT PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **chan) ...@@ -290,7 +289,7 @@ HRESULT PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **chan)
LPWSTR string_binding; LPWSTR string_binding;
/* connect to the apartment listener thread */ /* 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)); TRACE("proxy pipe: connecting to endpoint: %s\n", debugstr_w(endpoint));
...@@ -308,7 +307,8 @@ HRESULT PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **chan) ...@@ -308,7 +307,8 @@ HRESULT PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **chan)
if (status == RPC_S_OK) 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) if (status != RPC_S_OK)
RpcBindingFree(&bind); RpcBindingFree(&bind);
} }
...@@ -459,9 +459,9 @@ void RPC_UnregisterInterface(REFIID riid) ...@@ -459,9 +459,9 @@ void RPC_UnregisterInterface(REFIID riid)
#if 0 /* this is a stub in builtin and spams the console with FIXME's */ #if 0 /* this is a stub in builtin and spams the console with FIXME's */
IID iid = *riid; /* RpcServerUnregisterIf doesn't take const IID */ IID iid = *riid; /* RpcServerUnregisterIf doesn't take const IID */
RpcServerUnregisterIf((RPC_IF_HANDLE)&rif->If, &iid, 0); RpcServerUnregisterIf((RPC_IF_HANDLE)&rif->If, &iid, 0);
#endif
list_remove(&rif->entry); list_remove(&rif->entry);
HeapFree(GetProcessHeap(), 0, rif); HeapFree(GetProcessHeap(), 0, rif);
#endif
} }
break; break;
} }
...@@ -469,12 +469,11 @@ void RPC_UnregisterInterface(REFIID riid) ...@@ -469,12 +469,11 @@ void RPC_UnregisterInterface(REFIID riid)
LeaveCriticalSection(&csRegIf); LeaveCriticalSection(&csRegIf);
} }
/* FIXME: needs renaming */ /* make the apartment reachable by other threads and processes and create the
void start_apartment_listener_thread() * IRemUnknown object */
void RPC_StartRemoting(struct apartment *apt)
{ {
APARTMENT *apt = COM_CurrentApt(); /* FIXME: pass as parameter */ if (!InterlockedExchange(&apt->remoting_started, TRUE))
if (!apt->listenertid)
{ {
WCHAR endpoint[200]; WCHAR endpoint[200];
RPC_STATUS status; RPC_STATUS status;
...@@ -488,13 +487,14 @@ void start_apartment_listener_thread() ...@@ -488,13 +487,14 @@ void start_apartment_listener_thread()
NULL); NULL);
if (status != RPC_S_OK) if (status != RPC_S_OK)
ERR("Couldn't register endpoint %s\n", debugstr_w(endpoint)); 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 static HRESULT create_server(REFCLSID rclsid)
create_server(REFCLSID rclsid)
{ {
static const WCHAR embedding[] = { ' ', '-','E','m','b','e','d','d','i','n','g',0 }; static const WCHAR embedding[] = { ' ', '-','E','m','b','e','d','d','i','n','g',0 };
HKEY key; HKEY key;
...@@ -548,8 +548,7 @@ create_server(REFCLSID rclsid) ...@@ -548,8 +548,7 @@ create_server(REFCLSID rclsid)
/* /*
* start_local_service() - start a service given its name and parameters * start_local_service() - start a service given its name and parameters
*/ */
static DWORD static DWORD start_local_service(LPCWSTR name, DWORD num, LPWSTR *params)
start_local_service(LPCWSTR name, DWORD num, LPWSTR *params)
{ {
SC_HANDLE handle, hsvc; SC_HANDLE handle, hsvc;
DWORD r = ERROR_FUNCTION_FAILED; DWORD r = ERROR_FUNCTION_FAILED;
...@@ -586,8 +585,7 @@ start_local_service(LPCWSTR name, DWORD num, LPWSTR *params) ...@@ -586,8 +585,7 @@ start_local_service(LPCWSTR name, DWORD num, LPWSTR *params)
* *
* Note: Local Services are not supported under Windows 9x * Note: Local Services are not supported under Windows 9x
*/ */
static HRESULT static HRESULT create_local_service(REFCLSID rclsid)
create_local_service(REFCLSID rclsid)
{ {
HRESULT hres = REGDB_E_READREGDB; HRESULT hres = REGDB_E_READREGDB;
WCHAR buf[40], keyname[50]; WCHAR buf[40], keyname[50];
...@@ -655,7 +653,7 @@ create_local_service(REFCLSID rclsid) ...@@ -655,7 +653,7 @@ create_local_service(REFCLSID rclsid)
#define PIPEPREF "\\\\.\\pipe\\" #define PIPEPREF "\\\\.\\pipe\\"
/* FIXME: should call to rpcss instead */ /* 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; HRESULT hres;
HANDLE hPipe; HANDLE hPipe;
...@@ -667,7 +665,7 @@ HRESULT create_marshalled_proxy(REFCLSID rclsid, REFIID iid, LPVOID *ppv) ...@@ -667,7 +665,7 @@ HRESULT create_marshalled_proxy(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
ULARGE_INTEGER newpos; ULARGE_INTEGER newpos;
int tries = 0; 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)); TRACE("rclsid=%s, iid=%s\n", debugstr_guid(rclsid), debugstr_guid(iid));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment