summaryrefslogtreecommitdiff
path: root/src/vm/comconnectionpoints.h
diff options
context:
space:
mode:
authordotnet-bot <dotnet-bot@microsoft.com>2015-01-30 14:14:42 -0800
committerdotnet-bot <dotnet-bot@microsoft.com>2015-01-30 14:14:42 -0800
commitef1e2ab328087c61a6878c1e84f4fc5d710aebce (patch)
treedee1bbb89e9d722e16b0d1485e3cdd1b6c8e2cfa /src/vm/comconnectionpoints.h
downloadcoreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.tar.gz
coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.tar.bz2
coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.zip
Initial commit to populate CoreCLR repo
[tfs-changeset: 1407945]
Diffstat (limited to 'src/vm/comconnectionpoints.h')
-rw-r--r--src/vm/comconnectionpoints.h255
1 files changed, 255 insertions, 0 deletions
diff --git a/src/vm/comconnectionpoints.h b/src/vm/comconnectionpoints.h
new file mode 100644
index 0000000000..2efa6159af
--- /dev/null
+++ b/src/vm/comconnectionpoints.h
@@ -0,0 +1,255 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+// ===========================================================================
+// File: ComConnectionPoints.h
+//
+
+// ===========================================================================
+// Declaration of the classes used to expose connection points to COM.
+// ===========================================================================
+
+
+#pragma once
+
+#ifndef FEATURE_COMINTEROP
+#error FEATURE_COMINTEROP is required for this file
+#endif // FEATURE_COMINTEROP
+
+#include "vars.hpp"
+#include "comcallablewrapper.h"
+#include "comdelegate.h"
+
+//------------------------------------------------------------------------------------------
+// Definition of helper class used to expose connection points
+//------------------------------------------------------------------------------------------
+
+// Structure containing information regarding the methods that make up an event.
+struct EventMethodInfo
+{
+ MethodDesc* m_pEventMethod;
+ MethodDesc* m_pAddMethod;
+ MethodDesc* m_pRemoveMethod;
+};
+
+
+// Structure passed out as a cookie when Advise is called.
+struct ConnectionCookie
+{
+ ConnectionCookie(OBJECTHANDLE hndEventProvObj) : m_hndEventProvObj(hndEventProvObj)
+ {
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ PRECONDITION(NULL != hndEventProvObj);
+ }
+ CONTRACTL_END;
+ }
+
+ ~ConnectionCookie()
+ {
+ WRAPPER_NO_CONTRACT;
+ DestroyHandle(m_hndEventProvObj);
+ }
+
+ // Currently called only from Cooperative mode.
+ static ConnectionCookie* CreateConnectionCookie(OBJECTHANDLE hndEventProvObj)
+ {
+ CONTRACT (ConnectionCookie*)
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ INJECT_FAULT(COMPlusThrowOM());
+ PRECONDITION(NULL != hndEventProvObj);
+ }
+ CONTRACT_END;
+
+ RETURN (new ConnectionCookie(hndEventProvObj));
+ }
+
+ SLink m_Link;
+ OBJECTHANDLE m_hndEventProvObj;
+ DWORD m_id;
+};
+
+FORCEINLINE void ConnectionCookieRelease(ConnectionCookie* p)
+{
+ WRAPPER_NO_CONTRACT;
+
+ delete p;
+}
+
+// Connection cookie holder used to ensure the cookies are deleted when required.
+class ConnectionCookieHolder : public Wrapper<ConnectionCookie*, ConnectionCookieDoNothing, ConnectionCookieRelease, NULL>
+{
+public:
+ ConnectionCookieHolder(ConnectionCookie* p = NULL)
+ : Wrapper<ConnectionCookie*, ConnectionCookieDoNothing, ConnectionCookieRelease, NULL>(p)
+ {
+ WRAPPER_NO_CONTRACT;
+ }
+
+ FORCEINLINE void operator=(ConnectionCookie* p)
+ {
+ WRAPPER_NO_CONTRACT;
+ Wrapper<ConnectionCookie*, ConnectionCookieDoNothing, ConnectionCookieRelease, NULL>::operator=(p);
+ }
+};
+
+// List of connection cookies.
+typedef SList<ConnectionCookie, true> CONNECTIONCOOKIELIST;
+
+// ConnectionPoint class. This class implements IConnectionPoint and does the mapping
+// from a CP handler to a TCE provider.
+class ConnectionPoint : public IConnectionPoint
+{
+public:
+ // Encapsulate CrstHolder, so that clients of our lock don't have to know the
+ // details of its implementation.
+ class LockHolder : public CrstHolder
+ {
+ public:
+ LockHolder(ConnectionPoint *pCP) : CrstHolder(&pCP->m_Lock)
+ {
+ WRAPPER_NO_CONTRACT;
+ }
+ };
+
+ ConnectionPoint( ComCallWrapper *pWrap, MethodTable *pEventMT );
+ ~ConnectionPoint();
+
+ HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
+ ULONG __stdcall AddRef();
+ ULONG __stdcall Release();
+
+ HRESULT __stdcall GetConnectionInterface( IID *pIID );
+ HRESULT __stdcall GetConnectionPointContainer( IConnectionPointContainer **ppCPC );
+ HRESULT __stdcall Advise( IUnknown *pUnk, DWORD *pdwCookie );
+ HRESULT __stdcall Unadvise( DWORD dwCookie );
+ HRESULT __stdcall EnumConnections( IEnumConnections **ppEnum );
+
+ REFIID GetIID()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_rConnectionIID;
+ }
+
+ CONNECTIONCOOKIELIST *GetCookieList()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return &m_ConnectionList;
+ }
+
+private:
+ // Structures used for the AD callback wrappers.
+ struct GetConnectionPointContainer_Args
+ {
+ ConnectionPoint *pThis;
+ IConnectionPointContainer **ppCPC;
+ };
+
+ struct Advise_Args
+ {
+ ConnectionPoint *pThis;
+ IUnknown *pUnk;
+ DWORD *pdwCookie;
+ };
+
+ struct Unadvise_Args
+ {
+ ConnectionPoint *pThis;
+ DWORD dwCookie;
+ };
+
+ // Worker methods.
+ void AdviseWorker(IUnknown *pUnk, DWORD *pdwCookie);
+ void UnadviseWorker( DWORD dwCookie );
+ IConnectionPointContainer *GetConnectionPointContainerWorker();
+
+ // AD callback wrappers.
+ static void GetConnectionPointContainer_Wrapper(LPVOID ptr);
+ static void Advise_Wrapper(LPVOID ptr);
+ static void Unadvise_Wrapper(LPVOID ptr);
+
+ // Helper methods.
+ void SetupEventMethods();
+ MethodDesc *FindProviderMethodDesc( MethodDesc *pEventMethodDesc, EnumEventMethods MethodType );
+ void InvokeProviderMethod( OBJECTREF pProvider, OBJECTREF pSubscriber, MethodDesc *pProvMethodDesc, MethodDesc *pEventMethodDesc );
+ void InsertWithLock(ConnectionCookie* pConCookie);
+ void FindAndRemoveWithLock(ConnectionCookie* pConCookie);
+ ConnectionCookie* FindWithLock(DWORD idOfCookie);
+
+ ComCallWrapper* m_pOwnerWrap;
+ GUID m_rConnectionIID;
+ MethodTable* m_pTCEProviderMT;
+ MethodTable* m_pEventItfMT;
+ Crst m_Lock;
+ CONNECTIONCOOKIELIST m_ConnectionList;
+ EventMethodInfo* m_apEventMethods;
+ int m_NumEventMethods;
+ ULONG m_cbRefCount;
+ ConnectionCookie* m_pLastInserted;
+
+ const static DWORD idUpperLimit = 0xFFFFFFFF;
+};
+
+// Enumeration of connection points.
+class ConnectionPointEnum : IEnumConnectionPoints
+{
+public:
+ // Encapsulate CrstHolder, so that clients of our lock don't have to know the
+ // details of its implementation.
+ class LockHolder : public CrstHolder
+ {
+ public:
+ LockHolder(ConnectionPointEnum *pCP) : CrstHolder(&pCP->m_Lock)
+ {
+ WRAPPER_NO_CONTRACT;
+ }
+ };
+
+ ConnectionPointEnum(ComCallWrapper *pOwnerWrap, CQuickArray<ConnectionPoint*> *pCPList);
+ ~ConnectionPointEnum();
+
+ HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
+ ULONG __stdcall AddRef();
+ ULONG __stdcall Release();
+
+ HRESULT __stdcall Next(ULONG cConnections, IConnectionPoint **ppCP, ULONG *pcFetched);
+ HRESULT __stdcall Skip(ULONG cConnections);
+ HRESULT __stdcall Reset();
+ HRESULT __stdcall Clone(IEnumConnectionPoints **ppEnum);
+
+private:
+ ComCallWrapper* m_pOwnerWrap;
+ CQuickArray<ConnectionPoint*>* m_pCPList;
+ UINT m_CurrPos;
+ ULONG m_cbRefCount;
+ Crst m_Lock;
+};
+
+// Enumeration of connections.
+class ConnectionEnum : IEnumConnections
+{
+public:
+ ConnectionEnum(ConnectionPoint *pConnectionPoint);
+ ~ConnectionEnum();
+
+ HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
+ ULONG __stdcall AddRef();
+ ULONG __stdcall Release();
+
+ HRESULT __stdcall Next(ULONG cConnections, CONNECTDATA* rgcd, ULONG *pcFetched);
+ HRESULT __stdcall Skip(ULONG cConnections);
+ HRESULT __stdcall Reset();
+ HRESULT __stdcall Clone(IEnumConnections **ppEnum);
+
+private:
+ ConnectionPoint* m_pConnectionPoint;
+ ConnectionCookie* m_CurrCookie;
+ ULONG m_cbRefCount;
+};