Commit 8971f062 authored by Robert Shearman's avatar Robert Shearman Committed by Alexandre Julliard

- Rename apartment functions to become more object-oriented.

- Rename register_ifstub to marshal_object to more accurately describe what it does. - Add new function, apartment_getoxid, to prepare for a possible future patch where remoting is started on demand.
parent ac23f2c8
......@@ -162,8 +162,9 @@ static CRITICAL_SECTION_DEBUG dll_cs_debug =
};
static CRITICAL_SECTION csOpenDllList = { &dll_cs_debug, -1, 0, 0, 0, 0 };
static const WCHAR wszAptWinClass[] = {'W','I','N','E','_','O','L','E','3','2','_','A','P','T','_','C','L','A','S','S',0};
static LRESULT CALLBACK COM_AptWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
static const WCHAR wszAptWinClass[] = {'O','l','e','M','a','i','n','T','h','r','e','a','d','W','n','d','C','l','a','s','s',' ',
'0','x','#','#','#','#','#','#','#','#',' ',0};
static LRESULT CALLBACK apartment_wndproc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
static void COMPOBJ_DLLList_Add(HANDLE hLibrary);
static void COMPOBJ_DllList_FreeUnused(int Timeout);
......@@ -182,7 +183,7 @@ void COMPOBJ_InitProcess( void )
* was unmarshalled.
*/
memset(&wclass, 0, sizeof(wclass));
wclass.lpfnWndProc = COM_AptWndProc;
wclass.lpfnWndProc = apartment_wndproc;
wclass.hInstance = OLE32_hInstance;
wclass.lpszClassName = wszAptWinClass;
RegisterClassW(&wclass);
......@@ -198,7 +199,7 @@ void COM_TlsDestroy()
struct oletls *info = NtCurrentTeb()->ReservedForOle;
if (info)
{
if (info->apt) COM_ApartmentRelease(info->apt);
if (info->apt) apartment_release(info->apt);
if (info->errorinfo) IErrorInfo_Release(info->errorinfo);
if (info->state) IUnknown_Release(info->state);
HeapFree(GetProcessHeap(), 0, info);
......@@ -262,7 +263,7 @@ static APARTMENT *apartment_construct(DWORD model)
/* gets and existing apartment if one exists or otherwise creates an apartment
* structure which stores OLE apartment-local information and stores a pointer
* to it in the thread-local storage */
static APARTMENT *get_or_create_apartment(DWORD model)
static APARTMENT *apartment_get_or_create(DWORD model)
{
APARTMENT *apt = COM_CurrentApt();
......@@ -283,7 +284,7 @@ static APARTMENT *get_or_create_apartment(DWORD model)
if (MTA)
{
TRACE("entering the multithreaded apartment %s\n", wine_dbgstr_longlong(MTA->oxid));
COM_ApartmentAddRef(MTA);
apartment_addref(MTA);
}
else
MTA = apartment_construct(model);
......@@ -298,14 +299,14 @@ static APARTMENT *get_or_create_apartment(DWORD model)
return apt;
}
DWORD COM_ApartmentAddRef(struct apartment *apt)
DWORD apartment_addref(struct apartment *apt)
{
DWORD refs = InterlockedIncrement(&apt->refs);
TRACE("%s: before = %ld\n", wine_dbgstr_longlong(apt->oxid), refs - 1);
return refs;
}
DWORD COM_ApartmentRelease(struct apartment *apt)
DWORD apartment_release(struct apartment *apt)
{
DWORD ret;
......@@ -328,7 +329,7 @@ DWORD COM_ApartmentRelease(struct apartment *apt)
TRACE("destroying apartment %p, oxid %s\n", apt, wine_dbgstr_longlong(apt->oxid));
MARSHAL_Disconnect_Proxies(apt);
apartment_disconnectproxies(apt);
if (apt->win) DestroyWindow(apt->win);
......@@ -358,14 +359,12 @@ DWORD COM_ApartmentRelease(struct apartment *apt)
return ret;
}
/* The given OXID must be local to this process: you cannot use
* apartment windows to send RPCs to other processes. This all needs
* to move to rpcrt4.
/* The given OXID must be local to this process:
*
* The ref parameter is here mostly to ensure people remember that
* they get one, you should normally take a ref for thread safety.
*/
APARTMENT *COM_ApartmentFromOXID(OXID oxid, BOOL ref)
APARTMENT *apartment_findfromoxid(OXID oxid, BOOL ref)
{
APARTMENT *result = NULL;
struct list *cursor;
......@@ -377,7 +376,7 @@ APARTMENT *COM_ApartmentFromOXID(OXID oxid, BOOL ref)
if (apt->oxid == oxid)
{
result = apt;
if (ref) COM_ApartmentAddRef(result);
if (ref) apartment_addref(result);
break;
}
}
......@@ -389,7 +388,7 @@ APARTMENT *COM_ApartmentFromOXID(OXID oxid, BOOL ref)
/* gets the apartment which has a given creator thread ID. The caller must
* release the reference from the apartment as soon as the apartment pointer
* is no longer required. */
APARTMENT *COM_ApartmentFromTID(DWORD tid)
APARTMENT *apartment_findfromtid(DWORD tid)
{
APARTMENT *result = NULL;
struct list *cursor;
......@@ -401,7 +400,7 @@ APARTMENT *COM_ApartmentFromTID(DWORD tid)
if (apt->tid == tid)
{
result = apt;
COM_ApartmentAddRef(result);
apartment_addref(result);
break;
}
}
......@@ -410,17 +409,7 @@ APARTMENT *COM_ApartmentFromTID(DWORD tid)
return result;
}
HWND COM_GetApartmentWin(OXID oxid, BOOL ref)
{
APARTMENT *apt;
apt = COM_ApartmentFromOXID(oxid, ref);
if (!apt) return NULL;
return apt->win;
}
static LRESULT CALLBACK COM_AptWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
static LRESULT CALLBACK apartment_wndproc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
......@@ -608,7 +597,7 @@ HRESULT WINAPI CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
if (!(apt = COM_CurrentInfo()->apt))
{
apt = get_or_create_apartment(dwCoInit);
apt = apartment_get_or_create(dwCoInit);
if (!apt) return E_OUTOFMEMORY;
}
else if (dwCoInit != apt->model)
......@@ -686,7 +675,7 @@ void WINAPI CoUninitialize(void)
if (!--info->inits)
{
COM_ApartmentRelease(info->apt);
apartment_release(info->apt);
info->apt = NULL;
}
......@@ -759,7 +748,7 @@ HRESULT WINAPI CoDisconnectObject( LPUNKNOWN lpUnk, DWORD reserved )
if (!apt)
return CO_E_NOTINITIALIZED;
apartment_disconnect_object(apt, lpUnk);
apartment_disconnectobject(apt, lpUnk);
/* Note: native is pretty broken here because it just silently
* fails, without returning an appropriate error code if the object was
......
......@@ -159,7 +159,6 @@ extern void* StdGlobalInterfaceTableInstance;
extern HRESULT WINE_StringFromCLSID(const CLSID *id,LPSTR idstr);
HRESULT WINAPI __CLSIDFromStringA(LPCSTR idstr, CLSID *id);
HRESULT MARSHAL_Disconnect_Proxies(APARTMENT *apt);
HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv);
/* Stub Manager */
......@@ -172,15 +171,15 @@ ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs);
struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid);
struct stub_manager *get_stub_manager(APARTMENT *apt, OID oid);
struct stub_manager *get_stub_manager_from_object(APARTMENT *apt, void *object);
void apartment_disconnect_object(APARTMENT *apt, void *object);
BOOL stub_manager_notify_unmarshal(struct stub_manager *m);
BOOL stub_manager_is_table_marshaled(struct stub_manager *m);
void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs);
HRESULT register_ifstub(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *obj, MSHLFLAGS mshlflags);
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 start_apartment_remote_unknown(void);
HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *obj, MSHLFLAGS mshlflags);
/* RPC Backend */
void RPC_StartRemoting(struct apartment *apt);
......@@ -203,10 +202,17 @@ int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable);
/* Apartment Functions */
APARTMENT *COM_ApartmentFromOXID(OXID oxid, BOOL ref);
APARTMENT *COM_ApartmentFromTID(DWORD tid);
DWORD COM_ApartmentAddRef(struct apartment *apt);
DWORD COM_ApartmentRelease(struct apartment *apt);
APARTMENT *apartment_findfromoxid(OXID oxid, BOOL ref);
APARTMENT *apartment_findfromtid(DWORD tid);
DWORD apartment_addref(struct apartment *apt);
DWORD apartment_release(struct apartment *apt);
HRESULT apartment_disconnectproxies(struct apartment *apt);
void apartment_disconnectobject(struct apartment *apt, void *object);
static inline HRESULT apartment_getoxid(struct apartment *apt, OXID *oxid)
{
*oxid = apt->oxid;
return S_OK;
}
/* messages used by the apartment window (not compatible with native) */
#define DM_EXECUTERPC (WM_USER + 0) /* WPARAM = (RPCOLEMESSAGE *), LPARAM = (IRpcStubBuffer *) */
......
......@@ -86,7 +86,7 @@ get_facbuf_for_iid(REFIID riid,IPSFactoryBuffer **facbuf) {
}
/* creates a new stub manager */
HRESULT register_ifstub(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *obj, MSHLFLAGS mshlflags)
HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *obj, MSHLFLAGS mshlflags)
{
struct stub_manager *manager;
struct ifstub *ifstub;
......@@ -95,6 +95,10 @@ HRESULT register_ifstub(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnkn
IPSFactoryBuffer *psfb;
HRESULT hr;
hr = apartment_getoxid(apt, &stdobjref->oxid);
if (hr != S_OK)
return hr;
hr = get_facbuf_for_iid(riid, &psfb);
if (hr != S_OK)
{
......@@ -115,8 +119,6 @@ HRESULT register_ifstub(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnkn
else
stdobjref->flags = SORF_NULL;
stdobjref->oxid = apt->oxid;
/* FIXME: what happens if we register an interface twice with different
* marshaling flags? */
if ((manager = get_stub_manager_from_object(apt, obj)))
......@@ -127,7 +129,10 @@ HRESULT register_ifstub(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnkn
manager = new_stub_manager(apt, obj, mshlflags);
if (!manager)
{
IRpcStubBuffer_Release(stub);
return E_OUTOFMEMORY;
}
}
stdobjref->oid = manager->oid;
......@@ -712,7 +717,7 @@ static BOOL find_proxy_manager(APARTMENT * apt, OXID oxid, OID oid, struct proxy
return found;
}
HRESULT MARSHAL_Disconnect_Proxies(APARTMENT *apt)
HRESULT apartment_disconnectproxies(struct apartment *apt)
{
struct list * cursor;
......@@ -813,7 +818,7 @@ StdMarshalImpl_MarshalInterface(
return E_NOINTERFACE;
}
hres = register_ifstub(apt, &stdobjref, riid, pUnk, mshlflags);
hres = marshal_object(apt, &stdobjref, riid, pUnk, mshlflags);
IUnknown_Release(pUnk);
......@@ -894,6 +899,7 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
HRESULT hres;
APARTMENT *apt = COM_CurrentApt();
APARTMENT *stub_apt;
OXID oxid;
TRACE("(...,%s,....)\n",debugstr_guid(riid));
......@@ -907,9 +913,12 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
/* read STDOBJREF from wire */
hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res);
if (hres) return hres;
hres = apartment_getoxid(apt, &oxid);
if (hres) return hres;
/* check if we're marshalling back to ourselves */
if ((apt->oxid == stdobjref.oxid) && (stubmgr = get_stub_manager(apt, stdobjref.oid)))
if ((oxid == stdobjref.oxid) && (stubmgr = get_stub_manager(apt, stdobjref.oid)))
{
TRACE("Unmarshalling object marshalled in same apartment for iid %s, "
"returning original object %p\n", debugstr_guid(riid), stubmgr->object);
......@@ -929,7 +938,7 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
* ignore table marshaling and normal marshaling rules regarding number of
* unmarshals, etc, but if you abuse these rules then your proxy could end
* up returning RPC_E_DISCONNECTED. */
if ((stub_apt = COM_ApartmentFromOXID(stdobjref.oxid, TRUE)))
if ((stub_apt = apartment_findfromoxid(stdobjref.oxid, TRUE)))
{
if ((stubmgr = get_stub_manager(stub_apt, stdobjref.oid)))
{
......@@ -946,7 +955,7 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
hres = CO_E_OBJNOTCONNECTED;
}
COM_ApartmentRelease(stub_apt);
apartment_release(stub_apt);
}
else
TRACE("Treating unmarshal from OXID %s as inter-process\n",
......@@ -974,7 +983,7 @@ StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) {
hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res);
if (hres) return hres;
if (!(apt = COM_ApartmentFromOXID(stdobjref.oxid, TRUE)))
if (!(apt = apartment_findfromoxid(stdobjref.oxid, TRUE)))
{
WARN("Could not map OXID %s to apartment object\n",
wine_dbgstr_longlong(stdobjref.oxid));
......@@ -991,7 +1000,7 @@ StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) {
stub_manager_release_marshal_data(stubmgr, stdobjref.cPublicRefs);
stub_manager_int_release(stubmgr);
COM_ApartmentRelease(apt);
apartment_release(apt);
return S_OK;
}
......
......@@ -450,7 +450,7 @@ static void __RPC_STUB dispatch_rpc(RPC_MESSAGE *msg)
stub = ipid_to_apt_and_stubbuffer(&ipid, &apt);
if (!apt || !stub)
{
if (apt) COM_ApartmentRelease(apt);
if (apt) apartment_release(apt);
/* ipid_to_apt_and_stubbuffer will already have logged the error */
return RpcRaiseException(RPC_E_DISCONNECTED);
}
......@@ -463,7 +463,7 @@ static void __RPC_STUB dispatch_rpc(RPC_MESSAGE *msg)
else
RPC_ExecuteCall((RPCOLEMESSAGE *)msg, stub);
COM_ApartmentRelease(apt);
apartment_release(apt);
IRpcStubBuffer_Release(stub);
}
......
......@@ -148,7 +148,7 @@ struct stub_manager *get_stub_manager_from_object(APARTMENT *apt, void *object)
/* removes the apartment reference to an object, destroying it when no other
* threads have a reference to it */
void apartment_disconnect_object(APARTMENT *apt, void *object)
void apartment_disconnectobject(struct apartment *apt, void *object)
{
int found = FALSE;
struct stub_manager *stubmgr;
......@@ -327,9 +327,9 @@ HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub
{
/* FIXME: hack for IRemUnknown */
if (ipid->Data2 == 0xffff)
*stub_apt = COM_ApartmentFromOXID(*(OXID *)ipid->Data4, TRUE);
*stub_apt = apartment_findfromoxid(*(OXID *)ipid->Data4, TRUE);
else
*stub_apt = COM_ApartmentFromTID(ipid->Data2);
*stub_apt = apartment_findfromtid(ipid->Data2);
if (!*stub_apt)
{
ERR("Couldn't find apartment corresponding to TID 0x%04x\n", ipid->Data2);
......@@ -338,7 +338,7 @@ HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub
*stubmgr_ret = get_stub_manager_from_ipid(*stub_apt, ipid);
if (!*stubmgr_ret)
{
COM_ApartmentRelease(*stub_apt);
apartment_release(*stub_apt);
*stub_apt = NULL;
return RPC_E_INVALID_OBJECT;
}
......@@ -616,15 +616,15 @@ static HRESULT WINAPI RemUnknown_RemQueryInterface(IRemUnknown *iface,
for (i = 0; i < cIids; i++)
{
HRESULT hrobj = register_ifstub(apt, &(*ppQIResults)[i].std, &iids[i],
stubmgr->object, MSHLFLAGS_NORMAL);
HRESULT hrobj = marshal_object(apt, &(*ppQIResults)[i].std, &iids[i],
stubmgr->object, MSHLFLAGS_NORMAL);
if (hrobj == S_OK)
successful_qis++;
(*ppQIResults)[i].hResult = hrobj;
}
stub_manager_int_release(stubmgr);
COM_ApartmentRelease(apt);
apartment_release(apt);
if (successful_qis == cIids)
return S_OK; /* we got all requested interfaces */
......@@ -661,7 +661,7 @@ static HRESULT WINAPI RemUnknown_RemAddRef(IRemUnknown *iface,
FIXME("Adding %ld refs securely not implemented\n", InterfaceRefs[i].cPrivateRefs);
stub_manager_int_release(stubmgr);
COM_ApartmentRelease(apt);
apartment_release(apt);
}
return hr;
......@@ -694,7 +694,7 @@ static HRESULT WINAPI RemUnknown_RemRelease(IRemUnknown *iface,
FIXME("Releasing %ld refs securely not implemented\n", InterfaceRefs[i].cPrivateRefs);
stub_manager_int_release(stubmgr);
COM_ApartmentRelease(apt);
apartment_release(apt);
}
return hr;
......@@ -726,7 +726,7 @@ HRESULT start_apartment_remote_unknown()
{
STDOBJREF stdobjref; /* dummy - not used */
/* register it with the stub manager */
hr = register_ifstub(apt, &stdobjref, &IID_IRemUnknown, (IUnknown *)pRemUnknown, MSHLFLAGS_NORMAL);
hr = marshal_object(apt, &stdobjref, &IID_IRemUnknown, (IUnknown *)pRemUnknown, MSHLFLAGS_NORMAL);
/* release our reference to the object as the stub manager will manage the life cycle for us */
IRemUnknown_Release(pRemUnknown);
if (hr == S_OK)
......
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