diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c index 32b5308b8d1..925fbaa7f0b 100644 --- a/dlls/ole32/compobj.c +++ b/dlls/ole32/compobj.c @@ -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 diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h index 2006e9a80e8..307fc9b85e9 100644 --- a/dlls/ole32/compobj_private.h +++ b/dlls/ole32/compobj_private.h @@ -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 *) */ diff --git a/dlls/ole32/marshal.c b/dlls/ole32/marshal.c index 87243020389..d922b488d70 100644 --- a/dlls/ole32/marshal.c +++ b/dlls/ole32/marshal.c @@ -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; } diff --git a/dlls/ole32/rpc.c b/dlls/ole32/rpc.c index 07e0d46b2f9..f211522fb96 100644 --- a/dlls/ole32/rpc.c +++ b/dlls/ole32/rpc.c @@ -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); } diff --git a/dlls/ole32/stubmanager.c b/dlls/ole32/stubmanager.c index 171babbf480..a7e5523b5ca 100644 --- a/dlls/ole32/stubmanager.c +++ b/dlls/ole32/stubmanager.c @@ -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)