ReactOS 0.4.15-dev-7942-gd23573b
stubmanager.c File Reference
#include <assert.h>
#include <stdarg.h>
#include <limits.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "objbase.h"
#include "rpc.h"
#include "wine/debug.h"
#include "wine/exception.h"
#include "compobj_private.h"
Include dependency graph for stubmanager.c:

Go to the source code of this file.

Classes

struct  rem_unknown
 

Macros

#define COBJMACROS
 

Typedefs

typedef struct rem_unknown RemUnknown
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (ole)
 
static HRESULT generate_ipid (struct stub_manager *m, IPID *ipid)
 
struct ifstubstub_manager_new_ifstub (struct stub_manager *m, IRpcStubBuffer *sb, REFIID iid, DWORD dest_context, void *dest_context_data, MSHLFLAGS flags)
 
static void stub_manager_delete_ifstub (struct stub_manager *m, struct ifstub *ifstub)
 
static struct ifstubstub_manager_ipid_to_ifstub (struct stub_manager *m, const IPID *ipid)
 
struct ifstubstub_manager_find_ifstub (struct stub_manager *m, REFIID iid, MSHLFLAGS flags)
 
static struct stub_managernew_stub_manager (APARTMENT *apt, IUnknown *object)
 
void stub_manager_disconnect (struct stub_manager *m)
 
static void stub_manager_delete (struct stub_manager *m)
 
static ULONG stub_manager_int_addref (struct stub_manager *This)
 
ULONG stub_manager_int_release (struct stub_manager *This)
 
struct stub_managerget_stub_manager_from_object (APARTMENT *apt, IUnknown *obj, BOOL alloc)
 
struct stub_managerget_stub_manager (APARTMENT *apt, OID oid)
 
ULONG stub_manager_ext_addref (struct stub_manager *m, ULONG refs, BOOL tableweak)
 
ULONG stub_manager_ext_release (struct stub_manager *m, ULONG refs, BOOL tableweak, BOOL last_unlock_releases)
 
static struct stub_managerget_stub_manager_from_ipid (APARTMENT *apt, const IPID *ipid, struct ifstub **ifstub)
 
static HRESULT ipid_to_ifstub (const IPID *ipid, APARTMENT **stub_apt, struct stub_manager **stubmgr_ret, struct ifstub **ifstub)
 
static HRESULT ipid_to_stub_manager (const IPID *ipid, APARTMENT **stub_apt, struct stub_manager **stub)
 
HRESULT ipid_get_dispatch_params (const IPID *ipid, APARTMENT **stub_apt, struct stub_manager **manager, IRpcStubBuffer **stub, IRpcChannelBuffer **chan, IID *iid, IUnknown **iface)
 
BOOL stub_manager_notify_unmarshal (struct stub_manager *m, const IPID *ipid)
 
void stub_manager_release_marshal_data (struct stub_manager *m, ULONG refs, const IPID *ipid, BOOL tableweak)
 
BOOL stub_manager_is_table_marshaled (struct stub_manager *m, const IPID *ipid)
 
static RemUnknownimpl_from_IRemUnknown (IRemUnknown *iface)
 
static HRESULT RemUnknown_Construct (IRemUnknown **ppRemUnknown)
 
static HRESULT WINAPI RemUnknown_QueryInterface (IRemUnknown *iface, REFIID riid, void **ppv)
 
static ULONG WINAPI RemUnknown_AddRef (IRemUnknown *iface)
 
static ULONG WINAPI RemUnknown_Release (IRemUnknown *iface)
 
static HRESULT WINAPI RemUnknown_RemQueryInterface (IRemUnknown *iface, REFIPID ripid, ULONG cRefs, USHORT cIids, IID *iids, REMQIRESULT **ppQIResults)
 
static HRESULT WINAPI RemUnknown_RemAddRef (IRemUnknown *iface, USHORT cInterfaceRefs, REMINTERFACEREF *InterfaceRefs, HRESULT *pResults)
 
static HRESULT WINAPI RemUnknown_RemRelease (IRemUnknown *iface, USHORT cInterfaceRefs, REMINTERFACEREF *InterfaceRefs)
 
HRESULT start_apartment_remote_unknown (APARTMENT *apt)
 

Variables

static const IRemUnknownVtbl RemUnknown_Vtbl
 

Macro Definition Documentation

◆ COBJMACROS

#define COBJMACROS

Definition at line 26 of file stubmanager.c.

Typedef Documentation

◆ RemUnknown

Function Documentation

◆ generate_ipid()

static HRESULT generate_ipid ( struct stub_manager m,
IPID ipid 
)
inlinestatic

Definition at line 52 of file stubmanager.c.

53{
54 HRESULT hr;
55 hr = UuidCreate(ipid);
56 if (FAILED(hr))
57 {
58 ERR("couldn't create IPID for stub manager %p\n", m);
59 UuidCreateNil(ipid);
60 return hr;
61 }
62
63 ipid->Data1 = InterlockedIncrement(&m->apt->ipidc);
64 ipid->Data2 = (USHORT)m->apt->tid;
65 ipid->Data3 = (USHORT)GetCurrentProcessId();
66 return S_OK;
67}
#define InterlockedIncrement
Definition: armddk.h:53
#define ERR(fmt,...)
Definition: debug.h:110
const GLfloat * m
Definition: glext.h:10848
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
unsigned short USHORT
Definition: pedump.c:61
RPC_STATUS WINAPI UuidCreateNil(UUID *Uuid)
Definition: rpcrt4_main.c:284
RPC_STATUS WINAPI UuidCreate(UUID *Uuid)
Definition: rpcrt4_main.c:305
HRESULT hr
Definition: shlfolder.c:183
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1158

Referenced by stub_manager_new_ifstub().

◆ get_stub_manager()

struct stub_manager * get_stub_manager ( APARTMENT apt,
OID  oid 
)

Definition at line 380 of file stubmanager.c.

381{
382 struct stub_manager *result = NULL;
383 struct list *cursor;
384
387 {
388 struct stub_manager *m = LIST_ENTRY( cursor, struct stub_manager, entry );
389
390 if (m->oid == oid)
391 {
392 result = m;
394 break;
395 }
396 }
398
399 if (result)
400 TRACE("found %p for oid %s\n", result, wine_dbgstr_longlong(oid));
401 else
402 TRACE("not found for oid %s\n", wine_dbgstr_longlong(oid));
403
404 return result;
405}
Definition: list.h:37
#define NULL
Definition: types.h:112
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
GLuint64EXT * result
Definition: glext.h:11304
const char cursor[]
Definition: icontest.c:13
uint32_t entry
Definition: isohybrid.c:63
#define LIST_FOR_EACH(cursor, list)
Definition: list.h:188
#define TRACE(s)
Definition: solgame.cpp:4
CRITICAL_SECTION cs
struct list stubmgrs
APARTMENT * apt
static ULONG stub_manager_int_addref(struct stub_manager *This)
Definition: stubmanager.c:297
#define LIST_ENTRY(type)
Definition: queue.h:175
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)

Referenced by std_release_marshal_data(), and std_unmarshal_interface().

◆ get_stub_manager_from_ipid()

static struct stub_manager * get_stub_manager_from_ipid ( APARTMENT apt,
const IPID ipid,
struct ifstub **  ifstub 
)
static

Definition at line 474 of file stubmanager.c.

475{
476 struct stub_manager *result = NULL;
477 struct list *cursor;
478
481 {
482 struct stub_manager *m = LIST_ENTRY( cursor, struct stub_manager, entry );
483
484 if ((*ifstub = stub_manager_ipid_to_ifstub(m, ipid)))
485 {
486 result = m;
488 break;
489 }
490 }
492
493 if (result)
494 TRACE("found %p for ipid %s\n", result, debugstr_guid(ipid));
495 else
496 ERR("not found for ipid %s\n", debugstr_guid(ipid));
497
498 return result;
499}
#define debugstr_guid
Definition: kernel32.h:35
static struct ifstub * stub_manager_ipid_to_ifstub(struct stub_manager *m, const IPID *ipid)
Definition: stubmanager.c:137

Referenced by ipid_to_ifstub().

◆ get_stub_manager_from_object()

struct stub_manager * get_stub_manager_from_object ( APARTMENT apt,
IUnknown obj,
BOOL  alloc 
)

Definition at line 337 of file stubmanager.c.

338{
339 struct stub_manager *result = NULL;
340 struct list *cursor;
343
344 hres = IUnknown_QueryInterface(obj, &IID_IUnknown, (void**)&object);
345 if (FAILED(hres)) {
346 ERR("QueryInterface(IID_IUnknown failed): %08x\n", hres);
347 return NULL;
348 }
349
352 {
353 struct stub_manager *m = LIST_ENTRY( cursor, struct stub_manager, entry );
354
355 if (m->object == object)
356 {
357 result = m;
359 break;
360 }
361 }
363
364 if (result) {
365 TRACE("found %p for object %p\n", result, object);
366 }else if (alloc) {
367 TRACE("not found, creating new stub manager...\n");
368 result = new_stub_manager(apt, object);
369 }else {
370 TRACE("not found for object %p\n", object);
371 }
372
373 IUnknown_Release(object);
374 return result;
375}
const GUID IID_IUnknown
HRESULT hres
Definition: protocol.c:465
#define alloc
Definition: rosglue.h:13
static struct stub_manager * new_stub_manager(APARTMENT *apt, IUnknown *object)
Definition: stubmanager.c:180

Referenced by CoDisconnectObject(), CoLockObjectExternal(), and marshal_object().

◆ impl_from_IRemUnknown()

static RemUnknown * impl_from_IRemUnknown ( IRemUnknown iface)
inlinestatic

Definition at line 636 of file stubmanager.c.

637{
638 return CONTAINING_RECORD(iface, RemUnknown, IRemUnknown_iface);
639}
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by RemUnknown_AddRef(), and RemUnknown_Release().

◆ ipid_get_dispatch_params()

