summaryrefslogtreecommitdiff
path: root/src/inc/legacyactivationshim.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/inc/legacyactivationshim.h')
-rw-r--r--src/inc/legacyactivationshim.h1382
1 files changed, 1382 insertions, 0 deletions
diff --git a/src/inc/legacyactivationshim.h b/src/inc/legacyactivationshim.h
new file mode 100644
index 0000000000..4d8eaa5dd9
--- /dev/null
+++ b/src/inc/legacyactivationshim.h
@@ -0,0 +1,1382 @@
+// 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.
+//
+// LegacyActivationShim.h
+//
+// This file allows simple migration from .NET Runtime v2 Host Activation APIs
+// to the .NET Runtime v4 Host Activation APIs through simple shim functions.
+
+#ifndef __LEGACYACTIVATIONSHIM_H__
+#define __LEGACYACTIVATIONSHIM_H__
+
+#pragma warning(push)
+#pragma warning(disable:4127) // warning C4127: conditional expression is constant
+ // caused by IfHrFailRet's while(0) code.
+#pragma warning(disable:4917) // a GUID can only be associated with a class, interface or namespace
+#pragma warning(disable:4191) // 'reinterpret_cast' : unsafe conversion from 'FARPROC' to 'XXX'
+
+#ifdef _MANAGED
+// We are compiling Managed C++, switch to native code then (and store current managed/native status on the stack)
+#pragma managed(push, off)
+#endif //_MANAGED
+
+#include "mscoree.h"
+#include "metahost.h"
+
+#include "wchar.h"
+
+#include "corerror.h"
+
+// To minimize how much we perturb sources that we are included in, we make sure that
+// all macros we define/redefine are restored at the end of the header.
+#pragma push_macro("IfHrFailRet")
+#pragma push_macro("IfHrFailRetFALSE")
+#pragma push_macro("IfHrFailRetVOID")
+
+// ---IfHrFailRet------------------------------------------------------------------------------------
+#undef IfHrFailRet
+#undef IfHrFailRetFALSE
+#undef IfHrFailRetVOID
+#define IfHrFailRet(EXPR) do { hr = (EXPR); if(FAILED(hr)) { return (hr); } } while (0)
+#define IfHrFailRetFALSE(EXPR) do { HRESULT _hr_ = (EXPR); if(FAILED(_hr_)) { return false; } } while (0)
+#define IfHrFailRetVOID(EXPR) do { HRESULT _hr_ = (EXPR); if(FAILED(_hr_)) { return; } } while (0)
+
+#include "legacyactivationshimutil.h"
+
+// Use of deprecated APIs within LegacyActivationShim namespace will result in C4996 that we will
+// disable for our own use.
+#pragma warning(push)
+#pragma warning(disable:4996)
+// ---LEGACYACTIVATONSHIM NAMESPACE----------------------------------------------------------------
+namespace LegacyActivationShim
+{
+ // ---HELPERS----------------------------------------------------------------------------------
+#define GET_CLRMETAHOST(x) \
+ ICLRMetaHost *x = NULL; \
+ IfHrFailRet(Util::GetCLRMetaHost(&x))
+
+#define GET_CLRMETAHOSTPOLICY(x) \
+ ICLRMetaHostPolicy*x = NULL; \
+ IfHrFailRet(Util::GetCLRMetaHostPolicy(&x))
+
+#define GET_CLRINFO(x) \
+ ICLRRuntimeInfo *x = NULL; \
+ IfHrFailRet(Util::GetCLRRuntimeInfo(&x))
+
+#define LEGACY_API_PASS_THROUGH_STATIC(_name, _ret_type, _ret_value, _sig, _args) \
+ { \
+ hr = S_OK; \
+ _ret_value = ::_name _args; \
+ }
+
+#define LEGACY_API_PASS_THROUGH_STATIC_VOIDRET(_name, _sig, _args) \
+ { \
+ ::_name _args; \
+ }
+
+#define LEGACY_API_PASS_THROUGH_DELAYLOAD(_name, _ret_type, _ret_value, _sig, _args) \
+ { \
+ typedef _ret_type __stdcall t_FN _sig; \
+ Util::MscoreeFunctor<t_FN> FN; \
+ if (SUCCEEDED(hr = FN.Init(#_name))) { \
+ _ret_value = FN()_args; \
+ } \
+ }
+
+#define LEGACY_API_PASS_THROUGH_DELAYLOAD_VOIDRET(_name, _sig, _args) \
+ { \
+ typedef void __stdcall t_FN _sig; \
+ Util::MscoreeFunctor<t_FN> FN; \
+ if (SUCCEEDED(FN.Init(#_name))) { \
+ FN()_args; \
+ } \
+ }
+
+#ifndef LEGACY_ACTIVATION_SHIM_DELAY_LOAD
+#define CALL_LEGACY_API(_name, _sig, _args) \
+ LEGACY_API_PASS_THROUGH_STATIC(_name, HRESULT, hr, _sig, _args)
+#define CALL_LEGACY_API_VOIDRET(_name, _sig, _args) \
+ LEGACY_API_PASS_THROUGH_STATIC_VOIDRET(_name, _sig, _args)
+#else
+#define CALL_LEGACY_API(_name, _sig, _args) \
+ LEGACY_API_PASS_THROUGH_DELAYLOAD(_name, HRESULT, hr, _sig, _args)
+#define CALL_LEGACY_API_VOIDRET(_name, _sig, _args) \
+ LEGACY_API_PASS_THROUGH_DELAYLOAD_VOIDRET(_name, _sig, _args)
+#endif
+
+ // ---LEGACY SHIM FUNCTIONS--------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------------------
+ inline
+ HRESULT GetCORSystemDirectory(
+ __out_ecount(cchBuffer) LPWSTR pBuffer,
+ __in DWORD cchBuffer,
+ __out DWORD *pdwLength)
+ {
+ HRESULT hr = S_OK;
+
+ if (Util::HasNewActivationAPIs())
+ {
+ DWORD dwLengthDummy = cchBuffer;
+ if (pdwLength == NULL)
+ pdwLength = &dwLengthDummy;
+ else
+ *pdwLength = cchBuffer;
+
+ GET_CLRINFO(pInfo);
+ IfHrFailRet(pInfo->GetRuntimeDirectory(pBuffer, pdwLength));
+ }
+ else
+ {
+ CALL_LEGACY_API(GetCORSystemDirectory,
+ (LPWSTR pBuffer,
+ DWORD cchBuffer,
+ DWORD *pdwLength),
+ (pBuffer,
+ cchBuffer,
+ pdwLength));
+ }
+
+ return hr;
+ }
+
+ // --------------------------------------------------------------------------------------------
+ inline
+ HRESULT GetCORVersion(
+ __out_ecount(cchBuffer) LPWSTR pbBuffer,
+ __in DWORD cchBuffer,
+ __out DWORD *pdwLength)
+ {
+ HRESULT hr = S_OK;
+
+ if (Util::HasNewActivationAPIs())
+ {
+ DWORD dwLengthDummy = cchBuffer;
+ if (pdwLength == NULL)
+ pdwLength = &dwLengthDummy;
+ else
+ *pdwLength = cchBuffer;
+
+ GET_CLRINFO(pInfo);
+ IfHrFailRet(pInfo->GetVersionString(pbBuffer, pdwLength));
+ }
+ else
+ {
+ CALL_LEGACY_API(GetCORVersion,
+ (LPWSTR pbBuffer,
+ DWORD cchBuffer,
+ DWORD *pdwLength),
+ (pbBuffer,
+ cchBuffer,
+ pdwLength));
+
+ }
+
+ return hr;
+ }
+
+ // --------------------------------------------------------------------------------------------
+ inline
+ HRESULT GetFileVersion(
+ __in LPCWSTR szFileName,
+ __out_ecount(cchBuffer) LPWSTR szBuffer,
+ __in DWORD cchBuffer,
+ __out DWORD *pdwLength)
+ {
+ HRESULT hr = S_OK;
+
+ if (Util::HasNewActivationAPIs())
+ {
+ DWORD dwLengthDummy = cchBuffer;
+ if (pdwLength == NULL)
+ pdwLength = &dwLengthDummy;
+ else
+ *pdwLength = cchBuffer;
+
+ GET_CLRMETAHOST(pMH);
+ IfHrFailRet(pMH->GetVersionFromFile(szFileName, szBuffer, pdwLength));
+ }
+ else
+ {
+ CALL_LEGACY_API(GetFileVersion,
+ (LPCWSTR szFileName,
+ LPWSTR szBuffer,
+ DWORD cchBuffer,
+ DWORD *pdwLength),
+ (szFileName,
+ szBuffer,
+ cchBuffer,
+ pdwLength));
+ }
+
+ return hr;
+ }
+
+ // --------------------------------------------------------------------------------------------
+ inline
+ HRESULT GetCORRequiredVersion(
+ __out_ecount(cchBuffer) LPWSTR pBuffer,
+ __in DWORD cchBuffer,
+ __out DWORD *pdwLength)
+ {
+ HRESULT hr = S_OK;
+
+ if (Util::HasNewActivationAPIs())
+ {
+ DWORD dwLengthDummy = cchBuffer;
+ if (pdwLength == NULL)
+ pdwLength = &dwLengthDummy;
+ else
+ *pdwLength = cchBuffer;
+
+ IfHrFailRet(Util::GetConfigImageVersion(pBuffer, pdwLength));
+ }
+ else
+ {
+ CALL_LEGACY_API(GetCORRequiredVersion,
+ (LPWSTR pBuffer,
+ DWORD cchBuffer,
+ DWORD *pdwLength),
+ (pBuffer,
+ cchBuffer,
+ pdwLength));
+ }
+
+ return hr;
+ }
+
+ // --------------------------------------------------------------------------------------------
+ // This API is the one exception that we don't have fully equivalent functionality for
+ // in the new APIs. Specifically, we do not have the runtimeInfoFlags equivalent that
+ // allows platform differentiation. As such, we just send the call to the legacy API,
+ // which does not bind (thankfully) and so we do not cap this specific API to Whidbey.
+ inline
+ HRESULT GetRequestedRuntimeInfo(
+ __in_opt LPCWSTR pExe,
+ __in_opt LPCWSTR pwszVersion,
+ __in_opt LPCWSTR pConfigurationFile,
+ __in DWORD startupFlags,
+ __in DWORD runtimeInfoFlags,
+ __out_ecount(dwDirectory) LPWSTR pDirectory,
+ __in DWORD dwDirectory,
+ __out DWORD *pdwDirectoryLength,
+ __out_ecount(cchBuffer) LPWSTR pVersion,
+ __in DWORD cchBuffer,
+ __out DWORD *pdwLength)
+ {
+ HRESULT hr = S_OK;
+
+ CALL_LEGACY_API(GetRequestedRuntimeInfo,
+ (LPCWSTR pExe,
+ LPCWSTR pwszVersion,
+ LPCWSTR pConfigurationFile,
+ DWORD startupFlags,
+ DWORD runtimeInfoFlags,
+ LPWSTR pDirectory,
+ DWORD dwDirectory,
+ DWORD *pdwDirectoryLength,
+ LPWSTR pVersion,
+ DWORD cchBuffer,
+ DWORD *pdwLength),
+ (pExe,
+ pwszVersion,
+ pConfigurationFile,
+ startupFlags,
+ runtimeInfoFlags,
+ pDirectory,
+ dwDirectory,
+ pdwDirectoryLength,
+ pVersion,
+ cchBuffer,
+ pdwLength));
+
+ return hr;
+ }
+
+ // --------------------------------------------------------------------------------------------
+ inline
+ HRESULT GetRequestedRuntimeVersion(
+ __in LPWSTR pExe,
+ __out_ecount(cchBuffer) LPWSTR pVersion,
+ __in DWORD cchBuffer,
+ __out DWORD *pdwLength)
+ {
+ HRESULT hr = S_OK;
+
+ if (Util::HasNewActivationAPIs())
+ {
+ DWORD dwLengthDummy = cchBuffer;
+ if (pdwLength == NULL)
+ pdwLength = &dwLengthDummy;
+ else
+ *pdwLength = cchBuffer;
+
+ GET_CLRMETAHOSTPOLICY(pMHP);
+ ICLRRuntimeInfo *pInfo = NULL;
+ IfHrFailRet(pMHP->GetRequestedRuntime(
+ METAHOST_POLICY_USE_PROCESS_IMAGE_PATH,
+ pExe,
+ NULL, // config stream
+ pVersion,
+ pdwLength,
+ NULL, // image version str
+ NULL, // image version len
+ NULL,
+ IID_ICLRRuntimeInfo,
+ reinterpret_cast<LPVOID*>(&pInfo)));// ppRuntime
+ Util::ReleaseHolder<ICLRRuntimeInfo*> hInfo(pInfo);
+ }
+ else
+ {
+ CALL_LEGACY_API(GetRequestedRuntimeVersion,
+ (LPWSTR pExe,
+ LPWSTR pVersion,
+ DWORD cchBuffer,
+ DWORD *pdwLength),
+ (pExe,
+ pVersion,
+ cchBuffer,
+ pdwLength));
+ }
+
+ return hr;
+ }
+
+ // --------------------------------------------------------------------------------------------
+ inline
+ HRESULT CorBindToRuntimeHost(
+ LPCWSTR pwszVersion,
+ LPCWSTR pwszBuildFlavor,
+ LPCWSTR pwszHostConfigFile,
+ VOID* pReserved,
+ DWORD startupFlags,
+ REFCLSID rclsid,
+ REFIID riid,
+ LPVOID FAR *ppv)
+ {
+ HRESULT hr = S_OK;
+
+ if (Util::HasNewActivationAPIs())
+ {
+ IStream *pConfigStream = NULL;
+ Util::ReleaseHolder<IStream*> hConfigStream;
+ if (pwszHostConfigFile != NULL)
+ {
+ IfHrFailRet(Util::CreateIStreamFromFile(pwszHostConfigFile, &pConfigStream));
+ hConfigStream.Assign(pConfigStream);
+ }
+
+ WCHAR wszVersionLocal[512];
+ DWORD cchVersionLocal = 512;
+ if (pwszVersion != NULL)
+ wcsncpy_s(&wszVersionLocal[0], cchVersionLocal, pwszVersion, _TRUNCATE);
+
+ ICLRRuntimeInfo *pInfo = NULL;
+ IfHrFailRet(Util::GetCLRRuntimeInfo(
+ &pInfo,
+ NULL,
+ pConfigStream,
+ pwszVersion == NULL ? NULL : &wszVersionLocal[0],
+ pwszVersion == NULL ? NULL : &cchVersionLocal));
+
+ // We're intentionally ignoring the HRESULT return value, since CorBindToRuntimeEx
+ // always ignored these flags when a runtime had already been bound, and we need
+ // to emulate that behavior for when multiple calls to CorBindToRuntimeEx are made
+ // but with different startup flags (ICLRRuntimeInfo::SetDefaultStartupFlags will
+ // return E_INVALIDARG in the case that the runtime has already been started with
+ // different flags).
+ Util::AddStartupFlags(pInfo, pwszBuildFlavor, startupFlags, pwszHostConfigFile);
+
+ IfHrFailRet(pInfo->GetInterface(rclsid, riid, ppv));
+ }
+ else
+ {
+ CALL_LEGACY_API(CorBindToRuntimeHost,
+ (LPCWSTR pwszVersion,
+ LPCWSTR pwszBuildFlavor,
+ LPCWSTR pwszHostConfigFile,
+ VOID* pReserved,
+ DWORD startupFlags,
+ REFCLSID rclsid,
+ REFIID riid,
+ LPVOID FAR *ppv),
+ (pwszVersion,
+ pwszBuildFlavor,
+ pwszHostConfigFile,
+ pReserved,
+ startupFlags,
+ rclsid,
+ riid,
+ ppv));
+ }
+
+ return hr;
+ }
+
+ // --------------------------------------------------------------------------------------------
+ inline
+ HRESULT CorBindToRuntimeEx(
+ LPCWSTR pwszVersion,
+ LPCWSTR pwszBuildFlavor,
+ DWORD startupFlags,
+ REFCLSID rclsid,
+ REFIID riid,
+ LPVOID* ppv)
+ {
+ HRESULT hr = S_OK;
+
+ if (Util::HasNewActivationAPIs())
+ {
+ WCHAR wszVersionLocal[512];
+ DWORD cchVersionLocal = 512;
+ if (pwszVersion != NULL)
+ wcsncpy_s(&wszVersionLocal[0], cchVersionLocal, pwszVersion, _TRUNCATE);
+
+ ICLRRuntimeInfo *pInfo = NULL;
+ IfHrFailRet(Util::GetCLRRuntimeInfo(
+ &pInfo,
+ NULL, // exe path
+ NULL, // config stream
+ pwszVersion == NULL ? NULL : &wszVersionLocal[0],
+ pwszVersion == NULL ? NULL : &cchVersionLocal));
+
+ // We're intentionally ignoring the HRESULT return value, since CorBindToRuntimeEx
+ // always ignored these flags when a runtime had already been bound, and we need
+ // to emulate that behavior for when multiple calls to CorBindToRuntimeEx are made
+ // but with different startup flags (ICLRRuntimeInfo::SetDefaultStartupFlags will
+ // return E_INVALIDARG in the case that the runtime has already been started with
+ // different flags).
+ Util::AddStartupFlags(pInfo, pwszBuildFlavor, startupFlags, NULL);
+
+ IfHrFailRet(pInfo->GetInterface(rclsid, riid, ppv));
+ }
+ else
+ {
+ CALL_LEGACY_API(CorBindToRuntimeEx,
+ (LPCWSTR pwszVersion,
+ LPCWSTR pwszBuildFlavor,
+ DWORD startupFlags,
+ REFCLSID rclsid,
+ REFIID riid,
+ LPVOID* ppv),
+ (pwszVersion,
+ pwszBuildFlavor,
+ startupFlags,
+ rclsid,
+ riid,
+ ppv));
+ }
+
+ return hr;
+ }
+
+ // --------------------------------------------------------------------------------------------
+ inline
+ HRESULT CorBindToRuntimeByCfg(
+ IStream* pCfgStream,
+ DWORD reserved,
+ DWORD startupFlags,
+ REFCLSID rclsid,
+ REFIID riid,
+ LPVOID* ppv)
+ {
+ HRESULT hr = S_OK;
+
+ if (Util::HasNewActivationAPIs())
+ {
+ // The legacy CorBindToRuntimeByCfg picks up startup flags from both the config stream and
+ // application config file if it is present. For simplicity, we ignore the app config here.
+ ICLRRuntimeInfo *pInfo = NULL;
+ IfHrFailRet(Util::GetCLRRuntimeInfo(
+ &pInfo,
+ NULL, // exe path
+ pCfgStream));
+
+ // We're intentionally ignoring the HRESULT return value, since CorBindToRuntimeEx
+ // always ignored these flags when a runtime had already been bound, and we need
+ // to emulate that behavior for when multiple calls to CorBindToRuntimeEx are made
+ // but with different startup flags (ICLRRuntimeInfo::SetDefaultStartupFlags will
+ // return E_INVALIDARG in the case that the runtime has already been started with
+ // different flags).
+ Util::AddStartupFlags(pInfo, NULL, startupFlags, NULL);
+
+ IfHrFailRet(pInfo->GetInterface(rclsid, riid, ppv));
+ }
+ else
+ {
+ CALL_LEGACY_API(CorBindToRuntimeByCfg,
+ (IStream* pCfgStream,
+ DWORD reserved,
+ DWORD startupFlags,
+ REFCLSID rclsid,
+ REFIID riid,
+ LPVOID* ppv),
+ (pCfgStream,
+ reserved,
+ startupFlags,
+ rclsid,
+ riid,
+ ppv));
+ }
+
+ return hr;
+ }
+
+ // --------------------------------------------------------------------------------------------
+ inline
+ HRESULT CorBindToRuntime(
+ LPCWSTR pwszVersion,
+ LPCWSTR pwszBuildFlavor,
+ REFCLSID rclsid,
+ REFIID riid,
+ LPVOID* ppv)
+ {
+ HRESULT hr = S_OK;
+
+ if (Util::HasNewActivationAPIs())
+ {
+ WCHAR wszVersionLocal[512];
+ DWORD cchVersionLocal = 512;
+ if (pwszVersion != NULL)
+ wcsncpy_s(&wszVersionLocal[0], cchVersionLocal, pwszVersion, _TRUNCATE);
+
+ ICLRRuntimeInfo *pInfo = NULL;
+ IfHrFailRet(Util::GetCLRRuntimeInfo(
+ &pInfo,
+ NULL, // exe path
+ NULL, // config stream
+ pwszVersion == NULL ? NULL : &wszVersionLocal[0],
+ pwszVersion == NULL ? NULL : &cchVersionLocal));
+
+ // CorBindToRuntime has its special default flags
+ //
+ // We're intentionally ignoring the HRESULT return value, since CorBindToRuntimeEx
+ // always ignored these flags when a runtime had already been bound, and we need
+ // to emulate that behavior for when multiple calls to CorBindToRuntimeEx are made
+ // but with different startup flags (ICLRRuntimeInfo::SetDefaultStartupFlags will
+ // return E_INVALIDARG in the case that the runtime has already been started with
+ // different flags).
+ Util::AddStartupFlags(pInfo, NULL, STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST, NULL);
+
+ IfHrFailRet(pInfo->GetInterface(rclsid, riid, ppv));
+ }
+ else
+ {
+ CALL_LEGACY_API(CorBindToRuntime,
+ (LPCWSTR pwszVersion,
+ LPCWSTR pwszBuildFlavor,
+ REFCLSID rclsid,
+ REFIID riid,
+ LPVOID* ppv),
+ (pwszVersion,
+ pwszBuildFlavor,
+ rclsid,
+ riid,
+ ppv));
+ }
+
+ return hr;
+ }
+
+ // --------------------------------------------------------------------------------------------
+ inline
+ HRESULT CorBindToCurrentRuntime(
+ LPCWSTR pwszFileName,
+ REFCLSID rclsid,
+ REFIID riid,
+ LPVOID FAR *ppv)
+ {
+ HRESULT hr = S_OK;
+
+ if (Util::HasNewActivationAPIs())
+ {
+ ICLRRuntimeInfo *pInfo = NULL;
+ IfHrFailRet(Util::GetCLRRuntimeInfo(
+ &pInfo,
+ pwszFileName));
+
+ IfHrFailRet(pInfo->GetInterface(rclsid, riid, ppv));
+ }
+ else
+ {
+ CALL_LEGACY_API(CorBindToCurrentRuntime,
+ (LPCWSTR pwszFileName,
+ REFCLSID rclsid,
+ REFIID riid,
+ LPVOID FAR *ppv),
+ (pwszFileName,
+ rclsid,
+ riid,
+ ppv));
+ }
+
+ return hr;
+ }
+
+ // --------------------------------------------------------------------------------------------
+ inline
+ HRESULT ClrCreateManagedInstance(
+ LPCWSTR pTypeName,
+ REFIID riid,
+ void **ppObject)
+ {
+ HRESULT hr = S_OK;
+
+ if (Util::HasNewActivationAPIs())
+ {
+ GET_CLRINFO(pInfo);
+ HRESULT (STDMETHODCALLTYPE *pfnClrCreateManagedInstance)(LPCWSTR typeName, REFIID riid, void ** ppv) = NULL;
+ IfHrFailRet(pInfo->GetProcAddress("ClrCreateManagedInstance", (LPVOID *)&pfnClrCreateManagedInstance));
+ IfHrFailRet(pfnClrCreateManagedInstance(pTypeName, riid, ppObject));
+ }
+ else
+ {
+ CALL_LEGACY_API(ClrCreateManagedInstance,
+ (LPCWSTR pTypeName,
+ REFIID riid,
+ void **ppObject),
+ (pTypeName,
+ riid,
+ ppObject));
+ }
+
+ return hr;
+ }
+
+ // --------------------------------------------------------------------------------------------
+ inline
+ HRESULT LoadLibraryShim(
+ LPCWSTR szDllName,
+ LPCWSTR szVersion,
+ LPVOID pvReserved,
+ HMODULE *phModDll)
+ {
+ HRESULT hr = S_OK;
+
+ if (Util::HasNewActivationAPIs())
+ {
+ Util::ReleaseHolder<ICLRRuntimeInfo*> hInfo;
+ ICLRRuntimeInfo *pInfo = NULL;
+
+ // Semantics of LoadLibraryShim is that a non-null version must match exactly.
+ if (szVersion != NULL)
+ {
+ GET_CLRMETAHOST(pMH);
+ IfHrFailRet(pMH->GetRuntime(szVersion, IID_ICLRRuntimeInfo, reinterpret_cast<LPVOID*>(&pInfo)));
+ hInfo.Assign(pInfo);
+ }
+ else
+ {
+ IfHrFailRet(Util::GetCLRRuntimeInfo(&pInfo));
+ }
+ IfHrFailRet(pInfo->LoadLibrary(szDllName, phModDll));
+ }
+ else
+ {
+ CALL_LEGACY_API(LoadLibraryShim,
+ (LPCWSTR szDllName,
+ LPCWSTR szVersion,
+ LPVOID pvReserved,
+ HMODULE *phModDll),
+ (szDllName,
+ szVersion,
+ pvReserved,
+ phModDll));
+ }
+
+ return hr;
+ }
+
+ // --------------------------------------------------------------------------------------------
+ inline
+ HRESULT CallFunctionShim(
+ LPCWSTR szDllName,
+ LPCSTR szFunctionName,
+ LPVOID lpvArgument1,
+ LPVOID lpvArgument2,
+ LPCWSTR szVersion,
+ LPVOID pvReserved)
+ {
+ HRESULT hr = S_OK;
+
+ if (Util::HasNewActivationAPIs())
+ {
+ HMODULE hMod = NULL;
+ HRESULT (__stdcall * pfn)(LPVOID,LPVOID) = NULL;
+
+ // Load library
+ IfHrFailRet(LegacyActivationShim::LoadLibraryShim(szDllName, szVersion, pvReserved, &hMod));
+
+ // NOTE: Legacy CallFunctionShim does not release HMODULE, leak to maintain compat
+ // Util::HMODULEHolder hModHolder(hMod);
+
+ // Find function.
+ pfn = (HRESULT (__stdcall *)(LPVOID,LPVOID))GetProcAddress(hMod, szFunctionName);
+ if (pfn == NULL)
+ return HRESULT_FROM_WIN32(GetLastError());
+
+ // Call it.
+ return pfn(lpvArgument1, lpvArgument2);
+ }
+ else
+ {
+ CALL_LEGACY_API(CallFunctionShim,
+ (LPCWSTR szDllName,
+ LPCSTR szFunctionName,
+ LPVOID lpvArgument1,
+ LPVOID lpvArgument2,
+ LPCWSTR szVersion,
+ LPVOID pvReserved),
+ (szDllName,
+ szFunctionName,
+ lpvArgument1,
+ lpvArgument2,
+ szVersion,
+ pvReserved));
+ }
+
+ return hr;
+ }
+
+ // --------------------------------------------------------------------------------------------
+ inline
+ HRESULT GetRealProcAddress(
+ LPCSTR pwszProcName,
+ VOID **ppv)
+ {
+ HRESULT hr = S_OK;
+
+ if (Util::HasNewActivationAPIs())
+ {
+ GET_CLRINFO(pInfo);
+ IfHrFailRet(pInfo->GetProcAddress(pwszProcName, ppv));
+ }
+ else
+ {
+ CALL_LEGACY_API(GetRealProcAddress,
+ (LPCSTR pwszProcName,
+ VOID **ppv),
+ (pwszProcName,
+ ppv));
+ }
+
+ return hr;
+ }
+
+ // --------------------------------------------------------------------------------------------
+ inline
+ void CorExitProcess(
+ int exitCode)
+ {
+#ifndef LEGACY_ACTIVATION_SHIM_DELAY_LOAD
+ ::CorExitProcess(exitCode);
+#else
+ typedef void __stdcall t_CorExitProcess(
+ int exitCode);
+
+ Util::MscoreeFunctor<t_CorExitProcess> FN;
+ if (FAILED(FN.Init("CorExitProcess")))
+ return;
+
+ FN()(exitCode);
+#endif
+ }
+
+// Define this method only if it is not yet defined as macro (see ndp\clr\src\inc\UtilCode.h).
+#ifndef LoadStringRC
+ // --------------------------------------------------------------------------------------------
+ inline
+ HRESULT LoadStringRC(
+ UINT nResourceID,
+ __out_ecount(nMax) LPWSTR szBuffer,
+ int nMax,
+ int fQuiet)
+ {
+ HRESULT hr = S_OK;
+
+ if (Util::HasNewActivationAPIs())
+ {
+ GET_CLRINFO(pInfo);
+ DWORD cchMax = static_cast<DWORD>(nMax);
+ IfHrFailRet(pInfo->LoadErrorString(nResourceID, szBuffer, &cchMax, -1));
+ }
+ else
+ {
+ CALL_LEGACY_API(LoadStringRC,
+ (UINT nResourceID,
+ LPWSTR szBuffer,
+ int nMax,
+ int fQuiet),
+ (nResourceID,
+ szBuffer,
+ nMax,
+ fQuiet));
+ }
+
+ return hr;
+ }
+#endif //LoadStringRC
+
+// Define this method only if it is not yet defined as macro (see ndp\clr\src\inc\UtilCode.h).
+#if !defined(LoadStringRCEx) && !defined(FEATURE_CORESYSTEM)
+ // --------------------------------------------------------------------------------------------
+ inline
+ HRESULT LoadStringRCEx(
+ LCID lcid,
+ UINT nResourceID,
+ __out_ecount(nMax) LPWSTR szBuffer,
+ int nMax,
+ int fQuiet,
+ int *pcwchUsed)
+ {
+ HRESULT hr = S_OK;
+
+ if (Util::HasNewActivationAPIs())
+ {
+ GET_CLRINFO(pInfo);
+ DWORD cchUsed = static_cast<DWORD>(nMax);
+ IfHrFailRet(pInfo->LoadErrorString(nResourceID, szBuffer, &cchUsed, lcid));
+ *pcwchUsed = cchUsed;
+ }
+ else
+ {
+ CALL_LEGACY_API(LoadStringRCEx,
+ (LCID lcid,
+ UINT nResourceID,
+ LPWSTR szBuffer,
+ int nMax,
+ int fQuiet,
+ int *pcwchUsed),
+ (lcid,
+ nResourceID,
+ szBuffer,
+ nMax,
+ fQuiet,
+ pcwchUsed));
+ }
+
+ return hr;
+ }
+#endif //LoadStringRCEx
+
+ // --------------------------------------------------------------------------------------------
+ inline
+ HRESULT LockClrVersion(
+ FLockClrVersionCallback hostCallback,
+ FLockClrVersionCallback *pBeginHostSetup,
+ FLockClrVersionCallback *pEndHostSetup)
+ {
+ HRESULT hr = S_OK;
+
+ CALL_LEGACY_API(LockClrVersion,
+ (FLockClrVersionCallback hostCallback,
+ FLockClrVersionCallback *pBeginHostSetup,
+ FLockClrVersionCallback *pEndHostSetup),
+ (hostCallback,
+ pBeginHostSetup,
+ pEndHostSetup));
+
+ return hr;
+ }
+
+ // --------------------------------------------------------------------------------------------
+ inline
+ HRESULT CreateDebuggingInterfaceFromVersion(
+ int nDebuggerVersion,
+ LPCWSTR szDebuggeeVersion,
+ IUnknown ** ppCordb)
+ {
+ HRESULT hr = S_OK;
+
+ CALL_LEGACY_API(CreateDebuggingInterfaceFromVersion,
+ (int nDebuggerVersion,
+ LPCWSTR szDebuggeeVersion,
+ IUnknown ** ppCordb),
+ (nDebuggerVersion,
+ szDebuggeeVersion,
+ ppCordb));
+
+ return hr;
+ }
+
+ // --------------------------------------------------------------------------------------------
+ inline
+ HRESULT GetVersionFromProcess(
+ __in HANDLE hProcess,
+ __out_ecount(cchBuffer) LPWSTR pVersion,
+ __in DWORD cchBuffer,
+ __out DWORD *pdwLength)
+ {
+ HRESULT hr = S_OK;
+
+ CALL_LEGACY_API(GetVersionFromProcess,
+ (HANDLE hProcess,
+ LPWSTR pVersion,
+ DWORD cchBuffer,
+ DWORD *pdwLength),
+ (hProcess,
+ pVersion,
+ cchBuffer,
+ pdwLength));
+
+ return hr;
+ }
+
+ // --------------------------------------------------------------------------------------------
+// CoInitializeEE is declared in cor.h, define it only if explicitly requested
+#ifdef LEGACY_ACTIVATION_SHIM_DEFINE_CoInitializeEE
+ inline
+ HRESULT CoInitializeEE(DWORD flags)
+ {
+ HRESULT hr = S_OK;
+
+ if (Util::HasNewActivationAPIs())
+ {
+ GET_CLRINFO(pInfo);
+ HRESULT (* pfnCoInitializeEE)(DWORD);
+ IfHrFailRet(pInfo->GetProcAddress("CoInitializeEE", (LPVOID *)&pfnCoInitializeEE));
+ return (*pfnCoInitializeEE)(flags);
+ }
+ else
+ {
+ CALL_LEGACY_API(CoInitializeEE,
+ (DWORD flags),
+ (flags));
+ }
+
+ return hr;
+ }
+
+ inline
+ VOID CoUninitializeEE(BOOL flags)
+ {
+ if (Util::HasNewActivationAPIs())
+ {
+ ICLRRuntimeInfo *pInfo = NULL;
+ if (FAILED(Util::GetCLRRuntimeInfo(&pInfo)))
+ return;
+
+ VOID (* pfnCoUninitializeEE)(BOOL);
+ if (FAILED(pInfo->GetProcAddress("CoUninitializeEE", (LPVOID *)&pfnCoUninitializeEE)))
+ return;
+
+ (*pfnCoUninitializeEE)(flags);
+ }
+ else
+ {
+ CALL_LEGACY_API_VOIDRET(CoUninitializeEE,
+ (BOOL flags),
+ (flags));
+ }
+ }
+
+ inline
+ HRESULT CoInitializeCor(DWORD flags)
+ {
+ HRESULT hr = S_OK;
+
+ if (Util::HasNewActivationAPIs())
+ {
+ GET_CLRINFO(pInfo);
+ HRESULT (* pfnCoInitializeCor)(DWORD);
+ IfHrFailRet(pInfo->GetProcAddress("CoInitializeCor", (LPVOID *)&pfnCoInitializeCor));
+ return (*pfnCoInitializeCor)(flags);
+ }
+ else
+ {
+ CALL_LEGACY_API(CoInitializeCor,
+ (DWORD flags),
+ (flags));
+ }
+
+ return hr;
+ }
+
+ inline
+ VOID CoUninitializeCor()
+ {
+ if (Util::HasNewActivationAPIs())
+ {
+ ICLRRuntimeInfo *pInfo = NULL;
+ if (FAILED(Util::GetCLRRuntimeInfo(&pInfo)))
+ return;
+
+ VOID (* pfnCoUninitializeCor)();
+ if (FAILED(pInfo->GetProcAddress("CoUninitializeCor", (LPVOID *)&pfnCoUninitializeCor)))
+ return;
+
+ (*pfnCoUninitializeCor)();
+ }
+ else
+ {
+ CALL_LEGACY_API_VOIDRET(CoUninitializeCor,
+ (VOID),
+ ());
+ }
+ }
+
+#endif //LEGACY_ACTIVATION_SHIM_DEFINE_CoInitializeEE
+
+ // --------------------------------------------------------------------------------------------
+// CoEEShutDownCOM is declared in cor.h, define it only if explicitly requested
+#ifdef LEGACY_ACTIVATION_SHIM_DEFINE_CoEEShutDownCOM
+ inline
+ void CoEEShutDownCOM()
+ {
+ if (Util::HasNewActivationAPIs())
+ {
+ ICLRRuntimeInfo *pInfo = NULL;
+ IfHrFailRetVOID(Util::GetCLRRuntimeInfo(&pInfo));
+ void (* pfnCoEEShutDownCOM)();
+ IfHrFailRetVOID(pInfo->GetProcAddress("CoEEShutDownCOM", (LPVOID *)&pfnCoEEShutDownCOM));
+ (*pfnCoEEShutDownCOM)();
+ }
+ else
+ {
+ CALL_LEGACY_API_VOIDRET(CoEEShutDownCOM,
+ (),
+ ());
+ }
+
+ return;
+ }
+#endif //LEGACY_ACTIVATION_SHIM_DEFINE_CoEEShutDownCOM
+
+ // ---StrongName Function Helpers--------------------------------------------------------------
+#if !defined(LEGACY_ACTIVATION_SHIM_DELAY_LOAD) && defined(__STRONG_NAME_H)
+#define LEGACY_STRONGNAME_API_PASS_THROUGH(_name, _ret_type, _ret_value, _sig, _args) \
+ LEGACY_API_PASS_THROUGH_STATIC(_name, _ret_type, _ret_value, _sig, _args)
+#define LEGACY_STRONGNAME_API_PASS_THROUGH_VOIDRET(_name, _sig, _args) \
+ LEGACY_API_PASS_THROUGH_STATIC_VOIDRET(_name, _sig, _args)
+#else //defined(LEGACY_ACTIVATION_SHIM_DELAY_LOAD) || !defined(__STRONG_NAME_H)
+#define LEGACY_STRONGNAME_API_PASS_THROUGH(_name, _ret_type, _ret_value, _sig, _args) \
+ LEGACY_API_PASS_THROUGH_DELAYLOAD(_name, _ret_type, _ret_value, _sig, _args)
+#define LEGACY_STRONGNAME_API_PASS_THROUGH_VOIDRET(_name, _sig, _args) \
+ LEGACY_API_PASS_THROUGH_DELAYLOAD_VOIDRET(_name, _sig, _args)
+#endif //defined(LEGACY_ACTIVATION_SHIM_DELAY_LOAD) || !defined(__STRONG_NAME_H)
+
+// Defines a method that just delegates a call to the right runtime, this one is for SN APIs that
+// return HRESULT.
+#define PASS_THROUGH_IMPL_HRESULT(_name, _signature, _args) \
+ inline \
+ HRESULT _name##_signature \
+ { \
+ HRESULT hr = S_OK; \
+ if (Util::HasNewActivationAPIs()) \
+ { \
+ ICLRStrongName *pSN = NULL; \
+ IfHrFailRet(Util::GetCLRStrongName(&pSN)); \
+ IfHrFailRet(pSN->_name _args); \
+ } \
+ else \
+ { \
+ LEGACY_STRONGNAME_API_PASS_THROUGH( \
+ _name, HRESULT, hr, _signature, _args); \
+ IfHrFailRet(hr); \
+ } \
+ return hr; \
+ }
+
+// Defines a method that just delegates a call to the right runtime, this one is for SN APIs that
+// return BOOL.
+#define PASS_THROUGH_IMPL_BOOLEAN(_name, _signature, _args) \
+ inline \
+ BOOL _name##_signature \
+ { \
+ HRESULT hr = S_OK; \
+ if (Util::HasNewActivationAPIs()) \
+ { \
+ ICLRStrongName *pSN = NULL; \
+ IfHrFailRetFALSE(Util::GetCLRStrongName(&pSN)); \
+ IfHrFailRetFALSE(pSN->_name _args); \
+ return TRUE; \
+ } \
+ else \
+ { \
+ BOOL fResult = TRUE; \
+ LEGACY_STRONGNAME_API_PASS_THROUGH( \
+ _name, BOOL, fResult, _signature, _args); \
+ IfHrFailRetFALSE(hr); \
+ return fResult; \
+ } \
+ }
+
+// Defines a method that just delegates a call to the right runtime, this one is for SN APIs that
+// return VOID.
+#define PASS_THROUGH_IMPL_VOID(_name, _signature, _args) \
+ inline \
+ VOID _name##_signature \
+ { \
+ HRESULT hr = S_OK; \
+ if (Util::HasNewActivationAPIs()) \
+ { \
+ ICLRStrongName *pSN = NULL; \
+ IfHrFailRetVOID(Util::GetCLRStrongName(&pSN)); \
+ IfHrFailRetVOID(pSN->_name _args); \
+ return; \
+ } \
+ else \
+ { \
+ LEGACY_STRONGNAME_API_PASS_THROUGH_VOIDRET( \
+ _name, _signature, _args); \
+ IfHrFailRetVOID(hr); \
+ return; \
+ } \
+ }
+
+ // ---StrongName functions---------------------------------------------------------------------
+
+PASS_THROUGH_IMPL_HRESULT(GetHashFromAssemblyFile,
+ (LPCSTR pszFilePath, unsigned int *piHashAlg, BYTE *pbHash, DWORD cchHash, DWORD *pchHash),
+ (pszFilePath, piHashAlg, pbHash, cchHash, pchHash));
+
+PASS_THROUGH_IMPL_HRESULT(GetHashFromAssemblyFileW,
+ (LPCWSTR pwzFilePath, unsigned int *piHashAlg, BYTE *pbHash, DWORD cchHash, DWORD *pchHash),
+ (pwzFilePath, piHashAlg, pbHash, cchHash, pchHash));
+
+PASS_THROUGH_IMPL_HRESULT(GetHashFromBlob,
+ (BYTE *pbBlob, DWORD cchBlob, unsigned int *piHashAlg, BYTE *pbHash, DWORD cchHash, DWORD *pchHash),
+ (pbBlob, cchBlob, piHashAlg, pbHash, cchHash, pchHash));
+
+PASS_THROUGH_IMPL_HRESULT(GetHashFromFile,
+ (LPCSTR pszFilePath, unsigned int *piHashAlg, BYTE *pbHash, DWORD cchHash, DWORD *pchHash),
+ (pszFilePath, piHashAlg, pbHash, cchHash, pchHash));
+
+PASS_THROUGH_IMPL_HRESULT(GetHashFromFileW,
+ (LPCWSTR pwzFilePath, unsigned int *piHashAlg, BYTE *pbHash, DWORD cchHash, DWORD *pchHash),
+ (pwzFilePath, piHashAlg, pbHash, cchHash, pchHash));
+
+PASS_THROUGH_IMPL_HRESULT(GetHashFromHandle,
+ (HANDLE hFile, unsigned int *piHashAlg, BYTE *pbHash, DWORD cchHash, DWORD *pchHash),
+ (hFile, piHashAlg, pbHash, cchHash, pchHash));
+
+PASS_THROUGH_IMPL_BOOLEAN(StrongNameCompareAssemblies,
+ (LPCWSTR pwzAssembly1, LPCWSTR pwzAssembly2, DWORD *pdwResult),
+ (pwzAssembly1, pwzAssembly2, pdwResult));
+
+PASS_THROUGH_IMPL_VOID(StrongNameFreeBuffer,
+ (BYTE *pbMemory),
+ (pbMemory));
+
+PASS_THROUGH_IMPL_BOOLEAN(StrongNameGetBlob,
+ (LPCWSTR pwzFilePath, BYTE *pbBlob, DWORD *pcbBlob),
+ (pwzFilePath, pbBlob, pcbBlob));
+
+PASS_THROUGH_IMPL_BOOLEAN(StrongNameGetBlobFromImage,
+ (BYTE *pbBase, DWORD dwLength, BYTE *pbBlob, DWORD *pcbBlob),
+ (pbBase, dwLength, pbBlob, pcbBlob));
+
+PASS_THROUGH_IMPL_BOOLEAN(StrongNameGetPublicKey,
+ (LPCWSTR pwzKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, BYTE **ppbPublicKeyBlob, ULONG *pcbPublicKeyBlob),
+ (pwzKeyContainer, pbKeyBlob, cbKeyBlob, ppbPublicKeyBlob, pcbPublicKeyBlob));
+
+PASS_THROUGH_IMPL_BOOLEAN(StrongNameHashSize,
+ (ULONG ulHashAlg, DWORD *pcbSize),
+ (ulHashAlg, pcbSize));
+
+PASS_THROUGH_IMPL_BOOLEAN(StrongNameKeyDelete,
+ (LPCWSTR pwzKeyContainer),
+ (pwzKeyContainer));
+
+PASS_THROUGH_IMPL_BOOLEAN(StrongNameKeyGen,
+ (LPCWSTR pwzKeyContainer, DWORD dwFlags, BYTE **ppbKeyBlob, ULONG *pcbKeyBlob),
+ (pwzKeyContainer, dwFlags, ppbKeyBlob, pcbKeyBlob));
+
+PASS_THROUGH_IMPL_BOOLEAN(StrongNameKeyGenEx,
+ (LPCWSTR pwzKeyContainer, DWORD dwFlags, DWORD dwKeySize, BYTE **ppbKeyBlob, ULONG *pcbKeyBlob),
+ (pwzKeyContainer, dwFlags, dwKeySize, ppbKeyBlob, pcbKeyBlob));
+
+PASS_THROUGH_IMPL_BOOLEAN(StrongNameKeyInstall,
+ (LPCWSTR pwzKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob),
+ (pwzKeyContainer, pbKeyBlob, cbKeyBlob));
+
+PASS_THROUGH_IMPL_BOOLEAN(StrongNameSignatureGeneration,
+ (LPCWSTR pwzFilePath, LPCWSTR pwzKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, BYTE **ppbSignatureBlob, ULONG *pcbSignatureBlob),
+ (pwzFilePath, pwzKeyContainer, pbKeyBlob, cbKeyBlob, ppbSignatureBlob, pcbSignatureBlob));
+
+PASS_THROUGH_IMPL_BOOLEAN(StrongNameSignatureGenerationEx,
+ (LPCWSTR wszFilePath, LPCWSTR wszKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, BYTE **ppbSignatureBlob, ULONG *pcbSignatureBlob, DWORD dwFlags),
+ (wszFilePath, wszKeyContainer, pbKeyBlob, cbKeyBlob, ppbSignatureBlob, pcbSignatureBlob, dwFlags));
+
+PASS_THROUGH_IMPL_BOOLEAN(StrongNameSignatureSize,
+ (BYTE *pbPublicKeyBlob, ULONG cbPublicKeyBlob, DWORD *pcbSize),
+ (pbPublicKeyBlob, cbPublicKeyBlob, pcbSize));
+
+PASS_THROUGH_IMPL_BOOLEAN(StrongNameSignatureVerification,
+ (LPCWSTR pwzFilePath, DWORD dwInFlags, DWORD *pdwOutFlags),
+ (pwzFilePath, dwInFlags, pdwOutFlags));
+
+PASS_THROUGH_IMPL_BOOLEAN(StrongNameSignatureVerificationEx,
+ (LPCWSTR pwzFilePath, BOOLEAN fForceVerification, BOOLEAN *pfWasVerified),
+ (pwzFilePath, fForceVerification, pfWasVerified));
+
+PASS_THROUGH_IMPL_BOOLEAN(StrongNameSignatureVerificationFromImage,
+ (BYTE *pbBase, DWORD dwLength, DWORD dwInFlags, DWORD *pdwOutFlags),
+ (pbBase, dwLength, dwInFlags, pdwOutFlags));
+
+PASS_THROUGH_IMPL_BOOLEAN(StrongNameTokenFromAssembly,
+ (LPCWSTR pwzFilePath, BYTE **ppbStrongNameToken, ULONG *pcbStrongNameToken),
+ (pwzFilePath, ppbStrongNameToken, pcbStrongNameToken));
+
+PASS_THROUGH_IMPL_BOOLEAN(StrongNameTokenFromAssemblyEx,
+ (LPCWSTR pwzFilePath, BYTE **ppbStrongNameToken, ULONG *pcbStrongNameToken, BYTE **ppbPublicKeyBlob, ULONG *pcbPublicKeyBlob),
+ (pwzFilePath, ppbStrongNameToken, pcbStrongNameToken, ppbPublicKeyBlob, pcbPublicKeyBlob));
+
+PASS_THROUGH_IMPL_BOOLEAN(StrongNameTokenFromPublicKey,
+ (BYTE *pbPublicKeyBlob, ULONG cbPublicKeyBlob, BYTE **ppbStrongNameToken, ULONG *pcbStrongNameToken),
+ (pbPublicKeyBlob, cbPublicKeyBlob, ppbStrongNameToken, pcbStrongNameToken));
+
+#undef PASS_THROUGH_IMPL_HRESULT
+#undef PASS_THROUGH_IMPL_BOOLEAN
+#undef PASS_THROUGH_IMPL_VOID
+
+// Defines a method that just delegates a call to the right runtime, this one is for SN APIs that
+// return BOOLEAN.
+#define WRAP_HRESULT_IMPL_BOOLEAN(_WrapperName, _name, _signature, _args) \
+ inline \
+ HRESULT _WrapperName##_signature \
+ { \
+ HRESULT hr = S_OK; \
+ if (Util::HasNewActivationAPIs()) \
+ { \
+ ICLRStrongName *pSN = NULL; \
+ IfHrFailRet(Util::GetCLRStrongName(&pSN)); \
+ return pSN->_name _args; \
+ } \
+ else \
+ { \
+ typedef BOOL __stdcall t_FN _signature; \
+ Util::MscoreeFunctor<t_FN> FN; \
+ IfHrFailRet(FN.Init(#_name)); \
+ if ((FN() _args)) \
+ { \
+ return S_OK; \
+ } \
+ else \
+ { /*@TODO: Static bind version, if necessary*/ \
+ typedef DWORD __stdcall t_FNStrongNameErrorInfo(void); \
+ Util::MscoreeFunctor<t_FNStrongNameErrorInfo> FNStrongNameErrorInfo; \
+ IfHrFailRet(FNStrongNameErrorInfo.Init("StrongNameErrorInfo")); \
+ HRESULT hrResult = (HRESULT)FNStrongNameErrorInfo() (); \
+ if (SUCCEEDED(hrResult)) \
+ { \
+ hrResult = E_FAIL; \
+ } \
+ return hrResult; \
+ } \
+ } \
+ }
+
+WRAP_HRESULT_IMPL_BOOLEAN(StrongNameHashSize_HRESULT,
+ StrongNameHashSize,
+ (ULONG ulHashAlg, DWORD *pcbSize),
+ (ulHashAlg, pcbSize));
+
+WRAP_HRESULT_IMPL_BOOLEAN(StrongNameTokenFromPublicKey_HRESULT,
+ StrongNameTokenFromPublicKey,
+ (BYTE *pbPublicKeyBlob, ULONG cbPublicKeyBlob, BYTE **ppbStrongNameToken, ULONG *pcbStrongNameToken),
+ (pbPublicKeyBlob, cbPublicKeyBlob, ppbStrongNameToken, pcbStrongNameToken));
+
+WRAP_HRESULT_IMPL_BOOLEAN(StrongNameSignatureSize_HRESULT,
+ StrongNameSignatureSize,
+ (BYTE *pbPublicKeyBlob, ULONG cbPublicKeyBlob, DWORD *pcbSize),
+ (pbPublicKeyBlob, cbPublicKeyBlob, pcbSize));
+
+WRAP_HRESULT_IMPL_BOOLEAN(StrongNameGetPublicKey_HRESULT,
+ StrongNameGetPublicKey,
+ (LPCWSTR pwzKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, BYTE **ppbPublicKeyBlob, ULONG *pcbPublicKeyBlob),
+ (pwzKeyContainer, pbKeyBlob, cbKeyBlob, ppbPublicKeyBlob, pcbPublicKeyBlob));
+
+WRAP_HRESULT_IMPL_BOOLEAN(StrongNameKeyInstall_HRESULT,
+ StrongNameKeyInstall,
+ (LPCWSTR pwzKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob),
+ (pwzKeyContainer, pbKeyBlob, cbKeyBlob));
+
+WRAP_HRESULT_IMPL_BOOLEAN(StrongNameSignatureGeneration_HRESULT,
+ StrongNameSignatureGeneration,
+ (LPCWSTR pwzFilePath, LPCWSTR pwzKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, BYTE **ppbSignatureBlob, ULONG *pcbSignatureBlob),
+ (pwzFilePath, pwzKeyContainer, pbKeyBlob, cbKeyBlob, ppbSignatureBlob, pcbSignatureBlob));
+
+WRAP_HRESULT_IMPL_BOOLEAN(StrongNameKeyGen_HRESULT,
+ StrongNameKeyGen,
+ (LPCWSTR pwzKeyContainer, DWORD dwFlags, BYTE **ppbKeyBlob, ULONG *pcbKeyBlob),
+ (pwzKeyContainer, dwFlags, ppbKeyBlob, pcbKeyBlob));
+
+#undef WRAP_HRESULT_IMPL_BOOLEAN
+
+// Defines a method that just delegates a call to the right runtime, this one is for ICLRStrongName2
+// APIs that return BOOLEAN.
+#define WRAP_HRESULT_IMPL_BOOLEAN(_WrapperName, _name, _signature, _args) \
+ inline \
+ HRESULT _WrapperName##_signature \
+ { \
+ HRESULT hr = S_OK; \
+ if (Util::HasNewActivationAPIs()) \
+ { \
+ ICLRStrongName2 *pSN = NULL; \
+ IfHrFailRet(Util::GetCLRStrongName2(&pSN)); \
+ return pSN->_name _args; \
+ } \
+ else \
+ { \
+ return E_FAIL; \
+ } \
+ }
+
+
+WRAP_HRESULT_IMPL_BOOLEAN(StrongNameGetPublicKeyEx_HRESULT,
+ StrongNameGetPublicKeyEx,
+ (LPCWSTR pwzKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, BYTE **ppbPublicKeyBlob, ULONG *pcbPublicKeyBlob, ULONG uHashAlgId, ULONG uReserved),
+ (pwzKeyContainer, pbKeyBlob, cbKeyBlob, ppbPublicKeyBlob, pcbPublicKeyBlob, uHashAlgId, uReserved));
+
+#undef WRAP_HRESULT_IMPL_BOOLEAN
+
+ inline
+ HRESULT ClrCoCreateInstance(
+ REFCLSID rclsid,
+ LPUNKNOWN pUnkOuter,
+ DWORD dwClsContext,
+ REFIID riid,
+ LPVOID * ppv)
+ {
+ HRESULT hr = S_OK;
+
+ if (Util::HasNewActivationAPIs() /*&& Util::IsCLSIDHostedByClr(rclsid)*/)
+ {
+ GET_CLRINFO(pInfo);
+ IfHrFailRet(pInfo->GetInterface(rclsid, riid, ppv));
+ }
+ else
+ {
+ IfHrFailRet(::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv));
+ }
+
+ return hr;
+ }
+}; // namespace LegacyActivationShim
+#pragma warning(pop) // Revert C4996 status
+
+#undef LEGACY_API_PASS_THROUGH_STATIC
+#undef LEGACY_API_PASS_THROUGH_STATIC_VOIDRET
+#undef LEGACY_API_PASS_THROUGH_DELAYLOAD
+#undef LEGACY_API_PASS_THROUGH_DELAYLOAD_VOIDRET
+#undef CALL_LEGACY_API
+#undef LEGACY_STRONGNAME_API_PASS_THROUGH
+#undef LEGACY_STRONGNAME_API_PASS_THROUGH_VOIDRET
+
+#undef LEGACY_ACTIVATION_SHIM_DEFAULT_PRODUCT_VER_HELPER_L
+#undef LEGACY_ACTIVATION_SHIM_DEFAULT_PRODUCT_VER_STR_L
+
+#pragma pop_macro("IfHrFailRetVOID")
+#pragma pop_macro("IfHrFailRetFALSE")
+#pragma pop_macro("IfHrFailRet")
+
+#ifdef _MANAGED
+// We are compiling Managed C++, restore previous managed/native status from the stack
+#pragma managed(pop)
+#endif //_MANAGED
+
+#pragma warning(pop)
+
+#endif // __LEGACYACTIVATIONSHIM_H__