ReactOS 0.4.16-dev-2358-g0df3463
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 "initguid.h"
#include "dcom.h"
#include "combase_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 (struct 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 *m)
 
ULONG stub_manager_int_release (struct stub_manager *m)
 
struct stub_managerget_stub_manager_from_object (struct apartment *apt, IUnknown *obj, BOOL alloc)
 
struct stub_managerget_stub_manager (struct 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 (struct apartment *apt, const IPID *ipid, struct ifstub **ifstub)
 
static HRESULT ipid_to_ifstub (const IPID *ipid, struct apartment **stub_apt, struct stub_manager **stubmgr_ret, struct ifstub **ifstub)
 
static HRESULT ipid_to_stub_manager (const IPID *ipid, struct apartment **stub_apt, struct stub_manager **stub)
 
HRESULT ipid_get_dispatch_params (const IPID *ipid, struct apartment **stub_apt, struct stub_manager **manager, IRpcStubBuffer **stub, IRpcChannelBuffer **chan, IID *iid, IUnknown **iface)
 
HRESULT ipid_get_dest_context (const IPID *ipid, MSHCTX *dest_context, void **dest_context_data)
 
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 (struct 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 53 of file stubmanager.c.

54{
55 HRESULT hr;
56 hr = UuidCreate(ipid);
57 if (FAILED(hr))
58 {
59 ERR("couldn't create IPID for stub manager %p\n", m);
60 UuidCreateNil(ipid);
61 return hr;
62 }
63
64 ipid->Data1 = InterlockedIncrement(&m->apt->ipidc);
65 ipid->Data2 = !m->apt->multi_threaded ? (USHORT)m->apt->tid : 0;
66 ipid->Data3 = (USHORT)GetCurrentProcessId();
67 return S_OK;
68}
#define InterlockedIncrement
Definition: armddk.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
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:309
RPC_STATUS WINAPI UuidCreate(UUID *Uuid)
Definition: rpcrt4_main.c:330
HRESULT hr
Definition: shlfolder.c:183
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1156

Referenced by stub_manager_new_ifstub().

◆ get_stub_manager()

struct stub_manager * get_stub_manager ( struct apartment apt,
OID  oid 
)

Definition at line 381 of file stubmanager.c.

382{
383 struct stub_manager *result = NULL, *m;
384
386 LIST_FOR_EACH_ENTRY(m, &apt->stubmgrs, struct stub_manager, entry)
387 {
388 if (m->oid == oid)
389 {
390 result = m;
392 break;
393 }
394 }
396
397 if (result)
398 TRACE("found %p for oid %s\n", result, wine_dbgstr_longlong(oid));
399 else
400 TRACE("not found for oid %s\n", wine_dbgstr_longlong(oid));
401
402 return result;
403}
#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
uint32_t entry
Definition: isohybrid.c:63
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define TRACE(s)
Definition: solgame.cpp:4
struct apartment * apt
static ULONG stub_manager_int_addref(struct stub_manager *m)
Definition: stubmanager.c:295
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 ( struct apartment apt,
const IPID ipid,
struct ifstub **  ifstub 
)
static

Definition at line 472 of file stubmanager.c.

473{
474 struct stub_manager *result = NULL, *m;
475
477 LIST_FOR_EACH_ENTRY(m, &apt->stubmgrs, struct stub_manager, entry)
478 {
479 if ((*ifstub = stub_manager_ipid_to_ifstub(m, ipid)))
480 {
481 result = m;
483 break;
484 }
485 }
487
488 if (result)
489 TRACE("found %p for ipid %s\n", result, debugstr_guid(ipid));
490 else
491 ERR("not found for ipid %s\n", debugstr_guid(ipid));
492
493 return result;
494}
#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:138

Referenced by ipid_to_ifstub().

◆ get_stub_manager_from_object()

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

Definition at line 335 of file stubmanager.c.

336{
337 struct stub_manager *result = NULL, *m;
340
341 hres = IUnknown_QueryInterface(obj, &IID_IUnknown, (void**)&object);
342 if (FAILED(hres))
343 {
344 ERR("QueryInterface(IID_IUnknown failed): %#lx\n", hres);
345 return NULL;
346 }
347
349 LIST_FOR_EACH_ENTRY(m, &apt->stubmgrs, struct stub_manager, entry)
350 {
351 if (m->object == object)
352 {
353 result = m;
355 break;
356 }
357 }
359
360 if (result)
361 {
362 TRACE("found %p for object %p\n", result, object);
363 }
364 else if (alloc)
365 {
366 TRACE("not found, creating new stub manager...\n");
367 result = new_stub_manager(apt, object);
368 }
369 else
370 {
371 TRACE("not found for object %p\n", object);
372 }
373
374 IUnknown_Release(object);
375 return result;
376}
const GUID IID_IUnknown
HRESULT hres
Definition: protocol.c:465
#define alloc
Definition: rosglue.h:13
IUnknown * object
static struct stub_manager * new_stub_manager(struct apartment *apt, IUnknown *object)
Definition: stubmanager.c:178

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

◆ impl_from_IRemUnknown()

static RemUnknown * impl_from_IRemUnknown ( IRemUnknown iface)
inlinestatic

Definition at line 656 of file stubmanager.c.

657{
658 return CONTAINING_RECORD(iface, RemUnknown, IRemUnknown_iface);
659}
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by RemUnknown_AddRef(), and RemUnknown_Release().

◆ ipid_get_dest_context()

HRESULT ipid_get_dest_context ( const IPID ipid,
MSHCTX *  dest_context,
void **  dest_context_data 
)

Definition at line 557 of file stubmanager.c.

558{
559 struct stub_manager *stubmgr;
560 struct ifstub *ifstub;
561 struct apartment *apt;
562 void *data;
563 HRESULT hr;
564 DWORD ctx;
565
566 hr = ipid_to_ifstub(ipid, &apt, &stubmgr, &ifstub);
567 if (hr != S_OK) return RPC_E_DISCONNECTED;
568
569 hr = IRpcChannelBuffer_GetDestCtx(ifstub->chan, &ctx, &data);
570 if (SUCCEEDED(hr))
571 {
572 *dest_context = ctx;
573 *dest_context_data = data;
574 }
575
578
579 return hr;
580}
void apartment_release(struct apartment *apt)
Definition: apartment.c:444
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define SUCCEEDED(hr)
Definition: intsafe.h:50
IRpcChannelBuffer * chan
ULONG stub_manager_int_release(struct stub_manager *m)
Definition: stubmanager.c:309
static HRESULT ipid_to_ifstub(const IPID *ipid, struct apartment **stub_apt, struct stub_manager **stubmgr_ret, struct ifstub **ifstub)
Definition: stubmanager.c:496
#define RPC_E_DISCONNECTED
Definition: winerror.h:3556

Referenced by std_unmarshal_interface().

◆ ipid_get_dispatch_params()

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

Definition at line 530 of file stubmanager.c.

533{
534 struct stub_manager *stubmgr;
535 struct ifstub *ifstub;
536 struct apartment *apt;
537 HRESULT hr;
538
539 hr = ipid_to_ifstub(ipid, &apt, &stubmgr, &ifstub);
540 if (hr != S_OK) return RPC_E_DISCONNECTED;
541
543 IRpcStubBuffer_AddRef(*stub);
544 *chan = ifstub->chan;
545 IRpcChannelBuffer_AddRef(*chan);
546 *stub_apt = apt;
547 *iid = ifstub->iid;
548 *iface = ifstub->iface;
549
550 if (manager)
551 *manager = stubmgr;
552 else
554 return S_OK;
555}
Definition: stubgen.c:11
IUnknown * iface
IRpcStubBuffer * stubbuffer

Referenced by ClientRpcChannelBuffer_GetBuffer(), and dispatch_rpc().

◆ ipid_to_ifstub()

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

Definition at line 496 of file stubmanager.c.

498{
499 /* FIXME: hack for IRemUnknown */
500 if (ipid->Data2 == 0xffff)
501 *stub_apt = apartment_findfromoxid(*(const OXID *)ipid->Data4);
502 else if (!ipid->Data2 && (ipid->Data3 == (USHORT)GetCurrentProcessId()))
503 *stub_apt = apartment_get_mta();
504 else
505 *stub_apt = apartment_findfromtid(ipid->Data2);
506 if (!*stub_apt)
507 {
508 TRACE("Couldn't find apartment corresponding to TID 0x%04x, PID 0x%04x\n", ipid->Data2, ipid->Data3);
510 }
511 *stubmgr_ret = get_stub_manager_from_ipid(*stub_apt, ipid, ifstub);
512 if (!*stubmgr_ret)
513 {
514 apartment_release(*stub_apt);
515 *stub_apt = NULL;
517 }
518 return S_OK;
519}
struct apartment * apartment_get_mta(void)
Definition: apartment.c:607
struct apartment * apartment_findfromtid(DWORD tid)
Definition: apartment.c:657
struct apartment * apartment_findfromoxid(OXID oxid)
Definition: apartment.c:635
UINT64 OXID
Definition: marshal.c:86
static struct stub_manager * get_stub_manager_from_ipid(struct apartment *apt, const IPID *ipid, struct ifstub **ifstub)
Definition: stubmanager.c:472
#define RPC_E_INVALID_OBJECT
Definition: winerror.h:3568

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

◆ ipid_to_stub_manager()

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

Definition at line 521 of file stubmanager.c.

522{
523 struct ifstub *ifstub;
524 return ipid_to_ifstub(ipid, stub_apt, stub, &ifstub);
525}

Referenced by RemUnknown_RemAddRef(), and RemUnknown_RemRelease().

◆ new_stub_manager()

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

Definition at line 178 of file stubmanager.c.

179{
180 struct stub_manager *sm;
182
183 assert(apt);
184
185 sm = calloc(1, sizeof(struct stub_manager));
186 if (!sm) return NULL;
187
188 list_init(&sm->ifstubs);
189
191 sm->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": stub_manager");
192
193 IUnknown_AddRef(object);
194 sm->object = object;
195 sm->apt = apt;
196
197 /* start off with 2 references because the stub is in the apartment
198 * and the caller will also hold a reference */
199 sm->refs = 2;
200 sm->weakrefs = 0;
201
202 sm->oxid_info.dwPid = GetCurrentProcessId();
203 sm->oxid_info.dwTid = GetCurrentThreadId();
204 /*
205 * FIXME: this is a hack for marshalling IRemUnknown. In real
206 * DCOM, the IPID of the IRemUnknown interface is generated like
207 * any other and passed to the OXID resolver which then returns it
208 * when queried. We don't have an OXID resolver yet so instead we
209 * use a magic IPID reserved for IRemUnknown.
210 */
211 sm->oxid_info.ipidRemUnknown.Data1 = 0xffffffff;
212 sm->oxid_info.ipidRemUnknown.Data2 = 0xffff;
213 sm->oxid_info.ipidRemUnknown.Data3 = 0xffff;
214 assert(sizeof(sm->oxid_info.ipidRemUnknown.Data4) == sizeof(apt->oxid));
215 memcpy(sm->oxid_info.ipidRemUnknown.Data4, &apt->oxid, sizeof(OXID));
216 sm->oxid_info.dwAuthnHint = RPC_C_AUTHN_LEVEL_NONE;
217 sm->oxid_info.psa = NULL /* FIXME */;
218
219 /* Yes, that's right, this starts at zero. that's zero EXTERNAL
220 * refs, i.e., nobody has unmarshalled anything yet. We can't have
221 * negative refs because the stub manager cannot be explicitly
222 * killed, it has to die by somebody unmarshalling then releasing
223 * the marshalled ifptr.
224 */
225 sm->extrefs = 0;
226 sm->disconnected = FALSE;
227
228 hres = IUnknown_QueryInterface(object, &IID_IExternalConnection, (void**)&sm->extern_conn);
229 if(FAILED(hres))
230 sm->extern_conn = NULL;
231
233 sm->oid = apt->oidc++;
234 list_add_head(&apt->stubmgrs, &sm->entry);
236
237 TRACE("Created new stub manager (oid=%s) at %p for object with IUnknown %p\n", wine_dbgstr_longlong(sm->oid), sm, object);
238
239 return sm;
240}
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 FALSE
Definition: types.h:117
BOOL WINAPI InitializeCriticalSectionEx(OUT LPCRITICAL_SECTION lpCriticalSection, IN DWORD dwSpinCount, IN DWORD flags)
Definition: sync.c:107
#define assert(_expr)
Definition: assert.h:32
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define calloc
Definition: rosglue.h:14
#define RPC_C_AUTHN_LEVEL_NONE
Definition: rpcdce.h:146
PRTL_CRITICAL_SECTION_DEBUG DebugInfo
Definition: rtltypes.h:1450
CRITICAL_SECTION lock
OXID_INFO oxid_info
IExternalConnection * extern_conn
struct list ifstubs
struct list entry
#define DWORD_PTR
Definition: treelist.c:76
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
Definition: winnt_old.h:1156

Referenced by get_stub_manager_from_object().

◆ RemUnknown_AddRef()

static ULONG WINAPI RemUnknown_AddRef ( IRemUnknown iface)
static

Definition at line 695 of file stubmanager.c.

696{
697 ULONG refs;
698 RemUnknown *remunk = impl_from_IRemUnknown(iface);
699
700 refs = InterlockedIncrement(&remunk->refs);
701
702 TRACE("%p before: %ld\n", iface, refs-1);
703 return refs;
704}
static RemUnknown * impl_from_IRemUnknown(IRemUnknown *iface)
Definition: stubmanager.c:656
uint32_t ULONG
Definition: typedefs.h:59

◆ RemUnknown_Construct()

static HRESULT RemUnknown_Construct ( IRemUnknown **  ppRemUnknown)
static

Definition at line 662 of file stubmanager.c.

663{
664 RemUnknown *object = malloc(sizeof(*object));
665
666 if (!object)
667 return E_OUTOFMEMORY;
668
669 object->IRemUnknown_iface.lpVtbl = &RemUnknown_Vtbl;
670 object->refs = 1;
671
672 *ppRemUnknown = &object->IRemUnknown_iface;
673 return S_OK;
674}
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define malloc
Definition: debug_ros.c:4
static const IRemUnknownVtbl RemUnknown_Vtbl
Definition: stubmanager.c:654

Referenced by start_apartment_remote_unknown().

◆ RemUnknown_QueryInterface()

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

Definition at line 676 of file stubmanager.c.

677{
678 TRACE("%p, %s, %p\n", iface, debugstr_guid(riid), ppv);
679
682 {
683 *ppv = iface;
684 IRemUnknown_AddRef(iface);
685 return S_OK;
686 }
687
688 if (!IsEqualIID(riid, &IID_IExternalConnection))
689 FIXME("No interface for iid %s\n", debugstr_guid(riid));
690
691 *ppv = NULL;
692 return E_NOINTERFACE;
693}
#define FIXME(fmt,...)
Definition: precomp.h:53
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
static const IID IID_IRemUnknown
Definition: marshal.c:129
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define E_NOINTERFACE
Definition: winerror.h:3479

◆ RemUnknown_Release()

static ULONG WINAPI RemUnknown_Release ( IRemUnknown iface)
static

Definition at line 706 of file stubmanager.c.

707{
708 ULONG refs;
709 RemUnknown *remunk = impl_from_IRemUnknown(iface);
710
711 refs = InterlockedDecrement(&remunk->refs);
712 if (!refs)
713 free(remunk);
714
715 TRACE("%p after: %ld\n", iface, refs);
716 return refs;
717}
#define InterlockedDecrement
Definition: armddk.h:52
#define free
Definition: debug_ros.c:5

◆ RemUnknown_RemAddRef()

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

Definition at line 761 of file stubmanager.c.

765{
766 HRESULT hr = S_OK;
767 USHORT i;
768
769 TRACE("%p, %d, %p, %p\n", iface, cInterfaceRefs, InterfaceRefs, pResults);
770
771 for (i = 0; i < cInterfaceRefs; i++)
772 {
773 struct apartment *apt;
774 struct stub_manager *stubmgr;
775
776 pResults[i] = ipid_to_stub_manager(&InterfaceRefs[i].ipid, &apt, &stubmgr);
777 if (pResults[i] != S_OK)
778 {
779 hr = S_FALSE;
780 continue;
781 }
782
783 stub_manager_ext_addref(stubmgr, InterfaceRefs[i].cPublicRefs, FALSE);
784 if (InterfaceRefs[i].cPrivateRefs)
785 FIXME("Adding %ld refs securely not implemented\n", InterfaceRefs[i].cPrivateRefs);
786
789 }
790
791 return hr;
792}
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
ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs, BOOL tableweak)
Definition: stubmanager.c:406
static HRESULT ipid_to_stub_manager(const IPID *ipid, struct apartment **stub_apt, struct stub_manager **stub)
Definition: stubmanager.c:521
#define S_FALSE
Definition: winerror.h:3451

◆ RemUnknown_RemQueryInterface()

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

Definition at line 719 of file stubmanager.c.

722{
723 HRESULT hr;
724 USHORT i;
725 USHORT successful_qis = 0;
726 struct apartment *apt;
727 struct stub_manager *stubmgr;
728 struct ifstub *ifstub;
729 DWORD dest_context;
730 void *dest_context_data;
731
732 TRACE("%p, %s, %ld, %d, %p, %p.\n", iface, debugstr_guid(ripid), cRefs, cIids, iids, ppQIResults);
733
734 hr = ipid_to_ifstub(ripid, &apt, &stubmgr, &ifstub);
735 if (hr != S_OK) return hr;
736
737 IRpcChannelBuffer_GetDestCtx(ifstub->chan, &dest_context, &dest_context_data);
738
739 *ppQIResults = CoTaskMemAlloc(sizeof(REMQIRESULT) * cIids);
740
741 for (i = 0; i < cIids; i++)
742 {
743 HRESULT hrobj = marshal_object(apt, &(*ppQIResults)[i].std, &iids[i],
744 stubmgr->object, dest_context, dest_context_data, MSHLFLAGS_NORMAL);
745 if (hrobj == S_OK)
746 successful_qis++;
747 (*ppQIResults)[i].hResult = hrobj;
748 }
749
752
753 if (successful_qis == cIids)
754 return S_OK; /* we got all requested interfaces */
755 else if (successful_qis == 0)
756 return E_NOINTERFACE; /* we didn't get any interfaces */
757 else
758 return S_FALSE; /* we got some interfaces */
759}
HRESULT marshal_object(struct apartment *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *object, DWORD dest_context, void *dest_context_data, MSHLFLAGS mshlflags)
Definition: marshal.c:870
void *WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: malloc.c:381
Definition: features.h:417

◆ RemUnknown_RemRelease()

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

Definition at line 794 of file stubmanager.c.

797{
798 HRESULT hr = S_OK;
799 USHORT i;
800
801 TRACE("%p, %d, %p\n", iface, cInterfaceRefs, InterfaceRefs);
802
803 for (i = 0; i < cInterfaceRefs; i++)
804 {
805 struct apartment *apt;
806 struct stub_manager *stubmgr;
807
808 hr = ipid_to_stub_manager(&InterfaceRefs[i].ipid, &apt, &stubmgr);
809 if (hr != S_OK)
810 {
812 /* FIXME: we should undo any changes already made in this function */
813 break;
814 }
815
816 stub_manager_ext_release(stubmgr, InterfaceRefs[i].cPublicRefs, FALSE, TRUE);
817 if (InterfaceRefs[i].cPrivateRefs)
818 FIXME("Releasing %ld refs securely not implemented\n", InterfaceRefs[i].cPrivateRefs);
819
822 }
823
824 return hr;
825}
#define E_INVALIDARG
Definition: ddrawi.h:101
#define TRUE
Definition: types.h:120
ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tableweak, BOOL last_unlock_releases)
Definition: stubmanager.c:437

◆ start_apartment_remote_unknown()

HRESULT start_apartment_remote_unknown ( struct apartment apt)

Definition at line 838 of file stubmanager.c.

839{
840 IRemUnknown *pRemUnknown;
841 HRESULT hr = S_OK;
842
844 if (!apt->remunk_exported)
845 {
846 /* create the IRemUnknown object */
847 hr = RemUnknown_Construct(&pRemUnknown);
848 if (hr == S_OK)
849 {
850 STDOBJREF stdobjref; /* dummy - not used */
851 /* register it with the stub manager */
852 hr = marshal_object(apt, &stdobjref, &IID_IRemUnknown, (IUnknown *)pRemUnknown,
853 MSHCTX_DIFFERENTMACHINE, NULL, MSHLFLAGS_NORMAL|MSHLFLAGSP_REMUNKNOWN);
854 /* release our reference to the object as the stub manager will manage the life cycle for us */
855 IRemUnknown_Release(pRemUnknown);
856 if (hr == S_OK)
857 apt->remunk_exported = TRUE;
858 }
859 }
861 return hr;
862}
#define MSHLFLAGSP_REMUNKNOWN
CRITICAL_SECTION cs
BOOL remunk_exported
static HRESULT RemUnknown_Construct(IRemUnknown **ppRemUnknown)
Definition: stubmanager.c:662

Referenced by rpc_start_remoting().

◆ stub_manager_delete()

