ole32: Reorder some stubmanager functions to avoid forward declarations.

This commit is contained in:
Francois Gouget 2009-06-22 10:46:58 +02:00 committed by Alexandre Julliard
parent 0601902740
commit 887c395ce2
1 changed files with 161 additions and 163 deletions

View File

@ -42,8 +42,129 @@
WINE_DEFAULT_DEBUG_CHANNEL(ole);
static void stub_manager_delete_ifstub(struct stub_manager *m, struct ifstub *ifstub);
static struct ifstub *stub_manager_ipid_to_ifstub(struct stub_manager *m, const IPID *ipid);
/* generates an ipid in the following format (similar to native version):
* Data1 = apartment-local ipid counter
* Data2 = apartment creator thread ID
* Data3 = process ID
* Data4 = random value
*/
static inline HRESULT generate_ipid(struct stub_manager *m, IPID *ipid)
{
HRESULT hr;
hr = UuidCreate(ipid);
if (FAILED(hr))
{
ERR("couldn't create IPID for stub manager %p\n", m);
UuidCreateNil(ipid);
return hr;
}
ipid->Data1 = InterlockedIncrement(&m->apt->ipidc);
ipid->Data2 = (USHORT)m->apt->tid;
ipid->Data3 = (USHORT)GetCurrentProcessId();
return S_OK;
}
/* 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, IUnknown *iptr, REFIID iid, MSHLFLAGS flags)
{
struct ifstub *stub;
HRESULT hr;
TRACE("oid=%s, stubbuffer=%p, iptr=%p, iid=%s\n",
wine_dbgstr_longlong(m->oid), sb, iptr, debugstr_guid(iid));
stub = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct ifstub));
if (!stub) return NULL;
hr = RPC_CreateServerChannel(&stub->chan);
if (hr != S_OK)
{
HeapFree(GetProcessHeap(), 0, stub);
return NULL;
}
stub->stubbuffer = sb;
if (sb) IRpcStubBuffer_AddRef(sb);
IUnknown_AddRef(iptr);
stub->iface = iptr;
stub->flags = flags;
stub->iid = *iid;
/* FIXME: find a cleaner way of identifying that we are creating an ifstub
* for the remunknown interface */
if (flags & MSHLFLAGSP_REMUNKNOWN)
stub->ipid = m->oxid_info.ipidRemUnknown;
else
generate_ipid(m, &stub->ipid);
EnterCriticalSection(&m->lock);
list_add_head(&m->ifstubs, &stub->entry);
/* every normal marshal is counted so we don't allow more than we should */
if (flags & MSHLFLAGS_NORMAL) m->norm_refs++;
LeaveCriticalSection(&m->lock);
TRACE("ifstub %p created with ipid %s\n", stub, debugstr_guid(&stub->ipid));
return stub;
}
static void stub_manager_delete_ifstub(struct stub_manager *m, struct ifstub *ifstub)
{
TRACE("m=%p, m->oid=%s, ipid=%s\n", m, wine_dbgstr_longlong(m->oid), debugstr_guid(&ifstub->ipid));
list_remove(&ifstub->entry);
RPC_UnregisterInterface(&ifstub->iid);
if (ifstub->stubbuffer) IUnknown_Release(ifstub->stubbuffer);
IUnknown_Release(ifstub->iface);
IRpcChannelBuffer_Release(ifstub->chan);
HeapFree(GetProcessHeap(), 0, ifstub);
}
static struct ifstub *stub_manager_ipid_to_ifstub(struct stub_manager *m, const IPID *ipid)
{
struct list *cursor;
struct ifstub *result = NULL;
EnterCriticalSection(&m->lock);
LIST_FOR_EACH( cursor, &m->ifstubs )
{
struct ifstub *ifstub = LIST_ENTRY( cursor, struct ifstub, entry );
if (IsEqualGUID(ipid, &ifstub->ipid))
{
result = ifstub;
break;
}
}
LeaveCriticalSection(&m->lock);
return result;
}
struct ifstub *stub_manager_find_ifstub(struct stub_manager *m, REFIID iid, MSHLFLAGS flags)
{
struct ifstub *result = NULL;
struct ifstub *ifstub;
EnterCriticalSection(&m->lock);
LIST_FOR_EACH_ENTRY( ifstub, &m->ifstubs, struct ifstub, entry )
{
if (IsEqualIID(iid, &ifstub->iid) && (ifstub->flags == flags))
{
result = ifstub;
break;
}
}
LeaveCriticalSection(&m->lock);
return result;
}
/* creates a new stub manager and adds it into the apartment. caller must
* release stub manager when it is no longer required. the apartment and
@ -129,6 +250,44 @@ static void stub_manager_delete(struct stub_manager *m)
HeapFree(GetProcessHeap(), 0, m);
}
/* increments the internal refcount */
ULONG stub_manager_int_addref(struct stub_manager *This)
{
ULONG refs;
EnterCriticalSection(&This->apt->cs);
refs = ++This->refs;
LeaveCriticalSection(&This->apt->cs);
TRACE("before %d\n", refs - 1);
return refs;
}
/* decrements the internal refcount */
ULONG stub_manager_int_release(struct stub_manager *This)
{
ULONG refs;
APARTMENT *apt = This->apt;
EnterCriticalSection(&apt->cs);
refs = --This->refs;
TRACE("after %d\n", refs);
/* remove from apartment so no other thread can access it... */
if (!refs)
list_remove(&This->entry);
LeaveCriticalSection(&apt->cs);
/* ... so now we can delete it without being inside the apartment critsec */
if (!refs)
stub_manager_delete(This);
return refs;
}
/* 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 */
@ -214,44 +373,6 @@ struct stub_manager *get_stub_manager(APARTMENT *apt, OID oid)
return result;
}
/* increments the internal refcount */
ULONG stub_manager_int_addref(struct stub_manager *This)
{
ULONG refs;
EnterCriticalSection(&This->apt->cs);
refs = ++This->refs;
LeaveCriticalSection(&This->apt->cs);
TRACE("before %d\n", refs - 1);
return refs;
}
/* decrements the internal refcount */
ULONG stub_manager_int_release(struct stub_manager *This)
{
ULONG refs;
APARTMENT *apt = This->apt;
EnterCriticalSection(&apt->cs);
refs = --This->refs;
TRACE("after %d\n", refs);
/* remove from apartment so no other thread can access it... */
if (!refs)
list_remove(&This->entry);
LeaveCriticalSection(&apt->cs);
/* ... so now we can delete it without being inside the apartment critsec */
if (!refs)
stub_manager_delete(This);
return refs;
}
/* 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)
{
@ -297,46 +418,6 @@ ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tablewea
return rc;
}
static struct ifstub *stub_manager_ipid_to_ifstub(struct stub_manager *m, const IPID *ipid)
{
struct list *cursor;
struct ifstub *result = NULL;
EnterCriticalSection(&m->lock);
LIST_FOR_EACH( cursor, &m->ifstubs )
{
struct ifstub *ifstub = LIST_ENTRY( cursor, struct ifstub, entry );
if (IsEqualGUID(ipid, &ifstub->ipid))
{
result = ifstub;
break;
}
}
LeaveCriticalSection(&m->lock);
return result;
}
struct ifstub *stub_manager_find_ifstub(struct stub_manager *m, REFIID iid, MSHLFLAGS flags)
{
struct ifstub *result = NULL;
struct ifstub *ifstub;
EnterCriticalSection(&m->lock);
LIST_FOR_EACH_ENTRY( ifstub, &m->ifstubs, struct ifstub, entry )
{
if (IsEqualIID(iid, &ifstub->iid) && (ifstub->flags == flags))
{
result = ifstub;
break;
}
}
LeaveCriticalSection(&m->lock);
return result;
}
/* gets the stub manager associated with an ipid - 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 */
@ -426,89 +507,6 @@ HRESULT ipid_get_dispatch_params(const IPID *ipid, APARTMENT **stub_apt,
}
}
/* generates an ipid in the following format (similar to native version):
* Data1 = apartment-local ipid counter
* Data2 = apartment creator thread ID
* Data3 = process ID
* Data4 = random value
*/
static inline HRESULT generate_ipid(struct stub_manager *m, IPID *ipid)
{
HRESULT hr;
hr = UuidCreate(ipid);
if (FAILED(hr))
{
ERR("couldn't create IPID for stub manager %p\n", m);
UuidCreateNil(ipid);
return hr;
}
ipid->Data1 = InterlockedIncrement(&m->apt->ipidc);
ipid->Data2 = (USHORT)m->apt->tid;
ipid->Data3 = (USHORT)GetCurrentProcessId();
return S_OK;
}
/* 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, IUnknown *iptr, REFIID iid, MSHLFLAGS flags)
{
struct ifstub *stub;
HRESULT hr;
TRACE("oid=%s, stubbuffer=%p, iptr=%p, iid=%s\n",
wine_dbgstr_longlong(m->oid), sb, iptr, debugstr_guid(iid));
stub = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct ifstub));
if (!stub) return NULL;
hr = RPC_CreateServerChannel(&stub->chan);
if (hr != S_OK)
{
HeapFree(GetProcessHeap(), 0, stub);
return NULL;
}
stub->stubbuffer = sb;
if (sb) IRpcStubBuffer_AddRef(sb);
IUnknown_AddRef(iptr);
stub->iface = iptr;
stub->flags = flags;
stub->iid = *iid;
/* FIXME: find a cleaner way of identifying that we are creating an ifstub
* for the remunknown interface */
if (flags & MSHLFLAGSP_REMUNKNOWN)
stub->ipid = m->oxid_info.ipidRemUnknown;
else
generate_ipid(m, &stub->ipid);
EnterCriticalSection(&m->lock);
list_add_head(&m->ifstubs, &stub->entry);
/* every normal marshal is counted so we don't allow more than we should */
if (flags & MSHLFLAGS_NORMAL) m->norm_refs++;
LeaveCriticalSection(&m->lock);
TRACE("ifstub %p created with ipid %s\n", stub, debugstr_guid(&stub->ipid));
return stub;
}
static void stub_manager_delete_ifstub(struct stub_manager *m, struct ifstub *ifstub)
{
TRACE("m=%p, m->oid=%s, ipid=%s\n", m, wine_dbgstr_longlong(m->oid), debugstr_guid(&ifstub->ipid));
list_remove(&ifstub->entry);
RPC_UnregisterInterface(&ifstub->iid);
if (ifstub->stubbuffer) IUnknown_Release(ifstub->stubbuffer);
IUnknown_Release(ifstub->iface);
IRpcChannelBuffer_Release(ifstub->chan);
HeapFree(GetProcessHeap(), 0, ifstub);
}
/* returns TRUE if it is possible to unmarshal, FALSE otherwise. */
BOOL stub_manager_notify_unmarshal(struct stub_manager *m, const IPID *ipid)
{