HRESULT ipid_get_dispatch_params ( const IPID ipid,
APARTMENT **  stub_apt,
struct stub_manager **  manager,
IRpcStubBuffer **  stub,
IRpcChannelBuffer **  chan,
IID iid,
IUnknown **  iface 
)

Definition at line 533 of file stubmanager.c.

537{
538 struct stub_manager *stubmgr;
539 struct ifstub *ifstub;
540 APARTMENT *apt;
541 HRESULT hr;
542
543 hr = ipid_to_ifstub(ipid, &apt, &stubmgr, &ifstub);
544 if (hr != S_OK) return RPC_E_DISCONNECTED;
545
547 IRpcStubBuffer_AddRef(*stub);
548 *chan = ifstub->chan;
549 IRpcChannelBuffer_AddRef(*chan);
550 *stub_apt = apt;
551 *iid = ifstub->iid;
552 *iface = ifstub->iface;
553
554 if (manager)
555 *manager = stubmgr;
556 else
558 return S_OK;
559}
Definition: stubgen.c:11
IUnknown * iface
IRpcStubBuffer * stubbuffer
IRpcChannelBuffer * chan
ULONG stub_manager_int_release(struct stub_manager *This)
Definition: stubmanager.c:311
static HRESULT ipid_to_ifstub(const IPID *ipid, APARTMENT **stub_apt, struct stub_manager **stubmgr_ret, struct ifstub **ifstub)
Definition: stubmanager.c:501
#define RPC_E_DISCONNECTED
Definition: winerror.h:2484

Referenced by ClientRpcChannelBuffer_GetBuffer(), and dispatch_rpc().

◆ ipid_to_ifstub()

static HRESULT ipid_to_ifstub ( const IPID ipid,
APARTMENT **  stub_apt,
struct stub_manager **  stubmgr_ret,
struct ifstub **  ifstub 
)
static

Definition at line 501 of file stubmanager.c.

503{
504 /* FIXME: hack for IRemUnknown */
505 if (ipid->Data2 == 0xffff)
506 *stub_apt = apartment_findfromoxid(*(const OXID *)ipid->Data4, TRUE);
507 else
508 *stub_apt = apartment_findfromtid(ipid->Data2);
509 if (!*stub_apt)
510 {
511 TRACE("Couldn't find apartment corresponding to TID 0x%04x\n", ipid->Data2);
513 }
514 *stubmgr_ret = get_stub_manager_from_ipid(*stub_apt, ipid, ifstub);
515 if (!*stubmgr_ret)
516 {
517 apartment_release(*stub_apt);
518 *stub_apt = NULL;
520 }
521 return S_OK;
522}
#define TRUE
Definition: types.h:120
DWORD apartment_release(struct apartment *apt)
Definition: compobj.c:1172
APARTMENT * apartment_findfromoxid(OXID oxid, BOOL ref)
Definition: compobj.c:1276
APARTMENT * apartment_findfromtid(DWORD tid)
Definition: compobj.c:1300
UINT64 OXID
Definition: marshal.c:87
static struct stub_manager * get_stub_manager_from_ipid(APARTMENT *apt, const IPID *ipid, struct ifstub **ifstub)
Definition: stubmanager.c:474
#define RPC_E_INVALID_OBJECT
Definition: winerror.h:2496

Referenced by ipid_get_dispatch_params(), ipid_to_stub_manager(), and RemUnknown_RemQueryInterface().

◆ ipid_to_stub_manager()

static HRESULT ipid_to_stub_manager ( const IPID ipid,
APARTMENT **  stub_apt,
struct stub_manager **  stub 
)
static

Definition at line 524 of file stubmanager.c.

525{
526 struct ifstub *ifstub;
527 return ipid_to_ifstub(ipid, stub_apt, stub, &ifstub);
528}

Referenced by RemUnknown_RemAddRef(), and RemUnknown_RemRelease().

◆ new_stub_manager()

static struct stub_manager * new_stub_manager ( APARTMENT apt,
IUnknown object 
)
static

Definition at line 180 of file stubmanager.c.

181{
182 struct stub_manager *sm;
184
185 assert( apt );
186
187 sm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct stub_manager));
188 if (!sm) return NULL;
189
190 list_init(&sm->ifstubs);
191
193 DEBUG_SET_CRITSEC_NAME(&sm->lock, "stub_manager");
194
195 IUnknown_AddRef(object);
196 sm->object = object;
197 sm->apt = apt;
198
199 /* start off with 2 references because the stub is in the apartment
200 * and the caller will also hold a reference */
201 sm->refs = 2;
202 sm->weakrefs = 0;
203
204 sm->oxid_info.dwPid = GetCurrentProcessId();
205 sm->oxid_info.dwTid = GetCurrentThreadId();
206 /*
207 * FIXME: this is a hack for marshalling IRemUnknown. In real
208 * DCOM, the IPID of the IRemUnknown interface is generated like
209 * any other and passed to the OXID resolver which then returns it
210 * when queried. We don't have an OXID resolver yet so instead we
211 * use a magic IPID reserved for IRemUnknown.
212 */
213 sm->oxid_info.ipidRemUnknown.Data1 = 0xffffffff;
214 sm->oxid_info.ipidRemUnknown.Data2 = 0xffff;
215 sm->oxid_info.ipidRemUnknown.Data3 = 0xffff;
216 assert(sizeof(sm->oxid_info.ipidRemUnknown.Data4) == sizeof(apt->oxid));
217 memcpy(sm->oxid_info.ipidRemUnknown.Data4, &apt->oxid, sizeof(OXID));
218 sm->oxid_info.dwAuthnHint = RPC_C_AUTHN_LEVEL_NONE;
219 sm->oxid_info.psa = NULL /* FIXME */;
220
221 /* Yes, that's right, this starts at zero. that's zero EXTERNAL
222 * refs, i.e., nobody has unmarshalled anything yet. We can't have
223 * negative refs because the stub manager cannot be explicitly
224 * killed, it has to die by somebody unmarshalling then releasing
225 * the marshalled ifptr.
226 */
227 sm->extrefs = 0;
228 sm->disconnected = FALSE;
229
230 hres = IUnknown_QueryInterface(object, &IID_IExternalConnection, (void**)&sm->extern_conn);
231 if(FAILED(hres))
232 sm->extern_conn = NULL;
233
235 sm->oid = apt->oidc++;
238
239 TRACE("Created new stub manager (oid=%s) at %p for object with IUnknown %p\n", wine_dbgstr_longlong(sm->oid), sm, object);
240
241 return sm;
242}
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
static void list_init(struct list_entry *head)
Definition: list.h:51
#define DEBUG_SET_CRITSEC_NAME(cs, name)
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define assert(x)
Definition: debug.h:53
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define RPC_C_AUTHN_LEVEL_NONE
Definition: rpcdce.h:146
CRITICAL_SECTION lock
OXID_INFO oxid_info
IExternalConnection * extern_conn
IUnknown * object
struct list ifstubs
struct list entry
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459

Referenced by get_stub_manager_from_object().

◆ RemUnknown_AddRef()

static ULONG WINAPI RemUnknown_AddRef ( IRemUnknown iface)
static

Definition at line 675 of file stubmanager.c.

676{
677 ULONG refs;
679
680 refs = InterlockedIncrement(&This->refs);
681
682 TRACE("%p before: %d\n", iface, refs-1);
683 return refs;
684}
static RemUnknown * impl_from_IRemUnknown(IRemUnknown *iface)
Definition: stubmanager.c:636
uint32_t ULONG
Definition: typedefs.h:59

◆ RemUnknown_Construct()

static HRESULT RemUnknown_Construct ( IRemUnknown **  ppRemUnknown)
static

Definition at line 643 of file stubmanager.c.

644{
645 RemUnknown *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
646
647 if (!This) return E_OUTOFMEMORY;
648
649 This->IRemUnknown_iface.lpVtbl = &RemUnknown_Vtbl;
650 This->refs = 1;
651
652 *ppRemUnknown = &This->IRemUnknown_iface;
653 return S_OK;
654}
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
static const IRemUnknownVtbl RemUnknown_Vtbl
Definition: stubmanager.c:634

Referenced by start_apartment_remote_unknown().

◆ RemUnknown_QueryInterface()

static HRESULT WINAPI RemUnknown_QueryInterface ( IRemUnknown iface,
REFIID  riid,
void **  ppv 
)
static

Definition at line 656 of file stubmanager.c.

657{
658 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
659
662 {
663 *ppv = iface;
664 IRemUnknown_AddRef(iface);
665 return S_OK;
666 }
667
668 if (!IsEqualIID(riid, &IID_IExternalConnection))
669 FIXME("No interface for iid %s\n", debugstr_guid(riid));
670
671 *ppv = NULL;
672 return E_NOINTERFACE;
673}
#define FIXME(fmt,...)
Definition: debug.h:111
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
static const IID IID_IRemUnknown
Definition: marshal.c:130
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define E_NOINTERFACE
Definition: winerror.h:2364

◆ RemUnknown_Release()

static ULONG WINAPI RemUnknown_Release ( IRemUnknown iface)
static

Definition at line 686 of file stubmanager.c.

687{
688 ULONG refs;
690
691 refs = InterlockedDecrement(&This->refs);
692 if (!refs)
694
695 TRACE("%p after: %d\n", iface, refs);
696 return refs;
697}
#define InterlockedDecrement
Definition: armddk.h:52
#define HeapFree(x, y, z)
Definition: compat.h:735

◆ RemUnknown_RemAddRef()

static HRESULT WINAPI RemUnknown_RemAddRef ( IRemUnknown iface,
USHORT  cInterfaceRefs,
REMINTERFACEREF *  InterfaceRefs,
HRESULT pResults 
)
static

Definition at line 741 of file stubmanager.c.

745{
746 HRESULT hr = S_OK;
747 USHORT i;
748
749 TRACE("(%p)->(%d, %p, %p)\n", iface, cInterfaceRefs, InterfaceRefs, pResults);
750
751 for (i = 0; i < cInterfaceRefs; i++)
752 {
753 APARTMENT *apt;
754 struct stub_manager *stubmgr;
755
756 pResults[i] = ipid_to_stub_manager(&InterfaceRefs[i].ipid, &apt, &stubmgr);
757 if (pResults[i] != S_OK)
758 {
759 hr = S_FALSE;
760 continue;
761 }
762
763 stub_manager_ext_addref(stubmgr, InterfaceRefs[i].cPublicRefs, FALSE);
764 if (InterfaceRefs[i].cPrivateRefs)
765 FIXME("Adding %d refs securely not implemented\n", InterfaceRefs[i].cPrivateRefs);
766
769 }
770
771 return hr;
772}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub_manager **stub)
Definition: stubmanager.c:524
ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs, BOOL tableweak)
Definition: stubmanager.c:408
#define S_FALSE
Definition: winerror.h:2357

◆ RemUnknown_RemQueryInterface()

static HRESULT WINAPI RemUnknown_RemQueryInterface ( IRemUnknown iface,
REFIPID  ripid,
ULONG  cRefs,
USHORT  cIids,
IID iids,
REMQIRESULT **  ppQIResults 
)
static

Definition at line 699 of file stubmanager.c.

702{
703 HRESULT hr;
704 USHORT i;
705 USHORT successful_qis = 0;
706 APARTMENT *apt;
707 struct stub_manager *stubmgr;
708 struct ifstub *ifstub;
709 DWORD dest_context;
710 void *dest_context_data;
711
712 TRACE("(%p)->(%s, %d, %d, %p, %p)\n", iface, debugstr_guid(ripid), cRefs, cIids, iids, ppQIResults);
713
714 hr = ipid_to_ifstub(ripid, &apt, &stubmgr, &ifstub);
715 if (hr != S_OK) return hr;
716
717 IRpcChannelBuffer_GetDestCtx(ifstub->chan, &dest_context, &dest_context_data);
718
719 *ppQIResults = CoTaskMemAlloc(sizeof(REMQIRESULT) * cIids);
720
721 for (i = 0; i < cIids; i++)
722 {
723 HRESULT hrobj = marshal_object(apt, &(*ppQIResults)[i].std, &iids[i],
724 stubmgr->object, dest_context, dest_context_data, MSHLFLAGS_NORMAL);
725 if (hrobj == S_OK)
726 successful_qis++;
727 (*ppQIResults)[i].hResult = hrobj;
728 }
729
732
733 if (successful_qis == cIids)
734 return S_OK; /* we got all requested interfaces */
735 else if (successful_qis == 0)
736 return E_NOINTERFACE; /* we didn't get any interfaces */
737 else
738 return S_FALSE; /* we got some interfaces */
739}
HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *obj, DWORD dest_context, void *dest_context_data, MSHLFLAGS mshlflags) DECLSPEC_HIDDEN
Definition: marshal.c:121
unsigned long DWORD
Definition: ntddk_ex.h:95
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
Definition: features.h:417

◆ RemUnknown_RemRelease()

static HRESULT WINAPI RemUnknown_RemRelease ( IRemUnknown iface,
USHORT  cInterfaceRefs,
REMINTERFACEREF *  InterfaceRefs 
)
static

Definition at line 774 of file stubmanager.c.

777{
778 HRESULT hr = S_OK;
779 USHORT i;
780
781 TRACE("(%p)->(%d, %p)\n", iface, cInterfaceRefs, InterfaceRefs);
782
783 for (i = 0; i < cInterfaceRefs; i++)
784 {
785 APARTMENT *apt;
786 struct stub_manager *stubmgr;
787
788 hr = ipid_to_stub_manager(&InterfaceRefs[i].ipid, &apt, &stubmgr);
789 if (hr != S_OK)
790 {
792 /* FIXME: we should undo any changes already made in this function */
793 break;
794 }
795
796 stub_manager_ext_release(stubmgr, InterfaceRefs[i].cPublicRefs, FALSE, TRUE);
797 if (InterfaceRefs[i].cPrivateRefs)
798 FIXME("Releasing %d refs securely not implemented\n", InterfaceRefs[i].cPrivateRefs);
799
802 }
803
804 return hr;
805}
#define E_INVALIDARG
Definition: ddrawi.h:101
ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tableweak, BOOL last_unlock_releases)
Definition: stubmanager.c:439

◆ start_apartment_remote_unknown()

HRESULT start_apartment_remote_unknown ( APARTMENT apt)

Definition at line 818 of file stubmanager.c.

819{
820 IRemUnknown *pRemUnknown;
821 HRESULT hr = S_OK;
822
824 if (!apt->remunk_exported)
825 {
826 /* create the IRemUnknown object */
827 hr = RemUnknown_Construct(&pRemUnknown);
828 if (hr == S_OK)
829 {
830 STDOBJREF stdobjref; /* dummy - not used */
831 /* register it with the stub manager */
832 hr = marshal_object(apt, &stdobjref, &IID_IRemUnknown, (IUnknown *)pRemUnknown, MSHCTX_DIFFERENTMACHINE, NULL, MSHLFLAGS_NORMAL|MSHLFLAGSP_REMUNKNOWN);
833 /* release our reference to the object as the stub manager will manage the life cycle for us */
834 IRemUnknown_Release(pRemUnknown);
835 if (hr == S_OK)
836 apt->remunk_exported = TRUE;
837 }
838 }
840 return hr;
841}
#define MSHLFLAGSP_REMUNKNOWN
BOOL remunk_exported
static HRESULT RemUnknown_Construct(IRemUnknown **ppRemUnknown)
Definition: stubmanager.c:643

Referenced by RPC_StartRemoting().

◆ stub_manager_delete()

static void stub_manager_delete ( struct stub_manager m)
static

Definition at line 260 of file stubmanager.c.

261{
262 struct list *cursor;
263
264 TRACE("destroying %p (oid=%s)\n", m, wine_dbgstr_longlong(m->oid));
265
266 /* release every ifstub */
267 while ((cursor = list_head(&m->ifstubs)))
268 {
269 struct ifstub *ifstub = LIST_ENTRY(cursor, struct ifstub, entry);
271 }
272
273 if(m->extern_conn)
274 IExternalConnection_Release(m->extern_conn);
275
276 CoTaskMemFree(m->oxid_info.psa);
277
278 /* Some broken apps crash in object destructors. We have a test showing
279 * that on winxp+ those crashes are caught and ignored. */
280 __TRY
281 {
282 IUnknown_Release(m->object);
283 }
285 {
286 ERR("Got page fault when releasing stub!\n");
287 }
289
291 DeleteCriticalSection(&m->lock);
292
294}
#define DEBUG_CLEAR_CRITSEC_NAME(cs)
#define __TRY
Definition: compat.h:80
#define __ENDTRY
Definition: compat.h:82
#define __EXCEPT_PAGE_FAULT
Definition: compat.h:81
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
Definition: list.h:15
static void stub_manager_delete_ifstub(struct stub_manager *m, struct ifstub *ifstub)
Definition: stubmanager.c:121
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)

Referenced by stub_manager_int_release().

◆ stub_manager_delete_ifstub()

static void stub_manager_delete_ifstub ( struct stub_manager m,
struct ifstub ifstub 
)
static

Definition at line 121 of file stubmanager.c.

122{
123 TRACE("m=%p, m->oid=%s, ipid=%s\n", m, wine_dbgstr_longlong(m->oid), debugstr_guid(&ifstub->ipid));
124
126
127 if (!m->disconnected)
129
130 if (ifstub->stubbuffer) IRpcStubBuffer_Release(ifstub->stubbuffer);
131 IUnknown_Release(ifstub->iface);
132 IRpcChannelBuffer_Release(ifstub->chan);
133
135}
static void list_remove(struct list_entry *entry)
Definition: list.h:90
void RPC_UnregisterInterface(REFIID riid, BOOL wait) DECLSPEC_HIDDEN
Definition: rpc.c:1587
struct list entry

Referenced by stub_manager_delete().

◆ stub_manager_disconnect()

void stub_manager_disconnect ( struct stub_manager m)

Definition at line 244 of file stubmanager.c.

245{
246 struct ifstub *ifstub;
247
248 EnterCriticalSection(&m->lock);
249 if (!m->disconnected)
250 {
251 LIST_FOR_EACH_ENTRY(ifstub, &m->ifstubs, struct ifstub, entry)
253
254 m->disconnected = TRUE;
255 }
256 LeaveCriticalSection(&m->lock);
257}
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198

Referenced by CoDisconnectObject().

◆ stub_manager_ext_addref()

ULONG stub_manager_ext_addref ( struct stub_manager m,
ULONG  refs,
BOOL  tableweak 
)

Definition at line 408 of file stubmanager.c.

409{
410 BOOL first_extern_ref;
411 ULONG rc;
412
413 EnterCriticalSection(&m->lock);
414
415 first_extern_ref = refs && !m->extrefs;
416
417 /* make sure we don't overflow extrefs */
418 refs = min(refs, (ULONG_MAX-1 - m->extrefs));
419 rc = (m->extrefs += refs);
420
421 if (tableweak)
422 rc += ++m->weakrefs;
423
424 LeaveCriticalSection(&m->lock);
425
426 TRACE("added %u refs to %p (oid %s), rc is now %u\n", refs, m, wine_dbgstr_longlong(m->oid), rc);
427
428 /*
429 * NOTE: According to tests, creating a stub causes two AddConnection calls followed by
430 * one ReleaseConnection call (with fLastReleaseCloses=FALSE).
431 */
432 if(first_extern_ref && m->extern_conn)
433 IExternalConnection_AddConnection(m->extern_conn, EXTCONN_STRONG, 0);
434
435 return rc;
436}
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ULONG_MAX
Definition: limits.h:44
#define min(a, b)
Definition: monoChain.cc:55

Referenced by CoLockObjectExternal(), marshal_object(), and RemUnknown_RemAddRef().

◆ stub_manager_ext_release()

ULONG stub_manager_ext_release ( struct stub_manager m,
ULONG  refs,
BOOL  tableweak,
BOOL  last_unlock_releases 
)