static void stub_manager_delete ( struct stub_manager m)
static

Definition at line 258 of file stubmanager.c.

259{
260 struct list *cursor;
261
262 TRACE("destroying %p (oid=%s)\n", m, wine_dbgstr_longlong(m->oid));
263
264 /* release every ifstub */
265 while ((cursor = list_head(&m->ifstubs)))
266 {
267 struct ifstub *ifstub = LIST_ENTRY(cursor, struct ifstub, entry);
269 }
270
271 if(m->extern_conn)
272 IExternalConnection_Release(m->extern_conn);
273
274 CoTaskMemFree(m->oxid_info.psa);
275
276 /* Some broken apps crash in object destructors. We have a test showing
277 * that on winxp+ those crashes are caught and ignored. */
278 __TRY
279 {
280 IUnknown_Release(m->object);
281 }
283 {
284 ERR("Got page fault when releasing stub!\n");
285 }
287
288 m->lock.DebugInfo->Spare[0] = 0;
289 DeleteCriticalSection(&m->lock);
290
291 free(m);
292}
Definition: list.h:37
#define __TRY
Definition: compat.h:80
#define __ENDTRY
Definition: compat.h:82
#define __EXCEPT_PAGE_FAULT
Definition: compat.h:81
const char cursor[]
Definition: icontest.c:13
void WINAPI CoTaskMemFree(void *ptr)
Definition: malloc.c:389
Definition: list.h:15
static void stub_manager_delete_ifstub(struct stub_manager *m, struct ifstub *ifstub)
Definition: stubmanager.c:122
#define LIST_ENTRY(type)
Definition: queue.h:175
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 122 of file stubmanager.c.

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

Referenced by stub_manager_delete().

◆ stub_manager_disconnect()

void stub_manager_disconnect ( struct stub_manager m)

Definition at line 242 of file stubmanager.c.

243{
244 struct ifstub *ifstub;
245
246 EnterCriticalSection(&m->lock);
247 if (!m->disconnected)
248 {
249 LIST_FOR_EACH_ENTRY(ifstub, &m->ifstubs, struct ifstub, entry)
251
252 m->disconnected = TRUE;
253 }
254 LeaveCriticalSection(&m->lock);
255}

Referenced by CoDisconnectObject().

◆ stub_manager_ext_addref()

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

Definition at line 406 of file stubmanager.c.

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

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

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 156 of file stubmanager.c.

157{
158 struct ifstub *result = NULL;
159 struct ifstub *ifstub;
160
161 EnterCriticalSection(&m->lock);
162 LIST_FOR_EACH_ENTRY( ifstub, &m->ifstubs, struct ifstub, entry )
163 {
164 if (IsEqualIID(iid, &ifstub->iid) && (ifstub->flags == flags))
165 {
166 result = ifstub;
167 break;
168 }
169 }
170 LeaveCriticalSection(&m->lock);
171
172 return result;
173}
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 m)
static

Definition at line 295 of file stubmanager.c.

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

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 m)

