- 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.
This commit is contained in:
parent
ac23f2c810
commit
8971f06225
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue