summaryrefslogtreecommitdiff
path: root/src/vm/olecontexthelpers.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/olecontexthelpers.cpp')
-rw-r--r--src/vm/olecontexthelpers.cpp171
1 files changed, 171 insertions, 0 deletions
diff --git a/src/vm/olecontexthelpers.cpp b/src/vm/olecontexthelpers.cpp
new file mode 100644
index 0000000000..43dc318d78
--- /dev/null
+++ b/src/vm/olecontexthelpers.cpp
@@ -0,0 +1,171 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+
+#include "common.h"
+
+#ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT
+
+#include "mtx.h"
+#include "oletls.h"
+#include "contxt.h"
+#include "ctxtcall.h"
+
+HRESULT GetCurrentObjCtx(IUnknown **ppObjCtx)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ PRECONDITION(CheckPointer(ppObjCtx));
+#ifdef FEATURE_COMINTEROP
+ PRECONDITION(TRUE == g_fComStarted);
+#endif // FEATURE_COMINTEROP
+ }
+ CONTRACTL_END;
+
+ return CoGetObjectContext(IID_IUnknown, (void **)ppObjCtx);
+}
+
+//=====================================================================
+// LPVOID SetupOleContext()
+LPVOID SetupOleContext()
+{
+ CONTRACT (LPVOID)
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ ENTRY_POINT;
+ POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
+ }
+ CONTRACT_END;
+
+ IUnknown* pObjCtx = NULL;
+
+ BEGIN_ENTRYPOINT_VOIDRET;
+
+#ifdef FEATURE_COMINTEROP
+ if (g_fComStarted)
+ {
+ HRESULT hr = GetCurrentObjCtx(&pObjCtx);
+ if (hr == S_OK)
+ {
+ SOleTlsData* _pData = (SOleTlsData *) ClrTeb::GetOleReservedPtr();
+ if (_pData && _pData->pCurrentCtx == NULL)
+ {
+ _pData->pCurrentCtx = (CObjectContext*)pObjCtx; // no release !!!!
+ }
+ else
+ {
+ // We can't call SafeRelease here since that would transition
+ // to preemptive GC mode which is bad since SetupOleContext is called
+ // from places where we can't take a GC.
+ ULONG cbRef = pObjCtx->Release();
+ }
+ }
+ }
+#endif // FEATURE_COMINTEROP
+
+ END_ENTRYPOINT_VOIDRET;
+
+ RETURN pObjCtx;
+}
+
+//================================================================
+// LPVOID GetCurrentCtxCookie()
+LPVOID GetCurrentCtxCookie()
+{
+ CONTRACT (LPVOID)
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ SO_TOLERANT;
+ POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
+ }
+ CONTRACT_END;
+
+#ifdef FEATURE_COMINTEROP
+ // check if com is started
+ if (!g_fComStarted)
+ RETURN NULL;
+#endif // FEATURE_COMINTEROP
+
+ ULONG_PTR ctxptr = 0;
+
+ if (CoGetContextToken(&ctxptr) != S_OK)
+ ctxptr = 0;
+
+ RETURN (LPVOID)ctxptr;
+}
+
+//+-------------------------------------------------------------------------
+//
+// HRESULT GetCurrentThreadTypeNT5(THDTYPE* pType)
+//
+HRESULT GetCurrentThreadTypeNT5(THDTYPE* pType)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_TRIGGERS;
+ MODE_ANY;
+ SO_TOLERANT;
+ PRECONDITION(CheckPointer(pType));
+ }
+ CONTRACTL_END;
+
+ HRESULT hr = E_FAIL;
+
+ IObjectContext *pObjCurrCtx = (IObjectContext *)GetCurrentCtxCookie();
+ if(pObjCurrCtx)
+ {
+ GCX_PREEMP();
+
+ SafeComHolderPreemp<IComThreadingInfo> pThreadInfo;
+ hr = SafeQueryInterface(pObjCurrCtx, IID_IComThreadingInfo, (IUnknown **)&pThreadInfo);
+ if(hr == S_OK)
+ {
+ _ASSERTE(pThreadInfo);
+ hr = pThreadInfo->GetCurrentThreadType(pType);
+ }
+ }
+ return hr;
+}
+
+//+-------------------------------------------------------------------------
+//
+// HRESULT GetCurrentApartmentTypeNT5(APTTYPE* pType)
+//
+HRESULT GetCurrentApartmentTypeNT5(IObjectContext *pObjCurrCtx, APTTYPE* pType)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_TRIGGERS;
+ MODE_ANY;
+ PRECONDITION(CheckPointer(pType));
+ }
+ CONTRACTL_END;
+
+ HRESULT hr = E_FAIL;
+ if(pObjCurrCtx)
+ {
+ GCX_PREEMP();
+
+ SafeComHolderPreemp<IComThreadingInfo> pThreadInfo;
+ hr = SafeQueryInterface(pObjCurrCtx, IID_IComThreadingInfo, (IUnknown **)&pThreadInfo);
+ if(hr == S_OK)
+ {
+ _ASSERTE(pThreadInfo);
+ hr = pThreadInfo->GetCurrentApartmentType(pType);
+ }
+ }
+ return hr;
+}
+
+#endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
+