Definition at line 309 of file stubmanager.c.

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

Referenced by apartment_release(), CoDisconnectObject(), CoLockObjectExternal(), dispatch_rpc(), ipid_get_dest_context(), 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 138 of file stubmanager.c.

139{
140 struct ifstub *result = NULL, *ifstub;
141
142 EnterCriticalSection(&m->lock);
143 LIST_FOR_EACH_ENTRY(ifstub, &m->ifstubs, struct ifstub, entry)
144 {
145 if (IsEqualGUID(ipid, &ifstub->ipid))
146 {
147 result = ifstub;
148 break;
149 }
150 }
151 LeaveCriticalSection(&m->lock);
152
153 return result;
154}
#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 630 of file stubmanager.c.

631{
633
634 assert(ifstub);
635
636 return ifstub->flags & (MSHLFLAGS_TABLESTRONG | MSHLFLAGS_TABLEWEAK);
637}

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 71 of file stubmanager.c.

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

Referenced by marshal_object().

◆ stub_manager_notify_unmarshal()

BOOL stub_manager_notify_unmarshal ( struct stub_manager m,
const IPID ipid 
)

Definition at line 583 of file stubmanager.c.

584{
585 BOOL ret = TRUE;
586 struct ifstub *ifstub;
587
589 {
590 ERR("attempted unmarshal of unknown IPID %s\n", debugstr_guid(ipid));
591 return FALSE;
592 }
593
594 EnterCriticalSection(&m->lock);
595
596 /* track normal marshals so we can enforce rules whilst in-process */
597 if (ifstub->flags & MSHLFLAGS_NORMAL)
598 {
599 if (m->norm_refs)
600 m->norm_refs--;
601 else
602 {
603 ERR("attempted invalid normal unmarshal, norm_refs is zero\n");
604 ret = FALSE;
605 }
606 }
607
608 LeaveCriticalSection(&m->lock);
609
610 return ret;
611}
return ret
Definition: mutex.c:146

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 614 of file stubmanager.c.

615{
616 struct ifstub *ifstub;
617
619 return;
620
621 if (ifstub->flags & MSHLFLAGS_TABLEWEAK)
622 refs = 0;
623 else if (ifstub->flags & MSHLFLAGS_TABLESTRONG)
624 refs = 1;
625
626 stub_manager_ext_release(m, refs, tableweak, !tableweak);
627}

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:676
static HRESULT WINAPI RemUnknown_RemQueryInterface(IRemUnknown *iface, REFIPID ripid, ULONG cRefs, USHORT cIids, IID *iids, REMQIRESULT **ppQIResults)
Definition: stubmanager.c:719
static ULONG WINAPI RemUnknown_AddRef(IRemUnknown *iface)
Definition: stubmanager.c:695
static HRESULT WINAPI RemUnknown_RemRelease(IRemUnknown *iface, USHORT cInterfaceRefs, REMINTERFACEREF *InterfaceRefs)
Definition: stubmanager.c:794
static ULONG WINAPI RemUnknown_Release(IRemUnknown *iface)
Definition: stubmanager.c:706
static HRESULT WINAPI RemUnknown_RemAddRef(IRemUnknown *iface, USHORT cInterfaceRefs, REMINTERFACEREF *InterfaceRefs, HRESULT *pResults)
Definition: stubmanager.c:761

Definition at line 654 of file stubmanager.c.

Referenced by RemUnknown_Construct().