combase: Move stub manager.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9864f9c024
commit
6074eeda83
|
@ -14,7 +14,9 @@ C_SRCS = \
|
|||
roapi.c \
|
||||
rpc.c \
|
||||
string.c \
|
||||
stubmanager.c \
|
||||
usrmarshal.c
|
||||
|
||||
IDL_SRCS = \
|
||||
dcom.idl \
|
||||
irpcss.idl
|
||||
|
|
|
@ -444,7 +444,6 @@ void apartment_freeunusedlibraries(struct apartment *apt, DWORD delay)
|
|||
}
|
||||
|
||||
extern HRESULT WINAPI Internal_apartment_disconnectproxies(struct apartment *apt);
|
||||
extern ULONG WINAPI Internal_stub_manager_int_release(struct stub_manager *stubmgr);
|
||||
|
||||
void WINAPI apartment_release(struct apartment *apt)
|
||||
{
|
||||
|
@ -513,7 +512,7 @@ void WINAPI apartment_release(struct apartment *apt)
|
|||
* stub manager list in the apartment and all non-apartment users
|
||||
* must have a ref on the apartment and so it cannot be destroyed).
|
||||
*/
|
||||
Internal_stub_manager_int_release(stubmgr);
|
||||
stub_manager_int_release(stubmgr);
|
||||
}
|
||||
|
||||
/* if this assert fires, then another thread took a reference to a
|
||||
|
@ -654,7 +653,7 @@ struct apartment * WINAPI apartment_findfromoxid(OXID oxid)
|
|||
/* 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. */
|
||||
struct apartment * WINAPI apartment_findfromtid(DWORD tid)
|
||||
struct apartment * apartment_findfromtid(DWORD tid)
|
||||
{
|
||||
struct apartment *result = NULL;
|
||||
struct list *cursor;
|
||||
|
|
|
@ -2968,6 +2968,90 @@ ULONG WINAPI CoReleaseServerProcess(void)
|
|||
return refs;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CoDisconnectObject (combase.@)
|
||||
*/
|
||||
HRESULT WINAPI CoDisconnectObject(IUnknown *object, DWORD reserved)
|
||||
{
|
||||
struct stub_manager *manager;
|
||||
struct apartment *apt;
|
||||
IMarshal *marshal;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p, %#x\n", object, reserved);
|
||||
|
||||
if (!object)
|
||||
return E_INVALIDARG;
|
||||
|
||||
hr = IUnknown_QueryInterface(object, &IID_IMarshal, (void **)&marshal);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
hr = IMarshal_DisconnectObject(marshal, reserved);
|
||||
IMarshal_Release(marshal);
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (!(apt = apartment_get_current_or_mta()))
|
||||
{
|
||||
ERR("apartment not initialised\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
|
||||
manager = get_stub_manager_from_object(apt, object, FALSE);
|
||||
if (manager)
|
||||
{
|
||||
stub_manager_disconnect(manager);
|
||||
/* Release stub manager twice, to remove the apartment reference. */
|
||||
stub_manager_int_release(manager);
|
||||
stub_manager_int_release(manager);
|
||||
}
|
||||
|
||||
/* Note: native is pretty broken here because it just silently
|
||||
* fails, without returning an appropriate error code if the object was
|
||||
* not found, making apps think that the object was disconnected, when
|
||||
* it actually wasn't */
|
||||
|
||||
apartment_release(apt);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CoLockObjectExternal (combase.@)
|
||||
*/
|
||||
HRESULT WINAPI CoLockObjectExternal(IUnknown *object, BOOL lock, BOOL last_unlock_releases)
|
||||
{
|
||||
struct stub_manager *stubmgr;
|
||||
struct apartment *apt;
|
||||
|
||||
TRACE("%p, %d, %d\n", object, lock, last_unlock_releases);
|
||||
|
||||
if (!(apt = apartment_get_current_or_mta()))
|
||||
{
|
||||
ERR("apartment not initialised\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
|
||||
stubmgr = get_stub_manager_from_object(apt, object, lock);
|
||||
if (!stubmgr)
|
||||
{
|
||||
WARN("stub object not found %p\n", object);
|
||||
/* Note: native is pretty broken here because it just silently
|
||||
* fails, without returning an appropriate error code, making apps
|
||||
* think that the object was disconnected, when it actually wasn't */
|
||||
apartment_release(apt);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (lock)
|
||||
stub_manager_ext_addref(stubmgr, 1, FALSE);
|
||||
else
|
||||
stub_manager_ext_release(stubmgr, 1, FALSE, last_unlock_releases);
|
||||
|
||||
stub_manager_int_release(stubmgr);
|
||||
apartment_release(apt);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DllMain (combase.@)
|
||||
*/
|
||||
|
|
|
@ -89,7 +89,7 @@
|
|||
@ stdcall CoDecrementMTAUsage(ptr)
|
||||
@ stdcall CoDisableCallCancellation(ptr) ole32.CoDisableCallCancellation
|
||||
@ stub CoDisconnectContext
|
||||
@ stdcall CoDisconnectObject(ptr long) ole32.CoDisconnectObject
|
||||
@ stdcall CoDisconnectObject(ptr long)
|
||||
@ stdcall CoEnableCallCancellation(ptr) ole32.CoEnableCallCancellation
|
||||
@ stdcall CoFileTimeNow(ptr)
|
||||
@ stdcall CoFreeUnusedLibraries()
|
||||
|
@ -128,7 +128,7 @@
|
|||
@ stdcall CoInitializeWOW(long long) ole32.CoInitializeWOW
|
||||
@ stub CoInvalidateRemoteMachineBindings
|
||||
@ stdcall CoIsHandlerConnected(ptr) ole32.CoIsHandlerConnected
|
||||
@ stdcall CoLockObjectExternal(ptr long long) ole32.CoLockObjectExternal
|
||||
@ stdcall CoLockObjectExternal(ptr long long)
|
||||
@ stdcall CoMarshalHresult(ptr long)
|
||||
@ stdcall CoMarshalInterThreadInterfaceInStream(ptr ptr ptr)
|
||||
@ stdcall CoMarshalInterface(ptr ptr ptr long ptr long)
|
||||
|
@ -358,4 +358,15 @@
|
|||
@ stdcall apartment_findfromoxid(int64)
|
||||
@ stdcall apartment_getwindow(ptr)
|
||||
@ stdcall apartment_createwindowifneeded(ptr)
|
||||
@ stdcall apartment_findfromtid(long)
|
||||
@ stdcall stub_manager_int_release(ptr)
|
||||
@ stdcall get_stub_manager(ptr int64)
|
||||
@ stdcall stub_manager_is_table_marshaled(ptr ptr)
|
||||
@ stdcall stub_manager_notify_unmarshal(ptr ptr)
|
||||
@ stdcall stub_manager_ext_release(ptr long long long)
|
||||
@ stdcall stub_manager_release_marshal_data(ptr long ptr long)
|
||||
@ stdcall get_stub_manager_from_object(ptr ptr long)
|
||||
@ stdcall stub_manager_find_ifstub(ptr ptr long)
|
||||
@ stdcall stub_manager_ext_addref(ptr long long)
|
||||
@ stdcall stub_manager_new_ifstub(ptr ptr ptr long ptr long)
|
||||
@ stdcall ipid_get_dispatch_params(ptr ptr ptr ptr ptr ptr ptr)
|
||||
@ stdcall start_apartment_remote_unknown(ptr)
|
||||
|
|
|
@ -113,34 +113,6 @@ HRESULT rpc_get_local_class_object(REFCLSID rclsid, REFIID riid, void **obj) DEC
|
|||
HRESULT rpc_start_local_server(REFCLSID clsid, IStream *stream, BOOL multi_use, void **registration) DECLSPEC_HIDDEN;
|
||||
void rpc_stop_local_server(void *registration) DECLSPEC_HIDDEN;
|
||||
|
||||
/* stub managers hold refs on the object and each interface stub */
|
||||
struct stub_manager
|
||||
{
|
||||
struct list entry; /* entry in apartment stubmgr list (CS apt->cs) */
|
||||
struct list ifstubs; /* list of active ifstubs for the object (CS lock) */
|
||||
CRITICAL_SECTION lock;
|
||||
struct apartment *apt; /* owning apt (RO) */
|
||||
|
||||
ULONG extrefs; /* number of 'external' references (CS lock) */
|
||||
ULONG refs; /* internal reference count (CS apt->cs) */
|
||||
ULONG weakrefs; /* number of weak references (CS lock) */
|
||||
OID oid; /* apartment-scoped unique identifier (RO) */
|
||||
IUnknown *object; /* the object we are managing the stub for (RO) */
|
||||
ULONG next_ipid; /* currently unused (LOCK) */
|
||||
OXID_INFO oxid_info; /* string binding, ipid of rem unknown and other information (RO) */
|
||||
|
||||
IExternalConnection *extern_conn;
|
||||
|
||||
/* We need to keep a count of the outstanding marshals, so we can enforce the
|
||||
* marshalling rules (ie, you can only unmarshal normal marshals once). Note
|
||||
* that these counts do NOT include unmarshalled interfaces, once a stream is
|
||||
* unmarshalled and a proxy set up, this count is decremented.
|
||||
*/
|
||||
|
||||
ULONG norm_refs; /* refcount of normal marshals (CS lock) */
|
||||
BOOL disconnected; /* CoDisconnectObject has been called (CS lock) */
|
||||
};
|
||||
|
||||
enum class_reg_data_origin
|
||||
{
|
||||
CLASS_REG_ACTCTX,
|
||||
|
@ -175,7 +147,78 @@ HRESULT apartment_get_local_server_stream(struct apartment *apt, IStream **ret)
|
|||
IUnknown *com_get_registered_class_object(const struct apartment *apartment, REFCLSID rclsid,
|
||||
DWORD clscontext) DECLSPEC_HIDDEN;
|
||||
void apartment_revoke_all_classes(const struct apartment *apt) DECLSPEC_HIDDEN;
|
||||
struct apartment * WINAPI apartment_findfromoxid(OXID oxid);
|
||||
struct apartment * apartment_findfromtid(DWORD tid) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Stub Manager */
|
||||
|
||||
ULONG stub_manager_int_release(struct stub_manager *This) DECLSPEC_HIDDEN;
|
||||
/* signal to stub manager that this is a rem unknown object */
|
||||
#define MSHLFLAGSP_REMUNKNOWN 0x80000000
|
||||
|
||||
/* Thread-safety Annotation Legend:
|
||||
*
|
||||
* RO - The value is read only. It never changes after creation, so no
|
||||
* locking is required.
|
||||
* LOCK - The value is written to only using Interlocked* functions.
|
||||
* CS - The value is read or written to inside a critical section.
|
||||
* The identifier following "CS" is the specific critical section that
|
||||
* must be used.
|
||||
* MUTEX - The value is read or written to with a mutex held.
|
||||
* The identifier following "MUTEX" is the specific mutex that
|
||||
* must be used.
|
||||
*/
|
||||
|
||||
typedef enum ifstub_state
|
||||
{
|
||||
STUBSTATE_NORMAL_MARSHALED,
|
||||
STUBSTATE_NORMAL_UNMARSHALED,
|
||||
STUBSTATE_TABLE_WEAK_MARSHALED,
|
||||
STUBSTATE_TABLE_WEAK_UNMARSHALED,
|
||||
STUBSTATE_TABLE_STRONG,
|
||||
} STUB_STATE;
|
||||
|
||||
/* an interface stub */
|
||||
struct ifstub
|
||||
{
|
||||
struct list entry; /* entry in stub_manager->ifstubs list (CS stub_manager->lock) */
|
||||
IRpcStubBuffer *stubbuffer; /* RO */
|
||||
IID iid; /* RO */
|
||||
IPID ipid; /* RO */
|
||||
IUnknown *iface; /* RO */
|
||||
MSHLFLAGS flags; /* so we can enforce process-local marshalling rules (RO) */
|
||||
IRpcChannelBuffer*chan; /* channel passed to IRpcStubBuffer::Invoke (RO) */
|
||||
};
|
||||
|
||||
/* stub managers hold refs on the object and each interface stub */
|
||||
struct stub_manager
|
||||
{
|
||||
struct list entry; /* entry in apartment stubmgr list (CS apt->cs) */
|
||||
struct list ifstubs; /* list of active ifstubs for the object (CS lock) */
|
||||
CRITICAL_SECTION lock;
|
||||
struct apartment *apt; /* owning apt (RO) */
|
||||
|
||||
ULONG extrefs; /* number of 'external' references (CS lock) */
|
||||
ULONG refs; /* internal reference count (CS apt->cs) */
|
||||
ULONG weakrefs; /* number of weak references (CS lock) */
|
||||
OID oid; /* apartment-scoped unique identifier (RO) */
|
||||
IUnknown *object; /* the object we are managing the stub for (RO) */
|
||||
ULONG next_ipid; /* currently unused (LOCK) */
|
||||
OXID_INFO oxid_info; /* string binding, ipid of rem unknown and other information (RO) */
|
||||
|
||||
IExternalConnection *extern_conn;
|
||||
|
||||
/* We need to keep a count of the outstanding marshals, so we can enforce the
|
||||
* marshalling rules (ie, you can only unmarshal normal marshals once). Note
|
||||
* that these counts do NOT include unmarshalled interfaces, once a stream is
|
||||
* unmarshalled and a proxy set up, this count is decremented.
|
||||
*/
|
||||
|
||||
ULONG norm_refs; /* refcount of normal marshals (CS lock) */
|
||||
BOOL disconnected; /* CoDisconnectObject has been called (CS lock) */
|
||||
};
|
||||
|
||||
ULONG WINAPI stub_manager_int_release(struct stub_manager *stub_manager) DECLSPEC_HIDDEN;
|
||||
struct stub_manager * WINAPI get_stub_manager_from_object(struct apartment *apt, IUnknown *object, BOOL alloc);
|
||||
void stub_manager_disconnect(struct stub_manager *m) DECLSPEC_HIDDEN;
|
||||
ULONG WINAPI stub_manager_ext_addref(struct stub_manager *m, ULONG refs, BOOL tableweak) DECLSPEC_HIDDEN;
|
||||
ULONG WINAPI stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tableweak, BOOL last_unlock_releases) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright 2003 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/* see the official DCOM specification
|
||||
* (there's a copy at http://www.grimes.demon.co.uk/DCOM/DCOMSpec.htm) */
|
||||
|
||||
#pragma makedep header
|
||||
|
||||
#include "wine/orpc.idl"
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(00000131-0000-0000-c000-000000000046)
|
||||
]
|
||||
interface IRemUnknown : IUnknown
|
||||
{
|
||||
typedef [unique] IRemUnknown *LPREMUNKNOWN;
|
||||
|
||||
typedef struct tagREMQIRESULT
|
||||
{
|
||||
HRESULT hResult;
|
||||
STDOBJREF std;
|
||||
} REMQIRESULT;
|
||||
|
||||
typedef struct tagREMINTERFACEREF
|
||||
{
|
||||
IPID ipid;
|
||||
unsigned long cPublicRefs;
|
||||
unsigned long cPrivateRefs;
|
||||
} REMINTERFACEREF;
|
||||
|
||||
HRESULT RemQueryInterface(
|
||||
[in] REFIPID ripid,
|
||||
[in] ULONG cRefs,
|
||||
[in] unsigned short cIids,
|
||||
[in, size_is(cIids)] IID *iids,
|
||||
[out, size_is(,cIids)] REMQIRESULT **ppQIResults);
|
||||
|
||||
HRESULT RemAddRef(
|
||||
[in] unsigned short cInterfaceRefs,
|
||||
[in, size_is(cInterfaceRefs)] REMINTERFACEREF *InterfaceRefs,
|
||||
[out, size_is(cInterfaceRefs)] HRESULT *pResults);
|
||||
|
||||
HRESULT RemRelease(
|
||||
[in] unsigned short cInterfaceRefs,
|
||||
[in, size_is(cInterfaceRefs)] REMINTERFACEREF *InterfaceRefs);
|
||||
}
|
|
@ -38,10 +38,16 @@
|
|||
#include "wine/debug.h"
|
||||
#include "wine/exception.h"
|
||||
|
||||
#include "compobj_private.h"
|
||||
#include "initguid.h"
|
||||
#include "dcom.h"
|
||||
#include "combase_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
extern HRESULT WINAPI marshal_object(struct apartment *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *object,
|
||||
DWORD dest_context, void *dest_context_data, MSHLFLAGS mshlflags);
|
||||
extern HRESULT WINAPI RPC_CreateServerChannel(DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan);
|
||||
extern void WINAPI RPC_UnregisterInterface(REFIID riid, BOOL wait);
|
||||
|
||||
/* generates an ipid in the following format (similar to native version):
|
||||
* Data1 = apartment-local ipid counter
|
||||
|
@ -67,7 +73,7 @@ static inline HRESULT generate_ipid(struct stub_manager *m, IPID *ipid)
|
|||
}
|
||||
|
||||
/* registers a new interface stub COM object with the stub manager and returns registration record */
|
||||
struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, REFIID iid, DWORD dest_context,
|
||||
struct ifstub * WINAPI stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, REFIID iid, DWORD dest_context,
|
||||
void *dest_context_data, MSHLFLAGS flags)
|
||||
{
|
||||
struct ifstub *stub;
|
||||
|
@ -155,7 +161,7 @@ static struct ifstub *stub_manager_ipid_to_ifstub(struct stub_manager *m, const
|
|||
return result;
|
||||
}
|
||||
|
||||
struct ifstub *stub_manager_find_ifstub(struct stub_manager *m, REFIID iid, MSHLFLAGS flags)
|
||||
struct ifstub * WINAPI stub_manager_find_ifstub(struct stub_manager *m, REFIID iid, MSHLFLAGS flags)
|
||||
{
|
||||
struct ifstub *result = NULL;
|
||||
struct ifstub *ifstub;
|
||||
|
@ -182,15 +188,15 @@ static struct stub_manager *new_stub_manager(struct apartment *apt, IUnknown *ob
|
|||
struct stub_manager *sm;
|
||||
HRESULT hres;
|
||||
|
||||
assert( apt );
|
||||
|
||||
assert(apt);
|
||||
|
||||
sm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct stub_manager));
|
||||
if (!sm) return NULL;
|
||||
|
||||
list_init(&sm->ifstubs);
|
||||
|
||||
InitializeCriticalSection(&sm->lock);
|
||||
DEBUG_SET_CRITSEC_NAME(&sm->lock, "stub_manager");
|
||||
sm->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": stub_manager");
|
||||
|
||||
IUnknown_AddRef(object);
|
||||
sm->object = object;
|
||||
|
@ -287,51 +293,46 @@ static void stub_manager_delete(struct stub_manager *m)
|
|||
}
|
||||
__ENDTRY
|
||||
|
||||
DEBUG_CLEAR_CRITSEC_NAME(&m->lock);
|
||||
m->lock.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&m->lock);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, m);
|
||||
}
|
||||
|
||||
/* increments the internal refcount */
|
||||
static ULONG stub_manager_int_addref(struct stub_manager *This)
|
||||
static ULONG stub_manager_int_addref(struct stub_manager *m)
|
||||
{
|
||||
ULONG refs;
|
||||
|
||||
EnterCriticalSection(&This->apt->cs);
|
||||
refs = ++This->refs;
|
||||
LeaveCriticalSection(&This->apt->cs);
|
||||
EnterCriticalSection(&m->apt->cs);
|
||||
refs = ++m->refs;
|
||||
LeaveCriticalSection(&m->apt->cs);
|
||||
|
||||
TRACE("before %d\n", refs - 1);
|
||||
|
||||
return refs;
|
||||
}
|
||||
|
||||
ULONG WINAPI Internal_stub_manager_int_release(struct stub_manager *m)
|
||||
{
|
||||
return stub_manager_int_release(m);
|
||||
}
|
||||
|
||||
/* decrements the internal refcount */
|
||||
ULONG stub_manager_int_release(struct stub_manager *This)
|
||||
ULONG WINAPI stub_manager_int_release(struct stub_manager *m)
|
||||
{
|
||||
ULONG refs;
|
||||
struct apartment *apt = This->apt;
|
||||
struct apartment *apt = m->apt;
|
||||
|
||||
EnterCriticalSection(&apt->cs);
|
||||
refs = --This->refs;
|
||||
refs = --m->refs;
|
||||
|
||||
TRACE("after %d\n", refs);
|
||||
|
||||
/* remove from apartment so no other thread can access it... */
|
||||
if (!refs)
|
||||
list_remove(&This->entry);
|
||||
list_remove(&m->entry);
|
||||
|
||||
LeaveCriticalSection(&apt->cs);
|
||||
|
||||
/* ... so now we can delete it without being inside the apartment critsec */
|
||||
if (!refs)
|
||||
stub_manager_delete(This);
|
||||
stub_manager_delete(m);
|
||||
|
||||
return refs;
|
||||
}
|
||||
|
@ -339,7 +340,7 @@ ULONG stub_manager_int_release(struct stub_manager *This)
|
|||
/* gets the stub manager associated with an object - caller must have
|
||||
* a reference to the apartment while a reference to the stub manager is held.
|
||||
* it must also call release on the stub manager when it is no longer needed */
|
||||
struct stub_manager *get_stub_manager_from_object(struct apartment *apt, IUnknown *obj, BOOL alloc)
|
||||
struct stub_manager * WINAPI get_stub_manager_from_object(struct apartment *apt, IUnknown *obj, BOOL alloc)
|
||||
{
|
||||
struct stub_manager *result = NULL;
|
||||
struct list *cursor;
|
||||
|
@ -347,13 +348,14 @@ struct stub_manager *get_stub_manager_from_object(struct apartment *apt, IUnknow
|
|||
HRESULT hres;
|
||||
|
||||
hres = IUnknown_QueryInterface(obj, &IID_IUnknown, (void**)&object);
|
||||
if (FAILED(hres)) {
|
||||
if (FAILED(hres))
|
||||
{
|
||||
ERR("QueryInterface(IID_IUnknown failed): %08x\n", hres);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&apt->cs);
|
||||
LIST_FOR_EACH( cursor, &apt->stubmgrs )
|
||||
LIST_FOR_EACH(cursor, &apt->stubmgrs)
|
||||
{
|
||||
struct stub_manager *m = LIST_ENTRY( cursor, struct stub_manager, entry );
|
||||
|
||||
|
@ -366,12 +368,17 @@ struct stub_manager *get_stub_manager_from_object(struct apartment *apt, IUnknow
|
|||
}
|
||||
LeaveCriticalSection(&apt->cs);
|
||||
|
||||
if (result) {
|
||||
if (result)
|
||||
{
|
||||
TRACE("found %p for object %p\n", result, object);
|
||||
}else if (alloc) {
|
||||
}
|
||||
else if (alloc)
|
||||
{
|
||||
TRACE("not found, creating new stub manager...\n");
|
||||
result = new_stub_manager(apt, object);
|
||||
}else {
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("not found for object %p\n", object);
|
||||
}
|
||||
|
||||
|
@ -382,15 +389,15 @@ struct stub_manager *get_stub_manager_from_object(struct apartment *apt, IUnknow
|
|||
/* gets the stub manager associated with an object id - caller must have
|
||||
* a reference to the apartment while a reference to the stub manager is held.
|
||||
* it must also call release on the stub manager when it is no longer needed */
|
||||
struct stub_manager *get_stub_manager(struct apartment *apt, OID oid)
|
||||
struct stub_manager * WINAPI get_stub_manager(struct apartment *apt, OID oid)
|
||||
{
|
||||
struct stub_manager *result = NULL;
|
||||
struct list *cursor;
|
||||
|
||||
EnterCriticalSection(&apt->cs);
|
||||
LIST_FOR_EACH( cursor, &apt->stubmgrs )
|
||||
LIST_FOR_EACH(cursor, &apt->stubmgrs)
|
||||
{
|
||||
struct stub_manager *m = LIST_ENTRY( cursor, struct stub_manager, entry );
|
||||
struct stub_manager *m = LIST_ENTRY(cursor, struct stub_manager, entry);
|
||||
|
||||
if (m->oid == oid)
|
||||
{
|
||||
|
@ -410,7 +417,7 @@ struct stub_manager *get_stub_manager(struct apartment *apt, OID oid)
|
|||
}
|
||||
|
||||
/* add some external references (ie from a client that unmarshaled an ifptr) */
|
||||
ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs, BOOL tableweak)
|
||||
ULONG WINAPI stub_manager_ext_addref(struct stub_manager *m, ULONG refs, BOOL tableweak)
|
||||
{
|
||||
BOOL first_extern_ref;
|
||||
ULONG rc;
|
||||
|
@ -427,7 +434,7 @@ ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs, BOOL tableweak
|
|||
rc += ++m->weakrefs;
|
||||
|
||||
LeaveCriticalSection(&m->lock);
|
||||
|
||||
|
||||
TRACE("added %u refs to %p (oid %s), rc is now %u\n", refs, m, wine_dbgstr_longlong(m->oid), rc);
|
||||
|
||||
/*
|
||||
|
@ -441,7 +448,7 @@ ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs, BOOL tableweak
|
|||
}
|
||||
|
||||
/* remove some external references */
|
||||
ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tableweak, BOOL last_unlock_releases)
|
||||
ULONG WINAPI stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tableweak, BOOL last_unlock_releases)
|
||||
{
|
||||
BOOL last_extern_ref;
|
||||
ULONG rc;
|
||||
|
@ -460,7 +467,7 @@ ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tablewea
|
|||
last_extern_ref = refs && !m->extrefs;
|
||||
|
||||
LeaveCriticalSection(&m->lock);
|
||||
|
||||
|
||||
TRACE("removed %u refs from %p (oid %s), rc is now %u\n", refs, m, wine_dbgstr_longlong(m->oid), rc);
|
||||
|
||||
if (last_extern_ref && m->extern_conn)
|
||||
|
@ -482,9 +489,9 @@ static struct stub_manager *get_stub_manager_from_ipid(struct apartment *apt, co
|
|||
struct list *cursor;
|
||||
|
||||
EnterCriticalSection(&apt->cs);
|
||||
LIST_FOR_EACH( cursor, &apt->stubmgrs )
|
||||
LIST_FOR_EACH(cursor, &apt->stubmgrs)
|
||||
{
|
||||
struct stub_manager *m = LIST_ENTRY( cursor, struct stub_manager, entry );
|
||||
struct stub_manager *m = LIST_ENTRY(cursor, struct stub_manager, entry);
|
||||
|
||||
if ((*ifstub = stub_manager_ipid_to_ifstub(m, ipid)))
|
||||
{
|
||||
|
@ -535,7 +542,7 @@ static HRESULT ipid_to_stub_manager(const IPID *ipid, struct apartment **stub_ap
|
|||
/* gets the apartment, stub and channel of an object. the caller must
|
||||
* release the references to all objects (except iface) if the function
|
||||
* returned success, otherwise no references are returned. */
|
||||
HRESULT ipid_get_dispatch_params(const IPID *ipid, struct apartment **stub_apt,
|
||||
HRESULT WINAPI ipid_get_dispatch_params(const IPID *ipid, struct apartment **stub_apt,
|
||||
struct stub_manager **manager,
|
||||
IRpcStubBuffer **stub, IRpcChannelBuffer **chan,
|
||||
IID *iid, IUnknown **iface)
|
||||
|
@ -564,7 +571,7 @@ HRESULT ipid_get_dispatch_params(const IPID *ipid, struct apartment **stub_apt,
|
|||
}
|
||||
|
||||
/* returns TRUE if it is possible to unmarshal, FALSE otherwise. */
|
||||
BOOL stub_manager_notify_unmarshal(struct stub_manager *m, const IPID *ipid)
|
||||
BOOL WINAPI stub_manager_notify_unmarshal(struct stub_manager *m, const IPID *ipid)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
struct ifstub *ifstub;
|
||||
|
@ -595,13 +602,13 @@ BOOL stub_manager_notify_unmarshal(struct stub_manager *m, const IPID *ipid)
|
|||
}
|
||||
|
||||
/* handles refcounting for CoReleaseMarshalData */
|
||||
void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const IPID *ipid, BOOL tableweak)
|
||||
void WINAPI stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const IPID *ipid, BOOL tableweak)
|
||||
{
|
||||
struct ifstub *ifstub;
|
||||
|
||||
|
||||
if (!(ifstub = stub_manager_ipid_to_ifstub(m, ipid)))
|
||||
return;
|
||||
|
||||
|
||||
if (ifstub->flags & MSHLFLAGS_TABLEWEAK)
|
||||
refs = 0;
|
||||
else if (ifstub->flags & MSHLFLAGS_TABLESTRONG)
|
||||
|
@ -611,16 +618,15 @@ void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const
|
|||
}
|
||||
|
||||
/* is an ifstub table marshaled? */
|
||||
BOOL stub_manager_is_table_marshaled(struct stub_manager *m, const IPID *ipid)
|
||||
BOOL WINAPI stub_manager_is_table_marshaled(struct stub_manager *m, const IPID *ipid)
|
||||
{
|
||||
struct ifstub *ifstub = stub_manager_ipid_to_ifstub(m, ipid);
|
||||
|
||||
assert( ifstub );
|
||||
|
||||
assert(ifstub);
|
||||
|
||||
return ifstub->flags & (MSHLFLAGS_TABLESTRONG | MSHLFLAGS_TABLEWEAK);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* IRemUnknown implementation
|
||||
|
@ -643,24 +649,24 @@ static inline RemUnknown *impl_from_IRemUnknown(IRemUnknown *iface)
|
|||
return CONTAINING_RECORD(iface, RemUnknown, IRemUnknown_iface);
|
||||
}
|
||||
|
||||
|
||||
/* construct an IRemUnknown object with one outstanding reference */
|
||||
static HRESULT RemUnknown_Construct(IRemUnknown **ppRemUnknown)
|
||||
{
|
||||
RemUnknown *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
|
||||
RemUnknown *object = HeapAlloc(GetProcessHeap(), 0, sizeof(*object));
|
||||
|
||||
if (!This) return E_OUTOFMEMORY;
|
||||
if (!object)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
This->IRemUnknown_iface.lpVtbl = &RemUnknown_Vtbl;
|
||||
This->refs = 1;
|
||||
object->IRemUnknown_iface.lpVtbl = &RemUnknown_Vtbl;
|
||||
object->refs = 1;
|
||||
|
||||
*ppRemUnknown = &This->IRemUnknown_iface;
|
||||
*ppRemUnknown = &object->IRemUnknown_iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RemUnknown_QueryInterface(IRemUnknown *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
|
||||
TRACE("%p, %s, %p\n", iface, debugstr_guid(riid), ppv);
|
||||
|
||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
||||
IsEqualIID(riid, &IID_IRemUnknown))
|
||||
|
@ -680,9 +686,9 @@ static HRESULT WINAPI RemUnknown_QueryInterface(IRemUnknown *iface, REFIID riid,
|
|||
static ULONG WINAPI RemUnknown_AddRef(IRemUnknown *iface)
|
||||
{
|
||||
ULONG refs;
|
||||
RemUnknown *This = impl_from_IRemUnknown(iface);
|
||||
RemUnknown *remunk = impl_from_IRemUnknown(iface);
|
||||
|
||||
refs = InterlockedIncrement(&This->refs);
|
||||
refs = InterlockedIncrement(&remunk->refs);
|
||||
|
||||
TRACE("%p before: %d\n", iface, refs-1);
|
||||
return refs;
|
||||
|
@ -691,11 +697,11 @@ static ULONG WINAPI RemUnknown_AddRef(IRemUnknown *iface)
|
|||
static ULONG WINAPI RemUnknown_Release(IRemUnknown *iface)
|
||||
{
|
||||
ULONG refs;
|
||||
RemUnknown *This = impl_from_IRemUnknown(iface);
|
||||
RemUnknown *remunk = impl_from_IRemUnknown(iface);
|
||||
|
||||
refs = InterlockedDecrement(&This->refs);
|
||||
refs = InterlockedDecrement(&remunk->refs);
|
||||
if (!refs)
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
HeapFree(GetProcessHeap(), 0, remunk);
|
||||
|
||||
TRACE("%p after: %d\n", iface, refs);
|
||||
return refs;
|
||||
|
@ -714,7 +720,7 @@ static HRESULT WINAPI RemUnknown_RemQueryInterface(IRemUnknown *iface,
|
|||
DWORD dest_context;
|
||||
void *dest_context_data;
|
||||
|
||||
TRACE("(%p)->(%s, %d, %d, %p, %p)\n", iface, debugstr_guid(ripid), cRefs, cIids, iids, ppQIResults);
|
||||
TRACE("%p, %s, %d, %d, %p, %p\n", iface, debugstr_guid(ripid), cRefs, cIids, iids, ppQIResults);
|
||||
|
||||
hr = ipid_to_ifstub(ripid, &apt, &stubmgr, &ifstub);
|
||||
if (hr != S_OK) return hr;
|
||||
|
@ -751,7 +757,7 @@ static HRESULT WINAPI RemUnknown_RemAddRef(IRemUnknown *iface,
|
|||
HRESULT hr = S_OK;
|
||||
USHORT i;
|
||||
|
||||
TRACE("(%p)->(%d, %p, %p)\n", iface, cInterfaceRefs, InterfaceRefs, pResults);
|
||||
TRACE("%p, %d, %p, %p\n", iface, cInterfaceRefs, InterfaceRefs, pResults);
|
||||
|
||||
for (i = 0; i < cInterfaceRefs; i++)
|
||||
{
|
||||
|
@ -783,7 +789,7 @@ static HRESULT WINAPI RemUnknown_RemRelease(IRemUnknown *iface,
|
|||
HRESULT hr = S_OK;
|
||||
USHORT i;
|
||||
|
||||
TRACE("(%p)->(%d, %p)\n", iface, cInterfaceRefs, InterfaceRefs);
|
||||
TRACE("%p, %d, %p\n", iface, cInterfaceRefs, InterfaceRefs);
|
||||
|
||||
for (i = 0; i < cInterfaceRefs; i++)
|
||||
{
|
||||
|
@ -820,7 +826,7 @@ static const IRemUnknownVtbl RemUnknown_Vtbl =
|
|||
};
|
||||
|
||||
/* starts the IRemUnknown listener for the current apartment */
|
||||
HRESULT start_apartment_remote_unknown(struct apartment *apt)
|
||||
HRESULT WINAPI start_apartment_remote_unknown(struct apartment *apt)
|
||||
{
|
||||
IRemUnknown *pRemUnknown;
|
||||
HRESULT hr = S_OK;
|
||||
|
@ -834,7 +840,8 @@ HRESULT start_apartment_remote_unknown(struct apartment *apt)
|
|||
{
|
||||
STDOBJREF stdobjref; /* dummy - not used */
|
||||
/* register it with the stub manager */
|
||||
hr = marshal_object(apt, &stdobjref, &IID_IRemUnknown, (IUnknown *)pRemUnknown, MSHCTX_DIFFERENTMACHINE, NULL, MSHLFLAGS_NORMAL|MSHLFLAGSP_REMUNKNOWN);
|
||||
hr = marshal_object(apt, &stdobjref, &IID_IRemUnknown, (IUnknown *)pRemUnknown,
|
||||
MSHCTX_DIFFERENTMACHINE, NULL, MSHLFLAGS_NORMAL|MSHLFLAGSP_REMUNKNOWN);
|
||||
/* release our reference to the object as the stub manager will manage the life cycle for us */
|
||||
IRemUnknown_Release(pRemUnknown);
|
||||
if (hr == S_OK)
|
|
@ -37,7 +37,6 @@ C_SRCS = \
|
|||
stg_prop.c \
|
||||
stg_stream.c \
|
||||
storage32.c \
|
||||
stubmanager.c \
|
||||
usrmarshal.c
|
||||
|
||||
RC_SRCS = ole32res.rc
|
||||
|
|
|
@ -529,69 +529,6 @@ HRESULT WINAPI CoInitialize(LPVOID lpReserved)
|
|||
return CoInitializeEx(lpReserved, COINIT_APARTMENTTHREADED);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CoDisconnectObject [OLE32.@]
|
||||
*
|
||||
* Disconnects all connections to this object from remote processes. Dispatches
|
||||
* pending RPCs while blocking new RPCs from occurring, and then calls
|
||||
* IMarshal::DisconnectObject on the given object.
|
||||
*
|
||||
* Typically called when the object server is forced to shut down, for instance by
|
||||
* the user.
|
||||
*
|
||||
* PARAMS
|
||||
* lpUnk [I] The object whose stub should be disconnected.
|
||||
* reserved [I] Reserved. Should be set to 0.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK.
|
||||
* Failure: HRESULT code.
|
||||
*
|
||||
* SEE ALSO
|
||||
* CoMarshalInterface, CoReleaseMarshalData, CoLockObjectExternal
|
||||
*/
|
||||
HRESULT WINAPI CoDisconnectObject( LPUNKNOWN lpUnk, DWORD reserved )
|
||||
{
|
||||
struct stub_manager *manager;
|
||||
HRESULT hr;
|
||||
IMarshal *marshal;
|
||||
struct apartment *apt;
|
||||
|
||||
TRACE("(%p, 0x%08x)\n", lpUnk, reserved);
|
||||
|
||||
if (!lpUnk) return E_INVALIDARG;
|
||||
|
||||
hr = IUnknown_QueryInterface(lpUnk, &IID_IMarshal, (void **)&marshal);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
hr = IMarshal_DisconnectObject(marshal, reserved);
|
||||
IMarshal_Release(marshal);
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (!(apt = apartment_get_current_or_mta()))
|
||||
{
|
||||
ERR("apartment not initialised\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
|
||||
manager = get_stub_manager_from_object(apt, lpUnk, FALSE);
|
||||
if (manager) {
|
||||
stub_manager_disconnect(manager);
|
||||
/* Release stub manager twice, to remove the apartment reference. */
|
||||
stub_manager_int_release(manager);
|
||||
stub_manager_int_release(manager);
|
||||
}
|
||||
|
||||
/* Note: native is pretty broken here because it just silently
|
||||
* fails, without returning an appropriate error code if the object was
|
||||
* not found, making apps think that the object was disconnected, when
|
||||
* it actually wasn't */
|
||||
|
||||
apartment_release(apt);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* open HKCR\\CLSID\\{string form of clsid}\\{keyname} key */
|
||||
HRESULT COM_OpenKeyForCLSID(REFCLSID clsid, LPCWSTR keyname, REGSAM access, HKEY *subkey)
|
||||
{
|
||||
|
@ -698,64 +635,6 @@ void WINAPI CoFreeAllLibraries(void)
|
|||
/* NOP */
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CoLockObjectExternal [OLE32.@]
|
||||
*
|
||||
* Increments or decrements the external reference count of a stub object.
|
||||
*
|
||||
* PARAMS
|
||||
* pUnk [I] Stub object.
|
||||
* fLock [I] If TRUE then increments the external ref-count,
|
||||
* otherwise decrements.
|
||||
* fLastUnlockReleases [I] If TRUE then the last unlock has the effect of
|
||||
* calling CoDisconnectObject.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK.
|
||||
* Failure: HRESULT code.
|
||||
*
|
||||
* NOTES
|
||||
* If fLock is TRUE and an object is passed in that doesn't have a stub
|
||||
* manager then a new stub manager is created for the object.
|
||||
*/
|
||||
HRESULT WINAPI CoLockObjectExternal(
|
||||
LPUNKNOWN pUnk,
|
||||
BOOL fLock,
|
||||
BOOL fLastUnlockReleases)
|
||||
{
|
||||
struct stub_manager *stubmgr;
|
||||
struct apartment *apt;
|
||||
|
||||
TRACE("pUnk=%p, fLock=%s, fLastUnlockReleases=%s\n",
|
||||
pUnk, fLock ? "TRUE" : "FALSE", fLastUnlockReleases ? "TRUE" : "FALSE");
|
||||
|
||||
if (!(apt = apartment_get_current_or_mta()))
|
||||
{
|
||||
ERR("apartment not initialised\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
|
||||
stubmgr = get_stub_manager_from_object(apt, pUnk, fLock);
|
||||
if (!stubmgr)
|
||||
{
|
||||
WARN("stub object not found %p\n", pUnk);
|
||||
/* Note: native is pretty broken here because it just silently
|
||||
* fails, without returning an appropriate error code, making apps
|
||||
* think that the object was disconnected, when it actually wasn't */
|
||||
apartment_release(apt);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (fLock)
|
||||
stub_manager_ext_addref(stubmgr, 1, FALSE);
|
||||
else
|
||||
stub_manager_ext_release(stubmgr, 1, FALSE, fLastUnlockReleases);
|
||||
|
||||
stub_manager_int_release(stubmgr);
|
||||
apartment_release(apt);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CoInitializeWOW (OLE32.@)
|
||||
*
|
||||
|
|
|
@ -194,24 +194,8 @@ HRESULT FTMarshalCF_Create(REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
|
|||
|
||||
/* Stub Manager */
|
||||
|
||||
ULONG stub_manager_int_release(struct stub_manager *This) DECLSPEC_HIDDEN;
|
||||
ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs, BOOL tableweak) DECLSPEC_HIDDEN;
|
||||
ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tableweak, BOOL last_unlock_releases) DECLSPEC_HIDDEN;
|
||||
struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, REFIID iid,
|
||||
DWORD dest_context, void *dest_context_data, MSHLFLAGS flags) DECLSPEC_HIDDEN;
|
||||
struct ifstub *stub_manager_find_ifstub(struct stub_manager *m, REFIID iid, MSHLFLAGS flags) DECLSPEC_HIDDEN;
|
||||
struct stub_manager *get_stub_manager(struct apartment *apt, OID oid) DECLSPEC_HIDDEN;
|
||||
struct stub_manager *get_stub_manager_from_object(struct apartment *apt, IUnknown *object, BOOL alloc) DECLSPEC_HIDDEN;
|
||||
BOOL stub_manager_notify_unmarshal(struct stub_manager *m, const IPID *ipid) DECLSPEC_HIDDEN;
|
||||
BOOL stub_manager_is_table_marshaled(struct stub_manager *m, const IPID *ipid) DECLSPEC_HIDDEN;
|
||||
void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const IPID *ipid, BOOL tableweak) DECLSPEC_HIDDEN;
|
||||
void stub_manager_disconnect(struct stub_manager *m) DECLSPEC_HIDDEN;
|
||||
HRESULT ipid_get_dispatch_params(const IPID *ipid, struct apartment **stub_apt, struct stub_manager **manager, IRpcStubBuffer **stub,
|
||||
IRpcChannelBuffer **chan, IID *iid, IUnknown **iface) DECLSPEC_HIDDEN;
|
||||
HRESULT start_apartment_remote_unknown(struct apartment *apt) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT marshal_object(struct apartment *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *obj, DWORD dest_context,
|
||||
void *dest_context_data, MSHLFLAGS mshlflags) DECLSPEC_HIDDEN;
|
||||
extern ULONG WINAPI stub_manager_int_release(struct stub_manager *This) DECLSPEC_HIDDEN;
|
||||
extern struct stub_manager * WINAPI get_stub_manager(struct apartment *apt, OID oid) DECLSPEC_HIDDEN;
|
||||
|
||||
/* RPC Backend */
|
||||
|
||||
|
@ -222,9 +206,7 @@ HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid,
|
|||
const OXID_INFO *oxid_info, const IID *iid,
|
||||
DWORD dest_context, void *dest_context_data,
|
||||
IRpcChannelBuffer **chan, struct apartment *apt) DECLSPEC_HIDDEN;
|
||||
HRESULT RPC_CreateServerChannel(DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan) DECLSPEC_HIDDEN;
|
||||
HRESULT RPC_RegisterInterface(REFIID riid) DECLSPEC_HIDDEN;
|
||||
void RPC_UnregisterInterface(REFIID riid, BOOL wait) DECLSPEC_HIDDEN;
|
||||
HRESULT RPC_RegisterChannelHook(REFGUID rguid, IChannelHook *hook) DECLSPEC_HIDDEN;
|
||||
void RPC_UnregisterAllChannelHooks(void) DECLSPEC_HIDDEN;
|
||||
HRESULT RPC_ResolveOxid(OXID oxid, OXID_INFO *oxid_info) DECLSPEC_HIDDEN;
|
||||
|
@ -235,7 +217,6 @@ void OLEDD_UnInitialize(void) DECLSPEC_HIDDEN;
|
|||
/* Apartment Functions */
|
||||
|
||||
extern struct apartment * WINAPI apartment_findfromoxid(OXID oxid) DECLSPEC_HIDDEN;
|
||||
extern struct apartment * WINAPI apartment_findfromtid(DWORD tid) DECLSPEC_HIDDEN;
|
||||
extern void WINAPI apartment_release(struct apartment *apt) DECLSPEC_HIDDEN;
|
||||
static inline HRESULT apartment_getoxid(const struct apartment *apt, OXID *oxid)
|
||||
{
|
||||
|
|
|
@ -39,6 +39,16 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
extern BOOL WINAPI stub_manager_is_table_marshaled(struct stub_manager *m, const IPID *ipid);
|
||||
extern BOOL WINAPI stub_manager_notify_unmarshal(struct stub_manager *m, const IPID *ipid);
|
||||
extern ULONG WINAPI stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tableweak, BOOL last_unlock_releases);
|
||||
extern void WINAPI stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const IPID *ipid, BOOL tableweak);
|
||||
extern struct stub_manager * WINAPI get_stub_manager_from_object(struct apartment *apt, IUnknown *object, BOOL alloc);
|
||||
extern struct ifstub * WINAPI stub_manager_find_ifstub(struct stub_manager *m, REFIID iid, MSHLFLAGS flags);
|
||||
extern ULONG WINAPI stub_manager_ext_addref(struct stub_manager *m, ULONG refs, BOOL tableweak);
|
||||
extern struct ifstub * WINAPI stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, REFIID iid,
|
||||
DWORD dest_context, void *dest_context_data, MSHLFLAGS flags);
|
||||
|
||||
/* number of refs given out for normal marshaling */
|
||||
#define NORMALEXTREFS 5
|
||||
|
||||
|
@ -118,7 +128,7 @@ static inline HRESULT get_facbuf_for_iid(REFIID riid, IPSFactoryBuffer **facbuf)
|
|||
}
|
||||
|
||||
/* marshals an object into a STDOBJREF structure */
|
||||
HRESULT marshal_object(struct apartment *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *object,
|
||||
HRESULT WINAPI marshal_object(struct apartment *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *object,
|
||||
DWORD dest_context, void *dest_context_data, MSHLFLAGS mshlflags)
|
||||
{
|
||||
struct stub_manager *manager;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
@ stdcall CoCreateInstanceEx(ptr ptr long ptr long ptr) combase.CoCreateInstanceEx
|
||||
@ stdcall CoDecrementMTAUsage(ptr) combase.CoDecrementMTAUsage
|
||||
@ stdcall CoDisableCallCancellation(ptr)
|
||||
@ stdcall CoDisconnectObject(ptr long)
|
||||
@ stdcall CoDisconnectObject(ptr long) combase.CoDisconnectObject
|
||||
@ stdcall CoDosDateTimeToFileTime(long long ptr) kernel32.DosDateTimeToFileTime
|
||||
@ stdcall CoEnableCallCancellation(ptr)
|
||||
@ stdcall CoFileTimeNow(ptr) combase.CoFileTimeNow
|
||||
|
@ -56,7 +56,7 @@
|
|||
@ stdcall CoIsHandlerConnected(ptr)
|
||||
@ stdcall CoIsOle1Class (ptr)
|
||||
@ stdcall CoLoadLibrary(wstr long)
|
||||
@ stdcall CoLockObjectExternal(ptr long long)
|
||||
@ stdcall CoLockObjectExternal(ptr long long) combase.CoLockObjectExternal
|
||||
@ stdcall CoMarshalHresult(ptr long) combase.CoMarshalHresult
|
||||
@ stdcall CoMarshalInterThreadInterfaceInStream(ptr ptr ptr) combase.CoMarshalInterThreadInterfaceInStream
|
||||
@ stdcall CoMarshalInterface(ptr ptr ptr long ptr long) combase.CoMarshalInterface
|
||||
|
@ -298,6 +298,9 @@
|
|||
@ stdcall WriteFmtUserTypeStg(ptr long ptr)
|
||||
@ stub WriteOleStg
|
||||
@ stub WriteStringStream
|
||||
|
||||
@ stdcall Internal_apartment_disconnectproxies(ptr)
|
||||
@ stdcall Internal_RPC_ExecuteCall(ptr)
|
||||
@ stdcall Internal_stub_manager_int_release(ptr)
|
||||
@ stdcall marshal_object(ptr ptr ptr ptr long ptr long)
|
||||
@ stdcall RPC_CreateServerChannel(long ptr ptr)
|
||||
@ stdcall RPC_UnregisterInterface(ptr long)
|
||||
|
|
|
@ -43,6 +43,10 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
extern HRESULT WINAPI ipid_get_dispatch_params(const IPID *ipid, struct apartment **stub_apt,
|
||||
struct stub_manager **manager, IRpcStubBuffer **stub, IRpcChannelBuffer **chan, IID *iid, IUnknown **iface);
|
||||
extern HRESULT WINAPI start_apartment_remote_unknown(struct apartment *apt);
|
||||
|
||||
static void __RPC_STUB dispatch_rpc(RPC_MESSAGE *msg);
|
||||
|
||||
/* we only use one function to dispatch calls for all methods - we use the
|
||||
|
@ -1159,7 +1163,7 @@ HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT RPC_CreateServerChannel(DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan)
|
||||
HRESULT WINAPI RPC_CreateServerChannel(DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan)
|
||||
{
|
||||
RpcChannelBuffer *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
|
||||
if (!This)
|
||||
|
@ -1584,7 +1588,7 @@ HRESULT RPC_RegisterInterface(REFIID riid)
|
|||
}
|
||||
|
||||
/* stub unregistration */
|
||||
void RPC_UnregisterInterface(REFIID riid, BOOL wait)
|
||||
void WINAPI RPC_UnregisterInterface(REFIID riid, BOOL wait)
|
||||
{
|
||||
struct registered_if *rif;
|
||||
EnterCriticalSection(&csRegIf);
|
||||
|
|
Loading…
Reference in New Issue