Definition at line 439 of file stubmanager.c.

440{
441 BOOL last_extern_ref;
442 ULONG rc;
443
444 EnterCriticalSection(&m->lock);
445
446 /* make sure we don't underflow extrefs */
447 refs = min(refs, m->extrefs);
448 rc = (m->extrefs -= refs);
449
450 if (tableweak)
451 --m->weakrefs;
452 if (!last_unlock_releases)
453 rc += m->weakrefs;
454
455 last_extern_ref = refs && !m->extrefs;
456
457 LeaveCriticalSection(&m->lock);
458
459 TRACE("removed %u refs from %p (oid %s), rc is now %u\n", refs, m, wine_dbgstr_longlong(m->oid), rc);
460
461 if (last_extern_ref && m->extern_conn)
462 IExternalConnection_ReleaseConnection(m->extern_conn, EXTCONN_STRONG, 0, last_unlock_releases);
463
464 if (rc == 0)
465 if (!(m->extern_conn && last_unlock_releases && m->weakrefs))
467
468 return rc;
469}

Referenced by CoLockObjectExternal(), marshal_object(), RemUnknown_RemRelease(), std_unmarshal_interface(), and stub_manager_release_marshal_data().

◆ stub_manager_find_ifstub()

struct ifstub * stub_manager_find_ifstub ( struct stub_manager m,
REFIID  iid,
MSHLFLAGS  flags 
)

Definition at line 158 of file stubmanager.c.

159{
160 struct ifstub *result = NULL;
161 struct ifstub *ifstub;
162
163 EnterCriticalSection(&m->lock);
164 LIST_FOR_EACH_ENTRY( ifstub, &m->ifstubs, struct ifstub, entry )
165 {
166 if (IsEqualIID(iid, &ifstub->iid) && (ifstub->flags == flags))
167 {
168 result = ifstub;
169 break;
170 }
171 }
172 LeaveCriticalSection(&m->lock);
173
174 return result;
175}
GLbitfield flags
Definition: glext.h:7161
MSHLFLAGS flags

Referenced by marshal_object().

◆ stub_manager_int_addref()

static ULONG stub_manager_int_addref ( struct stub_manager This)
static

Definition at line 297 of file stubmanager.c.

298{
299 ULONG refs;
300
301 EnterCriticalSection(&This->apt->cs);
302 refs = ++This->refs;
303 LeaveCriticalSection(&This->apt->cs);
304
305 TRACE("before %d\n", refs - 1);
306
307 return refs;
308}

Referenced by get_stub_manager(), get_stub_manager_from_ipid(), and get_stub_manager_from_object().

◆ stub_manager_int_release()

ULONG stub_manager_int_release ( struct stub_manager This)

Definition at line 311 of file stubmanager.c.

312{
313 ULONG refs;
314 APARTMENT *apt = This->apt;
315
317 refs = --This->refs;
318
319 TRACE("after %d\n", refs);
320
321 /* remove from apartment so no other thread can access it... */
322 if (!refs)
323 list_remove(&This->entry);
324
326
327 /* ... so now we can delete it without being inside the apartment critsec */
328 if (!refs)
330
331 return refs;
332}
static void stub_manager_delete(struct stub_manager *m)
Definition: stubmanager.c:260

Referenced by apartment_release(), CoDisconnectObject(), CoLockObjectExternal(), dispatch_rpc(), ipid_get_dispatch_params(), marshal_object(), RemUnknown_RemAddRef(), RemUnknown_RemQueryInterface(), RemUnknown_RemRelease(), std_release_marshal_data(), std_unmarshal_interface(), and stub_manager_ext_release().

◆ stub_manager_ipid_to_ifstub()

static struct ifstub * stub_manager_ipid_to_ifstub ( struct stub_manager m,
const IPID ipid 
)
static

Definition at line 137 of file stubmanager.c.

138{
139 struct list *cursor;
140 struct ifstub *result = NULL;
141
142 EnterCriticalSection(&m->lock);
143 LIST_FOR_EACH( cursor, &m->ifstubs )
144 {
145 struct ifstub *ifstub = LIST_ENTRY( cursor, struct ifstub, entry );
146
147 if (IsEqualGUID(ipid, &ifstub->ipid))
148 {
149 result = ifstub;
150 break;
151 }
152 }
153 LeaveCriticalSection(&m->lock);
154
155 return result;
156}
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147

Referenced by get_stub_manager_from_ipid(), stub_manager_is_table_marshaled(), stub_manager_notify_unmarshal(), and stub_manager_release_marshal_data().

◆ stub_manager_is_table_marshaled()

BOOL stub_manager_is_table_marshaled ( struct stub_manager m,
const IPID ipid 
)

Definition at line 609 of file stubmanager.c.

610{
612
613 assert( ifstub );
614
615 return ifstub->flags & (MSHLFLAGS_TABLESTRONG | MSHLFLAGS_TABLEWEAK);
616}

Referenced by std_unmarshal_interface().

◆ stub_manager_new_ifstub()

