summaryrefslogtreecommitdiff
path: root/src/inc/fusionbind.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/inc/fusionbind.h')
-rw-r--r--src/inc/fusionbind.h316
1 files changed, 316 insertions, 0 deletions
diff --git a/src/inc/fusionbind.h b/src/inc/fusionbind.h
new file mode 100644
index 0000000000..8628d3f9ce
--- /dev/null
+++ b/src/inc/fusionbind.h
@@ -0,0 +1,316 @@
+// 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.
+
+
+
+/*============================================================
+**
+** Header: FusionBind.hpp
+**
+** Purpose: Implements FusionBind (loader domain) architecture
+**
+**
+===========================================================*/
+#ifndef _FUSIONBIND_H
+#define _FUSIONBIND_H
+
+#ifndef FEATURE_FUSION
+#error FEATURE_FUSION is not enabled, please do not include fusionbind.h
+#endif
+
+#include <fusion.h>
+#include <fusionpriv.h>
+#include "metadata.h"
+#include "fusionsink.h"
+#include "utilcode.h"
+#include "loaderheap.h"
+#include "fusionsetup.h"
+#include "sstring.h"
+#include "ex.h"
+#ifdef PAL_STDCPP_COMPAT
+#include <type_traits>
+#else
+#include "clr_std/type_traits"
+#endif
+
+#include "binderngen.h"
+#include "clrprivbinding.h"
+
+class FusionBind
+{
+public:
+
+ //****************************************************************************************
+ //
+
+ static HRESULT GetVersion(__out_ecount(*pdwVersion) LPWSTR pVersion, __inout DWORD* pdwVersion);
+
+
+ //****************************************************************************************
+ //
+ // Creates a fusion context for the application domain. All ApplicationContext properties
+ // must be set in the AppDomain store prior to this call. Any changes or additions to the
+ // AppDomain store are ignored.
+ static HRESULT CreateFusionContext(LPCWSTR pzName, IApplicationContext** ppFusionContext);
+
+
+ //****************************************************************************************
+ //
+ // Loads an environmental value into the fusion context
+ static HRESULT AddEnvironmentProperty(__in LPCWSTR variable,
+ __in LPCWSTR pProperty,
+ IApplicationContext* pFusionContext);
+
+ //****************************************************************************************
+ //
+ static HRESULT SetupFusionContext(LPCWSTR szAppBase,
+ LPCWSTR szPrivateBin,
+ IApplicationContext** ppFusionContext);
+
+ // Starts remote load of an assembly. The thread is parked on
+ // an event waiting for fusion to report success or failure.
+ static HRESULT RemoteLoad(IApplicationContext * pFusionContext,
+ FusionSink* pSink,
+ IAssemblyName *pName,
+ IAssembly *pParentAssembly,
+ LPCWSTR pCodeBase,
+ IAssembly** ppIAssembly,
+ IHostAssembly** ppIHostAssembly,
+ IBindResult** ppNativeFusionAssembly,
+ BOOL fForIntrospectionOnly,
+ BOOL fSuppressSecurityChecks);
+
+ static HRESULT RemoteLoadModule(IApplicationContext * pFusionContext,
+ IAssemblyModuleImport* pModule,
+ FusionSink *pSink,
+ IAssemblyModuleImport** pResult);
+
+ static BOOL VerifyBindingStringW(LPCWSTR pwStr) {
+ WRAPPER_NO_CONTRACT;
+ if (wcschr(pwStr, '\\') ||
+ wcschr(pwStr, '/') ||
+ wcschr(pwStr, ':'))
+ return FALSE;
+
+ return TRUE;
+ }
+
+ static HRESULT VerifyBindingString(LPCSTR pName) {
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ INJECT_FAULT(return E_OUTOFMEMORY;);
+ }
+ CONTRACTL_END;
+
+ DWORD dwStrLen = WszMultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, pName, -1, NULL, NULL);
+ CQuickBytes qb;
+ LPWSTR pwStr = (LPWSTR) qb.AllocNoThrow(dwStrLen*sizeof(WCHAR));
+ if (!pwStr)
+ return E_OUTOFMEMORY;
+
+ if(!WszMultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, pName, -1, pwStr, dwStrLen))
+ return HRESULT_FROM_GetLastError();
+
+ if (VerifyBindingStringW(pwStr))
+ return S_OK;
+ else
+ return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
+ }
+
+ static void GetAssemblyManifestModulePath(IAssembly *pFusionAssembly, SString &result)
+ {
+ CONTRACTL
+ {
+ THROWS;
+ INJECT_FAULT(ThrowOutOfMemory());
+ }
+ CONTRACTL_END;
+
+ DWORD dwSize = 0;
+ LPWSTR buffer = NULL;
+ COUNT_T allocation = result.GetUnicodeAllocation();
+ if (allocation > 0) {
+ // pass in the buffer if we got one
+ dwSize = allocation + 1;
+ buffer = result.OpenUnicodeBuffer(allocation);
+ }
+ HRESULT hr = pFusionAssembly->GetManifestModulePath(buffer, &dwSize);
+ if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
+ {
+ if (buffer != NULL)
+ result.CloseBuffer(0);
+ buffer = result.OpenUnicodeBuffer(dwSize-1);
+ hr = pFusionAssembly->GetManifestModulePath(buffer, &dwSize);
+ }
+ if (buffer != NULL)
+ result.CloseBuffer((SUCCEEDED(hr) && dwSize >= 1) ? (dwSize-1) : 0);
+ IfFailThrow(hr);
+ }
+
+ static SString& GetAssemblyNameDisplayName(
+ IAssemblyName *pName,
+ SString &result,
+ DWORD flags = 0 /* default */)
+ {
+ CONTRACTL
+ {
+ GC_NOTRIGGER;
+ THROWS;
+ INJECT_FAULT(ThrowOutOfMemory());
+ }
+ CONTRACTL_END;
+
+ DWORD dwSize = 0;
+ LPWSTR buffer = NULL;
+ COUNT_T allocation = result.GetUnicodeAllocation();
+ if (allocation > 0)
+ {
+ // pass in the buffer if we got one
+ dwSize = allocation + 1;
+ buffer = result.OpenUnicodeBuffer(allocation);
+ }
+
+ HRESULT hr = pName->GetDisplayName(buffer, &dwSize, flags);
+ if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
+ {
+ if (buffer != NULL)
+ result.CloseBuffer(0);
+ buffer = result.OpenUnicodeBuffer(dwSize-1);
+ hr = pName->GetDisplayName(buffer, &dwSize, flags);
+ }
+
+ if (buffer != NULL)
+ {
+ result.CloseBuffer((SUCCEEDED(hr) && dwSize >= 1) ? (dwSize-1) : 0);
+ }
+
+ IfFailThrow(hr);
+ return result;
+ }
+
+ static BOOL GetAssemblyNameStringProperty(IAssemblyName *pName, DWORD property, SString &result)
+ {
+ CONTRACTL
+ {
+ THROWS;
+ INJECT_FAULT(ThrowOutOfMemory());
+ }
+ CONTRACTL_END;
+
+ DWORD dwSize = 0;
+ LPWSTR buffer = NULL;
+ COUNT_T allocation = result.GetUnicodeAllocation();
+ if (allocation > 0) {
+ // pass in the buffer if we got one
+ dwSize = (allocation + 1) * sizeof(WCHAR);
+ buffer = result.OpenUnicodeBuffer(allocation);
+ }
+ HRESULT hr = pName->GetProperty(property, (LPVOID)buffer, &dwSize);
+ if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
+ {
+ if (buffer != NULL)
+ result.CloseBuffer(0);
+ buffer = result.OpenUnicodeBuffer(dwSize/sizeof(WCHAR) - 1);
+ hr = pName->GetProperty(property, (LPVOID)buffer, &dwSize);
+ }
+ if (buffer != NULL)
+ result.CloseBuffer((SUCCEEDED(hr) && dwSize >= sizeof(WCHAR)) ? (dwSize/sizeof(WCHAR)-1) : 0);
+ if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
+ {
+ return FALSE;
+ }
+ IfFailThrow(hr);
+
+ return TRUE;
+ }
+
+ static BOOL GetApplicationContextStringProperty(IApplicationContext *pContext,
+ LPCWSTR property, SString &result)
+ {
+ CONTRACTL
+ {
+ THROWS;
+ INJECT_FAULT(ThrowOutOfMemory());
+ }
+ CONTRACTL_END;
+
+ DWORD dwSize = 0;
+ LPWSTR buffer = NULL;
+ COUNT_T allocation = result.GetUnicodeAllocation();
+ if (allocation > 0) {
+ // pass in the buffer if we got one
+ dwSize = (allocation + 1) * sizeof(WCHAR);
+ buffer = result.OpenUnicodeBuffer(allocation);
+ }
+ HRESULT hr = pContext->Get(property, (LPVOID)buffer, &dwSize, 0);
+ if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
+ {
+ if (buffer != NULL)
+ result.CloseBuffer(0);
+ buffer = result.OpenUnicodeBuffer(dwSize/sizeof(WCHAR) - 1);
+ hr = pContext->Get(property, (LPVOID)buffer, &dwSize, 0);
+ }
+ if (buffer != NULL)
+ result.CloseBuffer((SUCCEEDED(hr) && dwSize >= sizeof(WCHAR)) ? (dwSize/sizeof(WCHAR)-1) : 0);
+ if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
+ {
+ return FALSE;
+ }
+ IfFailThrow(hr);
+
+ return TRUE;
+ }
+
+ static BOOL GetApplicationContextDWORDProperty(IApplicationContext *pContext,
+ LPCWSTR property, DWORD *result)
+ {
+ CONTRACTL
+ {
+ THROWS;
+ INJECT_FAULT(return E_OUTOFMEMORY;);
+ }
+ CONTRACTL_END;
+
+ DWORD dwSize = sizeof(DWORD);
+ HRESULT hr = pContext->Get(property, result, &dwSize, 0);
+ if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
+ return FALSE;
+
+ IfFailThrow(hr);
+
+ return TRUE;
+ }
+
+ static void SetApplicationContextStringProperty(IApplicationContext *pContext, LPCWSTR property,
+ SString &value)
+ {
+ CONTRACTL
+ {
+ THROWS;
+ INJECT_FAULT(ThrowOutOfMemory());
+ }
+ CONTRACTL_END;
+
+ IfFailThrow(pContext->Set(property, (void *) value.GetUnicode(),
+ (value.GetCount()+1)*sizeof(WCHAR), 0));
+ }
+
+ static void SetApplicationContextDWORDProperty(IApplicationContext *pContext, LPCWSTR property,
+ DWORD value)
+ {
+ CONTRACTL
+ {
+ THROWS;
+ INJECT_FAULT(ThrowOutOfMemory());
+ }
+ CONTRACTL_END;
+
+ IfFailThrow(pContext->Set(property, &value, sizeof(value), 0));
+ }
+};
+
+#endif
+