struct ifstub * stub_manager_new_ifstub ( struct stub_manager m,
IRpcStubBuffer sb,
REFIID  iid,
DWORD  dest_context,
void dest_context_data,
MSHLFLAGS  flags 
)

Definition at line 70 of file stubmanager.c.

72{
73 struct ifstub *stub;
74 HRESULT hr;
75
76 TRACE("oid=%s, stubbuffer=%p, iid=%s, dest_context=%x\n", wine_dbgstr_longlong(m->oid), sb,
77 debugstr_guid(iid), dest_context);
78
80 if (!stub) return NULL;
81
82 hr = IUnknown_QueryInterface(m->object, iid, (void **)&stub->iface);
83 if (hr != S_OK)
84 {
86 return NULL;
87 }
88
89 hr = RPC_CreateServerChannel(dest_context, dest_context_data, &stub->chan);
90 if (hr != S_OK)
91 {
92 IUnknown_Release(stub->iface);
94 return NULL;
95 }
96
97 stub->stubbuffer = sb;
98 if (sb) IRpcStubBuffer_AddRef(sb);
99
100 stub->flags = flags;
101 stub->iid = *iid;
102
103 /* FIXME: find a cleaner way of identifying that we are creating an ifstub
104 * for the remunknown interface */
106 stub->ipid = m->oxid_info.ipidRemUnknown;
107 else
108 generate_ipid(m, &stub->ipid);
109
110 EnterCriticalSection(&m->lock);
111 list_add_head(&m->ifstubs, &stub->entry);
112 /* every normal marshal is counted so we don't allow more than we should */
113 if (flags & MSHLFLAGS_NORMAL) m->norm_refs++;
114 LeaveCriticalSection(&m->lock);
115
116 TRACE("ifstub %p created with ipid %s\n", stub, debugstr_guid(&stub->ipid));
117
118 return stub;
119}
HRESULT RPC_CreateServerChannel(DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan) DECLSPEC_HIDDEN
Definition: rpc.c:1162
superblock * sb
Definition: btrfs.c:4261
struct _stub stub
static HRESULT generate_ipid(struct stub_manager *m, IPID *ipid)
Definition: stubmanager.c:52

Referenced by marshal_object().

◆ stub_manager_notify_unmarshal()

BOOL stub_manager_notify_unmarshal ( struct stub_manager m,
const IPID ipid 
)

Definition at line 562 of file stubmanager.c.

563{
564 BOOL ret = TRUE;
565 struct ifstub *ifstub;
566
568 {
569 ERR("attempted unmarshal of unknown IPID %s\n", debugstr_guid(ipid));
570 return FALSE;
571 }
572
573 EnterCriticalSection(&m->lock);
574
575 /* track normal marshals so we can enforce rules whilst in-process */
576 if (ifstub->flags & MSHLFLAGS_NORMAL)
577 {
578 if (m->norm_refs)
579 m->norm_refs--;
580 else
581 {
582 ERR("attempted invalid normal unmarshal, norm_refs is zero\n");
583 ret = FALSE;
584 }
585 }
586
587 LeaveCriticalSection(&m->lock);
588
589 return ret;
590}
int ret

Referenced by std_unmarshal_interface().

◆ stub_manager_release_marshal_data()

void stub_manager_release_marshal_data ( struct stub_manager m,
ULONG  refs,
const IPID ipid,
BOOL  tableweak 
)

Definition at line 593 of file stubmanager.c.

594{
595 struct ifstub *ifstub;
596
598 return;
599
600 if (ifstub->flags & MSHLFLAGS_TABLEWEAK)
601 refs = 0;
602 else if (ifstub->flags & MSHLFLAGS_TABLESTRONG)
603 refs = 1;
604
605 stub_manager_ext_release(m, refs, tableweak, !tableweak);
606}

Referenced by std_release_marshal_data().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( ole  )

Variable Documentation

◆ RemUnknown_Vtbl

static const IRemUnknownVtbl RemUnknown_Vtbl
static
Initial value:
=
{
}
static HRESULT WINAPI RemUnknown_QueryInterface(IRemUnknown *iface, REFIID riid, void **ppv)
Definition: stubmanager.c:656
static HRESULT WINAPI RemUnknown_RemQueryInterface(IRemUnknown *iface, REFIPID ripid, ULONG cRefs, USHORT cIids, IID *iids, REMQIRESULT **ppQIResults)
Definition: stubmanager.c:699
static ULONG WINAPI RemUnknown_AddRef(IRemUnknown *iface)
Definition: stubmanager.c:675
static HRESULT WINAPI RemUnknown_RemRelease(IRemUnknown *iface, USHORT cInterfaceRefs, REMINTERFACEREF *InterfaceRefs)
Definition: stubmanager.c:774
static ULONG WINAPI RemUnknown_Release(IRemUnknown *iface)
Definition: stubmanager.c:686
static HRESULT WINAPI RemUnknown_RemAddRef(IRemUnknown *iface, USHORT cInterfaceRefs, REMINTERFACEREF *InterfaceRefs, HRESULT *pResults)
Definition: stubmanager.c:741

Definition at line 634 of file stubmanager.c.

Referenced by RemUnknown_Construct().